Compile libleo against IDO 5.3

This commit is contained in:
Diamond Lewis 2023-07-25 22:15:22 -05:00
parent 8d85c0e27e
commit e8514a1f46
29 changed files with 1099 additions and 41 deletions

View File

@ -37,6 +37,8 @@ O_FILES := $(foreach file,$(C_FILES),$(BUILD_DIR)/$(file:.c=.c.o)) \
$(foreach file,$(DATA_FILES),$(BUILD_DIR)/$(file:.bin=.bin.o)) \
DECOMP_C_OBJS := $(filter %.c.o,$(filter-out $(BUILD_DIR)/src/libultra%,$(O_FILES)))
DECOMP_POKE_STADIUM := $(filter %.c.o,$(filter-out $(BUILD_DIR)/src/libleo%,$(DECOMP_C_OBJS)))
DECOMP_LIBLEO := $(filter $(BUILD_DIR)/src/libleo/%.c.o,$(O_FILES))
DEP_FILES := $(O_FILES:.o=.d) $(DECOMP_C_OBJS:.o=.asmproc.d)
@ -249,7 +251,8 @@ build/src/libultra/io/gbpakreadwrite.c.o: CC := $(CC_OLD)
build/src/libultra/io/gbpakselectbank.c.o: CC := $(CC_OLD)
# run ASM-processor on non-libultra source files
$(DECOMP_C_OBJS): CC := $(ASMPROC) $(ASMPROC_FLAGS) $(CC) -- $(AS) $(ASFLAGS) --
$(DECOMP_POKE_STADIUM): CC := $(ASMPROC) $(ASMPROC_FLAGS) $(CC) -- $(AS) $(ASFLAGS) --
$(DECOMP_LIBLEO): CC := $(ASMPROC) $(ASMPROC_FLAGS) $(CC_OLD) -- $(AS) $(ASFLAGS) --
# turn off syntax checking errors for libultra
build/src/libultra/al/%.c.o: CHECK_WARNINGS := -w

View File

@ -15,6 +15,31 @@ typedef struct {
/* 0xA */ u8 start_block;
} tgt_param_form; // size = 0xC
typedef union {
/* 0x00 */ struct {
/* 0x00 */ u32 country;
/* 0x04 */ u8 fmt_type;
/* 0x05 */ u8 disk_type;
/* 0x06 */ u16 ipl_load_len;
/* 0x08 */ u8 defect_num[20];
/* 0x1C */ void* loadptr;
/* 0x20 */ u8 defect_data[192];
/* 0xE0 */ u16 rom_end_lba;
/* 0xE2 */ u16 ram_start_lba;
/* 0xE4 */ u16 ram_end_lba;
} param;
/* 0x00 */ u64 u64_data[29];
} leo_sys_form; // size = 0xE8
typedef struct {
/* 0x0 */ u8 year;
/* 0x1 */ u8 month;
/* 0x2 */ u8 day;
/* 0x3 */ u8 hour;
/* 0x4 */ u8 minute;
/* 0x5 */ u8 second;
} __LOCTime; // size = 0x6
/* libleo conversion tables */
extern const u8 LEOBYTE_TBL1[];
extern const u16 LEOBYTE_TBL2[];
@ -73,6 +98,26 @@ extern const s32 LEORAM_BYTE[];
#define LEO_STATUS_MECHANIC_ERROR 0x00020000
#define LEO_STATUS_DISK_CHANGE 0x00010000
#define LEO_CUR_TK_INDEX_LOCK 0x60000000
#define LEO_BM_STATUS_RUNNING 0x80000000 //Running
#define LEO_BM_STATUS_ERROR 0x04000000 //Error
#define LEO_BM_STATUS_MICRO 0x02000000 //Micro Status?
#define LEO_BM_STATUS_BLOCK 0x01000000 //Block Transfer
#define LEO_BM_STATUS_C1CORRECTION 0x00800000 //C1 Correction
#define LEO_BM_STATUS_C1DOUBLE 0x00400000 //C1 Double
#define LEO_BM_STATUS_C1SINGLE 0x00200000 //C1 Single
#define LEO_BM_STATUS_C1ERROR 0x00010000 //C1 Error
#define LEO_BM_CTL_START 0x80000000 //Start Buffer Manager
#define LEO_BM_CTL_MODE 0x40000000 //Buffer Manager Mode
#define LEO_BM_CTL_IMASK 0x20000000 //BM Interrupt Mask
#define LEO_BM_CTL_RESET 0x10000000 //Buffer Manager Reset
#define LEO_BM_CTL_DISABLE_OR 0x08000000 //Disable OR Check?
#define LEO_BM_CTL_DISABLE_C1 0x04000000 //Disable C1 Correction
#define LEO_BM_CTL_BLOCK 0x02000000 //Block Transfer
#define LEO_BM_CTL_CLR_MECHANIC_INTR 0x01000000 //Mechanic Interrupt Reset
/* ASIC commands */
#define ASIC_NO_OPERATION 0x00000000
#define ASIC_RD_SEEK 0x00010001
@ -95,7 +140,11 @@ extern const s32 LEORAM_BYTE[];
#define ASIC_READ_TIMER_YEAR 0x00120000
#define ASIC_READ_TIMER_DATE 0x00130000
#define ASIC_READ_TIMER_MINUTE 0x00140000
#define ASIC_SET_LED_TIMER 0x00150000
#define ASIC_READ_PROGRAM_VERSION 0x001B0000
#define ASIC_NEED_DISK_IN 0x00000001
#define ASIC_SOFT_RESET_CODE 0x000a0000
#define ASIC_HARD_RESET_CODE 0xaaaa0000
// Functions
extern u8 leoAnalize_asic_status(void);
@ -120,24 +169,55 @@ extern void leoClrUA_RESET(void);
extern void leoClrUA_MEDIUM_CHANGED(void);
extern void leoSetUA_MEDIUM_CHANGED(void);
extern void leoInitUnit_atten(void);
extern void leoClr_queue(void);
extern void leointerrupt(void*);
extern void leomain(void*);
extern void leoRead_common(u32 offset);
extern void leoClrUA_MEDIUM_CHANGED(void);
extern void leoSetUA_MEDIUM_CHANGED(void);
extern int leoC2_Correction(void);
extern s32 leoVerifyRTC(u8 yearhi, u8 yearlo);
extern u8 __locReadTimer(__LOCTime* time);
extern s32 __leoSetReset(void);
extern s32 __osLeoInterrupt(void);
extern u16 leoLba_to_vzone(u32 lba);
extern u16 leoLba_to_phys(u32 lba);
extern s32 __leoActive;
extern s32 __leoResetCalled;
extern s32 __leoQueuesCreated;
extern s32 LEO_country_code;
extern u8 leoDiskStack[];
extern u32 LEOasic_bm_ctl_shadow;
extern u32 LEOasic_seq_ctl_shadow;
extern u8 LEOdisk_type;
extern u8 LEOdrive_flag;
extern u8 leoDiskStack[];
extern u8 LEOcommandThreadStack[0x400];
extern u8 LEOinterruptThreadStack[0x400];
extern u8* LEOwrite_pointer;
extern u8* LEOc2ctrl_que_buf;
extern LEOVersion __leoVersion;
extern LEOCmd* LEOcur_command;
extern OSMesgQueue LEOblock_que;
extern OSMesgQueue LEOevent_que;
extern OSMesgQueue LEOc2ctrl_que;
extern OSMesgQueue LEOcontrol_que;
extern OSMesgQueue LEOpost_que;
extern OSMesgQueue LEOcommand_que;
extern OSMesgQueue LEOdma_que;
extern OSMesg LEOevent_que_buf[1];
extern OSMesg LEOcontrol_que_buf[1];
extern OSMesg LEOdma_que_buf[2];
extern OSMesg LEOblock_que_buf[1];
extern OSMesg LEOpost_que_buf[1];
extern OSIoMesg LEOPiDmaParam;
extern OSPiHandle* LEOPiInfo;
extern OSThread LEOcommandThread;
extern OSThread LEOinterruptThread;
extern tgt_param_form LEOtgt_param;
extern leo_sys_form LEO_sys_data;
extern vu8 LEOclr_que_flag;
extern vu16 LEOrw_flags;
#endif

