diff --git a/64drive.inc b/64drive.inc index 9f79ce5..53abfc9 100644 --- a/64drive.inc +++ b/64drive.inc @@ -32,3 +32,21 @@ constant CI_WIFI_PARAM_RESULT_1($0428) // word constant CI_EEPROM($1000) // 2048 bytes constant CI_WRITEBACK_LBA($1800) // 1024 bytes (256 words) + +macro CI_WAIT() { + PI_WAIT() +- + lw t0, CI_STATUS(t9) + srl t0, t0, 12 // first 12 bits are reserved, so ignore them + bnez t0,- + nop // delay slot +} + +macro CI_USB_WRITE_WAIT() { + PI_WAIT() +- + lw t0, CI_USB_COMMAND_STATUS(t9) + srl t0, t0, 4 // shift out ARM status, leaving WRITE status + bnez t0,- + nop // delay slot +} diff --git a/debug.asm b/debug.asm index ae5d9c2..9af5b22 100644 --- a/debug.asm +++ b/debug.asm @@ -50,7 +50,7 @@ Drive64Write: sw t3, PI_RD_LEN(t5) // "read" from DRAM to cart // PI_WAIT() // if we always wait before doing operations, this shouldn't be necessary -Drive64TestPoint: +Drive64WriteDirect: // TODO: rewrite so this takes a0, a1 instead of a2, a3 lui at, 0x0100 // set printf channel or a3, a3, at lli t1, 0x08 // WRITE mode @@ -59,20 +59,56 @@ Drive64TestPoint: and a2, a2, t9 srl a2, a2, 1 - CI_USB_WRITE_WAIT() - sw a2, CI_USB_PARAM_RESULT_0(gp) + lui t9, K_BASE + lw t9, K_CI_BASE(t9) + + CI_USB_WRITE_WAIT() // clobbers t0, requires t9 + sw a2, CI_USB_PARAM_RESULT_0(t9) PI_WAIT() // yes, these waits seem to be necessary - sw a3, CI_USB_PARAM_RESULT_1(gp) + sw a3, CI_USB_PARAM_RESULT_1(t9) PI_WAIT() - sw t1, CI_USB_COMMAND_STATUS(gp) -// CI_USB_WRITE_WAIT() // if we always wait before doing operations, this shouldn't be necessary + sw t1, CI_USB_COMMAND_STATUS(t9) +// if we always wait before doing operations, this shouldn't be necessary: +// CI_USB_WRITE_WAIT() Drive64WriteExit: jr ra - nop // delay slot + nop Drive64TestWrite: li a2, 0xA0000020 lli a3, 0x20 - j Drive64TestPoint - nop // delay slot + j Drive64WriteDirect + nop + +include "xxd.asm" + +DumpAndWrite: + // a0: source address + // a1: source length + // a2: temp string address + // a3: temp string maximum length + // v0: error code (0 is OK) + subiu sp, sp, 0x20 + sw ra, 0x10(sp) + // TODO: i think i can just use the a0,a1,a2,a3 slots here? + sw s0, 0x14(sp) + sw s1, 0x18(sp) + + or s0, a2, r0 + jal xxd + or s1, a3, r0 + + bnez v0, DumpAndWriteExit + + ori a0, s0, r0 // delay slot + jal Drive64Write + ori a1, s1, r0 + // v0 passthru + +DumpAndWriteExit: + lw ra, 0x10(sp) + lw s0, 0x14(sp) + lw s1, 0x18(sp) + jr ra + addiu sp, sp, 0x20 diff --git a/kernel.asm b/kernel.asm index cbfd59b..88904b1 100644 --- a/kernel.asm +++ b/kernel.asm @@ -28,37 +28,37 @@ Start: lui sp, K_STACK_INIT_BASE // SP should always be 8-byte aligned // so that SD and LD instructions don't fail on it. - subiu sp, sp, 8 + // we also need 4 empty words for storing the 32-bit values of a0,a1,a2,a3 + subiu sp, sp, 0x10 // TODO: just wipe a portion of RAM? sw r0, K_64DRIVE_MAGIC(k0) sw r0, K_REASON(k0) Drive64Init: - lui gp, CI_BASE + lui t9, CI_BASE lui t2, 0x5544 // "UD" of "UDEV" - lw t1, CI_HW_MAGIC(gp) + lw t1, CI_HW_MAGIC(t9) ori t2, t2, 0x4556 // "EV" of "UDEV" beq t1, t2, Drive64Confirmed nop Drive64TryExtended: - lui gp, CI_BASE_EXTENDED - lw t1, CI_HW_MAGIC(gp) + lui t9, CI_BASE_EXTENDED + lw t1, CI_HW_MAGIC(t9) bne t1, t2, Drive64Done nop Drive64Confirmed: sw t2, K_64DRIVE_MAGIC(k0) - sw gp, K_CI_BASE(k0) + sw t9, K_CI_BASE(k0) // enable writing to cartROM (SDRAM) for USB writing later lli t1, 0xF0 - - CI_WAIT() - sw t1, CI_COMMAND(gp) // send our command - CI_WAIT() + CI_WAIT() // clobbers t0, requires t9 + sw t1, CI_COMMAND(t9) + CI_WAIT() // clobbers t0, requires t9 Drive64Done: @@ -199,7 +199,30 @@ InterruptHandler: sd t0, K_DUMP+0x100(k0) sd t1, K_DUMP+0x108(k0) - // free to modify any GPR here + // be wary, this is a tiny temporary stack! + ori sp, k0, K_STACK + +IHMain: // free to modify any GPR from here to IHExit + la a2, IHString + jal Drive64WriteDirect + lli a3, 0x20 //IHString.size + + ori a0, k0, K_DUMP + lli a1, 0x100 + ori a2, k0, K_XXD + jal DumpAndWrite + lli a3, 0x400 + + ori a0, k0, K_DUMP + addiu a0, a0, 0x100 + lli a1, 0x100 + ori a2, k0, K_XXD + jal DumpAndWrite + lli a3, 0x400 + +IHExit: + + jal Drive64Write lui k0, K_BASE ld t0, K_DUMP+0x100(k0) @@ -257,4 +280,11 @@ ReturnFromInterrupt: jr k0 or k1, r0, r0 +include "debug.asm" + +align(4) +IHString: + db " ~~~ Interrupt Handled ~~~ ", 0 + +align(4) nops((K_BASE << 16) + 0x10000) diff --git a/main.asm b/main.asm index 40c7013..834b42d 100644 --- a/main.asm +++ b/main.asm @@ -24,7 +24,6 @@ include "kernel.asm" Main: lui t0, K_BASE - lw gp, K_CI_BASE(t0) lui s0, BLAH_BASE @@ -94,8 +93,6 @@ MainLoop: j MainLoop nop // delay slot -include "debug.asm" // assumes gp is set to CI base - SetupScreen: // NTSC: 640x480, 32BPP, Interlace, Resample Only, DRAM Origin VIDEO_BUFFER ScreenNTSC(640, 480, BPP32|INTERLACE|AA_MODE_2, VIDEO_BUFFER | UNCACHED) @@ -116,8 +113,8 @@ LoadRSPBoot: PushVideoTask: // a0: Task RDRAM Pointer (size: 0x40) - subiu sp, sp, 0x8 - sw ra, 0(sp) + subiu sp, sp, 0x18 + sw ra, 0x10(sp) lli t0, 1 // mode: video lli t1, 4 // flags: ??? @@ -154,9 +151,9 @@ PushVideoTask: jal PushRSPTask // a0 passthru nop - lw ra, 0(sp) + lw ra, 0x10(sp) jr ra - addiu sp, sp, 0x8 + addiu sp, sp, 0x18 PushRSPTask: lli t3, 0x40 - 1 // DMA quirk @@ -168,8 +165,6 @@ PushRSPTask: jr ra nop -include "xxd.asm" - align(16); insert F3DZEX_BOOT, "F3DZEX2.boot.bin" align(16); insert F3DZEX_DMEM, "F3DZEX2.data.bin" align(16); insert F3DZEX_IMEM, "F3DZEX2.bin" diff --git a/main.inc b/main.inc index 35af654..57b3382 100644 --- a/main.inc +++ b/main.inc @@ -9,8 +9,10 @@ constant K_REASON(0x0600) constant K_CAUSE(0x0604) constant K_STATUS(0x0608) constant K_EPC(0x060C) -constant K_64DRIVE_MAGIC(0x0800) -constant K_CI_BASE(0x0804) +constant K_64DRIVE_MAGIC(0x0700) +constant K_CI_BASE(0x0704) +constant K_STACK(0xC00 - 8) +constant K_XXD(0x0C00) // size: 0x400 (any larger and you overwrite kernel code) constant K_STACK_INIT_BASE(0x803F) // note that this gets subtracted by 8 // and that the stack grows *backwards.* @@ -60,22 +62,3 @@ macro SP_DMA_WAIT() { // external bnez t0,- nop } - -macro CI_WAIT() { - PI_WAIT() -- - lw t0, CI_STATUS(gp) - srl t0, t0, 12 // first 12 bits are reserved, so ignore them - bnez t0,- - nop // delay slot -} - -macro CI_USB_WRITE_WAIT() { - PI_WAIT() -- - lw t0, CI_USB_COMMAND_STATUS(gp) - srl t0, t0, 4 // shift out ARM status, leaving WRITE status - bnez t0,- - nop // delay slot -} -