From 2ed6489dbdbcea99e94998c45cf9d5c0c51407a4 Mon Sep 17 00:00:00 2001 From: sorgelig Date: Fri, 18 May 2018 03:06:48 +0800 Subject: [PATCH] Use UAE CHS for header-less HDF images. --- minimig_hdd.cpp | 187 ++++++++++++++++++++++++------------------------ 1 file changed, 95 insertions(+), 92 deletions(-) diff --git a/minimig_hdd.cpp b/minimig_hdd.cpp index d94f689..c644932 100644 --- a/minimig_hdd.cpp +++ b/minimig_hdd.cpp @@ -88,14 +88,14 @@ static unsigned char GetDiskStatus(void) return status; } -static void RDBChecksum(unsigned long *p) +static void RDBChecksum(uint32_t *p) { - unsigned long count = p[1]; - unsigned long c2; - long result = 0; + uint32_t count = SWAP(p[1]); + uint32_t result = 0; p[2] = 0; - for (c2 = 0; c2rdb_ID = 'R' << 24 | 'D' << 16 | 'S' << 8 | 'K'; - rdb->rdb_Summedlongs = 0x40; - rdb->rdb_HostID = 0x07; - rdb->rdb_BlockBytes = 0x200; - rdb->rdb_Flags = 0x12; // (Disk ID valid, no LUNs after this one) - rdb->rdb_BadBlockList = 0xffffffff; // We don't provide a bad block list - rdb->rdb_PartitionList = 1; - rdb->rdb_FileSysHeaderList = 0xffffffff; - rdb->rdb_DriveInit = 0xffffffff; - rdb->rdb_Reserved1[0] = 0xffffffff; - rdb->rdb_Reserved1[1] = 0xffffffff; - rdb->rdb_Reserved1[2] = 0xffffffff; - rdb->rdb_Reserved1[3] = 0xffffffff; - rdb->rdb_Reserved1[4] = 0xffffffff; - rdb->rdb_Reserved1[5] = 0xffffffff; - rdb->rdb_Cylinders = hdf[unit].cylinders; - rdb->rdb_Sectors = hdf[unit].sectors; - rdb->rdb_Heads = hdf[unit].heads; - rdb->rdb_Interleave = 1; - rdb->rdb_Park = rdb->rdb_Cylinders; - rdb->rdb_WritePreComp = rdb->rdb_Cylinders; - rdb->rdb_ReducedWrite = rdb->rdb_Cylinders; - rdb->rdb_StepRate = 3; - rdb->rdb_RDBBlocksLo = 0; - rdb->rdb_RDBBlocksHi = 1; - rdb->rdb_LoCylinder = 1; - rdb->rdb_HiCylinder = rdb->rdb_Cylinders - 1; - rdb->rdb_CylBlocks = rdb->rdb_Heads * rdb->rdb_Sectors; - rdb->rdb_AutoParkSeconds = 0; - rdb->rdb_HighRDSKBlock = 1; - strcpy(rdb->rdb_DiskVendor, "Do not "); - strcpy(rdb->rdb_DiskProduct, "repartition!"); - // swap byte order of strings to be able to "unswap" them after checksum - unsigned long *p = (unsigned long*)rdb; - for (i = 0; i<(8 + 16) / 4; i++) p[40 + i] = SWAP(p[40 + i]); - RDBChecksum((unsigned long *)rdb); - // swap byte order of first 0x40 long values - for (i = 0; i<0x40; i++) p[i] = SWAP(p[i]); - break; - } - case 1: { - // Partition - hdd_debugf("FAKE: Partition"); - struct PartitionBlock *pb = (struct PartitionBlock *)sector_buffer; - pb->pb_ID = 'P' << 24 | 'A' << 16 | 'R' << 8 | 'T'; - pb->pb_Summedlongs = 0x40; - pb->pb_HostID = 0x07; - pb->pb_Next = 0xffffffff; - pb->pb_Flags = 0x1; // bootable - pb->pb_DevFlags = 0; - strcpy(pb->pb_DriveName, "0HD\003"); // "DHx" BCPL string - pb->pb_DriveName[0] = unit + '0'; - pb->pb_Environment.de_TableSize = 0x10; - pb->pb_Environment.de_SizeBlock = 0x80; - pb->pb_Environment.de_Surfaces = hdf[unit].heads; - pb->pb_Environment.de_SectorPerBlock = 1; - pb->pb_Environment.de_BlocksPerTrack = hdf[unit].sectors; - pb->pb_Environment.de_Reserved = 2; - pb->pb_Environment.de_LowCyl = 1; - pb->pb_Environment.de_HighCyl = hdf[unit].cylinders - 1; - pb->pb_Environment.de_NumBuffers = 30; - pb->pb_Environment.de_MaxTransfer = 0xffffff; - pb->pb_Environment.de_Mask = 0x7ffffffe; - pb->pb_Environment.de_DosType = 0x444f5301; - RDBChecksum((unsigned long *)pb); - // swap byte order of first 0x40 entries - unsigned long *p = (unsigned long*)pb; - for (i = 0; i<0x40; i++) p[i] = SWAP(p[i]); - break; - } - default: { - break; - } + switch (block) + { + case 0: { + // RDB + struct RigidDiskBlock *rdb = (struct RigidDiskBlock *)sector_buffer; + rdb->rdb_ID = 'R' << 24 | 'D' << 16 | 'S' << 8 | 'K'; + rdb->rdb_Summedlongs = 0x40; + rdb->rdb_HostID = 0x07; + rdb->rdb_BlockBytes = 0x200; + rdb->rdb_Flags = 0x12; // (Disk ID valid, no LUNs after this one) + rdb->rdb_BadBlockList = 0xffffffff; // We don't provide a bad block list + rdb->rdb_PartitionList = 1; + rdb->rdb_FileSysHeaderList = 0xffffffff; + rdb->rdb_DriveInit = 0xffffffff; + rdb->rdb_Reserved1[0] = 0xffffffff; + rdb->rdb_Reserved1[1] = 0xffffffff; + rdb->rdb_Reserved1[2] = 0xffffffff; + rdb->rdb_Reserved1[3] = 0xffffffff; + rdb->rdb_Reserved1[4] = 0xffffffff; + rdb->rdb_Reserved1[5] = 0xffffffff; + rdb->rdb_Cylinders = hdf[unit].cylinders; + rdb->rdb_Sectors = hdf[unit].sectors; + rdb->rdb_Heads = hdf[unit].heads; + rdb->rdb_Interleave = 1; + rdb->rdb_Park = rdb->rdb_Cylinders; + rdb->rdb_WritePreComp = rdb->rdb_Cylinders; + rdb->rdb_ReducedWrite = rdb->rdb_Cylinders; + rdb->rdb_StepRate = 3; + rdb->rdb_RDBBlocksLo = 0; + rdb->rdb_RDBBlocksHi = 1; + rdb->rdb_LoCylinder = 1; + rdb->rdb_HiCylinder = rdb->rdb_Cylinders - 1; + rdb->rdb_CylBlocks = rdb->rdb_Heads * rdb->rdb_Sectors; + rdb->rdb_AutoParkSeconds = 0; + rdb->rdb_HighRDSKBlock = 1; + strcpy(rdb->rdb_DiskVendor, "DON'T REPARTITION! 0.00"); + uint32_t *p = (uint32_t*)(sector_buffer); + for (int i = 0; i < 40; i++) p[i] = SWAP(p[i]); + RDBChecksum(p); + break; + } + case 1: { + // Partition + struct PartitionBlock *pb = (struct PartitionBlock *)sector_buffer; + pb->pb_ID = 'P' << 24 | 'A' << 16 | 'R' << 8 | 'T'; + pb->pb_Summedlongs = 0x40; + pb->pb_HostID = 0x07; + pb->pb_Next = 0xffffffff; + pb->pb_Flags = 0x1; // bootable + pb->pb_DevFlags = 0; + strcpy(pb->pb_DriveName, "0HD\003"); // "DHx" BCPL string + pb->pb_DriveName[0] = unit + '0'; + pb->pb_Environment.de_TableSize = 0x10; + pb->pb_Environment.de_SizeBlock = 0x80; + pb->pb_Environment.de_Surfaces = hdf[unit].heads; + pb->pb_Environment.de_SectorPerBlock = 1; + pb->pb_Environment.de_BlocksPerTrack = hdf[unit].sectors; + pb->pb_Environment.de_Reserved = 2; + pb->pb_Environment.de_LowCyl = 1; + pb->pb_Environment.de_HighCyl = hdf[unit].cylinders - 1; + pb->pb_Environment.de_NumBuffers = 30; + pb->pb_Environment.de_MaxTransfer = 0xffffff; + pb->pb_Environment.de_Mask = 0x7ffffffe; + pb->pb_Environment.de_DosType = 0x444f5301; + uint32_t *p = (uint32_t*)(sector_buffer); + for (int i = 0; i < 64; i++) p[i] = SWAP(p[i]); + RDBChecksum(p); + break; + } } } @@ -202,17 +193,16 @@ static void IdentifyDevice(unsigned short *pBuffer, unsigned char unit) pBuffer[6] = hdf[unit].sectors; // sectors per track // FIXME - can get serial no from card itself. memcpy((char*)&pBuffer[10], "MiniMigHardfile0000 ", 20); // serial number - byte swapped - memcpy((char*)&pBuffer[23], ".100 ", 8); // firmware version - byte swapped p = (char*)&pBuffer[27]; if (hdf[unit].offset < 0) { - memcpy(p, "DON'T ", 40); - p += 7; - memcpy(p, "REPARTITION! ", 16); + memcpy((char*)&pBuffer[23], ".000 ", 8); // firmware version - byte swapped + memcpy(p, "DON'T REPARTITION! ", 40); } else { + memcpy((char*)&pBuffer[23], ".100 ", 8); // firmware version - byte swapped memcpy(p, "MiSTer ", 40); // model name - byte swapped p += 8; char *s = strrchr(config.hardfile[unit].filename, '/'); @@ -445,8 +435,6 @@ static void ATA_ReadMultiple(unsigned char* tfr, unsigned char unit) { if (hdf[unit].file.size) HardFileSeek(&hdf[unit], (lba + hdf[unit].offset) < 0 ? 0 : lba + hdf[unit].offset); - // FIXME - READM could cross the fake RDB -> real disk boundary. - // FIXME - but first we should make some attempt to generate fake RGB in multiple mode. while (sector_count) { while (!(GetDiskStatus() & CMD_IDECMD)); // wait for empty sector buffer @@ -457,7 +445,14 @@ static void ATA_ReadMultiple(unsigned char* tfr, unsigned char unit) { if (hdf[unit].file.size) { - FileReadSec(&hdf[unit].file, sector_buffer); + if ((lba + hdf[unit].offset)<0) + { + FakeRDB(unit, lba); + } + else + { + FileReadSec(&hdf[unit].file, sector_buffer); + } SendSector(); } if (sector_count != 1) @@ -477,6 +472,7 @@ static void ATA_ReadMultiple(unsigned char* tfr, unsigned char unit) sector++; } } + lba++; sector_count--; } WriteTaskFile(0, tfr[2], sector, (unsigned char)cylinder, (unsigned char)(cylinder >> 8), (tfr[6] & 0xF0) | head); @@ -738,8 +734,15 @@ static void SetHardfileGeometry(hdfTYPE *pHDF, int isHDF) if (isHDF && flg) { + //use UAE settings. + pHDF->heads = 1; + pHDF->sectors = 32; + + int spc = pHDF->heads * pHDF->sectors; + pHDF->cylinders = pHDF->file.size / (512 * spc) + 1; + pHDF->offset = -spc; + printf("No RDB header found in HDF image. Assume it's image of single partition. Use Virtual RDB header.\n"); - pHDF->offset = -(pHDF->heads * pHDF->sectors); } else {