View File

@ -127,38 +127,38 @@ segments:
- [0x518A0, asm]
- [0x51B20, asm]
- [0x51BC0, c, libleo/readwrite]
- [0x51C50, asm, libleo/leofunc]
- [0x520C0, asm, libleo/leoint]
- [0x52AC0, asm, libleo/leocmdex]
- [0x51C50, c, libleo/leofunc]
- [0x520C0, c, libleo/leoint]
- [0x52AC0, c, libleo/leocmdex]
- [0x53150, c, libleo/leoread]
- [0x53310, asm, libleo/lbatobyte]
- [0x53460, asm, libleo/driverominit]
- [0x535C0, asm, libleo/inquiry]
- [0x53310, c, libleo/lbatobyte]
- [0x53460, c, libleo/driverominit]
- [0x535C0, c, libleo/leoinquiry]
- [0x53670, c, libleo/leodiskinit]
- [0x53710, c, libleo/readdiskid]
- [0x53770, asm, libleo/leord_diskid]
- [0x53770, c, libleo/leord_diskid]
- [0x53900, c, libleo/leomecha]
- [0x54250, asm, libleo/spdlmotor]
- [0x54250, c, libleo/spdlmotor]
- [0x54310, c, libleo/leoc2ecc]
- [0x55400, c, libleo/setrtc]
- [0x55570, asm, libleo/leomseq_tbl]
- [0x55720, asm, libleo/leomotor]
- [0x55810, asm, libleo/leomode_sel]
- [0x55570, c, libleo/leomseq_tbl]
- [0x55720, c, libleo/leomotor]
- [0x55810, c, libleo/leomode_sel]
- [0x558C0, c, libleo/leord_capa]
- [0x55960, asm, libleo/leoutil]
- [0x55BB0, asm, libleo/leorezero]
- [0x55C50, asm, libleo/bytetolba]
- [0x55DB0, asm, libleo/leoreset]
- [0x55ED0, asm, libleo/leotranslat]
- [0x56170, asm, libleo/leotimer]
- [0x56680, asm, libleo/leowrite]
- [0x55960, c, libleo/leoutil]
- [0x55BB0, c, libleo/leorezero]
- [0x55C50, c, libleo/bytetolba]
- [0x55DB0, c, libleo/leoreset]
- [0x55ED0, c, libleo/leotranslat]
- [0x56170, c, libleo/leotimer]
- [0x56680, c, libleo/leowrite]
- [0x567B0, c, libleo/cjcreateleomanager]
- [0x569F0, c, libleo/leointerrupt]
- [0x570C0, c, libleo/driveexist]
- [0x57190, c, libleo/testunitready]
- [0x57230, c, libleo/leotestunit]
- [0x57270, c, libleo/readrtc]
- [0x572D0, asm, libleo/leoseek]
- [0x572D0, c, libleo/leoseek]
- [0x57390, c, libleo/seek]
- [0x573F0, c, libultra/io/piacs]
- [0x574B0, hasm, libultra/os/setcause]

41
src/libleo/bytetolba.c Normal file
View File

@ -0,0 +1,41 @@
#include <ultra64.h>
#include "libleo/internal.h"
s32 LeoByteToLBA(s32 startlba, u32 nbytes, s32* lba) {
u32 reslba;
u32 byte_p_blk;
u16 zone;
u16 vzone;
u8 flag;
if (!__leoActive) {
return -1;
}
reslba = 0;
flag = vzone = 1;
startlba += 0x18;
while (nbytes != 0) {
if ((flag != 0) || (LEOVZONE_TBL[LEOdisk_type][vzone] == startlba)) {
vzone = leoLba_to_vzone(startlba);
zone = LEOVZONE_PZONEHD_TBL[LEOdisk_type][vzone];
if (zone >= 8) {
zone += -7;
}
byte_p_blk = LEOBYTE_TBL2[zone];
}
if (nbytes < byte_p_blk) {
nbytes = 0;
} else {
nbytes -= byte_p_blk;
}
reslba++;
startlba++;
if ((nbytes != 0) && ((u32) startlba >= NUM_LBAS+0x18)) {
return LEO_ERROR_LBA_OUT_OF_RANGE;
}
flag = 0;
}
*lba = reslba;
return 0;
}

View File

