Merge pull request #68 from LuigiBlood/libleo

Libleo
This commit is contained in:
Revo
2023-08-15 09:58:54 -04:00
committed by GitHub
3 changed files with 165 additions and 9 deletions

View File

@@ -198,6 +198,7 @@ extern s32 __leoSetReset(void);
extern s32 __osLeoInterrupt(void);
extern u16 leoLba_to_vzone(u32 lba);
extern u16 leoLba_to_phys(u32 lba);
extern void leoSet_mseq(u16 rwmode);
extern s32 __leoActive;
extern s32 __leoResetCalled;

View File

@@ -3,8 +3,12 @@
extern vu16 LEOrw_flags;
extern u8 LEOC2_Syndrome[2][0xE8*4];
extern block_param_form LEOc2_param;
void* read_write_track();
u32 read_write_track();
u32 leoChk_mecha_int(void);
void leosetup_BM(void);
u32 leochk_err_reg(void);
void leointerrupt(void* arg) {
u32 result;
@@ -50,7 +54,164 @@ void leointerrupt(void* arg) {
}
}
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leoint/read_write_track.s")
u32 read_write_track(void) {
u32 message;
u32 block;
u32 retry_cntr;
block_param_form block_param;
u16 bnum;
u8* temp;
u32 c2datasize;
block_param.bytes = LEOtgt_param.sec_bytes;
block_param.blkbytes = LEOtgt_param.blk_bytes;
if (LEOrw_flags & 0x2000) {
//Sector Mode
block_param.blkbytes = block_param.bytes;
}
block_param.pntr = LEOwrite_pointer;
LEOwrite_pointer += block_param.blkbytes;
if (LEOtgt_param.rdwr_blocks == 2) {
LEOwrite_pointer += block_param.blkbytes;
}
retry_cntr = 0;
for (;;) {
LEOPiInfo->transferInfo.transferMode = 1;
LEOPiInfo->transferInfo.blockNum = 0;
LEOPiInfo->transferInfo.block[0].C1ErrNum = 0;
LEOPiInfo->transferInfo.block[0].sectorSize = block_param.bytes;
LEOPiInfo->transferInfo.block[0].dramAddr = block_param.pntr;
LEOPiInfo->transferInfo.block[0].C2Addr = &LEOC2_Syndrome[0];
if (LEOrw_flags & 0x2000) {
//Sector Mode
LEOtgt_param.rdwr_blocks = 1;
LEOPiInfo->transferInfo.transferMode = 3;
} else if (LEOtgt_param.rdwr_blocks == 2) {
LEOPiInfo->transferInfo.transferMode = 2;
LEOPiInfo->transferInfo.block[1] = LEOPiInfo->transferInfo.block[0];
LEOPiInfo->transferInfo.block[1].C2Addr = &LEOC2_Syndrome[1];
LEOPiInfo->transferInfo.block[1].dramAddr = ((u8*)LEOPiInfo->transferInfo.block[1].dramAddr + block_param.blkbytes);
}
message = leoChk_mecha_int();
if (message == 0) {
if (LEOrw_flags & 0x8000) {
//Write Mode
leoSet_mseq(1);
} else {
//Read Mode
leoSet_mseq(0);
}
leosetup_BM();
LEOPiInfo->transferInfo.bmCtlShadow = LEOasic_bm_ctl_shadow;
LEOPiInfo->transferInfo.seqCtlShadow = LEOasic_seq_ctl_shadow;
if (LEOrw_flags & 0x8000) {
LEOPiInfo->transferInfo.cmdType = 1;
osWritebackDCache(block_param.pntr, block_param.blkbytes * LEOtgt_param.rdwr_blocks);
osEPiStartDma(LEOPiInfo, &LEOPiDmaParam, 1);
osRecvMesg(&LEOdma_que, NULL, 1);
LEOasic_bm_ctl_shadow = LEOPiInfo->transferInfo.bmCtlShadow;
LEOasic_seq_ctl_shadow = LEOPiInfo->transferInfo.seqCtlShadow;
bnum = LEOPiInfo->transferInfo.blockNum;
message = LEOPiInfo->transferInfo.block[bnum].errStatus;
if (message == 0) {
return message;
}
goto track_end;
} else {
if (LEOrw_flags & 0x4000) {
osRecvMesg(&LEOc2ctrl_que, NULL, 1);
osSendMesg(&LEOc2ctrl_que, NULL, 0);
}
LEOPiInfo->transferInfo.cmdType = 0;
osInvalDCache(block_param.pntr, block_param.blkbytes * LEOtgt_param.rdwr_blocks);
osEPiStartDma(LEOPiInfo, &LEOPiDmaParam, 0);
block = 0;
while (LEOtgt_param.rdwr_blocks != 0) {
osRecvMesg(&LEOdma_que, NULL, 1);
LEOasic_bm_ctl_shadow = LEOPiInfo->transferInfo.bmCtlShadow;
LEOasic_seq_ctl_shadow = LEOPiInfo->transferInfo.seqCtlShadow;
message = LEOPiInfo->transferInfo.block[block].errStatus;
if (message != 0) {
goto track_end;
}
if (LEOrw_flags & 0x2000) {
return 0;
}
if (LEOPiInfo->transferInfo.block[block].C1ErrNum) {
if (LEOPiInfo->transferInfo.block[block].C1ErrSector[0] < 0x55) {
if (LEOtgt_param.rdwr_blocks == 1) {
osEPiReadIo(LEOPiInfo, 0x05000514, &message);
if (message & 0x10000000) {
message = 4;
goto track_end;
}
}
if (block == 0) {
temp = LEOC2_Syndrome[0];
} else {
temp = LEOC2_Syndrome[1];
}
c2datasize = block_param.bytes * 4;
block_param.c2buff_e = temp + c2datasize;
osInvalDCache(temp, c2datasize);
block_param.err_num = LEOPiInfo->transferInfo.block[block].C1ErrNum;
block_param.err_pos[0] = LEOPiInfo->transferInfo.block[block].C1ErrSector[0];
block_param.err_pos[1] = LEOPiInfo->transferInfo.block[block].C1ErrSector[1];
block_param.err_pos[2] = LEOPiInfo->transferInfo.block[block].C1ErrSector[2];
block_param.err_pos[3] = LEOPiInfo->transferInfo.block[block].C1ErrSector[3];
osRecvMesg(&LEOc2ctrl_que, NULL, 1);
LEOrw_flags |= 0x4000;
LEOc2_param = block_param;
osSendMesg(&LEOcontrol_que, (void* )0x80000, 1);
}
} else {
if (LEOtgt_param.rdwr_blocks == 1) {
if ((*(u32*)&LEOC2_Syndrome[block][0x00] | *(u32*)&LEOC2_Syndrome[block][0x04] | *(u32*)&LEOC2_Syndrome[block][0x08] | *(u32*)&LEOC2_Syndrome[block][0x0C]) != 0) {
message = 0x17;
goto track_end;
}
}
}
block++;
block_param.pntr += block_param.blkbytes;
LEOtgt_param.start_block ^= 1;
LEOtgt_param.rdwr_blocks--;
}
}
return 0;
}
track_end:
if (message == 0x16) {
message = leochk_err_reg();
}
do_retry:
if (leoChk_err_retry(message) || (LEOrw_flags & 0x1000) || retry_cntr++ == 0x40) {
break;
}
if ((retry_cntr & 7) == 0) {
message = leoSend_asic_cmd_w(0x30001, 0);
if (message != 0) {
goto do_retry;
}
}
if (message == 0x18 || (message == 0x17 && retry_cntr == 0x20)) {
message = leoDetect_index_w();
if (message != 0) {
goto do_retry;
}
}
if (LEOrw_flags & 0x8000) {
message = leoSeek_i(1);
} else {
message = leoSeek_i(0);
}
if (message != 0) {
goto do_retry;
}
}
return message;
}
u32 leoChk_mecha_int(void) {
u32 stat = leoWait_mecha_cmd_done(ASIC_RD_SEEK);

View File

@@ -3,6 +3,7 @@
extern u32 asic_cur_status; // static?
extern u32 unit_atten; // static?
extern s32 currentCommand;
s32 osEPiWriteIo(OSPiHandle *, u32 , u32 );
@@ -245,8 +246,6 @@ s32 leoRecv_event_mesg(s32 control) {
return 0;
}
#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) {
@@ -265,10 +264,8 @@ u32 leoChk_err_retry(u32 sense) {
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:
@@ -282,9 +279,6 @@ u32 leoChk_err_retry(u32 sense) {
return 0;
}
#else
#pragma GLOBAL_ASM("asm/nonmatchings/libleo/leomecha/leoChk_err_retry.s")
#endif
u8 leoChk_cur_drvmode(void) {
u8 devstat = 0;