mirror of
https://github.com/zeldaret/oot.git
synced 2025-05-10 02:54:24 +00:00
* progress * z64.h issues sorted * remove variables.h * format * n64 fix * another fix * did the wrong fix * fix libleo * fix bss * review * remove instead of comment
109 lines
2.9 KiB
C
109 lines
2.9 KiB
C
#include "ultra64.h"
|
|
#include "ultra64/leo.h"
|
|
#include "ultra64/leoappli.h"
|
|
#include "ultra64/leodrive.h"
|
|
|
|
#include "macros.h"
|
|
|
|
u16 leoLba_to_phys(u32 lba) {
|
|
u16 vzone_num;
|
|
u16 zone_slba;
|
|
u16 zone_scyl;
|
|
u16 zone_tk;
|
|
u16 bad_tk_num;
|
|
u32 counter;
|
|
u16 def_offset;
|
|
u16 defect;
|
|
u8 def_zone_no;
|
|
|
|
// 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
|
|
switch (lba & 3) {
|
|
case 0:
|
|
case 3:
|
|
LEOtgt_param.start_block = 0;
|
|
break;
|
|
default:
|
|
LEOtgt_param.start_block = 1;
|
|
break;
|
|
}
|
|
|
|
// Get Virtual & Physical Disk Zones from LBA
|
|
vzone_num = leoLba_to_vzone(lba);
|
|
|
|
// Set Parameter Disk Head & Zone
|
|
LEOtgt_param.zone = def_zone_no = LEOVZONE_PZONEHD_TBL[LEOdisk_type][vzone_num];
|
|
LEOtgt_param.head = 0;
|
|
if (LEOtgt_param.zone > 7) {
|
|
LEOtgt_param.zone -= 7;
|
|
LEOtgt_param.head = 1;
|
|
}
|
|
|
|
// Get the start cylinder from current zone
|
|
zone_scyl = LEOZONE_SCYL_TBL[def_zone_no];
|
|
|
|
// Get Virtual Zone LBA start, if Zone 0, it's LBA 0
|
|
if (vzone_num != 0) {
|
|
zone_slba = LEOVZONE_TBL[LEOdisk_type][vzone_num - 1];
|
|
} else {
|
|
zone_slba = 0;
|
|
}
|
|
// Get Cylinder relative of the current Zone
|
|
zone_tk = (lba - zone_slba) / 2;
|
|
// Calculate Physical Cylinder
|
|
if (LEOtgt_param.head != 0) {
|
|
LEOtgt_param.cylinder = zone_scyl - zone_tk;
|
|
zone_scyl = LEOZONE_OUTERCYL_TBL[LEOtgt_param.zone - 1];
|
|
} else {
|
|
LEOtgt_param.cylinder = zone_scyl + zone_tk;
|
|
}
|
|
|
|
// Get the relative offset to defect tracks for the current zone (if Zone 0, then it's 0)
|
|
if ((u32)def_zone_no != 0) {
|
|
def_offset = LEO_sys_data.param.defect_num[def_zone_no - 1];
|
|
} else {
|
|
def_offset = 0;
|
|
}
|
|
// Get amount of defect tracks for the current zone
|
|
bad_tk_num = LEO_sys_data.param.defect_num[def_zone_no] - def_offset;
|
|
|
|
// Skip defective cylinders
|
|
while (bad_tk_num != 0) {
|
|
defect = zone_scyl + LEO_sys_data.param.defect_data[def_offset];
|
|
if (LEOtgt_param.cylinder < defect) {
|
|
break;
|
|
}
|
|
|
|
LEOtgt_param.cylinder++;
|
|
def_offset++;
|
|
bad_tk_num--;
|
|
}
|
|
|
|
// 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 < 12) {
|
|
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];
|
|
|
|
for (i = 0; i < ARRAY_COUNT(LEOVZONE_TBL[LEOdisk_type]); i++, ptr++) {
|
|
if (lba < *ptr) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return 0xFF;
|
|
}
|