@ -1,13 +1,16 @@
#include <ultra64.h>
#include "libleo/internal.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
#ifdef NON_MATCHING
// https://decomp.me/scratch/OYMx2
s32 LeoCJCreateLeoManager(OSPri comPri, OSPri intPri, OSMesg *cmdBuf, s32 cmdMsgCnt) {
OSPiHandle* driveRomHandle;
OSPiHandle* leoDiskHandle;
volatile LEOCmdInquiry cmdBlockInq;
volatile LEOCmd cmdBlockID;
UNUSED volatile LEOCmdInquiry cmdBlockInq;
UNUSED volatile LEOCmd cmdBlockID;
LEODiskID thisID;
u32 stat;
u32 data;
@ -24,7 +27,7 @@ s32 LeoCJCreateLeoManager(OSPri comPri, OSPri intPri, OSMesg *cmdBuf, s32 cmdMsg
driveRomHandle = osDriveRomInit();
__leoActive = 1;
__osSetHWIntrRoutine(1, __osLeoInterrupt, leoDiskStack + 0xFF0);
__osSetHWIntrRoutine(1, __osLeoInterrupt, leoDiskStack);
leoInitialize(comPri, intPri, cmdBuf, cmdMsgCnt);
if (osResetType == 1) {

57
src/libleo/driverominit.c Normal file
View File

@ -0,0 +1,57 @@
#include <ultra64.h>
#include "libleo/internal.h"
void __osPiRelAccess(void);
void __osPiGetAccess(void);
extern OSPiHandle* __osCurrentHandle[];
extern OSPiHandle __DriveRomHandle;
#ifdef NON_MATCHING
// https://decomp.me/scratch/uNZ73
OSPiHandle* osDriveRomInit(void) {
register s32 saveMask;
register u32 value;
register s32 status;
static s32 first = 1; // D_80079580
__osPiGetAccess();
if (!first) {
__osPiRelAccess();
return &__DriveRomHandle;
}
first = 0;
__DriveRomHandle.type = DEVICE_TYPE_BULK;
__DriveRomHandle.baseAddress = PHYS_TO_K1(PI_DOM1_ADDR1);
__DriveRomHandle.domain = PI_DOMAIN1;
__DriveRomHandle.speed = 0;
bzero(&__DriveRomHandle.transferInfo, sizeof(__OSTranxInfo));
while (status = HW_REG(PI_STATUS_REG, u32), status & (PI_STATUS_IO_BUSY | PI_STATUS_DMA_BUSY)) {}
HW_REG(PI_BSD_DOM1_LAT_REG, u32) = 0xff;
HW_REG(PI_BSD_DOM1_PGS_REG, u32) = 0;
HW_REG(PI_BSD_DOM1_RLS_REG, u32) = 3;
HW_REG(PI_BSD_DOM1_PWD_REG, u32) = 0xff;
value = HW_REG(__DriveRomHandle.baseAddress, u32);
__DriveRomHandle.latency = value & 0xFF;
__DriveRomHandle.pulse = (value >> 8) & 0xFF;
__DriveRomHandle.pageSize = (value >> 0x10) & 0xF;
__DriveRomHandle.relDuration = (value >> 0x14) & 0xF;
HW_REG(PI_BSD_DOM1_LAT_REG, u32) = (u8)value;
HW_REG(PI_BSD_DOM1_PGS_REG, u32) = __DriveRomHandle.pageSize;
HW_REG(PI_BSD_DOM1_RLS_REG, u32) = __DriveRomHandle.relDuration;
HW_REG(PI_BSD_DOM1_PWD_REG, u32) = __DriveRomHandle.pulse;
saveMask = __osDisableInt();
__DriveRomHandle.next = __osPiTable;
__osPiTable = &__DriveRomHandle;
__osRestoreInt(saveMask);
__osPiRelAccess();
return &__DriveRomHandle;
}
#else
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/driverominit/osDriveRomInit.s")
#endif

37
src/libleo/lbatobyte.c Normal file
View File

@ -0,0 +1,37 @@
#include <ultra64.h>
#include "libleo/internal.h"
s32 LeoLBAToByte(s32 startlba, u32 nlbas, s32* bytes) {
u32 resbytes;
u32 byte_p_blk;
u16 zone;
u16 vzone;
u8 flag;
if (!__leoActive) {
return -1;
}
resbytes = 0;
flag = vzone = 1;
startlba += 0x18;
while (nlbas > 0) {
if ((flag != 0) || (LEOVZONE_TBL[LEOdisk_type][vzone] == startlba)) {
vzone = leoLba_to_vzone(startlba);
zone = LEOVZONE_PZONEHD_TBL[LEOdisk_type][vzone];
if (zone >= 8) {
zone -= 7;
}
byte_p_blk = LEOBYTE_TBL2[zone];
}
resbytes += byte_p_blk;
nlbas -= 1;
startlba += 1;
if ((nlbas > 0) && ((u32)startlba >= NUM_LBAS+0x18)) {
return LEO_ERROR_LBA_OUT_OF_RANGE;
}
flag = 0;
}
*bytes = resbytes;
return LEO_ERROR_GOOD;
}

View File

@ -1,5 +1,8 @@
#include "common.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leoc2ecc/leoC2_Correction.s")
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leoc2ecc/leoC2_single_ecc.s")

5
src/libleo/leocmdex.c Normal file
View File

@ -0,0 +1,5 @@
#include "common.h"
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leocmdex/leomain.s")
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leocmdex/leoRead_system_area.s")

133
src/libleo/leofunc.c Normal file
View File

@ -0,0 +1,133 @@
#include <ultra64.h>
#include "libleo/internal.h"
#include "PR/os_message.h"
const u8 LEO_ZERO_MESG[] = { 0 };
#ifdef NON_MATCHING
// https://decomp.me/scratch/dB2K5
void leoInitialize(OSPri compri, OSPri intpri, OSMesg* command_que_buf, u32 cmd_buff_size) {
u32 savedMask;
OSPri oldPri;
OSPri myPri;
OSPri pri;
if (intpri < compri) {
pri = compri;
} else {
pri = intpri;
}
oldPri = -1;
myPri = osGetThreadPri(NULL);
if (myPri < pri) {
oldPri = myPri;
osSetThreadPri(NULL, pri);
}
savedMask = __osDisableInt();
__leoQueuesCreated = true;
osCreateMesgQueue(&LEOcommand_que, command_que_buf, cmd_buff_size);
osCreateMesgQueue(&LEOcontrol_que, LEOcontrol_que_buf, ARRAY_COUNT(LEOcontrol_que_buf));
osCreateMesgQueue(&LEOevent_que, LEOevent_que_buf, ARRAY_COUNT(LEOevent_que_buf));
osCreateMesgQueue(&LEOdma_que, LEOdma_que_buf, ARRAY_COUNT(LEOdma_que_buf));
osCreateMesgQueue(&LEOblock_que, LEOblock_que_buf, ARRAY_COUNT(LEOblock_que_buf));
osCreateMesgQueue(&LEOpost_que, LEOpost_que_buf, ARRAY_COUNT(LEOpost_que_buf));
osCreateThread(&LEOcommandThread, 1, leomain, NULL, LEOcommandThreadStack + sizeof(LEOcommandThreadStack), compri);
osStartThread(&LEOcommandThread);
// LEOinterruptThreadStack reused the same memory address (D_80100638) as LEOcommand_que
// This won't compile
osCreateThread(&LEOinterruptThread, 1, leointerrupt, NULL, LEOinterruptThreadStack + sizeof(LEOinterruptThreadStack), intpri);
osStartThread(&LEOinterruptThread);
osSetEventMesg(OS_EVENT_CART, &LEOevent_que, (OSMesg)0x30000);
osSendMesg(&LEOblock_que, NULL, 0);
__osRestoreInt(savedMask);
if (oldPri != -1) {
osSetThreadPri(NULL, oldPri);
}
}
#else
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leofunc/leoInitialize.s")
#endif
void leoCommand(void* cmd_blk_addr) {
if (__leoResetCalled != 0) {
((LEOCmd*)cmd_blk_addr)->header.status = LEO_STATUS_CHECK_CONDITION;
((LEOCmd*)cmd_blk_addr)->header.sense = LEO_SENSE_WAITING_NMI;
if ((((LEOCmd*)cmd_blk_addr)->header.control & LEO_CONTROL_POST) != 0) {
osSendMesg(((LEOCmd*)cmd_blk_addr)->header.post, (OSMesg)LEO_SENSE_WAITING_NMI, 1); // Presumably
}
return;
}
osRecvMesg(&LEOblock_que, NULL, 1);
((LEOCmd*)cmd_blk_addr)->header.status = LEO_STATUS_BUSY;
((LEOCmd*)cmd_blk_addr)->header.sense = LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION;
switch (((LEOCmd*)cmd_blk_addr)->header.command) {
case 1:
LEOclr_que_flag = 0xFF;
leoClr_queue();
LEOclr_que_flag = 0;
((LEOCmd*)cmd_blk_addr)->header.status = LEO_STATUS_GOOD;
if (((LEOCmd*)cmd_blk_addr)->header.control & LEO_CONTROL_POST) {
osSendMesg(((LEOCmd*)cmd_blk_addr)->header.post, (OSMesg)0, 1);
}
break;
case 5:
case 6:
((LEOCmd*)cmd_blk_addr)->data.readwrite.rw_bytes = 0;
goto cmd_queing;
default:
if ((u32)(((LEOCmd*)cmd_blk_addr)->header.command - 1) >= 0xE) {
((LEOCmd*)cmd_blk_addr)->header.sense = LEO_SENSE_INVALID_COMMAND_OPERATION_CODE;
((LEOCmd*)cmd_blk_addr)->header.status = LEO_STATUS_CHECK_CONDITION;
break;
}
cmd_queing:
if (osSendMesg(&LEOcommand_que, (OSMesg)cmd_blk_addr, 0) != 0) {
((LEOCmd*)cmd_blk_addr)->header.sense = LEO_SENSE_QUEUE_FULL;
((LEOCmd*)cmd_blk_addr)->header.status = LEO_STATUS_CHECK_CONDITION;
}
}
osSendMesg(&LEOblock_que, (OSMesg)0, 1);
}
void LeoReset(void) {
__leoResetCalled = true;
if (__leoQueuesCreated) {
LEOclr_que_flag = 0xFF;
leoClr_queue();
LEOclr_que_flag = 0;
osRecvMesg(&LEOevent_que, NULL, 0);
osSendMesg(&LEOevent_que, (OSMesg)ASIC_SOFT_RESET_CODE, 1);
osSendMesg(&LEOcommand_que, (OSMesg)LEO_ZERO_MESG, 1);
}
}
s32 __leoSetReset(void) {
leoDrive_reset();
return 0;
}
s32 LeoResetClear(void) {
LEOCmdHeader resetclear;
resetclear.command = 0xF;
resetclear.control = LEO_CONTROL_POST;
resetclear.status = 0;
resetclear.post = &LEOpost_que;
if (osSendMesg(&LEOcommand_que, &resetclear.command, 0) != 0) {
return LEO_SENSE_QUEUE_FULL;
}
osRecvMesg(&LEOpost_que, NULL, 1);
if (resetclear.status == LEO_STATUS_GOOD) {
return LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION;
}
return resetclear.sense;
}

22
src/libleo/leoinquiry.c Normal file
View File

@ -0,0 +1,22 @@
#include <ultra64.h>
#include "libleo/internal.h"
void leoInquiry(void) {
u32 asic_id;
osEPiReadIo(LEOPiInfo, LEO_ID_REG, &asic_id);
if (leoSend_asic_cmd_w(ASIC_READ_PROGRAM_VERSION, 0) == 0) {
u32 asic_data;
osEPiReadIo(LEOPiInfo, LEO_DATA, &asic_data);
if (asic_data & LEO_STATUS_DISK_CHANGE) {
asic_id |= LEO_STATUS_MOTOR_NOT_SPINNING;
}
}
((LEOCmdInquiry*)LEOcur_command)->dev_type = 0;
((LEOCmdInquiry*)LEOcur_command)->version = asic_id >> 0x10;
((LEOCmdInquiry*)LEOcur_command)->dev_num = 1;
((LEOCmdInquiry*)LEOcur_command)->leo_bios_ver = 0;
LEOcur_command->header.status = LEO_STATUS_GOOD;
}

115
src/libleo/leoint.c Normal file
View File

@ -0,0 +1,115 @@
#include <ultra64.h>
#include "libleo/internal.h"
// #pragma GLOBAL_ASM("asm/nonmatchings/libleo/leoint/leointerrupt.s")
void* read_write_track();
void leointerrupt(void* arg) {
u32 result;
u32 tg_blocks;
osCreateMesgQueue(&LEOc2ctrl_que, (OSMesg)&LEOc2ctrl_que_buf, 1);
while (true) {
osStopThread(&LEOinterruptThread);
tg_blocks = LEOcur_command->data.readwrite.xfer_blks;
LEOwrite_pointer = LEOcur_command->data.readwrite.buff_ptr;
do {
leoLba_to_phys(LEOtgt_param.lba);
if (LEOrw_flags & 0x8000) {
result = leoSeek_i(1);
} else {
result = leoSeek_i(0);
}
if (result != 0) {
goto complete;
}
if (LEOrw_flags & 0x2000) {
LEOtgt_param.rdwr_blocks = 1;
} else if (LEOtgt_param.rdwr_blocks > tg_blocks) {
LEOtgt_param.rdwr_blocks = tg_blocks;
}
LEOtgt_param.lba += LEOtgt_param.rdwr_blocks;
tg_blocks -= LEOtgt_param.rdwr_blocks;
result = read_write_track();
if (result != 0) {
goto complete;
}
LEOcur_command->data.readwrite.rw_bytes = LEOwrite_pointer - (u8*)LEOcur_command->data.readwrite.buff_ptr;
} while (tg_blocks != 0);
result = 0x90000; // Inaccessible?
complete:;
osSendMesg(&LEOcontrol_que, result, 1);
}
}
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leoint/read_write_track.s")
u32 leoChk_mecha_int(void) {
u32 stat = leoWait_mecha_cmd_done(ASIC_RD_SEEK);
u32 index_stat;
if (stat == 0) {
osEPiReadIo(LEOPiInfo, LEO_CUR_TK, &index_stat);
if ((index_stat & LEO_CUR_TK_INDEX_LOCK) != LEO_CUR_TK_INDEX_LOCK) {
stat = 0x18;
}
}
return stat;
}
void leosetup_BM(void) {
osEPiWriteIo(LEOPiInfo, 0x05000510U, LEOasic_bm_ctl_shadow | 0x10000000);
osEPiWriteIo(LEOPiInfo, 0x05000510U, LEOasic_bm_ctl_shadow);
if (LEOtgt_param.start_block != 0) {
LEOasic_bm_ctl_shadow = 0x5A0000;
} else {
LEOasic_bm_ctl_shadow = 0;
}
if (!(LEOrw_flags & 0x8000)) {
LEOasic_bm_ctl_shadow |= 0x40000000;
}
if (LEOtgt_param.rdwr_blocks == 2) {
LEOasic_bm_ctl_shadow |= 0x02000000;
}
osEPiWriteIo(LEOPiInfo, 0x05000510U, LEOasic_bm_ctl_shadow);
}
#ifdef NON_MATCHING
u32 leochk_err_reg(void) {
u32 sense;
u32 index_status;
osEPiReadIo(LEOPiInfo, 0x05000514U, &sense);
osEPiWriteIo(LEOPiInfo, 0x05000510U, LEOasic_bm_ctl_shadow | 0x10000000);
osEPiWriteIo(LEOPiInfo, 0x05000510U, LEOasic_bm_ctl_shadow);
if (sense & 0x04000000) {
return 0x31;
}
if (sense & 0x10000000) {
return 4;
}
if (sense & 0x42000000) {
if (LEOrw_flags & 0x8000) {
return 0x16;
}
return 0x17;
}
if (sense & 0x80000000) {
return 0x18;
}
osEPiReadIo(LEOPiInfo, 0x0500050CU, &index_status);
if ((index_status & 0x60000000) == 0x60000000) {
return 0x19;
}
return 0x18;
}
#else
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leoint/leochk_err_reg.s")
#endif

View File

@ -215,7 +215,14 @@ u8 leoRecal_w(void) {
return leoSend_asic_cmd_w(ASIC_RECAL, 0);
}
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leomecha/leoSeek_i.s")
u8 leoSeek_i(u16 rwmode) {
u32 tgt_tk = ((LEOtgt_param.head << 0xC) + LEOtgt_param.cylinder) << 0x10;
if (rwmode == 0) {
return leoSend_asic_cmd_i(0x10001, tgt_tk);
}
return leoSend_asic_cmd_i(0x20001, tgt_tk);
}
u8 leoSeek_w(void) {
u8 sksense = leoSeek_i(0);
@ -231,7 +238,7 @@ s32 leoRecv_event_mesg(s32 control) {
u32 done_mesg;
if (osRecvMesg(&LEOevent_que, (OSMesg*)&done_mesg, control) == 0) {
if (done_mesg == 0xA0000) {
if (done_mesg == ASIC_SOFT_RESET_CODE) {
leoDrive_reset();
return 0xFF;
}
@ -239,12 +246,63 @@ s32 leoRecv_event_mesg(s32 control) {
return 0;
}
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leomecha/leoChk_err_retry.s")
#ifdef NON_MATCHING
// https://decomp.me/scratch/BFO8S
u32 leoChk_err_retry(u32 sense) {
if ((currentCommand == LEO_COMMAND_READ_DISK_ID) || (currentCommand == LEO_COMMAND_START_STOP)) {
switch (sense) {
case LEO_SENSE_POWERONRESET_DEVICERESET_OCCURED:
unit_atten |= 2;
case LEO_SENSE_DIAGNOSTIC_FAILURE:
case LEO_SENSE_COMMAND_PHASE_ERROR:
case LEO_SENSE_WAITING_NMI:
case LEO_SENSE_DEVICE_COMMUNICATION_FAILURE:
case LEO_SENSE_MEDIUM_NOT_PRESENT:
case LEO_SENSE_EJECTED_ILLEGALLY_RESUME:
LEOdrive_flag = 0;
return -1;
}
} else {
switch (sense) {
case LEO_SENSE_POWERONRESET_DEVICERESET_OCCURED:
unit_atten |= 2;
break;
case LEO_SENSE_MEDIUM_MAY_HAVE_CHANGED:
unit_atten |= 1;
break;
case LEO_SENSE_DIAGNOSTIC_FAILURE:
case LEO_SENSE_COMMAND_PHASE_ERROR:
case LEO_SENSE_WAITING_NMI:
case LEO_SENSE_DEVICE_COMMUNICATION_FAILURE:
case LEO_SENSE_MEDIUM_NOT_PRESENT:
case LEO_SENSE_EJECTED_ILLEGALLY_RESUME:
LEOdrive_flag = 0;
return -1;
}
}
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leomecha/leoChk_cur_drvmode.s")
return 0;
}
#else
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leomecha/leoChk_err_retry.s")
#endif
u8 leoChk_cur_drvmode(void) {
u8 devstat = 0;
if (!(asic_cur_status & 0x1000000)) {
devstat = 1;
}
if (asic_cur_status & 0x80000) {
devstat |= 2;
}
if (asic_cur_status & 0x100000) {
devstat |= 4;
}
return devstat;
}
void leoDrive_reset() {
osEPiWriteIo(LEOPiInfo, LEO_HARD_RESET, 0xAAAA0000);
osEPiWriteIo(LEOPiInfo, LEO_HARD_RESET, ASIC_HARD_RESET_CODE);
}
u32 leoChkUnit_atten(void) {

25
src/libleo/leomode_sel.c Normal file
View File

@ -0,0 +1,25 @@
#include <ultra64.h>
#include "libleo/internal.h"
void leoMode_sel(void) {
u32 sense;
sense = leoSend_asic_cmd_w_nochkDiskChange(ASIC_SET_STBY, LEOcur_command->data.time.yearlo << 0x10);
if (sense != LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION) {
goto mselerror;
}
sense = leoSend_asic_cmd_w_nochkDiskChange(ASIC_SET_SLEEP, LEOcur_command->data.time.month << 0x10);
if (sense != LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION) {
goto mselerror;
}
sense = leoSend_asic_cmd_w_nochkDiskChange(ASIC_SET_LED_TIMER, LEOcur_command->data.readwrite.xfer_blks);
if (sense != LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION) {
mselerror:
LEOcur_command->header.sense = sense;
LEOcur_command->header.status = LEO_STATUS_CHECK_CONDITION;
return;
}
LEOcur_command->header.sense = sense;
LEOcur_command->header.status = LEO_STATUS_GOOD;
}

35
src/libleo/leomotor.c Normal file
View File

@ -0,0 +1,35 @@
#include <ultra64.h>
#include "libleo/internal.h"
void leoStart_stop(void) {
u32 send_cmd;
u8 sense_code;
u8 retry_cntr = 8;
u32 send_data;
do {
send_data = 0;
if ((LEOcur_command->header.control & 1)) {
send_cmd = 0x50001;
} else if ((LEOcur_command->header.control & 2)) {
send_cmd = 0xD0000;
} else {
if ((LEOcur_command->header.control & 4)) {
send_data = 0x10000;
}
send_cmd = 0x40000;
}
sense_code = leoSend_asic_cmd_w_nochkDiskChange(send_cmd, send_data);
if (sense_code == 0) {
LEOcur_command->header.status = 0;
return;
}
if (leoChk_err_retry(sense_code)) {
break;
}
} while (retry_cntr--);
LEOcur_command->header.sense = sense_code;
LEOcur_command->header.status = 2;
return;
}

51
src/libleo/leomseq_tbl.c Normal file
View File

@ -0,0 +1,51 @@
#include <ultra64.h>
#include "libleo/internal.h"
u32 mseq_tbl[0x10];
const u32 rd_mseq_code[0x10] = {
0x00010000, 0x00020200, 0x80030100, 0x82040000, 0xA8050000, 0xA0060600, 0x31760000, 0x00020300,
0, 0, 0, 0, 0, 0, 0, 0x4060000,
};
const u32 wt_mseq_code[0x10] = {
0x40020000, 0x00020000, 0x40130B00, 0x42140100, 0x68050000, 0x50060600, 0x401702FF, 0x01870000,
0x40020000, 0, 0, 0, 0, 0, 0, 0x40F0000,
};
void leoSet_mseq(u16 rwmode) {
u32* tbl;
u32 sct_byte_x;
u32 sct_byte_u;
u8 i;
LEOasic_seq_ctl_shadow &= 0xBFFFFFFF;
osEPiWriteIo(LEOPiInfo, LEO_SEQ_STATUS, LEOasic_seq_ctl_shadow);
if (rwmode == 1) {
tbl = wt_mseq_code;
} else {
tbl = rd_mseq_code;
}
for (i = 0; i < 0x10; i++, tbl++) {
mseq_tbl[i] = *tbl;
}
sct_byte_x = sct_byte_u = LEOtgt_param.sec_bytes - 1;
sct_byte_u += 7;
sct_byte_x <<= 8;
mseq_tbl[4] |= sct_byte_x;
osWritebackDCache(mseq_tbl, 0x40);
LEOPiDmaParam.dramAddr = mseq_tbl;
LEOPiDmaParam.devAddr = LEO_RAM_ADDR;
LEOPiDmaParam.size = 0x40;
LEOPiInfo->transferInfo.cmdType = 2;
osEPiStartDma(LEOPiInfo, &LEOPiDmaParam, 1);
osRecvMesg(&LEOdma_que, NULL, 1);
osEPiWriteIo(LEOPiInfo, LEO_SEC_BYTE, (sct_byte_u | 0x5900) << 0x10);
if (LEOrw_flags & 0x800) {
sct_byte_x += 0x100;
}
osEPiWriteIo(LEOPiInfo, LEO_HOST_SECBYTE, sct_byte_x << 8);
LEOasic_seq_ctl_shadow |= LEO_STATUS_DATA_REQUEST;
osEPiWriteIo(LEOPiInfo, LEO_SEQ_CTL, LEOasic_seq_ctl_shadow);
}

View File

@ -22,5 +22,3 @@ void leoRd_capacity(void) {
}
LEOcur_command->header.status = LEO_STATUS_GOOD;
}
// #pragma GLOBAL_ASM("asm/nonmatchings/libleo/leord_capa/leoRd_capacity.s")

View File

@ -0,0 +1,3 @@
#include "common.h"
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leord_diskid/leoReadDiskId.s")

View File

@ -1,8 +1,6 @@
#include <ultra64.h>
#include "libleo/internal.h"
void leoRead_common(u32 offset);
void leoRead(void) {
LEOrw_flags = 0;
leoRead_common(0x18);

27
src/libleo/leoreset.c Normal file
View File

@ -0,0 +1,27 @@
#include <ultra64.h>
#include "libleo/internal.h"
void leoClr_queue(void) {
OSMesg clr_cmd;
while (osRecvMesg(&LEOcommand_que, &clr_cmd, OS_MESG_NOBLOCK) == 0) {
((LEOCmd*)clr_cmd)->header.sense = LEO_SENSE_COMMAND_TERMINATED;
((LEOCmd*)clr_cmd)->header.status = LEO_STATUS_CHECK_CONDITION;
if (((LEOCmd*)clr_cmd)->header.control & LEO_CONTROL_POST) {
osSendMesg(((LEOCmd*)clr_cmd)->header.post, (OSMesg)LEO_SENSE_COMMAND_TERMINATED, OS_MESG_BLOCK);
}
}
}
void leoClr_reset(void) {
u32 code = leoAnalize_asic_status();
if ((code == LEO_SENSE_COMMAND_PHASE_ERROR) || (code == LEO_SENSE_DEVICE_COMMUNICATION_FAILURE) ||
(code == LEO_SENSE_POWERONRESET_DEVICERESET_OCCURED)) {
LEOcur_command->header.sense = code;
LEOcur_command->header.status = LEO_STATUS_CHECK_CONDITION;
} else {
LEOcur_command->header.sense = LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION;
LEOcur_command->header.status = LEO_STATUS_GOOD;
}
}

26
src/libleo/leorezero.c Normal file
View File

@ -0,0 +1,26 @@
#include <ultra64.h>
#include "libleo/internal.h"
void leoRezero(void) {
u8 sense_code;
u8 retry_cntr = 8;
do {
sense_code = leoRecal_w();
if (sense_code == LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION) {
LEOtgt_param.cylinder = 0;
LEOtgt_param.head = 0;
LEOtgt_param.zone = 0;
LEOcur_command->header.status = LEO_STATUS_GOOD;
return;
}
if (leoChk_err_retry(sense_code) != 0) {
break;
}
} while (retry_cntr--);
LEOcur_command->header.sense = sense_code;
LEOcur_command->header.status = LEO_STATUS_CHECK_CONDITION;
}

31
src/libleo/leoseek.c Normal file
View File

@ -0,0 +1,31 @@
#include <ultra64.h>
#include "libleo/internal.h"
void leoSeek(void) {
u8 sense_code;
u8 retry_cntr = 20;
if (LEOcur_command->data.seek.lba > LEO_LBA_MAX) {
LEOcur_command->header.sense = LEO_SENSE_LBA_OUT_OF_RANGE;
LEOcur_command->header.status = LEO_STATUS_CHECK_CONDITION;
return;
}
leoLba_to_phys(LEOcur_command->data.seek.lba + 0x18);
do {
sense_code = leoSeek_w();
if (sense_code == LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION) {
LEOcur_command->header.status = LEO_STATUS_GOOD;
return;
}
if (leoChk_err_retry(sense_code) != 0) {
break;
}
} while (retry_cntr--);
LEOcur_command->header.sense = sense_code;
LEOcur_command->header.status = LEO_SENSE_DIAGNOSTIC_FAILURE;
return;
}

83
src/libleo/leotimer.c Normal file
View File

@ -0,0 +1,83 @@
#include <ultra64.h>
#include "libleo/internal.h"
void leoReadTimer(void) {
UNUSED u8* filler;
UNUSED u8 padding[4];
__LOCTime time;
u8 sense_code = __locReadTimer(&time);
LEOcur_command->data.time.yearlo = time.year;
LEOcur_command->data.time.month = time.month;
LEOcur_command->data.time.day = time.day;
LEOcur_command->data.time.hour = time.hour;
LEOcur_command->data.time.minute = time.minute;
LEOcur_command->data.time.second = time.second;
if (sense_code != 0) {
LEOcur_command->header.sense = sense_code;
LEOcur_command->header.status = LEO_STATUS_CHECK_CONDITION;
return;
}
if ((u8) LEOcur_command->data.time.yearlo >= 0x96U) {
LEOcur_command->data.time.yearhi = 0x19;
} else {
LEOcur_command->data.time.yearhi = 0x20;
}
LEOcur_command->header.status = 0;
}
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leotimer/leoSetTimer.s")
u8 __locReadTimer(__LOCTime* time) {
u32 data;
u8 sense_code;
sense_code = leoSend_asic_cmd_w_nochkDiskChange(ASIC_READ_TIMER_MINUTE, 0U);
if (sense_code != 0) {
return sense_code;
}
osEPiReadIo(LEOPiInfo, LEO_DATA, &data);
time->minute = (u8) ((u32) (data & 0xFF000000) >> 0x18);
time->second = (s8) ((u32) (data & 0xFF0000) >> 0x10);
sense_code = leoSend_asic_cmd_w_nochkDiskChange(ASIC_READ_TIMER_DATE, 0U);
if (sense_code != 0) {
time->minute = (u8) (time->minute & 0xFF7F);
return sense_code;
}
osEPiReadIo(LEOPiInfo, LEO_DATA, &data);
time->day = (s8) ((u32) (data & 0xFF000000) >> 0x18);
time->hour = (s8) ((u32) (data & 0xFF0000) >> 0x10);
sense_code = leoSend_asic_cmd_w_nochkDiskChange(ASIC_READ_TIMER_YEAR, 0U);
if (sense_code != 0) {
time->minute = (u8) (time->minute & 0xFF7F);
return sense_code;
}
osEPiReadIo(LEOPiInfo, LEO_DATA, &data);
sense_code = time->minute;
time->year = (s8) ((u32) (data & 0xFF000000) >> 0x18);
time->month = (s8) ((u32) (data & 0xFF0000) >> 0x10);
if (sense_code & 0x80) {
time->minute = (u8) (sense_code & 0xFF7F);
return 5;
}
return 0;
}
u8 __locSetTimer(__LOCTime* time) {
u32 yearMonth;
u32 dayHour;
u32 minuteSecond;
u8 temp_v0;
u8 temp_v0_2;
u8 temp_v0_3;
u8 result;
yearMonth = (time->year << 0x18) + (time->month << 0x10);
dayHour = (time->day << 0x18) + (time->hour << 0x10);
minuteSecond = (time->minute << 0x18) + (time->second << 0x10);
temp_v0 = leoSend_asic_cmd_w_nochkDiskChange(ASIC_SET_TIMER_YEAR, yearMonth);
result = temp_v0;
if ((temp_v0 != 0) || (temp_v0_2 = leoSend_asic_cmd_w_nochkDiskChange(ASIC_SET_TIMER_DATE, dayHour), result = temp_v0_2, (temp_v0_2 != 0)) || (temp_v0_3 = leoSend_asic_cmd_w_nochkDiskChange(ASIC_SET_TIMER_MINUTE, minuteSecond), result = temp_v0_3, (temp_v0_3 != 0))) {
return result;
}
return 0;
}

75
src/libleo/leotranslat.c Normal file
View File

@ -0,0 +1,75 @@
#include <ultra64.h>
#include "libleo/internal.h"
void leoTranslate(void) {
u32 lba;
u32 calc_bytes;
u32 calc_blks;
u32 byte_p_blk;
u16 zone;
u16 vzone;
u8 flag; // boolean
if (LEOcur_command->data.readwrite.lba >= NUM_LBAS) {
LEOcur_command->header.sense = LEO_SENSE_LBA_OUT_OF_RANGE;
LEOcur_command->header.status = LEO_STATUS_CHECK_CONDITION;
return;
}
lba = LEOcur_command->data.readwrite.lba + 0x18;
calc_blks = 0;
calc_bytes = 0;
flag = vzone = 1;
if (LEOcur_command->header.control & LEO_CONTROL_TBL) {
calc_bytes = LEOcur_command->data.readwrite.xfer_blks;
while (calc_bytes != 0) {
if (flag || (LEOVZONE_TBL[LEOdisk_type][vzone] == lba)) {
vzone = leoLba_to_vzone(lba);
zone = LEOVZONE_PZONEHD_TBL[LEOdisk_type][vzone];
if (zone >= 8)
zone -= 7;
byte_p_blk = LEOBYTE_TBL2[zone];
}
if (calc_bytes < byte_p_blk) {
calc_bytes = 0;
} else {
calc_bytes -= byte_p_blk;
}
calc_blks++;
lba++;
if ((calc_bytes != 0) && (lba >= 0x10DC)) {
LEOcur_command->header.sense = LEO_SENSE_LBA_OUT_OF_RANGE;
LEOcur_command->header.status = LEO_STATUS_CHECK_CONDITION;
return;
}
flag = false;
}
LEOcur_command->data.readwrite.buff_ptr = calc_blks;
} else {
calc_blks = LEOcur_command->data.readwrite.xfer_blks;
while (calc_blks != 0) {
if (flag || (LEOVZONE_TBL[LEOdisk_type][vzone] == lba)) {
vzone = leoLba_to_vzone(lba);
zone = LEOVZONE_PZONEHD_TBL[LEOdisk_type][vzone];
if (zone >= 8)
zone -= 7;
byte_p_blk = LEOBYTE_TBL2[zone];
}
calc_bytes += byte_p_blk;
calc_blks--;
lba++;
if ((calc_blks != 0) && (lba >= 0x10DC)) {
LEOcur_command->header.sense = LEO_SENSE_LBA_OUT_OF_RANGE;
LEOcur_command->header.status = LEO_STATUS_CHECK_CONDITION;
return;
}
flag = false;
}
LEOcur_command->data.readwrite.buff_ptr = calc_bytes;
}
LEOcur_command->header.status = LEO_STATUS_GOOD;
}

34
src/libleo/leoutil.c Normal file
View File

@ -0,0 +1,34 @@
#include <ultra64.h>
#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 },
{ 0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x06A2, 0x07C6, 0x08D8, 0x09EA, 0x0AFC, 0x0BC8, 0x0C94, 0x0DA6, 0x0EB8,
0x0FCA, 0x10DC },
{ 0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x08C6, 0x09EA, 0x0AFC, 0x0C0E, 0x0CDA, 0x0DA6, 0x0EB8,
0x0FCA, 0x10DC },
{ 0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x08B4, 0x09C6, 0x0AEA, 0x0C0E, 0x0D20, 0x0DEC, 0x0EB8,
0x0FCA, 0x10DC },
{ 0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x08B4, 0x09C6, 0x0AD8, 0x0BEA, 0x0D0E, 0x0E32, 0x0EFE,
0x0FCA, 0x10DC },
{ 0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x086E, 0x0980, 0x0A92, 0x0BA4, 0x0CB6, 0x0DC8, 0x0EEC,
0x1010, 0x10DC },
{ 0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x086E, 0x093A, 0x0A4C, 0x0B5E, 0x0C70, 0x0D82, 0x0E94,
0x0FB8, 0x10DC },
};
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;
}

54
src/libleo/leowrite.c Normal file
View File

@ -0,0 +1,54 @@
#include <ultra64.h>
#include "libleo/internal.h"
#ifdef NON_MATCHING
void leoWrite(void) {
u32 message;
u32 start_lba;
u32 xfer_blk;
u32 write_bytes = 0;
u8 retry_count = 0;
start_lba = LEOcur_command->data.readwrite.lba;
xfer_blk = LEOcur_command->data.readwrite.xfer_blks;
if (((start_lba | xfer_blk) & 0xFFFF0000) != 0) {
goto invalid_lba;
}
start_lba += 0x18;
if ((start_lba >= 0x10DC) || (start_lba + xfer_blk > 0x10DC)) {
invalid_lba:
LEOcur_command->header.sense = LEO_SENSE_LBA_OUT_OF_RANGE;
LEOcur_command->header.status = LEO_STATUS_CHECK_CONDITION;
return;
}
if (start_lba < LEORAM_START_LBA[LEOdisk_type]) {
LEOcur_command->header.sense = LEO_SENSE_WRITE_PROTECT_ERROR;
LEOcur_command->header.status = LEO_STATUS_CHECK_CONDITION;
return;
}
if (xfer_blk == 0) {
LEOcur_command->header.sense = LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION;
LEOcur_command->header.status = LEO_STATUS_GOOD;
return;
}
LEOrw_flags = 0x8000;
LEOtgt_param.lba = start_lba;
osStartThread(&LEOinterruptThread);
osRecvMesg(&LEOcontrol_que, (OSMesg*)&message, OS_MESG_BLOCK);
if (message != 0x90000) {
LEOcur_command->header.sense = message;
LEOcur_command->header.status = LEO_STATUS_CHECK_CONDITION;
return;
}
LEOcur_command->header.sense = LEO_SENSE_NO_ADDITIONAL_SENSE_INFOMATION;
LEOcur_command->header.status = LEO_STATUS_GOOD;
}
#else
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leowrite/leoWrite.s")
#endif

View File

@ -22,13 +22,11 @@ s32 LeoSetRTC(LEOCmd* cmdBlock, LEODiskTime* RTCdata, OSMesgQueue* mq) {
return 0;
}
#ifdef NON_MATCHING
/*
* The "year" is expressed in 4 digits with the high 2 digits being yearhi and low 2 digits being yearlo. 2023 = 0x20, 0x23
* The "hour" member uses the 24-hour clock.
* Return 0 if year is between ranges from 1996 to 2095
*/
// https://decomp.me/scratch/NUHIy
s32 leoVerifyRTC(u8 yearhi, u8 yearlo) {
u32 year;
if (((yearlo & 0xF) >= 0xA) || ((yearlo & 0xF0) >= 0x91) || ((yearhi & 0xF) >= 0xA) || ((yearhi & 0xF0) >= 0x91)) {
@ -40,6 +38,3 @@ s32 leoVerifyRTC(u8 yearhi, u8 yearlo) {
}
return 0;
}
#else
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/setrtc/leoVerifyRTC.s")
#endif

34
src/libleo/spdlmotor.c Normal file
View File

@ -0,0 +1,34 @@
#include <ultra64.h>
#include "libleo/internal.h"
s32 LeoSpdlMotor(LEOCmd* cmdBlock, u8 mode, OSMesgQueue* mq) {
if (!__leoActive) {
return -1;
}
cmdBlock->header.command = LEO_COMMAND_START_STOP;
cmdBlock->header.reserve1 = 0;
switch (mode) {
case LEO_MOTOR_ACTIVE:
cmdBlock->header.control = LEO_CONTROL_START;
break;
case LEO_MOTOR_STANDBY:
cmdBlock->header.control = LEO_CONTROL_STBY;
break;
case LEO_MOTOR_SLEEP:
cmdBlock->header.control = 0;
break;
case LEO_MOTOR_BRAKE:
cmdBlock->header.control = LEO_CONTROL_BRAKE;
break;
}
cmdBlock->header.reserve3 = 0;
if (mq != NULL) {
cmdBlock->header.post = mq;
cmdBlock->header.control |= LEO_CONTROL_POST;
}
leoCommand(cmdBlock);
return 0;
}

View File

@ -16,6 +16,7 @@ _Litob = 0x80064CA0;
_Printf = 0x8005D850;
_Putfld = 0x8005D1E0;
__leoSetReset = 0x80051414;
__leoResetCalled = 0x80079510;
__ll_div = 0x8005751C;
__ll_lshift = 0x800574B4;
__ll_mod = 0x80057608;
@ -76,6 +77,8 @@ __ull_div = 0x80057478;
__ull_divremi = 0x800575A8;
__ull_rem = 0x8005743C;
__ull_rshift = 0x80057410;
__locReadTimer = 0x80055864;
__locSetTimer = 0x800559D4;
guLookAtReflect = 0x8005AECC;
guLookAtReflectF = 0x8005AAC0;
guMtxF2L = 0x8005AF50;
@ -92,16 +95,37 @@ guTranslateF = 0x8005E5A0;
ldiv = 0x80064C10;
LEOcur_command = 0x801006C8;
LEOPiInfo = 0x80100710;
LEOPiDmaParam = 0x80100718;
mseq_tbl = 0x80101090;
rd_mseq_code = 0x8007E170;
wt_mseq_code = 0x8007E1B0;
unit_atten = 0x80100844;
asic_cur_status = 0x80100840;
currentCommand = 0x80100730;
LEOinterruptThread = 0x800FFC88;
LEOc2ctrl_que = 0x801006F8;
LEOcommand_que = 0x80100638;
LEOcontrol_que = 0x80100668;
LEOcontrol_que_buf = 0x801006B4;
LEOevent_que = 0x80100650;
LEOevent_que_buf = 0x801006B0;
LEOdma_que = 0x80100680;
LEOdma_que_buf = 0x801006B8;
LEOpost_que = 0x800FF9D0;
LEOpost_que_buf = 0x800FF9E8;
LEOblock_que = 0x80100698;
LEOblock_que_buf = 0x801006C0;
LEOcommandThread = 0x800FFAD8;
LEOcommandThreadStack = 0x80100238;
LEOinterruptThread = 0x800FFC88;
LEOinterruptThreadStack = 0x80100638;
LEOclr_que_flag = 0x801006D5;
LEO_ZERO_MESG = 0X8007DA30;
LEORAM_START_LBA = 0x8007DD18;
LEORAM_BYTE = 0x8007DD28;
LEOVZONE_TBL = 0x8007DB98;
LEOVZONE_PZONEHD_TBL = 0x8007DC98;
LEOBYTE_TBL2 = 0x8007DB84;
LEOdrive_flag = 0x801006D4;
LEOevent_que = 0x80100650;
LEOtgt_param = 0x801006E0;
leoDiskStack = 0x801020D0;
LEOdisk_type = 0x801006D8;
@ -156,6 +180,14 @@ leoTest_unit_rdy = 0x80056630;
leoTranslate = 0x800552D0;
leoWait_mecha_cmd_done = 0x80053150;
leointerrupt = 0x800514C0;
read_write_track = 0x80051650;
leoChk_mecha_int = 0x80051C4C;
leosetup_BM = 0x80051CB4;
leochk_err_reg = 0x80051D9C;
LEOwrite_pointer = 0x801006C4;
LEOc2ctrl_que_buf = 0x801006F0;
LEOasic_bm_ctl_shadow = 0x801006CC;
LEOasic_seq_ctl_shadow = 0x801006D0;
leomain = 0x80051EC0;
lldiv = 0x80064B10;
main_func = 0x80000530;
@ -415,7 +447,7 @@ __CartRomHandle = 0x801038D0;
__DriveRomHandle = 0x80100740;
__osPfsLastChannel = 0x8007AE50;
__osViDevMgr = 0x8007AE90;
__osLeoDevMgr = 0x80079514;
__leoQueuesCreated = 0x80079514;
__leoActive = 0x800795B0;
__leoVersion = 0x801010D0;
__additional_scanline = 0x8007AEAC;