/**************************************************************************** * * * Project64 - A Nintendo 64 emulator. * * http://www.pj64-emu.com/ * * Copyright (C) 2012 Project64. All rights reserved. * * * * License: * * GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * * * ****************************************************************************/ #pragma once #include #include class CN64Disk { public: CN64Disk(); ~CN64Disk(); bool LoadDiskImage(const char * FileLoc); bool SaveDiskImage(); void SwapDiskImage(const char * FileLoc); static bool IsValidDiskImage(uint8_t Test[0x20]); void SaveDiskSettingID(bool temp); void ClearDiskSettingID(); uint8_t * GetDiskAddress() { return m_DiskImage; } uint8_t * GetDiskAddressBuffer() { return m_DiskImage + m_DiskBufAddress; } uint8_t * GetDiskAddressSys() { return m_DiskImage + m_DiskSysAddress; } uint8_t * GetDiskAddressID() { return m_DiskImage + m_DiskIDAddress; } uint8_t * GetDiskAddressRom() { return m_DiskImage + m_DiskRomAddress; } uint8_t * GetDiskAddressRam() { return m_DiskImage + m_DiskRamAddress; } uint8_t * GetDiskHeader() { return m_DiskHeader; } void SetDiskAddressBuffer(uint32_t address) { m_DiskBufAddress = address; } uint32_t GetDiskAddressBlock(uint16_t head, uint16_t track, uint16_t block, uint16_t sector, uint16_t sectorsize); uint32_t CalculateCrc(); stdstr GetRomName() const { return m_RomName; } stdstr GetFileName() const { return m_FileName; } stdstr GetDiskIdent() const { return m_DiskIdent; } Country GetCountry() const { return m_Country; } void UnallocateDiskImage(); LanguageStringID GetError() const { return m_ErrorMsg; } private: bool AllocateDiskImage(uint32_t DiskFileSize); bool AllocateDiskHeader(); bool AllocateAndLoadDiskImage(const char * FileLoc); bool LoadDiskRAMImage(); void ByteSwapDisk(); void ForceByteSwapDisk(); void SetError(LanguageStringID ErrorMsg); void DetectSystemArea(); bool IsSysSectorGood(uint32_t block, uint32_t sectorsize); Country GetDiskCountryCode(); void InitSysDataD64(); void DeinitSysDataD64(); void GenerateLBAToPhysTable(); void DetectRamAddress(); uint32_t LBAToVZone(uint32_t lba); uint32_t LBAToByte(uint32_t lba, uint32_t nlbas); uint16_t LBAToPhys(uint32_t lba); uint16_t PhysToLBA(uint16_t head, uint16_t track, uint16_t block); //constant values enum { ReadFromRomSection = 0x400000, MameFormatSize = 0x0435B0C0, SDKFormatSize = 0x03DEC800, DiskFormatMAME = 0x0, DiskFormatSDK = 0x1, DiskFormatD64 = 0x2 }; //class variables CFile m_DiskFile; uint8_t * m_DiskImage; uint8_t * m_DiskImageBase; uint8_t * m_DiskHeader; uint8_t * m_DiskHeaderBase; uint32_t m_DiskFileSize; uint32_t m_DiskBufAddress; uint32_t m_DiskSysAddress; uint32_t m_DiskIDAddress; uint32_t m_DiskRomAddress; uint32_t m_DiskRamAddress; LanguageStringID m_ErrorMsg; Country m_Country; stdstr m_RomName, m_FileName, m_DiskIdent; uint8_t m_DiskFormat; //0 = MAME, 1 = SDK, 2 = D64 uint8_t m_DiskType; bool m_isShadowDisk; //Disk Defines #define MAX_LBA 0x10DB #define SIZE_LBA MAX_LBA+1 #define SYSTEM_LBAS 24 #define DISKID_LBA 14 #define DISK_COUNTRY_JPN 0xE848D316 #define DISK_COUNTRY_USA 0x2263EE56 #define DISK_COUNTRY_DEV 0x00000000 #define SECTORS_PER_BLOCK 85 #define BLOCKS_PER_TRACK 2 const uint32_t SECTORSIZE[16] = { 232, 216, 208, 192, 176, 160, 144, 128, 216, 208, 192, 176, 160, 144, 128, 112 }; const uint32_t SECTORSIZE_P[9] = { 232, 216, 208, 192, 176, 160, 144, 128, 112 }; const uint32_t ZoneTracks[16] = { 158, 158, 149, 149, 149, 149, 149, 114, 158, 158, 149, 149, 149, 149, 149, 114 }; const uint16_t VZONE_LBA_TBL[7][16] = { {0x0124, 0x0248, 0x035A, 0x047E, 0x05A2, 0x06B4, 0x07C6, 0x08D8, 0x09EA, 0x0AB6, 0x0B82, 0x0C94, 0x0DA6, 0x0EB8, 0x0FCA, 0x10DC}, {0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x06A2, 0x07C6, 0x08D8, 0x09EA, 0x0AFC, 0x0BC8, 0x0C94, 0x0DA6, 0x0EB8, 0x0FCA, 0x10DC}, {0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x08C6, 0x09EA, 0x0AFC, 0x0C0E, 0x0CDA, 0x0DA6, 0x0EB8, 0x0FCA, 0x10DC}, {0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x08B4, 0x09C6, 0x0AEA, 0x0C0E, 0x0D20, 0x0DEC, 0x0EB8, 0x0FCA, 0x10DC}, {0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x08B4, 0x09C6, 0x0AD8, 0x0BEA, 0x0D0E, 0x0E32, 0x0EFE, 0x0FCA, 0x10DC}, {0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x086E, 0x0980, 0x0A92, 0x0BA4, 0x0CB6, 0x0DC8, 0x0EEC, 0x1010, 0x10DC}, {0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x086E, 0x093A, 0x0A4C, 0x0B5E, 0x0C70, 0x0D82, 0x0E94, 0x0FB8, 0x10DC} }; const uint8_t VZONE_PZONE_TBL[7][16] = { {0x0, 0x1, 0x2, 0x9, 0x8, 0x3, 0x4, 0x5, 0x6, 0x7, 0xF, 0xE, 0xD, 0xC, 0xB, 0xA}, {0x0, 0x1, 0x2, 0x3, 0xA, 0x9, 0x8, 0x4, 0x5, 0x6, 0x7, 0xF, 0xE, 0xD, 0xC, 0xB}, {0x0, 0x1, 0x2, 0x3, 0x4, 0xB, 0xA, 0x9, 0x8, 0x5, 0x6, 0x7, 0xF, 0xE, 0xD, 0xC}, {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xC, 0xB, 0xA, 0x9, 0x8, 0x6, 0x7, 0xF, 0xE, 0xD}, {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0xD, 0xC, 0xB, 0xA, 0x9, 0x8, 0x7, 0xF, 0xE}, {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xE, 0xD, 0xC, 0xB, 0xA, 0x9, 0x8, 0xF}, {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xF, 0xE, 0xD, 0xC, 0xB, 0xA, 0x9, 0x8} }; const uint16_t SCYL_ZONE_TBL[2][8] = { {0x000, 0x09E, 0x13C, 0x1D1, 0x266, 0x2FB, 0x390, 0x425}, {0x091, 0x12F, 0x1C4, 0x259, 0x2EE, 0x383, 0x418, 0x48A} }; const uint16_t OUTERCYL_TBL[8] = { 0x000, 0x09E, 0x13C, 0x1D1, 0x266, 0x2FB, 0x390, 0x425 }; const uint16_t RAM_START_LBA[7] = { 0x5A2, 0x7C6, 0x9EA, 0xC0E, 0xE32, 0x1010, 0x10DC }; const uint32_t RAM_SIZES[7] = { 0x24A9DC0, 0x1C226C0, 0x1450F00, 0xD35680, 0x6CFD40, 0x1DA240, 0x0 }; #define BLOCKSIZE(_zone) SECTORSIZE[_zone] * SECTORS_PER_BLOCK #define TRACKSIZE(_zone) BLOCKSIZE(_zone) * BLOCKS_PER_TRACK #define ZONESIZE(_zone) TRACKSIZE(_zone) * ZoneTracks[_zone] #define VZONESIZE(_zone) TRACKSIZE(_zone) * (ZoneTracks[_zone] - 0xC) #define VZoneToPZone(x, y) VZONE_PZONE_TBL[y][x] //Used for MAME format const uint32_t MAMEStartOffset[16] = { 0x0, 0x5F15E0, 0xB79D00, 0x10801A0, 0x1523720, 0x1963D80, 0x1D414C0, 0x20BBCE0, 0x23196E0, 0x28A1E00, 0x2DF5DC0, 0x3299340, 0x36D99A0, 0x3AB70E0, 0x3E31900, 0x4149200 }; //Used for SDK and D64 format uint16_t LBAToPhysTable[SIZE_LBA]; };