From a4cc3ad3504d634e379369862c9f9fd8eed379f3 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Thu, 16 May 2024 01:43:09 -0400 Subject: Add Jindrich Kubec's tools. --- jindroush/lib/adsk_di.cpp | 271 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 jindroush/lib/adsk_di.cpp (limited to 'jindroush/lib/adsk_di.cpp') diff --git a/jindroush/lib/adsk_di.cpp b/jindroush/lib/adsk_di.cpp new file mode 100644 index 0000000..b49bb9d --- /dev/null +++ b/jindroush/lib/adsk_di.cpp @@ -0,0 +1,271 @@ +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include "adsk_di.h" +#include "autil.h" +#include "cfile.h" + +BYTE di_crc( BYTE* pbt, int iLen ) +{ + WORD crc = 0; + + while( iLen-- ) + { + crc += *( pbt++ ); + if( crc >= 0x100 ) + crc -= 0xFF; + } + + return crc; +} + +CDi::CDi() : ADisk() +{ + #ifdef _MEMORY_DUMP_ + printf( "CDi constructed: %p\n", this ); + #endif +} + +CDi::~CDi() +{ + #ifdef _MEMORY_DUMP_ + printf( "CDi destructed: %p\n", this ); + #endif +} + +#ifndef __CDISK_NOLOAD__ +BOOL CDi::Load( char* szFname, BOOL bRepair, BOOL bRepairAuto ) +{ + m_iErrorCode = 0; + + CFile cf; + if ( !cf.Open( szFname ) ) + { + sprintf( m_szLastError, "DI: Can't open '%s'", szFname ); + m_iErrorCode = CDISK_ERROR_CANT_OPEN; + return FALSE; + } + + strcpy( m_szFname, szFname ); + + WORD wMagic = cf.readLEw(); + + if ( wMagic != 18756 ) //'DI' + { + sprintf( m_szLastError, "DI: File '%s' is not an DI file!", szFname ); + return FALSE; + } + + BYTE btVerLo = cf.readb(); + BYTE btVerHi = cf.readb(); + + if( ( btVerLo != 0x20 ) || ( btVerHi != 0x02 ) ) + { + sprintf( m_szLastError, "DI: The file '%s' has strange version!\n" + "This program can't work with it now.\n" + "Send the file for the analysis.", szFname ); + m_iErrorCode = CDI_FORMAT_VIOLATED; + return FALSE; + } + + int iMax = 200; + while( iMax-- ) + { + if( ! cf.readb() ) + break; + } + + if( !iMax ) + { + sprintf( m_szLastError, "DI: Runaway in header ('%s')", szFname ); + m_iErrorCode = CDI_FORMAT_VIOLATED; + return FALSE; + } + + //todo: this need the documentation! Is it number of sides? + //BYTE btUnk1 = + cf.readb(); + + BYTE btTracks = cf.readb(); + WORD wSectorsPerTrack = cf.readBEw(); + + //todo: are these the flags? + //WORD wUnk2 = + //cf.readBEw(); + BYTE btSides = cf.readb() + 1; + cf.readb(); + + WORD wSectorSize = cf.readBEw(); + + //todo: and what about this? + //BYTE btUnk3 = + cf.readb(); + + switch( wSectorSize ) + { + case 0x80: + case 0x100: + break; + + default: + { + sprintf( m_szLastError, "DI: Invalid sector size: %04X", wSectorSize ); + m_iErrorCode = CDI_FORMAT_VIOLATED; + return FALSE; + } + } + + DISK_GEOMETRY dg; + + dg.iSides = btSides; + dg.iTracks = btTracks; + dg.iSectorsPerTrack = wSectorsPerTrack; + dg.iBytesPerSector = wSectorSize; + + if ( !Format( &dg ) ) + return FALSE; + + BYTE abtBuff[ 0x100 ]; + memset( abtBuff, 0, 0x100 ); + + int iSectors = m_geometry.iSectors; + + BYTE* pBuf = new BYTE[ iSectors ]; + cf.Read( pBuf, iSectors ); + + BYTE* p = pBuf; + + for( int i = 0; i < iSectors; i++ ) + { + if( *p ) + { + int iSecSize = ( i < 3 ) ? 0x80 : wSectorSize; + + int iRead; + + cf.Read( abtBuff, iSecSize, &iRead ); + + if ( iRead != iSecSize ) + { + sprintf( m_szLastError, "DI: Read error. File truncated?" ); + delete [] pBuf; + cf.Close(); + m_iErrorCode = CDI_FORMAT_VIOLATED; + return FALSE; + } + + BYTE crc = di_crc( abtBuff, iSecSize ); + + if( *p != crc ) + { + sprintf( m_szLastError, "DI: Sector checksum failed: Sector %d Given: %02X Computed: %02X", i + 1, *p, crc ); + delete [] pBuf; + cf.Close(); + m_iErrorCode = CDI_FORMAT_VIOLATED; + return FALSE; + } + + WriteSector( i + 1, abtBuff ); + } + p++; + } + + delete [] pBuf; + + cf.Close(); + return TRUE; + +} + +#endif + +#ifdef __CDISK_SAVE__ + +char szDIhd[] = "Jindroush's DI class v1.00"; +//char szDIhd[] = "XL/ST-link 2.2.0› "; + +BOOL CDi::Save( char* szOutFile, BOOL bOverWrite ) +{ + if( ( m_geometry.iTracks > 0xFF ) || + ( m_geometry.iSectorsPerTrack > 0xFFFF ) || + ( m_geometry.iSides > 2 ) ) + { + sprintf( m_szLastError, "DI: Can't create such file! Is it possible? :-)" ); + return FALSE; + } + + CFile cf; + + if ( !bOverWrite && !access( szOutFile, F_OK ) ) + { + sprintf( m_szLastError, "DI: File already exists! '%s'", szOutFile ); + return FALSE; + } + + if ( !cf.Create( szOutFile ) ) + { + sprintf( m_szLastError, "DI: Can't create '%s'", szOutFile ); + return FALSE; + } + + cf.writeb( 'D' ); + cf.writeb( 'I' ); + cf.writeb( 0x20 ); + cf.writeb( 0x02 ); + + cf.Write( szDIhd, strlen( szDIhd ) + 1 ); + + cf.writeb( 1 ); + cf.writeb( m_geometry.iTracks ); + cf.writeBEw( m_geometry.iSectorsPerTrack ); + cf.writeb( m_geometry.iSides - 1 ); + cf.writeb( 0 ); + cf.writeBEw( m_geometry.iBytesPerSector ); + cf.writeb( 0 ); + + BYTE abtBuff[ 0x100 ]; + memset( abtBuff, 0, 0x100 ); + + BYTE* pBuf = new BYTE[ m_geometry.iSectors ]; + + for( int i = 0; i < m_geometry.iSectors; i++ ) + { + int iSecSize = ( i < 3 ) ? 0x80 : m_geometry.iBytesPerSector; + + ReadSector( abtBuff, i + 1 ); + pBuf[ i ] = di_crc( abtBuff, iSecSize ); + } + + cf.Write( pBuf, m_geometry.iSectors ); + + for( int i = 0; i < m_geometry.iSectors; i++ ) + { + int iSecSize = ( i < 3 ) ? 0x80 : m_geometry.iBytesPerSector; + + ReadSector( abtBuff, i + 1 ); + if( pBuf[ i ] || !IsBlockEmpty( abtBuff, iSecSize ) ) + { + cf.Write( abtBuff, iSecSize ); + } + } + + delete [] pBuf; + + cf.Close(); + + return TRUE; +} + +#endif //__CDISK_WRITE__ -- cgit v1.2.3