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_scp.cpp | 281 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 jindroush/lib/adsk_scp.cpp (limited to 'jindroush/lib/adsk_scp.cpp') diff --git a/jindroush/lib/adsk_scp.cpp b/jindroush/lib/adsk_scp.cpp new file mode 100644 index 0000000..51d3dae --- /dev/null +++ b/jindroush/lib/adsk_scp.cpp @@ -0,0 +1,281 @@ +// 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_scp.h" +#include "autil.h" +#include "cfile.h" + +#define SCP_MAGIC 0xFDFD + +CScp::CScp() : ADisk() +{ + #ifdef _MEMORY_DUMP_ + printf( "CScp constructed: %p\n", this ); + #endif +} + +CScp::~CScp() +{ + #ifdef _MEMORY_DUMP_ + printf( "CScp destructed: %p\n", this ); + #endif +} + +#ifndef __CDISK_NOLOAD__ +BOOL CScp::Load( char* szFname, BOOL, BOOL ) +{ + WORD wMagic; + BYTE btSectorSize; + BYTE btTracks; + BYTE btSectorsPerTrack; + + CFile cf; + + if( !cf.Open( szFname ) ) + { + sprintf( m_szLastError, "SCP: Can't open '%s'", szFname ); + return FALSE; + } + + strcpy( m_szFname, szFname ); + + wMagic = cf.readLEw(); + + if ( wMagic != SCP_MAGIC ) + { + sprintf( m_szLastError, "SCP: File '%s' is not an SCP file!", szFname ); + return FALSE; + } + + btSectorSize = cf.readb(); + btTracks = cf.readb(); + btSectorsPerTrack = cf.readb(); + + int iSectorSize; + + switch( btSectorSize ) + { + case 0x80: + iSectorSize = 0x80; + break; + + case 0x00: + iSectorSize = 0x100; + break; + + default: + { + sprintf( m_szLastError, "SCP: Invalid sector size: %02X", btSectorSize ); + return FALSE; + } + } + + DISK_GEOMETRY dg; + dg.iSides = 1; + dg.iTracks = btTracks; + dg.iSectorsPerTrack = btSectorsPerTrack; + dg.iBytesPerSector = iSectorSize; + + if ( !Format( &dg ) ) + return FALSE; + + BYTE *pbtTable = new BYTE [ btSectorsPerTrack * btTracks ]; + + if ( ! pbtTable ) + { + sprintf( m_szLastError, "SCP: Not enough memory for sector table!" ); + return FALSE; + } + + if ( !cf.Read( pbtTable, btSectorsPerTrack * btTracks ) ) + { + sprintf( m_szLastError, "SCP: Can't read sector table!" ); + return FALSE; + } + + BYTE abtBuff[ 0x100 ]; + memset( abtBuff, 0, 0x100 ); + + BYTE* pbtPtr = pbtTable; + + for( int iTrack = 0; iTrack < btTracks; iTrack++ ) + { + for( int iSector = 0; iSector < btSectorsPerTrack; iSector++ ) + { + if ( *pbtPtr ) + { + int iNowRead; + + if ( !iTrack && ( iSector < 3 ) ) + iNowRead = 0x80; + else + iNowRead = iSectorSize; + + int iReallyRead; + + if ( !cf.Read( abtBuff, iNowRead, &iReallyRead ) || ( iNowRead != iReallyRead ) ) + { + delete [] pbtTable; + sprintf( m_szLastError, "SCP: Image broken!" ); + return FALSE; + } + + if ( !WriteSector( *pbtPtr + iTrack* btSectorsPerTrack, abtBuff ) ) + { + delete [] pbtTable; + return FALSE; + } + + } + pbtPtr++; + } + + } + + delete [] pbtTable; + + cf.Close(); + return TRUE; + +} +#endif + +#ifdef __CDISK_SAVE__ + +BOOL CScp::Save( char* szOutFile, BOOL bOverWrite ) +{ + if ( !bOverWrite && !access( szOutFile, F_OK ) ) + { + sprintf( m_szLastError, "SCP: File already exists! '%s'", szOutFile ); + return FALSE; + } + + BYTE btSize; + BYTE btTracks; + BYTE btSpT; + + switch ( m_geometry.iBytesPerSector ) + { + case 0x80: + btSize = 0x80; + break; + + case 0x100: + default: + btSize = 0x00; + break; + } + + BOOL bGood = FALSE; + + btTracks = m_geometry.iTracks; + btSpT = m_geometry.iSectorsPerTrack; + + if ( ( m_geometry.iTracks == 40 ) && ( m_geometry.iSectorsPerTrack == 18 ) ) + bGood = TRUE; + + if ( ( m_geometry.iTracks == 40 ) && ( m_geometry.iSectorsPerTrack == 26 ) ) + bGood = TRUE; + + if ( !bGood ) + { + sprintf( m_szLastError, "SCP: Can't export, because of invalid disk size!" ); + return FALSE; + } + + int iMapSize = m_geometry.iTracks * m_geometry.iSectorsPerTrack; + + BYTE* pMap = new BYTE [ iMapSize ]; + + if ( !pMap ) + { + sprintf( m_szLastError, "SCP: Can't allocate memory for map!" ); + return FALSE; + } + + memset( pMap, 0, iMapSize ); + + + CFile cf; + + if ( !cf.Create( szOutFile ) ) + { + sprintf( m_szLastError, "SCP: Can't create '%s'", szOutFile ); + delete [] pMap; + return FALSE; + } + + WORD wMagic = SCP_MAGIC; + + cf.writeLEw( wMagic ); + cf.writeb( btSize ); + cf.writeb( btTracks ); + cf.writeb( btSpT ); + + cf.Seek( iMapSize, SEEK_CUR ); + + BYTE abtBuff[ 0x100 ]; + + int iSectors = m_geometry.iSectors; + + for( int i = 0; i < iSectors; i++ ) + { + if ( !ReadSector( abtBuff, i + 1 ) ) + { + delete [] pMap; + cf.Close(); + unlink( szOutFile ); + return FALSE; + } + + int iBytesNow = ( i < 3 ) ? 0x80 : m_geometry.iBytesPerSector; + + if ( !IsBlockEmpty( abtBuff, iBytesNow ) ) + { + int iWritten; + if ( !cf.Write( abtBuff, iBytesNow, &iWritten ) || ( iBytesNow != iWritten ) ) + { + sprintf( m_szLastError, "SCP: Error writing to '%s'", szOutFile ); + delete [] pMap; + cf.Close( ); + unlink( szOutFile ); + return FALSE; + + } + + pMap[ i ] = ( i % btSpT ) + 1; + } + } + + cf.Seek( 5, SEEK_SET ); + + if ( !cf.Write( pMap, iMapSize ) ) + { + sprintf( m_szLastError, "SCP: Can't write!" ); + delete [] pMap; + cf.Close( ); + unlink( szOutFile ); + return FALSE; + + } + + delete [] pMap; + + cf.Close(); + + return TRUE; +} + +#endif //__CDISK_SAVE__ -- cgit v1.2.3