diff --git a/src/libleo/leord_diskid.c b/src/libleo/leord_diskid.c index 5606042..0568a29 100644 --- a/src/libleo/leord_diskid.c +++ b/src/libleo/leord_diskid.c @@ -1,3 +1,57 @@ -#include "common.h" +#include +#include "libleo/internal.h" + +/* +u8 leo_disk_id_lba[] = {14, 15}; //D_8007DAF0 + +LEOCmdRead read_id_cmd = { //D_80079590 + {LEO_COMMAND_READ, 0,0,0, 0,0,0,0, 0}, + 14, 1, LEO_TempBuffer, 0 +}; +*/ + +extern u16 LEOrw_flags; +extern u8 LEO_TempBuffer[0xE8]; +extern u8 leo_disk_id_lba[2]; +extern LEOCmdRead read_id_cmd; + +void leoReadDiskId(void) { + LEOCmdRead dummy_cmd; + u8* temp_pointer; + u32 cntr; + + //Keep Disk ID Command and replace + temp_pointer = (u8*)LEOcur_command; + + //Read Disk ID to Temp Buffer + LEOcur_command = (LEOCmd*)&dummy_cmd; + for (cntr = 0; cntr < (sizeof(leo_disk_id_lba)); cntr++) { + LEOrw_flags = 0x2000; + dummy_cmd = read_id_cmd; + dummy_cmd.lba = leo_disk_id_lba[cntr]; + leoRead_common(0); + if (dummy_cmd.header.sense != LEO_SENSE_UNRECOVERED_READ_ERROR) break; + } + + //Put back the old ReadDiskID command + LEOcur_command = (LEOCmd*)temp_pointer; + + //Copy Disk ID to buffer pointed by ReadDiskID command + temp_pointer = (u8*)LEOcur_command->data.readdiskid.buffer_pointer; + for (cntr = 0; cntr < (sizeof(LEODiskID)); cntr += sizeof(u32)) + { + *(u32 *)temp_pointer = *((u32 *)&LEO_TempBuffer[cntr]); + temp_pointer += sizeof(u32); + } + + //Copy status and sense + LEOcur_command->header.sense = dummy_cmd.header.sense; + LEOcur_command->header.status = dummy_cmd.header.status; + + if (LEOcur_command->header.status == LEO_STATUS_GOOD) { + leoClrUA_MEDIUM_CHANGED(); + } else { + leoSetUA_MEDIUM_CHANGED(); + } +} -#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leord_diskid/leoReadDiskId.s") diff --git a/src/libleo/leoutil.c b/src/libleo/leoutil.c index af1ae63..22c854c 100644 --- a/src/libleo/leoutil.c +++ b/src/libleo/leoutil.c @@ -1,8 +1,6 @@ #include #include "libleo/internal.h" -#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leoutil/leoLba_to_phys.s") - const u16 LEOVZONE_TBL[][0x10] = { { 0x0124, 0x0248, 0x035A, 0x047E, 0x05A2, 0x06B4, 0x07C6, 0x08D8, 0x09EA, 0x0AB6, 0x0B82, 0x0C94, 0x0DA6, 0x0EB8, 0x0FCA, 0x10DC }, @@ -20,6 +18,85 @@ const u16 LEOVZONE_TBL[][0x10] = { 0x0FB8, 0x10DC }, }; +u16 leoLba_to_phys(u32 lba) { + u32 vzone; + u32 pzone; + u16 pzone_cylinder_start; + u16 defect_offset; + u16 defect_amount; + + //A cylinder track is made of two blocks, so we may be able to only read one of it if the next block is on the next cylinder + LEOtgt_param.rdwr_blocks = 2 - (lba & 1); + + //Blocks are interleaved between cylinders + if (((lba & 3) != 0) && ((lba & 3) != 3)) { + LEOtgt_param.start_block = 1; + } else { + LEOtgt_param.start_block = 0; + } + + //Get Virtual & Physical Disk Zones from LBA + vzone = leoLba_to_vzone(lba); + pzone = LEOVZONE_PZONEHD_TBL[LEOdisk_type][vzone]; + + //Set Parameter Disk Head & Zone + LEOtgt_param.head = 0; + LEOtgt_param.zone = pzone; + if (LEOtgt_param.zone > 7) + { + LEOtgt_param.zone -= 7; + LEOtgt_param.head = 1; + } + + //Get the start cylinder from current zone + pzone_cylinder_start = LEOZONE_SCYL_TBL[pzone]; + + { + //Get Virtual Zone LBA start, if Zone 0, it's LBA 0 + u16 vzone_lba_start = (vzone != 0) ? LEOVZONE_TBL[LEOdisk_type][vzone - 1] : 0; + //Get Cylinder relative of the current Zone + u16 zone_cylinder = ((lba - vzone_lba_start) >> 1); + //Calculate Physical Cylinder + if (LEOtgt_param.head != 0) { + LEOtgt_param.cylinder = pzone_cylinder_start - zone_cylinder; + pzone_cylinder_start = LEOZONE_OUTERCYL_TBL[LEOtgt_param.zone - 1]; + } else { + LEOtgt_param.cylinder = pzone_cylinder_start + zone_cylinder; + } + } + + { + u32 pzone_prev = pzone - 1; + //Get the relative offset to defect tracks for the current zone (if Zone 0, then it's 0) + defect_offset = (pzone != 0) ? LEO_sys_data.param.defect_num[pzone_prev] : 0; + //Get amount of defect tracks for the current zone + defect_amount = LEO_sys_data.param.defect_num[pzone] - defect_offset; + } + + //Skip defective cylinders + while (defect_amount != 0) { + u16 defect_cylinder = (pzone_cylinder_start + LEO_sys_data.param.defect_data[defect_offset]); + if (LEOtgt_param.cylinder < defect_cylinder) break; + + LEOtgt_param.cylinder++; + defect_offset++; + defect_amount--; + } + + //Set sector and block size info + LEOtgt_param.sec_bytes = LEOBYTE_TBL1[LEOtgt_param.zone]; + LEOtgt_param.blk_bytes = LEOBYTE_TBL2[LEOtgt_param.zone]; + + //For development disks + if ((LEO_country_code == 0) && (lba < 0xC)) { + LEOtgt_param.sec_bytes = 0xC0; + LEOtgt_param.blk_bytes = 0x3FC0; + } + + return 0; +} + + u16 leoLba_to_vzone(u32 lba) { u16 i; const u16* ptr = LEOVZONE_TBL[LEOdisk_type]; diff --git a/tools/symbol_addrs.txt b/tools/symbol_addrs.txt index 21905f0..005887a 100644 --- a/tools/symbol_addrs.txt +++ b/tools/symbol_addrs.txt @@ -123,8 +123,14 @@ LEO_ZERO_MESG = 0X8007DA30; LEORAM_START_LBA = 0x8007DD18; LEORAM_BYTE = 0x8007DD28; LEOVZONE_TBL = 0x8007DB98; +LEOZONE_SCYL_TBL = 0x8007DC78; LEOVZONE_PZONEHD_TBL = 0x8007DC98; +LEOBYTE_TBL1 = 0x8007DB78; LEOBYTE_TBL2 = 0x8007DB84; +LEOZONE_OUTERCYL_TBL = 0x8007DD08; +LEO_TempBuffer = 0x80100850; +read_id_cmd = 0x80079590; +leo_disk_id_lba = 0x8007DAF0; leo_sys_read_cmd = 0x80079560; leo_sys_form_lbas = 0x8007DA40; LEO_sys_data = 0x800FF9F0;