1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-05-10 02:54:24 +00:00
oot/src/libleo/leo/leoutil.c
fig02 2278bcb2c3
Remove Variables.h; Decouple z64.h from global.h (#2507)
* 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
2025-04-19 22:04:08 -04:00

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;
}