// 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.h" ADisk::ADisk() : CDisk() { #ifdef _MEMORY_DUMP_ printf( "ADisk constructed: %p\n", this ); #endif } ADisk::~ADisk() { #ifdef _MEMORY_DUMP_ printf( "ADisk destructed: %p\n", this ); #endif } 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; } } void ForceClassicSize( DISK_GEOMETRY* pGeometry ) { ForceClassicSize( pGeometry->iSectors, pGeometry->iBytesPerSector, pGeometry ); } void ForceClassicSize( int iSectors, int iSectorSize, DISK_GEOMETRY* pGeometry ) { pGeometry->iSides = 1; pGeometry->iBytesPerSector = iSectorSize; pGeometry->iTracks = 1; pGeometry->iSectorsPerTrack = iSectors; switch( iSectorSize ) { case 0x80: if ( iSectors <= 720 ) { pGeometry->iTracks = 40; pGeometry->iSectorsPerTrack = 18; } else if ( ( iSectors > 720 ) && ( iSectors <= 1040 ) ) { pGeometry->iTracks = 40; pGeometry->iSectorsPerTrack = 26; } else { GuessClassicSizes( iSectors, iSectorSize, pGeometry ); } break; case 0x100: default: if ( iSectors <= 720 ) { pGeometry->iTracks = 40; pGeometry->iSectorsPerTrack = 18; } else { GuessClassicSizes( iSectors, iSectorSize, pGeometry ); } break; } 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"; case DISK_DI: return "DI"; 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"; case DISK_DI: return "di"; default: return "xxx"; } } #ifndef __CDISK_NOLOAD__ DISKINIT_RETCODE InitializeDisk( ADisk** 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; case DISK_DI: *ppDisk = new CDi(); 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: case CDI_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; } #endif BOOL ADisk::ReadSectors( void* pBuf, int iStartSec, int iSecs ) { while( iSecs ) { if ( !ReadSector( pBuf, iStartSec ) ) return FALSE; pBuf = (BYTE*)pBuf + ( ( iStartSec <= 3 ) ? 0x80 :m_geometry.iBytesPerSector ); iStartSec++; iSecs--; } return TRUE; } BOOL ADisk::WriteSectors( int iStartSec, void* pBuf, int iSecs ) { while( iSecs ) { if ( !WriteSector( iStartSec, pBuf ) ) return FALSE; pBuf = (BYTE*)pBuf + ( ( iStartSec <= 3 ) ? 0x80 :m_geometry.iBytesPerSector ); iStartSec++; iSecs--; } return TRUE; } int ADisk::GetBootSectorCount() { return m_pbtMemory[ 1 ]; } int ADisk::GetBootSectorSize() { int iSecCount = GetBootSectorCount(); if ( iSecCount > 3 ) return ( ( iSecCount - 3 ) * GetSectorSize() + 0x180 ); else return iSecCount * 0x80; } BOOL ADisk::GetBootSector( BYTE* pbtData ) { return ReadSectors( pbtData, 1, GetBootSectorCount() ); }