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
264 lines
8.6 KiB
C
264 lines
8.6 KiB
C
#include "ultra64/leo.h"
|
|
#include "ultra64/leoappli.h"
|
|
#include "ultra64/leodrive.h"
|
|
#include "attributes.h"
|
|
|
|
#include "ultra64.h"
|
|
|
|
extern vu16 LEOrw_flags;
|
|
|
|
static void (*cmd_tbl[16])(void) = {
|
|
NULL, leoClr_queue, leoInquiry, leoTest_unit_rdy, leoRezero, leoRead,
|
|
leoWrite, leoSeek, leoStart_stop, leoRd_capacity, leoTranslate, leoMode_sel,
|
|
leoReadDiskId, leoReadTimer, leoSetTimer, leoClr_reset,
|
|
};
|
|
|
|
static LEOCmdRead system_read_cmd = {
|
|
{ LEO_COMMAND_READ, 0, 0, 0, 0, 0, 0, 0, 0 }, 12, 1, 0, 0,
|
|
};
|
|
|
|
static const u8 system_lba[8] = { 0, 1, 8, 9, 0, 0, 0, 0 };
|
|
|
|
OSPiHandle* LEOPiInfo;
|
|
OSIoMesg LEOPiDmaParam;
|
|
s32 currentCommand;
|
|
|
|
u8 leoRead_system_area(void);
|
|
|
|
void leomain(void* arg0) {
|
|
u32 cur_status;
|
|
u32 sense_code;
|
|
u8 disktype_bak;
|
|
|
|
((u8*)&LEO_country_code)[0] = *(vu8*)OS_PHYSICAL_TO_K1(0x10);
|
|
((u8*)&LEO_country_code)[1] = *(vu8*)OS_PHYSICAL_TO_K1(0x90);
|
|
((u8*)&LEO_country_code)[2] = *(vu8*)OS_PHYSICAL_TO_K1(0x110);
|
|
((u8*)&LEO_country_code)[3] = *(vu8*)OS_PHYSICAL_TO_K1(0x190);
|
|
|
|
LEOasic_seq_ctl_shadow = 0;
|
|
LEOasic_bm_ctl_shadow = 0;
|
|
LEOdrive_flag = 0;
|
|
LEOclr_que_flag = 0;
|
|
leoInitUnit_atten();
|
|
LEOPiInfo = osLeoDiskInit();
|
|
LEOPiDmaParam.hdr.pri = 1;
|
|
LEOPiDmaParam.hdr.retQueue = &LEOdma_que;
|
|
osEPiReadIo(LEOPiInfo, ASIC_STATUS, &cur_status);
|
|
if (!(cur_status & 0x400000) && (cur_status & 0x06800000)) {
|
|
leoDrive_reset();
|
|
}
|
|
|
|
while (true) {
|
|
osRecvMesg(&LEOcommand_que, (OSMesg*)&LEOcur_command, OS_MESG_BLOCK);
|
|
currentCommand = LEOcur_command->header.command;
|
|
if (LEOcur_command->header.command == 0) {
|
|
leoDrive_reset();
|
|
osRecvMesg(&LEOevent_que, NULL, OS_MESG_NOBLOCK);
|
|
continue;
|
|
}
|
|
|
|
sense_code = leoChk_asic_ready(0x10001);
|
|
cur_status = leoChkUnit_atten();
|
|
|
|
do {
|
|
if (cur_status == 0) {
|
|
if (sense_code == 0) {
|
|
continue;
|
|
}
|
|
} else {
|
|
switch (sense_code) {
|
|
case 3:
|
|
case 37:
|
|
case 41:
|
|
case 43:
|
|
break;
|
|
case 49:
|
|
if (leoRetUnit_atten() == 43) {
|
|
sense_code = 43;
|
|
}
|
|
break;
|
|
default:
|
|
sense_code = leoRetUnit_atten();
|
|
}
|
|
}
|
|
|
|
switch (sense_code) {
|
|
case 47:
|
|
switch (LEOcur_command->header.command) {
|
|
case 2:
|
|
case 8:
|
|
case 11:
|
|
case 12:
|
|
case 13:
|
|
case 14:
|
|
case 15:
|
|
continue;
|
|
}
|
|
break;
|
|
case 49:
|
|
switch (LEOcur_command->header.command) {
|
|
case 2:
|
|
case 11:
|
|
case 13:
|
|
case 14:
|
|
case 15:
|
|
continue;
|
|
default:
|
|
sense_code = 42;
|
|
}
|
|
break;
|
|
case 43:
|
|
switch (LEOcur_command->header.command) {
|
|
case 15:
|
|
leoClrUA_RESET();
|
|
FALLTHROUGH;
|
|
case 2:
|
|
case 13:
|
|
case 14:
|
|
continue;
|
|
}
|
|
break;
|
|
default:
|
|
/* empty */;
|
|
}
|
|
|
|
if (LEOcur_command->header.command == 3) {
|
|
LEOcur_command->data.modeSelect.reserve1 = leoChk_cur_drvmode();
|
|
}
|
|
LEOcur_command->header.sense = sense_code;
|
|
LEOcur_command->header.status = 2;
|
|
goto post_exe;
|
|
} while (0);
|
|
|
|
if (LEOdrive_flag == 0) {
|
|
switch (LEOcur_command->header.command) {
|
|
case 2:
|
|
case 3:
|
|
case 8:
|
|
case 11:
|
|
case 13:
|
|
case 14:
|
|
case 15:
|
|
break;
|
|
default:
|
|
if (LEO_country_code == 0) {
|
|
osEPiReadIo(LEOPiInfo, ASIC_ID_REG, &cur_status);
|
|
if ((cur_status & 0x70000) != 0x40000) {
|
|
while (true) {}
|
|
}
|
|
}
|
|
|
|
if (leoRead_system_area() != 0) {
|
|
LEOcur_command->header.status = 2;
|
|
goto post_exe;
|
|
}
|
|
|
|
if ((LEOcur_command->header.sense =
|
|
leoSend_asic_cmd_w(0xB0001, LEO_sys_data.param.disk_type << 16)) != 0) {
|
|
LEOcur_command->header.status = 2;
|
|
goto post_exe;
|
|
}
|
|
|
|
if ((LEO_sys_data.param.disk_type & 0xF0) != 0x10) {
|
|
goto invalid_disktype;
|
|
}
|
|
|
|
LEOdisk_type = (LEO_sys_data.param.disk_type & 0xF);
|
|
if (LEOdisk_type >= 7) {
|
|
invalid_disktype:
|
|
LEOcur_command->header.sense = 0xBU;
|
|
LEOcur_command->header.status = 2;
|
|
goto post_exe;
|
|
}
|
|
|
|
LEOdrive_flag = -1;
|
|
}
|
|
}
|
|
|
|
cmd_tbl[LEOcur_command->header.command]();
|
|
|
|
post_exe:
|
|
if (LEOcur_command->header.control & 0x80) {
|
|
osSendMesg(LEOcur_command->header.post, (void*)(s32)LEOcur_command->header.sense, OS_MESG_BLOCK);
|
|
}
|
|
if (LEOclr_que_flag != 0) {
|
|
leoClr_queue();
|
|
}
|
|
}
|
|
}
|
|
|
|
u8 leoRead_system_area(void) {
|
|
LEOCmdRead dummy_cmd;
|
|
void* backup_pointer;
|
|
u32 retry_cntr;
|
|
s32 read_mode;
|
|
|
|
backup_pointer = LEOcur_command;
|
|
LEOcur_command = (LEOCmd*)&dummy_cmd;
|
|
read_mode = 0;
|
|
retry_cntr = 0;
|
|
|
|
while (true) {
|
|
LEOdisk_type = 0;
|
|
// For lba_to_phys to avoid dealing with alternative tracks on the disk
|
|
LEO_sys_data.param.defect_num[0] = 0;
|
|
LEOrw_flags = 0x3000;
|
|
dummy_cmd = system_read_cmd;
|
|
dummy_cmd.buffPtr = &LEO_sys_data;
|
|
|
|
if (read_mode == 0) {
|
|
// read System LBA 12 (+0, this is an offset value for leoRead_common)
|
|
// see system_read_cmd premade struct
|
|
leoRead_common(0);
|
|
switch (dummy_cmd.header.sense) {
|
|
case LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION:
|
|
do {
|
|
// if expecting a retail disk, LBA 12 is expected to do a read error, if not then freeze
|
|
} while (LEO_country_code != 0);
|
|
retry_cntr = 0;
|
|
read_mode--;
|
|
continue;
|
|
case LEO_SENSE_UNRECOVERED_READ_ERROR:
|
|
do {
|
|
// if expecting a development disk, LBA 12 is expected to read correctly, if not then freeze
|
|
} while (LEO_country_code == 0);
|
|
retry_cntr = 0;
|
|
read_mode--;
|
|
continue;
|
|
}
|
|
} else {
|
|
// read System LBA 0,1,8,9 (or 2,3,10,11 for dev)
|
|
dummy_cmd.lba = system_lba[retry_cntr & 3];
|
|
if (LEO_country_code == 0) {
|
|
dummy_cmd.lba += 2;
|
|
}
|
|
leoRead_common(0);
|
|
if (dummy_cmd.header.status == LEO_STATUS_GOOD) {
|
|
do {
|
|
// if disk country and set country code in libleo mismatch, then freeze
|
|
} while (LEO_sys_data.param.country != LEO_country_code);
|
|
goto sys_read_end;
|
|
}
|
|
}
|
|
|
|
system_retry:
|
|
if (leoChk_err_retry(dummy_cmd.header.sense) != LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION) {
|
|
break;
|
|
}
|
|
if (retry_cntr++ >= 0x40U) {
|
|
break;
|
|
}
|
|
if ((retry_cntr & 7) == 0) {
|
|
// Recalibrate drive every 8th tries
|
|
if ((dummy_cmd.header.sense = leoSend_asic_cmd_w(0x30001, 0)) == LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION) {
|
|
continue;
|
|
}
|
|
goto system_retry;
|
|
}
|
|
}
|
|
|
|
sys_read_end:
|
|
LEOcur_command = backup_pointer;
|
|
LEOcur_command->header.sense = dummy_cmd.header.sense;
|
|
return GET_ERROR(*LEOcur_command);
|
|
}
|