void CN64Disk::ConvertDiskFormat() { //Original code by Happy_ m_DiskFile.SeekToBegin(); const uint32_t ZoneSecSize[16] = { 232, 216, 208, 192, 176, 160, 144, 128, 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 uint32_t DiskTypeZones[7][16] = { { 0, 1, 2, 9, 8, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10 }, { 0, 1, 2, 3, 10, 9, 8, 4, 5, 6, 7, 15, 14, 13, 12, 11 }, { 0, 1, 2, 3, 4, 11, 10, 9, 8, 5, 6, 7, 15, 14, 13, 12 }, { 0, 1, 2, 3, 4, 5, 12, 11, 10, 9, 8, 6, 7, 15, 14, 13 }, { 0, 1, 2, 3, 4, 5, 6, 13, 12, 11, 10, 9, 8, 7, 15, 14 }, { 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8, 15 }, { 0, 1, 2, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10, 9, 8 } }; const uint32_t RevDiskTypeZones[7][16] = { { 0, 1, 2, 5, 6, 7, 8, 9, 4, 3, 15, 14, 13, 12, 11, 10 }, { 0, 1, 2, 3, 7, 8, 9, 10, 6, 5, 4, 15, 14, 13, 12, 11 }, { 0, 1, 2, 3, 4, 9, 10, 11, 8, 7, 6, 5, 15, 14, 13, 12 }, { 0, 1, 2, 3, 4, 5, 11, 12, 10, 9, 8, 7, 6, 15, 14, 13 }, { 0, 1, 2, 3, 4, 5, 6, 13, 12, 11, 10, 9, 8, 7, 15, 14 }, { 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8, 15 }, { 0, 1, 2, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10, 9, 8 } }; const uint32_t StartBlock[7][16] = { { 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1 }, { 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1 }, { 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 }, { 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 }, { 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 } }; uint32_t disktype = 0; uint32_t zone, track = 0; int32_t atrack = 0; int32_t block = 0; uint8_t SystemData[0xE8]; uint8_t BlockData0[0x100 * SECTORS_PER_BLOCK]; uint8_t BlockData1[0x100 * SECTORS_PER_BLOCK]; uint32_t InOffset, OutOffset = 0; uint32_t InStart[16]; uint32_t OutStart[16]; InStart[0] = 0; OutStart[0] = 0; //Read System Area m_DiskFile.Read(&SystemData, 0xE8); disktype = SystemData[5] & 0xF; //Prepare Input Offsets for (zone = 1; zone < 16; zone++) { InStart[zone] = InStart[zone - 1] + VZONESIZE(DiskTypeZones[disktype][zone - 1]); } //Prepare Output Offsets for (zone = 1; zone < 16; zone++) { OutStart[zone] = OutStart[zone - 1] + ZONESIZE(zone - 1); } //Copy Head 0 for (zone = 0; zone < 8; zone++) { OutOffset = OutStart[zone]; InOffset = InStart[RevDiskTypeZones[disktype][zone]]; m_DiskFile.Seek(InOffset, CFileBase::begin); block = StartBlock[disktype][zone]; atrack = 0; for (track = 0; track < ZoneTracks[zone]; track++) { if (atrack < 0xC && track == SystemData[0x20 + zone * 0xC + atrack]) { memset((void *)(&BlockData0), 0, BLOCKSIZE(zone)); memset((void *)(&BlockData1), 0, BLOCKSIZE(zone)); atrack += 1; } else { if ((block % 2) == 1) { m_DiskFile.Read(&BlockData1, BLOCKSIZE(zone)); m_DiskFile.Read(&BlockData0, BLOCKSIZE(zone)); } else { m_DiskFile.Read(&BlockData0, BLOCKSIZE(zone)); m_DiskFile.Read(&BlockData1, BLOCKSIZE(zone)); } block = 1 - block; } memcpy(m_DiskImage + OutOffset, &BlockData0, BLOCKSIZE(zone)); OutOffset += BLOCKSIZE(zone); memcpy(m_DiskImage + OutOffset, &BlockData1, BLOCKSIZE(zone)); OutOffset += BLOCKSIZE(zone); } } //Copy Head 1 for (zone = 8; zone < 16; zone++) { //OutOffset = OutStart[zone]; InOffset = InStart[RevDiskTypeZones[disktype][zone]]; m_DiskFile.Seek(InOffset, CFileBase::begin); block = StartBlock[disktype][zone]; atrack = 0xB; for (track = 1; track < ZoneTracks[zone] + 1; track++) { if (atrack > -1 && (ZoneTracks[zone] - track) == SystemData[0x20 + (zone)* 0xC + atrack]) { memset((void *)(&BlockData0), 0, BLOCKSIZE(zone)); memset((void *)(&BlockData1), 0, BLOCKSIZE(zone)); atrack -= 1; } else { if ((block % 2) == 1) { m_DiskFile.Read(&BlockData1, BLOCKSIZE(zone)); m_DiskFile.Read(&BlockData0, BLOCKSIZE(zone)); } else { m_DiskFile.Read(&BlockData0, BLOCKSIZE(zone)); m_DiskFile.Read(&BlockData1, BLOCKSIZE(zone)); } block = 1 - block; } OutOffset = OutStart[zone] + (ZoneTracks[zone] - track) * TRACKSIZE(zone); memcpy(m_DiskImage + OutOffset, &BlockData0, BLOCKSIZE(zone)); OutOffset += BLOCKSIZE(zone); memcpy(m_DiskImage + OutOffset, &BlockData1, BLOCKSIZE(zone)); OutOffset += BLOCKSIZE(zone); } } }
void CN64Disk::ConvertDiskFormatBack() { //Original code by Happy_ const uint32_t ZoneSecSize[16] = { 232, 216, 208, 192, 176, 160, 144, 128, 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 uint32_t DiskTypeZones[7][16] = { { 0, 1, 2, 9, 8, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10 }, { 0, 1, 2, 3, 10, 9, 8, 4, 5, 6, 7, 15, 14, 13, 12, 11 }, { 0, 1, 2, 3, 4, 11, 10, 9, 8, 5, 6, 7, 15, 14, 13, 12 }, { 0, 1, 2, 3, 4, 5, 12, 11, 10, 9, 8, 6, 7, 15, 14, 13 }, { 0, 1, 2, 3, 4, 5, 6, 13, 12, 11, 10, 9, 8, 7, 15, 14 }, { 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8, 15 }, { 0, 1, 2, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10, 9, 8 } }; const uint32_t RevDiskTypeZones[7][16] = { { 0, 1, 2, 5, 6, 7, 8, 9, 4, 3, 15, 14, 13, 12, 11, 10 }, { 0, 1, 2, 3, 7, 8, 9, 10, 6, 5, 4, 15, 14, 13, 12, 11 }, { 0, 1, 2, 3, 4, 9, 10, 11, 8, 7, 6, 5, 15, 14, 13, 12 }, { 0, 1, 2, 3, 4, 5, 11, 12, 10, 9, 8, 7, 6, 15, 14, 13 }, { 0, 1, 2, 3, 4, 5, 6, 13, 12, 11, 10, 9, 8, 7, 15, 14 }, { 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8, 15 }, { 0, 1, 2, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10, 9, 8 } }; const uint32_t StartBlock[7][16] = { { 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1 }, { 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1 }, { 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 }, { 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 }, { 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 } }; uint32_t disktype = 0; uint32_t zone, track = 0; int32_t atrack = 0; int32_t block = 0; uint8_t SystemData[0xE8]; uint8_t BlockData0[0x100 * SECTORS_PER_BLOCK]; uint8_t BlockData1[0x100 * SECTORS_PER_BLOCK]; uint32_t InOffset, OutOffset = 0; uint32_t InStart[16]; uint32_t OutStart[16]; //SDK DISK RAM WriteTrace(TraceN64System, TraceDebug, "Allocating memory for disk SDK format"); AUTO_PTR<uint8_t> ImageBase(new uint8_t[SDKFormatSize + 0x1000]); if (ImageBase.get() == NULL) { SetError(MSG_MEM_ALLOC_ERROR); WriteTrace(TraceN64System, TraceError, "Failed to allocate memory for disk SDK format (size: 0x%X)", SDKFormatSize); return; } uint8_t * Image = (uint8_t *)(((uint64_t)ImageBase.get() + 0xFFF) & ~0xFFF); // start at begining of memory page WriteTrace(TraceN64System, TraceDebug, "Allocated disk SDK format memory (%p)", Image); //save information about the disk loaded uint8_t * s_DiskImageBase = ImageBase.release(); uint8_t * s_DiskImage = Image; //END InStart[0] = 0; OutStart[0] = 0; //Read System Area memcpy(&SystemData, m_DiskImage, 0xE8); disktype = SystemData[5] & 0xF; //Prepare Input Offsets for (zone = 1; zone < 16; zone++) { InStart[zone] = InStart[zone - 1] + VZONESIZE(DiskTypeZones[disktype][zone - 1]); } //Prepare Output Offsets for (zone = 1; zone < 16; zone++) { OutStart[zone] = OutStart[zone - 1] + ZONESIZE(zone - 1); } //Copy Head 0 for (zone = 0; zone < 8; zone++) { block = StartBlock[disktype][zone]; atrack = 0; for (track = 0; track < ZoneTracks[zone]; track++) { InOffset = OutStart[zone] + (track)* TRACKSIZE(zone); OutOffset = InStart[RevDiskTypeZones[disktype][zone]] + (track - atrack) * TRACKSIZE(zone); if (atrack < 0xC && track == SystemData[0x20 + zone * 0xC + atrack]) { atrack += 1; } else { if ((block % 2) == 1) { memcpy(&BlockData1, m_DiskImage + InOffset, BLOCKSIZE(zone)); InOffset += BLOCKSIZE(zone); memcpy(&BlockData0, m_DiskImage + InOffset, BLOCKSIZE(zone)); InOffset += BLOCKSIZE(zone); } else { memcpy(&BlockData0, m_DiskImage + InOffset, BLOCKSIZE(zone)); InOffset += BLOCKSIZE(zone); memcpy(&BlockData1, m_DiskImage + InOffset, BLOCKSIZE(zone)); InOffset += BLOCKSIZE(zone); } block = 1 - block; memcpy(s_DiskImage + OutOffset, &BlockData0, BLOCKSIZE(zone)); OutOffset += BLOCKSIZE(zone); memcpy(s_DiskImage + OutOffset, &BlockData1, BLOCKSIZE(zone)); OutOffset += BLOCKSIZE(zone); } } } //Copy Head 1 for (zone = 8; zone < 16; zone++) { block = StartBlock[disktype][zone]; atrack = 0xB; for (track = 1; track < ZoneTracks[zone] + 1; track++) { InOffset = OutStart[zone] + (ZoneTracks[zone] - track) * TRACKSIZE(zone); OutOffset = InStart[RevDiskTypeZones[disktype][zone]] + (track - (0xB - atrack) - 1) * TRACKSIZE(zone); if (atrack > -1 && (ZoneTracks[zone] - track) == SystemData[0x20 + (zone)* 0xC + atrack]) { atrack -= 1; } else { if ((block % 2) == 1) { memcpy(&BlockData1, m_DiskImage + InOffset, BLOCKSIZE(zone)); InOffset += BLOCKSIZE(zone); memcpy(&BlockData0, m_DiskImage + InOffset, BLOCKSIZE(zone)); InOffset += BLOCKSIZE(zone); } else { memcpy(&BlockData0, m_DiskImage + InOffset, BLOCKSIZE(zone)); InOffset += BLOCKSIZE(zone); memcpy(&BlockData1, m_DiskImage + InOffset, BLOCKSIZE(zone)); InOffset += BLOCKSIZE(zone); } block = 1 - block; memcpy(s_DiskImage + OutOffset, &BlockData0, BLOCKSIZE(zone)); OutOffset += BLOCKSIZE(zone); memcpy(s_DiskImage + OutOffset, &BlockData1, BLOCKSIZE(zone)); OutOffset += BLOCKSIZE(zone); } } } if (!m_DiskFile.Write(s_DiskImage, SDKFormatSize)) { m_DiskFile.Close(); WriteTrace(TraceN64System, TraceError, "Failed to write file"); } WriteTrace(TraceN64System, TraceDebug, "Unallocating disk SDK format memory"); delete[] s_DiskImageBase; s_DiskImageBase = NULL; s_DiskImage = NULL; }