// 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 "cdisk.h" #include "cdsk_atr.h" #include "cdsk_xfd.h" #include "cdsk_dcm.h" #include "cdsk_scp.h" CDisk::CDisk() { m_bOpened = FALSE; m_pbtMemory = NULL; #ifdef _MEMORY_DUMP_ printf( "CDisk constructed: %08X\n", this ); #endif } CDisk::~CDisk() { if ( m_pbtMemory ) { delete [] m_pbtMemory; m_pbtMemory = NULL; } #ifdef _MEMORY_DUMP_ printf( "CDisk destructed: %08X\n", this ); #endif } BOOL CDisk::Duplicate( CDisk* pDisk ) { if ( !Format( & ( pDisk->m_geometry ) ) ) return FALSE; memcpy( m_pbtMemory, pDisk->m_pbtMemory, pDisk->m_iAllocated ); return TRUE; } BOOL CDisk::Format( DISK_GEOMETRY* pgeo ) { int iSectors = pgeo->iSides * pgeo->iTracks * pgeo->iSectorsPerTrack; if ( m_pbtMemory ) delete [] m_pbtMemory; m_iAllocated = iSectors * pgeo->iBytesPerSector; m_pbtMemory = new BYTE [ m_iAllocated ]; if ( !m_pbtMemory ) { sprintf( m_szLastError, "DISK: Can't format - Not enough memory!" ); return FALSE; } memset( m_pbtMemory, 0, m_iAllocated ); m_geometry.iSides = pgeo->iSides; m_geometry.iTracks = pgeo->iTracks; m_geometry.iSectorsPerTrack = pgeo->iSectorsPerTrack; m_geometry.iBytesPerSector = pgeo->iBytesPerSector; m_geometry.iSectors = iSectors; return TRUE; } BOOL CDisk::ReadSector( void* pBuf, int iStartSec ) { if ( iStartSec && ( iStartSec <= m_geometry.iSectors ) ) memcpy( pBuf, m_pbtMemory + ( iStartSec - 1 ) * m_geometry.iBytesPerSector, m_geometry.iBytesPerSector ); else { sprintf( m_szLastError, "DISK: Reading non-existent sector: %04X", iStartSec ); return FALSE; } return TRUE; } BOOL CDisk::ReadSectors( void* pBuf, int iStartSec, int iSecs ) { while( iSecs ) { if ( !ReadSector( pBuf, iStartSec ) ) return FALSE; iStartSec++; iSecs--; pBuf = (BYTE*)pBuf + m_geometry.iBytesPerSector; } return TRUE; } BOOL CDisk::WriteSector( int iStartSec, void* pBuf ) { //printf( " ws: %d ", iStartSec ); if ( iStartSec && ( iStartSec <= m_geometry.iSectors ) ) memcpy( m_pbtMemory + ( iStartSec - 1 ) * m_geometry.iBytesPerSector, pBuf, m_geometry.iBytesPerSector ); else { sprintf( m_szLastError, "DISK: Writing non-existent sector: %04X", iStartSec ); return FALSE; } return TRUE; } void GuessClassicSizes( int iSectors, int iSectorSize, DISK_GEOMETRY* pGeometry ) { pGeometry->iSides = 1; pGeometry->iBytesPerSector = iSectorSize; pGeometry->iTracks = 1; pGeometry->iSectorsPerTrack = iSectors; switch( iSectors ) { case 720: switch( iSectorSize ) { case 0x80: pGeometry->iTracks = 40; pGeometry->iSectorsPerTrack = 18; break; case 0x100: pGeometry->iTracks = 40; pGeometry->iSectorsPerTrack = 18; break; } break; case 1040: pGeometry->iTracks = 40; pGeometry->iSectorsPerTrack = 26; break; } } //returns ptr to disk type name char* GetDiskTypeName( DISK_TYPE disktype ) { switch( disktype ) { case DISK_XFD: return "XFD"; case DISK_ATR: return "ATR"; case DISK_XFDb: return "XFDb"; case DISK_ATRb: return "ATRb"; case DISK_DCM: return "DCM"; case DISK_SCP: return "SCP"; default: return "None"; } } //returns ptr to disk type extension char* GetDiskTypeExt( DISK_TYPE disktype ) { switch( disktype ) { case DISK_XFD: case DISK_XFDb: return "xfd"; case DISK_ATR: case DISK_ATRb: return "atr"; case DISK_DCM: return "dcm"; case DISK_SCP: return "scp"; default: return "xxx"; } } DISKINIT_RETCODE InitializeDisk( CDisk** ppDisk, DISK_TYPE disktype, char* szFname, BOOL bVerbose, BOOL bRepair, BOOL bRepairAuto ) { switch( disktype ) { case DISK_ATR: *ppDisk = new CAtr(); break; case DISK_SCP: *ppDisk = new CScp(); break; case DISK_DCM: *ppDisk = new CDcm(); break; case DISK_XFD: *ppDisk = new CXfd(); break; default: if ( bVerbose ) fprintf( stderr, "Invalid disk type specified!\n" ); return DI_RET_CANT_CONTINUE; } if ( !*ppDisk ) { if ( bVerbose ) fprintf( stderr, "Can't initialize disk driver!\n" ); return DI_RET_CONTINUE; } if ( !(*ppDisk)->Load( szFname, bRepair, bRepairAuto ) ) { int iError = (*ppDisk)->GetErrorCode(); DISKINIT_RETCODE ret = DI_RET_CONTINUE; switch( iError ) { case CATR_FORMAT_VIOLATED: case CXFD_FORMAT_VIOLATED: case CDISK_ERROR_CANT_OPEN: case CDCM_FORMAT_VIOLATED: case CSCP_FORMAT_VIOLATED: ret = DI_RET_CANT_CONTINUE; break; } if ( bVerbose || ( ret == DI_RET_CANT_CONTINUE ) ) { printf( "Input file '%s' ", szFname ); printf( "(%s)\n", GetDiskTypeName( disktype ) ); printf( "Load failed because:\n%s\n", (*ppDisk)->GetLastError() ); } if ( ret != DI_RET_OK ) { delete *ppDisk; return ret; } } return DI_RET_OK; }