commit 5f143cae817ceca736573c4ca9c8f3ed29401879 Author: Connor Olding Date: Thu Aug 16 19:53:31 2018 +0200 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..43badcc --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +old.asm +_old +microcodes +*.bin +!F3DZEX2.data.bin +!6102.bin +*.z64 +*.c +*.tmp +*.txt diff --git a/6102.bin b/6102.bin new file mode 100644 index 0000000..a53352e Binary files /dev/null and b/6102.bin differ diff --git a/64drive.inc b/64drive.inc new file mode 100644 index 0000000..9f79ce5 --- /dev/null +++ b/64drive.inc @@ -0,0 +1,34 @@ +// set 64Drive interface constants. + +// NOTE: although STATUSes are marked as halfwords, +// you should use lw/sw to interact with them. + +constant CI_BASE($B800) +constant CI_BASE_EXTENDED($BF80) + +constant CI_GENERAL_BUFFER($0000) // 512 bytes + +constant CI_STATUS($0200) // halfword +constant CI_COMMAND($0208) // word +constant CI_LBA($0210) // word +constant CI_LENGTH($0218) // word +constant CI_RESULT($0220) // word + +constant CI_SDRAM_SIZE($02E8) // word +constant CI_HW_MAGIC($02EC) // word ("UDEV") +constant CI_HW_VARIANT($02F0) // word +constant CI_PERSISTENT($02F4) // word (RESERVED) +constant CI_BUTTON_STATUS($02F8) // halfword (needs debouncing) +constant CI_UPGRADE_MOD_STATUS($02FA) // halfword +constant CI_REVISION_NUMBER($02FC) // halfword + +constant CI_USB_COMMAND_STATUS($0400) // byte +constant CI_USB_PARAM_RESULT_0($0404) // word +constant CI_USB_PARAM_RESULT_1($0408) // word + +constant CI_WIFI_COMMAND_STATUS($0420) // byte +constant CI_WIFI_PARAM_RESULT_0($0424) // word +constant CI_WIFI_PARAM_RESULT_1($0428) // word + +constant CI_EEPROM($1000) // 2048 bytes +constant CI_WRITEBACK_LBA($1800) // 1024 bytes (256 words) diff --git a/F3DZEX.asm b/F3DZEX.asm new file mode 100644 index 0000000..572696d --- /dev/null +++ b/F3DZEX.asm @@ -0,0 +1,1049 @@ +// this file implements the bootloader and main program for: +// RSP Gfx ucode F3DZEX.NoN fifo 2.08J Yoshitaka Yasumoto/Kawasedo 1999 +// assemble with bass: https://github.com/ARM9/bass + +arch n64.rsp +endian msb + +constant r0(0); constant at(1); constant v0(2); constant v1(3) +constant a0(4); constant a1(5); constant a2(6); constant a3(7) +constant t0(8); constant t1(9); constant t2(10); constant t3(11) +constant t4(12); constant t5(13); constant t6(14); constant t7(15) +constant s0(16); constant s1(17); constant s2(18); constant s3(19) +constant s4(20); constant s5(21); constant s6(22); constant s7(23) +constant t8(24); constant t9(25); constant k0(26); constant k1(27) +constant gp(28); constant sp(29); constant fp(30); constant ra(31) + +// n64-rsp.arch asserts that registers are preceeded by the letter "v", +// so this makes the most of it without colliding with the existing v0 and v1. +constant ec0(0); constant ec1(1); constant ec2(2); constant ec3(3) +constant ec4(4); constant ec5(5); constant ec6(6); constant ec7(7) +constant ec8(8); constant ec9(9); constant ec10(10); constant ec11(11) +constant ec12(12); constant ec13(13); constant ec14(14); constant ec15(15) +constant ec16(16); constant ec17(17); constant ec18(18); constant ec19(19) +constant ec20(20); constant ec21(21); constant ec22(22); constant ec23(23) +constant ec24(24); constant ec25(25); constant ec26(26); constant ec27(27) +constant ec28(28); constant ec29(29); constant ec30(30); constant ec31(31) + +macro nops(new_pc) { + while (pc() < {new_pc}) { + nop + } +} + +// when we're in the RSP, the registers accessible by mtc0/mfc0 +// are the ones associated with the RSP. they are memory-mapped as well. +constant SP_COP_MEM_ADDR(0) // 0x04040000 +constant SP_COP_DRAM_ADDR(1) // 0x04040004 +constant SP_COP_RD_LEN(2) // 0x04040008 +constant SP_COP_WR_LEN(3) // 0x0404000C +constant SP_COP_STATUS(4) // 0x04040010 +constant SP_COP_DMA_FULL(5) // 0x04040014 +constant SP_COP_DMA_BUSY(6) // 0x04040018 +constant SP_COP_SEMAPHORE(7) // 0x0404001C +// RDP registers: +constant SP_COP_COMMAND_START(8) // 0x04100000 +constant SP_COP_COMMAND_END(9) // 0x04100004 +constant SP_COP_COMMAND_CURRENT(10) // 0x04100008 +constant SP_COP_RDP_STATUS(11) // 0x0410000C +constant SP_COP_COUNT(12) // 0x04100010 +constant SP_COP_COMMAND_BUSY(13) // 0x04100014 +constant SP_COP_PIPE_BUSY(14) // 0x04100018 +constant SP_COP_TMEM_BUSY(15) // 0x0410001C + +output "F3DZEX2.boot.bin", create +fill 0xD0 + +origin 0x00000000 +base 0x04001000 + + j label_1054 + addi at, r0, 0x0FC0 // OS data, tells us where the real microcode is + +label_1008: + lw v0, 0x10(at) // TASK_UCODE + addi v1, r0, 0x0F7F // copy 0xF80 bytes + addi a3, r0, 0x1080 // to 0xA4001080 + mtc0 a3, SP_COP_MEM_ADDR + mtc0 v0, SP_COP_DRAM_ADDR + mtc0 v1, SP_COP_RD_LEN // start the DMA + +label_1020: +- + mfc0 a0, SP_COP_DMA_BUSY // wait until it finishes + bnez a0,- + nop + jal func_103C // check error status + nop + jr a3 // jump to the new code we just loaded + mtc0 r0, SP_COP_SEMAPHORE + +func_103C: + mfc0 t0, SP_COP_STATUS +label_1040: + andi t0, t0, 1<<7 // check flag 7: signal 0 set + bnez t1,+ // branch if signal 0 is set + nop + jr ra ++ + mtc0 r0, SP_COP_SEMAPHORE + ori t0, r0, 1<<9|1<<12|1<<14 // clear signal 0, set signal 1, set signal 2 + mtc0 t0, SP_COP_STATUS + break 0 + nop + +label_1054: + lw v0, 0x04(at) // load TASK_FLAGS + andi v0, v0, 2 // check flag 1 + beqz v0,+ + nop + jal func_103C + nop + mfc0 v0, SP_COP_RDP_STATUS + +// note: this marks 0x80, meaning everything below gets overwritten later. + andi v0, v0, 0x0100 + bgtz v0,func_103C + nop ++ + lw v0, 0x18(at) // load TASK_UCODE_DATA + lw v1, 0x1C(at) // load TASK_UCODE_DATA_SIZE + subi v1, v1, 1 // subtract 1 for DMA quirk +- + mfc0 fp, SP_COP_DMA_FULL + bnez fp,- // wait until the last DMA is finished? + nop + mtc0 r0, SP_COP_MEM_ADDR // target: A4000000 (DMEM) + mtc0 v0, SP_COP_DRAM_ADDR + mtc0 v1, SP_COP_RD_LEN // start the DMA +- + mfc0 a0, SP_COP_DMA_BUSY // wait until it finishes + bnez a0,- + nop + jal func_103C // check error status + nop + j label_1008 + nop + nop + +output "F3DZEX2.bin", create +fill 0xF80 + +origin 0x00000000 +base 0x04001080 + +// be careful here, the "v" prefix in n64-rsp.arch is tricky + + vxor vec0,vec0,vec0 // clear vector 0 + lqv vec31[e0], 0x1B0(r0) // read some? data from DMEM+1B0 +func_1088: + lqv vec30[e0], 0x1C0(r0) // read the next row, too + addi s7, r0, 0xBA8 + vadd vec1,vec0,vec0 // multiply vector 0 by 2 + addi s6, r0, 0xD00 + vsub vec1,vec0,vec31[e8] + lw t3, 0xF0(r0) + lw t4, 0xFC4(r0) + addi at, r0, 0x2800 + beqz t3,+ + mtc0 at, SP_COP_STATUS + + andi t4, t4, 1 + beqz t4,label_1130 + sw r0, 0xFC4(r0) + + j func_1168 & 0x1FFF + lw k0, 0xBF8(r0) + ++ + mfc0 t3, SP_COP_RDP_STATUS + andi t3, t3, 1 + bnez t3,+ + mfc0 v0, SP_COP_COMMAND_END + + lw v1, 0xFE8(r0) + sub t3, v1, v0 + bgtz t3,+ + mfc0 at, SP_COP_COMMAND_CURRENT + + lw a0, 0xFEC(r0) + beqz at,+ + sub t3,at,a0 + + bgez t3,+ + nop + + bne at, v0,++ ++ +- + mfc0 t3, SP_COP_RDP_STATUS + + andi t3, t3, 0x0400 + bnez t3,- + addi t3, r0, 1 + + mtc0 t3, SP_COP_RDP_STATUS + lw v0, 0xFEC(r0) + mtc0 v0, SP_COP_COMMAND_START + mtc0 v0, SP_COP_COMMAND_END ++ + sw v0, 0xF0(r0) + lw t3, 0xF4(r0) + bnez t3, label_1130 + lw t3, 0xFE0(r0) + + sw t3, 0xF4(r0) +label_1130: + lw at, 0xFD0(r0) + lw v0, 0x2E0(r0) + lw v1, 0x2E8(r0) + lw a0, 0x410(r0) + lw a1, 0x418(r0) + add v0, v0, at + add v1, v1, at + sw v0, 0x2E0(r0) + sw v1, 0x2E8(r0) + add a0, a0, at + add a1, a1, at + sw a0, 0x410(r0) + sw a1, 0x418(r0) + lw k0, 0xFF0(r0) +func_1168: + addi t3, r0, 0x2E8 + nop + jal func_1FB4 & 0x1FFF + ori t4, ra, 0 + +- + addi s3, r0, 0xA7 + ori t8, k0, 0 + + jal func_1FD8 & 0x1FFF + addiu s4, r0, 0x0920 + + addiu k0, k0, 0x00A8 + addi k1, r0, 0xFF58 + jal func_1FC8 & 0x1FFF +func_1194: + mfc0 at, SP_COP_STATUS + lw t9, 0x09C8(k1) + beqz k1,- + andi at, at, 0x0080 + + sra t4, t9, 24 + sll t3, t4, 1 + lhu t3, 0x036E(t3) + bnez at, label_1FAC + lw t8, 0x09CC(k1) + + jr t3 + addiu k1, k1, SP_COP_COMMAND_START + jal func_1224 & 0x1FFF + lh s4, 0x09C1(k1) + + andi s3, t9, 0x0FF8 + sra s4, s4, 2 + j func_1FD8 & 0x1FFF + addi ra, r0, 0x1190 + + lw t3, 0x01EC(r0) + and t3, t3, t9 + or t3, t3, t8 + j func_1194 & 0x1FFF + sw t3, 0x01EC(r0) + +label_11EC: + lbu at, 0x00DE(r0) + beqz at, label_1FAC + addi at, at, 0xFFFC + + j label_1020 & 0x1FFF + lw k0, 0x0138(at) + + ldv vec29[e0], 0xD0(0) + lw t9, 0x00D8(r0) + addi s7, s7, SP_COP_COMMAND_START + sdv vec29[e0], 0x3F8(23) +func_1210: + sw t8, 0x4(s7) + sw t9, 0x0(s7) + j label_1258 & 0x1FFF + addi s7, s7, SP_COP_COMMAND_START + + addi ra, r0, 0x1210 +func_1224: + srl t3, t8, 22 + andi t3, t3, 0x003C + lw t3, 0x00F8(t3) + sll t8, t8, 8 + srl t8, t8, 8 + jr ra + add t8, t8, t3 + sw t9, 0x00C8(r0) + j func_1210 & 0x1FFF + sw t8, 0x00CC(r0) + + sw t9, 0x00C0(r0) + j func_1210 & 0x1FFF + sw t8, 0x00C4(r0) + +label_1258: + addi ra, r0, 0x1194 +label_125C: + sub t3, s7, s6 + blez t3, label_1FD4 +- + mfc0 t4, SP_COP_DMA_BUSY + + lw t8, 0x00F0(r0) + addiu s3, t3, 0x0158 + bnez t4,- + lw t4, 0x0FEC(r0) + + mtc0 t8, SP_COP_COMMAND_END + add t3, t8, s3 + sub t4, t4, t3 + bgez t4,+ +- + mfc0 t3, SP_COP_RDP_STATUS + + andi t3, t3, 0x0400 + bnez t3,- + lw t8, 0x0FE8(r0) +- + mfc0 t3, SP_COP_COMMAND_CURRENT + beq t3, t8,- + nop + + mtc0 t8, SP_COP_COMMAND_START ++ +- + mfc0 t3, SP_COP_COMMAND_CURRENT + sub t3, t3, t8 + blez t3,+ + + sub t3, t3, s3 + blez t3,- + ++ + add t3, t8, s3 + sw t3, 0x00F0(r0) + addi s3, s3, 0xFFFF + addi s4, s6, 0xDEA8 + xori s6, s6, 0x0208 + j func_1FD8 & 0x1FFF + addi s7, s6, 0xFEA8 +label_12D8: + addi t3, r0, 0x0410 + j func_1FB4 & 0x1FFF + addi t4, r0, 0x12D8 +label_12E4: + ori fp, ra, 0x0 + addiu a1, r0, 0x0014 + addiu s2, r0, 0x6 + addiu t7, r0, 0x09C8 + sh at, 0x03CA(s2) + sh v0, 0x03CC(s2) + sh v1, 0x03CE(s2) + sh r0, 0x03D0(s2) + lw sp, 0x03CC(r0) +label_1308: + lw t1, 0x03F8(a1) + lw s0, 0x0024(v1) + and s0, s0, t1 + addi s1, s2, 0xFFFA + xori s2, s2, 0x001C + addi s5, s2, 0xFFFA +func_1320: + lhu v0, 0x03D0(s1) + addi s1, s1, 0x2 + beqz v0, label_14A8 + lw t3, 0x0024(v0) + + and t3, t3, t1 + beq t3, s0, label_1494 + ori s0, t3, 0x0 + + beqz s0,+ + ori s3, v0, 0x0 + + ori s3, v1, 0x0 + ori v1, v0, 0x0 ++ + sll t3, a1, 1 + + ldv vec2[e0], 0x180(11) + ldv vec4[e0], 0x8(19) + ldv vec5[e0], 0x0(19) + ldv vec6[e0], 0x8(3) + ldv vec7[e0], 0x0(3) + vmudh vec3,vec2,vec31[e8] + vmudn vec8,vec4,vec2[e0] + vmadh vec9,vec5,vec2[e0] + vmadn vec10,vec6,vec3[e0] + vmadh vec11,vec7,vec3[e0] + vaddc vec8,vec8,vec8[e2] + lqv vec25[e0], 0x1D0(0) + vadd vec9,vec9,vec9[e2] + vaddc vec10,vec10,vec10[e2] + vadd vec11,vec11,vec11[e2] + vaddc vec8,vec8,vec8[e5] + vadd vec9,vec9,vec9[e5] + vaddc vec10,vec10,vec10[e5] + vadd vec11,vec11,vec11[e5] + vor vec29,vec11,vec1[e8] + vrcph vec3[e11],vec11[e11] + vrcpl vec2[e11],vec10[e11] + vrcph vec3[e11],vec0[e8] + vabs vec29,vec29,vec25[e11] + vmudn vec2,vec2,vec29[e11] + vmadh vec3,vec3,vec29[e11] + veq vec3,vec3,vec0[e8] + vmrg vec2,vec2,vec31[e8] + vmudl vec29,vec10,vec2[e11] + vmadm vec11,vec11,vec2[e11] + vmadn vec10,vec0,vec0[e8] + vrcph vec13[e11],vec11[e11] + vrcpl vec12[e11],vec10[e11] + vrcph vec13[e11],vec0[e8] +label_13D8: + vmudl vec29,vec12,vec10[e0] + vmadm vec29,vec13,vec10[e0] + vmadn vec10,vec12,vec11[e0] + vmadh vec11,vec13,vec11[e0] + vmudh vec29,vec1,vec31[e9] + vmadn vec10,vec10,vec31[e12] + vmadh vec11,vec11,vec31[e12] + vmudl vec29,vec12,vec10[e0] + vmadm vec29,vec13,vec10[e0] + vmadn vec12,vec12,vec11[e0] + vmadh vec13,vec13,vec11[e0] + vmudl vec29,vec8,vec12[e0] + luv vec26[e0], 0x10(3) + vmadm vec29,vec9,vec12[e0] + llv vec26[e8], 0x14(3) + vmadn vec10,vec8,vec13[e0] + luv vec25[e0], 0x10(19) + vmadh vec11,vec9,vec13[e0] + llv vec25[e8], 0x14(19) + vmudl vec29,vec10,vec2[e11] + vmadm vec11,vec11,vec2[e11] + vmadn vec10,vec10,vec0[e8] + vlt vec11,vec11,vec1[e8] + vmrg vec10,vec10,vec31[e8] + vsubc vec29,vec10,vec1[e8] + vge vec11,vec11,vec0[e8] + vmrg vec10,vec10,vec1[e8] + vmudn vec2,vec10,vec31[e8] + vmudl vec29,vec6,vec10[e11] + vmadm vec29,vec7,vec10[e11] + vmadl vec29,vec4,vec2[e11] + vmadm vec24,vec5,vec2[e11] + vmadn vec23,vec0,vec0[e8] + vmudm vec29,vec26,vec10[e11] + vmadm vec22,vec25,vec2[e11] + + addi a3, r0, 0x0 + addi at, r0, 0x2 + sh t7, 0x03D0(s5) + j func_19F4 & 0x1FFF + addi ra, r0, 0x9870 + +label_1478: + slv vec25[e0], 0x1C8(15) + ssv vec26[e4], 0xCE(15) + suv vec22[e0], 0x3C0(15) + slv vec22[e8], 0x1C4(15) + ssv vec3[e4], 0xCC(15) + addi t7, t7, 0xFFD8 + addi s5, s5, 0x2 + +label_1494: + bnez s0, func_1320 + ori v1, v0, 0x0 + + sh v1, 0x03D0(s5) + j func_1320 & 0x1FFF + addi s5, s5, 0x2 + +label_14A8: + sub t3, s5, s2 + bltz t3,+ + sh r0, 0x03D0(s5) + lhu v1, 0x03CE(s5) + bnez a1, label_1308 + addi a1, a1, 0xFFFC + sw r0, 0x03CC(r0) + +- + lhu at, 0x03CA(s2) + lhu v0, 0x03CC(s2) + lhu v1, 0x03CE(s5) + mtc2 at,vec2[e10] + vor vec3,vec0,vec31[e13] + mtc2 v0,vec4[e12] + jal func_1A7C & 0x1FFF + mtc2 v1,vec2[e14] + bne s5, s2,- + addi s2, s2, 0x2 + ++ + jr fp + sw sp, 0x03CC(r0) + + nops(0x4001780) + + lhu s4, 0x0380(t9) + jal func_1224 & 0x1FFF + lhu at, 0x09C1(k1) + + sub s4, s4, at + jal func_1FD8 & 0x1FFF + addi s3, at, 0xFFFF + + lhu a1, 0x01EC(r0) + srl at, at, 3 + sub t7, t9, at + lhu t7, 0x0380(t7) + ori t6, s4, 0x0 + lbu t0, 0x01D9(r0) + andi a2, a1, 0x2 + bnez a2, label_12D8 + andi a3, a1, 0x1 + + bnez t0,+ + sll a3, a3, 3 + + sb t9, 0x01D9(r0) + addi s5, r0, 0x0040 + addi s4, r0, 0x0 + jal func_1088 & 0x1FFF + addi s3, r0, 0x0080 + ++ + lqv vec8[e0], 0x80(0) + lqv vec10[e0], 0x90(0) + lqv vec12[e0], 0xA0(0) + lqv vec14[e0], 0xB0(0) + vadd vec9,vec8,vec0[e8] + ldv vec9[e0], 0x88(0) + vadd vec11,vec10,vec0[e8] + ldv vec11[e0], 0x98(0) + vadd vec13,vec12,vec0[e8] + ldv vec13[e0], 0xA8(0) + vadd vec15,vec14,vec0[e8] + ldv vec15[e0], 0xB8(0) + ldv vec8[e8], 0x80(0) + ldv vec10[e8], 0x90(0) + jal func_19F4 & 0x1FFF + ldv vec12[e8], 0xA0(0) + + jal func_1FC8 & 0x1FFF + ldv vec14[e8], 0xB0(0) + + ldv vec20[e0], 0x0(14) + vmov vec16[e13],vec21[e9] + ldv vec20[e8], 0x10(14) +label_182C: + vmudn vec29,vec15,vec1[e8] + lw t3, 0x001C(t6) + vmadh vec29,vec11,vec1[e8] + llv vec22[e12], 0x8(14) + vmadn vec29,vec12,vec20[e4] + ori t1, a2, 0x0 + vmadh vec29,vec8,vec20[e4] + lpv vec2[e0], 0xB0(9) + vmadn vec29,vec13,vec20[e5] + sw t3, 0x8(t6) + vmadh vec29,vec9,vec20[e5] + lpv vec7[e0], 0x8(14) + vmadn vec23,vec14,vec20[e6] + bnez a2, label_13D8 + vmadh vec24,vec10,vec20[e6] + + vge vec27,vec25,vec31[e11] + llv vec22[e4], 0x18(14) + vge vec3,vec25,vec0[e8] + addi at, at, 0xFFFC + vmudl vec29,vec23,vec18[e12] + sub t3, t0, a3 + vmadm vec2,vec24,vec18[e12] + sbv vec27[e15], 0x73(11) + vmadn vec21,vec0,vec0[e8] + sbv vec27[e7], 0x4B(11) + vmov vec26[e9],vec3[e10] + ssv vec3[e12], 0xF4(8) + vmudn vec7,vec23,vec18[e13] + slv vec25[e8], 0x1F0(8) + vmadh vec6,vec24,vec18[e13] + sdv vec25[e0], 0x3C8(8) + vrcph vec29[e8],vec2[e11] + ssv vec26[e12], 0xF6(8) + vrcpl vec5[e11],vec21[e11] + slv vec26[e2], 0x1CC(8) + vrcph vec4[e11],vec2[e15] + ldv vec3[e0], 0x8(14) + vrcpl vec5[e15],vec21[e15] + sra t3, at, 31 + vrcph vec4[e15],vec0[e8] + andi t3, t3, 0x0028 + vch vec29,vec24,vec24[e7] + addi t7, t7, 0x0050 + vcl vec29,vec23,vec23[e7] + sub t0, t7, t3 + vmudl vec29,vec21,vec5[e0] + dw 0x484A0800 // TODO: unknown instruction. similar to mfc2/mtc2 + vmadm vec29,vec2,vec5[e0] + sdv vec23[e8], 0x3E0(8) + vmadn vec21,vec21,vec4[e0] + ldv vec20[e0], 0x20(14) + vmadh vec2,vec2,vec4[e0] + sdv vec23[e0], 0x3B8(15) + vge vec29,vec24,vec0[e8] + lsv vec23[e14], 0xE4(8) + vmudh vec29,vec1,vec31[e9] + sdv vec24[e8], 0x3D8(8) + vmadn vec26,vec21,vec31[e12] + lsv vec23[e6], 0xBC(15) + vmadh vec25,vec2,vec31[e12] + sdv vec24[e0], 0x3B0(15) + vmrg vec2,vec0,vec31[e15] + ldv vec20[e8], 0x30(14) + vch vec29,vec24,vec6[e7] + slv vec3[e0], 0x1E8(8) + vmudl vec29,vec26,vec5[e0] + lsv vec24[e14], 0xDC(8) + vmadm vec29,vec25,vec5[e0] + slv vec3[e4], 0x1C0(15) + vmadn vec5,vec26,vec4[e0] + lsv vec24[e6], 0xB4(15) + vmadh vec4,vec25,vec4[e0] + sh t2, 0xFFFE(t0) + vmadh vec2,vec2,vec31[e15] + sll t3, t2, 4 + vcl vec29,vec23,vec7[e7] + dw 0x484A0800 // TODO: unknown instruction. similar to mfc2/mtc2 + vmudl vec29,vec23,vec5[e7] + ssv vec5[e14], 0xFA(8) + vmadm vec29,vec24,vec5[e7] + addi t6, t6, 0x0020 + vmadn vec26,vec23,vec2[e7] + sh t2, 0xFFFC(t0) + vmadh vec25,vec24,vec2[e7] + sll t2, t2, 4 + vmudm vec3,vec22,vec18[e0] + sh t3, 0xFFD6(t7) + sh t2, 0xFFD4(t7) + vmudl vec29,vec26,vec18[e12] + ssv vec5[e6], 0xD2(15) + vmadm vec25,vec25,vec18[e12] + ssv vec4[e14], 0xF8(8) + vmadn vec26,vec0,vec0[e8] + ssv vec4[e6], 0xD0(15) + slv vec3[e4], 0x1EC(8) + vmudh vec29,vec17,vec1[e8] + slv vec3[e12], 0x1C4(15) + vmadh vec29,vec19,vec31[e11] + vmadn vec26,vec26,vec16[e0] + bgtz at, label_182C + vmadh vec25,vec25,vec16[e0] + + bltz ra, label_1478 + vge vec3,vec25,vec0[e8] + + slv vec25[e8], 0x1F0(8) + vge vec27,vec25,vec31[e11] + slv vec25[e0], 0x1C8(15) + ssv vec26[e12], 0xF6(8) + ssv vec26[e4], 0xCE(15) + ssv vec3[e12], 0xF4(8) + beqz a3, func_1194 + ssv vec3[e4], 0xCC(15) + + sbv vec27[e15], 0x6B(8) + j func_1194 & 0x1FFF + sbv vec27[e7], 0x43(15) + +func_19F4: + addi t5, r0, 0x0180 + ldv vec16[e0], 0xE0(0) + ldv vec16[e8], 0xE0(0) + llv vec29[e0], 0x60(13) + ldv vec17[e0], 0xE8(0) + ldv vec17[e8], 0xE8(0) + vlt vec19,vec31,vec31[e11] + vsub vec21,vec0,vec16[e0] + llv vec18[e4], 0x68(13) + vmrg vec16,vec16,vec29[e8] + llv vec18[e12], 0x68(13) + vmrg vec19,vec0,vec1[e8] + llv vec18[e8], 0xDC(0) + vmrg vec17,vec17,vec29[e9] + lsv vec18[e10], 0x6(13) + vmov vec16[e9],vec21[e9] + jr ra + addi t0, s7, 0x0050 + jal func_1A4C & 0x1FFF + sw t8, 0x4(s7) + + addi ra, r0, 0x1194 + sw t9, 0x4(s7) +func_1A4C: + lpv vec2[e0], 0x0(23) + lbu at, 0x5(s7) + lbu v0, 0x6(s7) + lbu v1, 0x7(s7) + vor vec3,vec0,vec31[e13] + lhu at, 0x0380(at) + vmudn vec4,vec1,vec31[e14] + lhu v0, 0x0380(v0) + vmadl vec2,vec2,vec30[e9] + lhu v1, 0x0380(v1) + vmadn vec4,vec0,vec0[e8] + ori a0, at, 0x0 +func_1A7C: + vnxor vec5,vec0,vec31[e15] + llv vec6[e0], 0x18(1) + vnxor vec7,vec0,vec31[e15] + llv vec4[e0], 0x18(2) + vmov vec6[e14],vec2[e13] + llv vec8[e0], 0x18(3) + vnxor vec9,vec0,vec31[e15] + lw a1, 0x0024(at) + vmov vec8[e14],vec2[e15] + lw a2, 0x0024(v0) + vadd vec2,vec0,vec6[e9] + lw a3, 0x0024(v1) + vsub vec10,vec6,vec4[e0] + andi t3, a1, 0x70B0 + vsub vec11,vec4,vec6[e0] + and t3, a2, t3 + vsub vec12,vec6,vec8[e0] + and t3, a3, t3 + vlt vec13,vec2,vec4[e9] + vmrg vec14,vec6,vec4[e0] + bnez t3, label_1FD4 + lbu t3, 0x01EE(r0) + + vmudh vec29,vec10,vec12[e9] + lw t4, 0x03CC(r0) + vmadh vec29,vec12,vec11[e9] + or a1, a1, a2 + vge vec2,vec2,vec4[e9] + or a1, a1, a3 + vmrg vec10,vec6,vec4[e0] + lw t3, 0x03C2(t3) + vge vec6,vec13,vec8[e9] + mfc2 a2,vec29[e0] + vmrg vec4,vec14,vec8[e0] + and a1, a1, t4 + vmrg vec14,vec8,vec14[e0] + bnez a1, label_12E4 + add t3, a2, t3 + + vlt vec6,vec6,vec2[e0] + bgez t3, label_1FD4 + vmrg vec2,vec4,vec10[e0] + + vmrg vec10,vec10,vec4[e0] + + mfc2 at,vec14[e12] + vmudn vec4,vec14,vec31[e13] + beqz a2, label_1FD4 + vsub vec6,vec2,vec14[e0] + + mfc2 v0,vec2[e12] + vsub vec8,vec10,vec14[e0] + mfc2 v1,vec10[e12] + vsub vec11,vec14,vec2[e0] + lw a2, 0x01EC(r0) + vsub vec12,vec14,vec10[e0] + llv vec13[e0], 0x20(1) + vsub vec15,vec10,vec2[e0] + llv vec13[e8], 0x20(2) + vmudh vec16,vec6,vec8[e8] + llv vec13[e12], 0x20(3) + vmadh vec16,vec8,vec11[e8] + sll t3, a2, 10 + vsar vec17,vec17,vec17[e8] + bgez t3,+ + vsar vec16,vec16,vec16[e9] + + lpv vec18[e0], 0x10(1) + vmov vec15[e10],vec6[e8] + lpv vec19[e0], 0x10(2) + vrcp vec20[e8],vec15[e9] + lpv vec21[e0], 0x10(3) + vrcph vec22[e8],vec17[e9] + vrcpl vec23[e9],vec16[e9] + j func_1BC0 & 0x1FFF + vrcph vec24[e9],vec0[e8] + ++ + lpv vec18[e0], 0x10(4) + vrcp vec20[e8],vec15[e9] + lbv vec18[e6], 0x13(1) + vrcph vec22[e8],vec17[e9] + lpv vec19[e0], 0x10(4) + vrcpl vec23[e9],vec16[e9] + lbv vec19[e6], 0x13(2) + vrcph vec24[e9],vec0[e8] + lpv vec21[e0], 0x10(4) + vmov vec15[e10],vec6[e8] + lbv vec21[e6], 0x13(3) +func_1BC0: + vrcp vec20[e10],vec6[e9] + vrcph vec22[e10],vec6[e9] + lw a1, 0x0020(at) + vrcp vec20[e11],vec8[e9] + lw a3, 0x0020(v0) + vrcph vec22[e11],vec8[e9] + lw t0, 0x0020(v1) + vmudl vec18,vec18,vec30[e11] + lbu t1, 0x01E7(r0) + vmudl vec19,vec19,vec30[e11] + sub t3, a1, a3 + vmudl vec21,vec21,vec30[e11] + sra t4, t3, 31 + vmov vec15[e11],vec8[e8] + and t3, t3, t4 + vmudl vec29,vec20,vec30[e15] + sub a1, a1, t3 + vmadm vec22,vec22,vec30[e15] + sub t3, a1, t0 + vmadn vec20,vec0,vec0[e8] + sra t4, t3, 31 + vmudm vec25,vec15,vec30[e10] + and t3, t3, t4 + vmadn vec15,vec0,vec0[e8] + sub a1, a1, t3 + vsubc vec4,vec0,vec4[e0] + sw a1, 0x0010(s7) + vsub vec26,vec0,vec0[e0] + llv vec27[e0], 0x10(23) + vmudm vec29,vec25,vec20[e0] + dw 0x48058880 + vmadl vec29,vec15,vec20[e0] + lbu a3, 0x01E6(r0) + vmadn vec20,vec15,vec22[e0] + lsv vec19[e14], 0x1C(2) + vmadh vec15,vec25,vec22[e0] + lsv vec21[e14], 0x1C(3) + vmudl vec29,vec23,vec16[e0] + lsv vec7[e14], 0x1E(2) + vmadm vec29,vec24,vec16[e0] + lsv vec9[e14], 0x1E(3) + vmadn vec16,vec23,vec17[e0] + ori t3, a2, 0x00C8 + vmadh vec17,vec24,vec17[e0] + or t3, t3, t1 + vand vec22,vec20,vec30[e13] + vcr vec15,vec15,vec30[e11] + sb t3, 0x0(s7) + vmudh vec29,vec1,vec30[e14] + ssv vec10[e2], 0x2(23) + vmadn vec16,vec16,vec30[e12] + ssv vec2[e2], 0x4(23) + vmadh vec17,vec17,vec30[e12] + ssv vec14[e2], 0x6(23) + vmudn vec29,vec3,vec14[e8] + andi t4, a1, 0x0080 + vmadl vec29,vec22,vec4[e9] + or t4, t4, a3 + vmadm vec29,vec15,vec4[e9] + sb t4, 0x1(s7) + vmadn vec2,vec22,vec26[e9] + beqz t1,+ + vmadh vec3,vec15,vec26[e9] + + vrcph vec29[e8],vec27[e8] + vrcpl vec10[e8],vec27[e9] + vadd vec14,vec0,vec13[e3] + vrcph vec27[e8],vec0[e8] + vor vec22,vec0,vec31[e15] + vmudm vec29,vec13,vec10[e8] + vmadl vec29,vec14,vec10[e8] + llv vec22[e0], 0x14(1) + vmadn vec14,vec14,vec27[e8] + llv vec22[e8], 0x14(2) + vmadh vec13,vec13,vec27[e8] + vor vec10,vec0,vec31[e15] + vge vec29,vec30,vec30[e15] + llv vec10[e8], 0x14(3) + vmudm vec29,vec22,vec14[e4] + vmadh vec22,vec22,vec13[e4] + vmadn vec25,vec0,vec0[e8] + vmudm vec29,vec10,vec14[e14] + vmadh vec10,vec10,vec13[e14] + vmadn vec13,vec0,vec0[e8] + sdv vec22[e0], 0x20(23) + vmrg vec19,vec19,vec22[e0] + sdv vec25[e0], 0x28(23) + vmrg vec7,vec7,vec25[e0] + ldv vec18[e8], 0x20(23) + + vmrg vec21,vec21,vec10[e0] + ldv vec5[e8], 0x28(23) + vmrg vec9,vec9,vec13[e0] + ++ + vmudl vec29,vec16,vec23[e0] + lsv vec5[e14], 0x1E(1) + vmadm vec29,vec17,vec23[e0] + lsv vec18[e14], 0x1C(1) + vmadn vec23,vec16,vec24[e0] + lh at, 0x0018(v0) + vmadh vec24,vec17,vec24[e0] + addiu v0, s7, 0x0020 + vsubc vec10,vec9,vec5[e0] + andi v1, a2, 0x4 + vsub vec9,vec21,vec18[e0] + sll at, at, 14 + vsubc vec13,vec7,vec5[e0] + sw at, 0x8(s7) + vsub vec7,vec19,vec18[e0] + ssv vec3[e6], 0x10(23) + vmudn vec29,vec10,vec6[e9] + ssv vec2[e6], 0x12(23) + vmadh vec29,vec9,vec6[e9] + ssv vec3[e4], 0x18(23) + vmadn vec29,vec13,vec12[e9] + ssv vec2[e4], 0x1A(23) + vmadh vec29,vec7,vec12[e9] + ssv vec15[e0], 0xC(23) + vsar vec2,vec2,vec2[e9] + ssv vec20[e0], 0xE(23) + vsar vec3,vec3,vec3[e8] + ssv vec15[e6], 0x14(23) + vmudn vec29,vec13,vec8[e8] + ssv vec20[e6], 0x16(23) + vmadh vec29,vec7,vec8[e8] + ssv vec15[e4], 0x1C(23) + vmadn vec29,vec10,vec11[e8] + ssv vec20[e4], 0x1E(23) + vmadh vec29,vec9,vec11[e8] + sll t3, v1, 4 + vsar vec6,vec6,vec6[e9] + add at, v0, t3 + vsar vec7,vec7,vec7[e8] + sll t3, t1, 5 + vmudl vec29,vec2,vec23[e9] + add s7, at, t3 + vmadm vec29,vec3,vec23[e9] + andi a2, a2, 0x1 + vmadn vec2,vec2,vec24[e9] + sll t3, a2, 4 + vmadh vec3,vec3,vec24[e9] + add s7, s7, t3 + vmudl vec29,vec6,vec23[e9] + vmadm vec29,vec7,vec23[e9] + vmadn vec6,vec6,vec24[e9] + sdv vec2[e0], 0x18(2) + vmadh vec7,vec7,vec24[e9] + sdv vec3[e0], 0x8(2) + vmadl vec29,vec2,vec20[e11] + sdv vec2[e8], 0x18(1) + vmadm vec29,vec3,vec20[e11] + sdv vec3[e8], 0x8(1) + vmadn vec8,vec2,vec15[e11] + sdv vec6[e0], 0x38(2) + vmadh vec9,vec3,vec15[e11] + sdv vec7[e0], 0x28(2) + vmudn vec29,vec5,vec1[e8] + sdv vec6[e8], 0x38(1) + vmadh vec29,vec18,vec1[e8] + sdv vec7[e8], 0x28(1) + vmadl vec29,vec8,vec4[e9] + sdv vec8[e0], 0x30(2) + vmadm vec29,vec9,vec4[e9] + sdv vec9[e0], 0x20(2) + vmadn vec5,vec8,vec26[e9] + sdv vec8[e8], 0x30(1) + vmadh vec18,vec9,vec26[e9] + sdv vec9[e8], 0x20(1) + vmudn vec10,vec8,vec4[e9] + beqz a2,+ + vmudn vec8,vec8,vec30[e15] + + vmadh vec9,vec9,vec30[e15] + sdv vec5[e0], 0x10(2) + vmudn vec2,vec2,vec30[e15] + sdv vec18[e0], 0x0(2) + vmadh vec3,vec3,vec30[e15] + sdv vec5[e8], 0x10(1) + vmudn vec6,vec6,vec30[e15] + sdv vec18[e8], 0x0(1) + vmadh vec7,vec7,vec30[e15] + ssv vec8[e14], 0xFA(23) + vmudl vec29,vec10,vec30[e15] + ssv vec9[e14], 0xF8(23) + vmadn vec5,vec5,vec30[e15] + ssv vec2[e14], 0xF6(23) + vmadh vec18,vec18,vec30[e15] + ssv vec3[e14], 0xF4(23) + ssv vec6[e14], 0xFE(23) + ssv vec7[e14], 0xFC(23) + ssv vec5[e14], 0xF2(23) + j label_125C & 0x1FFF + ssv vec18[e14], 0xF0(23) + ++ + sdv vec5[e0], 0x10(2) + sdv vec18[e0], 0x0(2) + sdv vec5[e8], 0x10(1) + j label_125C & 0x1FFF + sdv vec18[e8], 0x0(1) + + lhu t9, 0x380(t9) + lhu t8, 0x380(t8) + addiu at, r0, 0x70B0 + lw t3, 0x24(t9) +- + and at, at, t3 + beqz at, func_1194 + lw t3, 0x4C(t9) + bne t9, t8,- + addiu t9, t9, 0x0028 + j label_11EC & 0x1FFF + lhu t9, 0x380(t9) + + lh t9, 6(t9) + sub v0, t9, t8 + bgez v0, func_1194 + lw t8, 0x00D8(r0) + j label_1008 & 0x1FFF + lbu at, 0x09C1(k1) + j label_1040 & 0x1FFF + lhu t9, 0x0380(t9) + + nops(0x4001FAC) + +label_1FAC: + addi t4, r0, 0x1000 + addi t3, r0, 0x02E0 +func_1FB4: + lw t8, 0x0(t3) + lhu s3, 0x4(t3) + jal func_1FD8 & 0x1FFF + lhu s4, 0x6(t3) + ori ra, t4, 0x0 +func_1FC8: + mfc0 t3, SP_COP_DMA_BUSY +- + bnez t3,- + mfc0 t3, SP_COP_DMA_BUSY +label_1FD4: + jr ra +func_1FD8: + mfc0 t3, SP_COP_DMA_FULL +- + bnez t3,- + mfc0 t3, SP_COP_DMA_FULL + mtc0 s4, SP_COP_MEM_ADDR + bltz s4,+ + mtc0 t8, SP_COP_DRAM_ADDR + jr ra + mtc0 s3, SP_COP_RD_LEN ++ + jr ra + mtc0 s3, SP_COP_WR_LEN diff --git a/F3DZEX2.data.bin b/F3DZEX2.data.bin new file mode 100644 index 0000000..ac47c43 Binary files /dev/null and b/F3DZEX2.data.bin differ diff --git a/Image.lz b/Image.lz new file mode 100644 index 0000000..c9a908c Binary files /dev/null and b/Image.lz differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..9de51d9 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +nothing to see here (yet). + +currently borrowing some code from [krom's repo.](https://github.com/PeterLemon/N64/) diff --git a/build b/build new file mode 100644 index 0000000..b693780 --- /dev/null +++ b/build @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# TODO: make this crap actually portable +set -e + +ROM_NAME=test.z64 + +#while inotifywait -q -e create,modify *.asm *.inc; do +bass F3DZEX.asm +bass main.asm +/tmp/z64crc "$ROM_NAME" +#done + +# don't use -z in msys2 because it hangs +64drive_usb -c 1 -l "$ROM_NAME" #-z diff --git a/devcart.asm b/devcart.asm new file mode 100644 index 0000000..ae5d9c2 --- /dev/null +++ b/devcart.asm @@ -0,0 +1,78 @@ +// debug routines for the 64drive, not a real devcart! + +Drive64Write: + // a0: RAM address to copy from + // a1: length of data to copy in bytes + // v0: error code (0 is OK) + + // TODO: a0 should be double-word aligned if used directly with DMA + + // assert a0 (RAM address) is word-aligned + andi t9, a0, 3 + bnezl t9, Drive64WriteExit + lli v0, 1 + + // assert a1 (copy length) is word-aligned + andi t9, a1, 3 + bnezl t9, Drive64WriteExit + lli v0, 2 + + blez a1, Drive64WriteExit // nothing to write? nothing to do! + lli v0, 0 // delay slot + + lui a2, 0x103F // SDRAM destination + move a3, a1 // SDRAM length + + // flush the cache at a0 to RAM before doing any DMA + andi t6, a0, 0xF + addu t7, a0, a1 // stop flushing around here + subu t6, a0, t6 // align a0 to data line + subiu t7, t7, 1 // turn inclusive end-point into exclusive instead +- + cache 1, 0(t6) // peter says: "Index Writeback Invalidate" + sltu at, t6, t7 + bnez at,- + addiu t6, 0x10 // (delay slot) += data line size + + // AND off the DRAM address + li t9, 0x007FFFFF // __osPiRawStartDma uses 0x1FFFFFFF? + and t1, a0, t9 + + // cart address + move t2, a2 + + // set length (needs to be decremented due to DMA quirk) + subiu t3, a3, 1 + + PI_WAIT() + sw t1, PI_DRAM_ADDR(t5) + sw t2, PI_CART_ADDR(t5) + 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: + lui at, 0x0100 // set printf channel + or a3, a3, at + lli t1, 0x08 // WRITE mode + // SDRAM parameter is given in multiples of halfwords + li t9, 0x0FFFFFFF + and a2, a2, t9 + srl a2, a2, 1 + + CI_USB_WRITE_WAIT() + sw a2, CI_USB_PARAM_RESULT_0(gp) + PI_WAIT() // yes, these waits seem to be necessary + sw a3, CI_USB_PARAM_RESULT_1(gp) + 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 + +Drive64WriteExit: + jr ra + nop // delay slot + +Drive64TestWrite: + li a2, 0xA0000020 + lli a3, 0x20 + j Drive64TestPoint + nop // delay slot diff --git a/dwarf.1bpp b/dwarf.1bpp new file mode 100644 index 0000000..20cb28e Binary files /dev/null and b/dwarf.1bpp differ diff --git a/header.asm b/header.asm new file mode 100644 index 0000000..35008ba --- /dev/null +++ b/header.asm @@ -0,0 +1,38 @@ +//============ +// N64 Header +//============ +// PI_BSB_DOM1 + db $80 // Initial PI_BSB_DOM1_LAT_REG Value + db $37 // Initial PI_BSB_DOM1_PGS_REG Value + db $12 // Initial PI_BSB_DOM1_PWD_REG Value + db $40 // Initial PI_BSB_DOM1_PGS_REG Value + +// CLOCK RATE + dw $000F // Initial Clock Rate + +// VECTOR + dw Start // Boot Address Offset + dw $1444 // Release Offset + +// COMPLEMENT CHECK & CHECKSUM + db "CRC1" // CRC1: COMPLEMENT CHECK + db "CRC2" // CRC2: CHECKSUM + + dd 0 // UNUSED + +// PROGRAM TITLE (27 Byte ASCII String, Use Spaces For Unused Bytes) + db "NOTWA'S TESTING THE 64DRIVE" +// "123456789012345678901234567" + +// DEVELOPER ID CODE + db $00 // "N" = Nintendo + +// CARTRIDGE ID CODE + db $00 + + db 0 // UNUSED + +// COUNTRY CODE + db $00 // "D" = Germany, "E" = USA, "J" = Japan, "P" = Europe, "U" = Australia + + db 0 // UNUSED diff --git a/lz.asm b/lz.asm new file mode 100644 index 0000000..19f7868 --- /dev/null +++ b/lz.asm @@ -0,0 +1,55 @@ +// by krom (Peter Lemon) +// https://github.com/PeterLemon/N64/tree/master/Compress/LZ77/LZ77GFX + +LZInit: + la a0, LZ+4 // A0 = Source Address + lui a1, 0xA010 // A1 = Destination Address (DRAM Start Offset) + + lbu t0, -1(a0) // T0 = HI Data Length Byte + sll t0, 8 + lbu t1, -2(a0) // T1 = MID Data Length Byte + or t0, t1 + sll t0, 8 + lbu t1, -3(a0) // T1 = LO Data Length Byte + or t0, t1 // T0 = Data Length + addu t0, a1 // T0 = Destination End Offset (DRAM End Offset) + +LZLoop: + lbu t1, 0(a0) // T1 = Flag Data For Next 8 Blocks (0 = Uncompressed Byte, 1 = Compressed Bytes) + addiu a0, 1 // Add 1 To LZ Offset + ori t2, r0, %10000000 // T2 = Flag Data Block Type Shifter + +LZBlockLoop: + beq a1, t0, LZEnd // IF (Destination Address == Destination End Offset) LZEnd + and t4, t1, t2 // Test Block Type (Delay Slot) + beqz t2, LZLoop // IF (Flag Data Block Type Shifter == 0) LZLoop + srl t2, 1 // Shift T2 To Next Flag Data Block Type (Delay Slot) + lbu t3, 0(a0) // T3 = Copy Uncompressed Byte / Number Of Bytes To Copy & Disp MSB's + bnez t4, LZDecode // IF (BlockType != 0) LZDecode Bytes + addiu a0, 1 // Add 1 To LZ Offset (Delay Slot) + sb t3, 0(a1) // Store Uncompressed Byte To Destination + j LZBlockLoop + addiu a1, 1 // Add 1 To DRAM Offset (Delay Slot) + +LZDecode: + lbu t4, 0(a0) // T4 = Disp LSB's + addiu a0, 1 // Add 1 To LZ Offset + sll t5, t3, 8 // T5 = Disp MSB's + or t4, t5 // T4 = Disp 16-Bit + andi t4, 0xFFF // T4 &= 0xFFF (Disp 12-Bit) + not t4 // T4 = -Disp - 1 + addu t4, a1 // T4 = Destination - Disp - 1 + srl t3, 4 // T3 = Number Of Bytes To Copy (Minus 3) + addiu t3, 3 // T3 = Number Of Bytes To Copy + +LZCopy: + lbu t5, 0(t4) // T5 = Byte To Copy + addiu t4, 1 // Add 1 To T4 Offset + sb t5, 0(a1) // Store Byte To DRAM + subiu t3, 1 // Number Of Bytes To Copy -= 1 + bnez t3, LZCopy // IF (Number Of Bytes To Copy != 0) LZCopy Bytes + addiu a1, 1 // Add 1 To DRAM Offset (Delay Slot) + j LZBlockLoop + nop // Delay Slot + +LZEnd: diff --git a/main.asm b/main.asm new file mode 100644 index 0000000..e92bb47 --- /dev/null +++ b/main.asm @@ -0,0 +1,217 @@ +// built on the N64 ROM template by krom +arch n64.cpu +endian msb +include "n64.inc" +include "n64_gfx.inc" +include "64drive.inc" + +output "test.z64", create +fill 1052672 // Set ROM Size + +origin 0x00000000 +base 0x80000000 + +include "header.asm" +insert "6102.bin" +// after inserting the header and bootrom, +// origin should be at 0x1000. + +include "main.inc" + +Start: + N64_INIT() // enable interrupts + + // SP defaults to RSP instruction memory: 0xA4001FF0 + // we can do better than that. + lui sp, BLAH_BASE + // SP should always be 8-byte aligned + // so that SD and LD instructions don't fail on it. + subiu sp, sp, 8 + + lui s0, BLAH_BASE + +Drive64Init: + lui gp, CI_BASE + lui t2, 0x5544 // "UD" of "UDEV" + lw t1, CI_HW_MAGIC(gp) + ori t2, t2, 0x4556 // "EV" of "UDEV" + + beq t1, t2, Drive64Confirmed + nop // delay slot + +Drive64TryExtended: + lui gp, CI_BASE_EXTENDED + lw t1, CI_HW_MAGIC(gp) + bne t1, t2, Main + nop // delay slot + +Drive64Confirmed: + sw t2, BLAH_CONFIRMED(s0) + sw gp, BLAH_CI_BASE(s0) + + // enable writing to cartROM (SDRAM) for USB writing later + lli t1, 0xF0 + + CI_WAIT() + sw t1, CI_COMMAND(gp) // send our command + CI_WAIT() + +Main: +if 0 { + mfc0 t0, 0x9 // move cycle Count register from COP 0 + sw t0, BLAH_COUNTS+0(s0) + mfc0 t0, 0x9 // move cycle Count register from COP 0 + sw t0, BLAH_COUNTS+4(s0) + // seems like 41 half-cycles between the two mfc0's, rarely 42? +} else { + mfc0 t0, 0x9 + mfc0 t1, 0x9 + sw t0, BLAH_COUNTS+0(s0) + sw t1, BLAH_COUNTS+4(s0) + // seems like 22 half-cycles between the two mfc0's +} + + // what is our stack pointer set to, anyway? + sw sp, 0xC(s0) + +// decompress our picture +include "lz.asm" + + mfc0 t0, 0x9 + sw t0, BLAH_COUNTS+8(s0) + lw t1, BLAH_CONFIRMED(s0) + beqz t1, InitVideo + nop // delay slot + +// jal Drive64TestWrite +// nop // delay slot + + lui a0, BLAH_BASE + lli a1, 0x20 + ori a2, a0, BLAH_XXD + lli a3, 0x20 * 4 + jal xxd + nop // delay slot + + lui a0, BLAH_BASE // write address + ori a0, a0, BLAH_XXD // (RAM gets copied to SDRAM by routine) + lli a1, 0x20 * 4 + jal Drive64Write + nop // delay slot + +InitVideo: // currently 80001190 (this comment is likely out of date) + // A4000FC0 + + jal LoadRSPBoot + nop + + lui a0, BLAH_BASE + jal PushVideoTask + ori a0, a0, BLAH_SP_TASK + + jal SetupScreen + nop + + mfc0 t0, 0x9 // move cycle Count register from COP 0 + sw t0, BLAH_COUNTS+0xC(s0) + +MainLoop: + // borrowing code from krom for now: + WaitScanline(0x1E0) // Wait For Scanline To Reach Vertical Blank + WaitScanline(0x1E2) + // WaitScanline sets a0 + + ori t0, r0, 0x00000800 // Even Field + sw t0, VI_Y_SCALE(a0) + + WaitScanline(0x1E0) // Wait For Scanline To Reach Vertical Blank + WaitScanline(0x1E2) + // WaitScanline sets a0 + + li t0, 0x02000800 // Odd Field + sw t0, VI_Y_SCALE(a0) + + j MainLoop + nop // delay slot + +include "devcart.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) + jr ra + nop + +LoadRSPBoot: + li t2, F3DZEX_BOOT + li t3, F3DZEX_BOOT.size + subiu t3, t3, 1 // DMA quirk + SP_DMA_WAIT() // clobbers t0, t5 + ori t1, t5, 0x1000 + sw t1, SP_MEM_ADDR(t5) + sw t2, SP_DRAM_ADDR(t5) + sw t3, SP_RD_LEN(t5) // pull data from RDRAM into DMEM/IMEM + jr ra + nop + +PushVideoTask: + // a0: Task RDRAM Pointer (size: 0x40) + subiu sp, sp, 0x8 + sw ra, 0(sp) + + lli t0, 1 // mode: video + lli t1, 4 // flags: ??? + li t2, F3DZEX_BOOT + li t3, F3DZEX_BOOT.size + li t4, F3DZEX_IMEM & ADDR_MASK + li t5, F3DZEX_IMEM.size // note: Zelda uses 0x1000 for some reason (0x80 too big). + li t6, F3DZEX_DMEM & ADDR_MASK + li t7, F3DZEX_DMEM.size // note: Zelda uses 0x800 for some reason (way too big). + sw t0, 0x00(a0) + sw t1, 0x04(a0) + sw t2, 0x08(a0) + sw t3, 0x0C(a0) + sw t4, 0x10(a0) + sw t5, 0x14(a0) + sw t6, 0x18(a0) + sw t7, 0x1C(a0) + li t0, VIDEO_STACK & ADDR_MASK // ? + li t1, VIDEO_STACK_SIZE + li t2, VIDEO_BUFFER & ADDR_MASK + li t3, (VIDEO_BUFFER & ADDR_MASK) + VIDEO_BUFFER_SIZE // end pointer (not size!) + li t4, BLAH_DLIST_JUMPER & ADDR_MASK // initial DList (best to just be one jump command) + lli t5, 8 // size of one jump command + li t6, VIDEO_YIELD & ADDR_MASK + li t7, VIDEO_YIELD_SIZE + sw t0, 0x20(a0) + sw t1, 0x24(a0) + sw t2, 0x28(a0) + sw t3, 0x2C(a0) + sw t4, 0x30(a0) + sw t5, 0x34(a0) + sw t6, 0x38(a0) + sw t7, 0x3C(a0) + jal PushRSPTask // a0 passthru + nop + + lw ra, 0(sp) + jr ra + addiu sp, sp, 0x8 + +PushRSPTask: + lli t3, 0x40 - 1 // DMA quirk + SP_DMA_WAIT() // clobbers t0, t5 + ori t1, t5, 0xFC0 + sw t1, SP_MEM_ADDR(t5) + sw a0, SP_DRAM_ADDR(t5) + sw t3, SP_RD_LEN(t5) // pull data from RDRAM into DMEM/IMEM + 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" +align(16); insert FONT, "dwarf.1bpp" +align(16); insert LZ, "Image.lz" diff --git a/main.inc b/main.inc new file mode 100644 index 0000000..6391be5 --- /dev/null +++ b/main.inc @@ -0,0 +1,56 @@ +constant UNCACHED(0xA0000000) +constant ADDR_MASK(0x1FFFFFFF) + +constant BLAH_BASE(0x803F) +constant BLAH_CONFIRMED(0x0000) +constant BLAH_CI_BASE(0x0004) +constant BLAH_COUNTS(0x0010) +constant BLAH_SP_TASK(0x0040) +constant BLAH_DLIST_JUMPER(0x0080) +constant BLAH_XXD(0x0100) +constant VIDEO_BUFFER(0x80100000) +constant VIDEO_BUFFER_SIZE(640 * 480 * 4) +constant VIDEO_STACK(VIDEO_BUFFER + VIDEO_BUFFER_SIZE) +constant VIDEO_STACK_SIZE(0x400) +constant VIDEO_YIELD(VIDEO_STACK + VIDEO_STACK_SIZE) +constant VIDEO_YIELD_SIZE(0xC00) + +macro PI_WAIT() { + lui t5, PI_BASE +- + lw t0, PI_STATUS(t5) + andi t0, t0, 3 + bnez t0,- + nop // delay slot +} + +macro SP_DMA_WAIT() { // external + lui t5, SP_BASE +- + lw t0, SP_DMA_FULL(t5) + bnez t0,- + nop +- + lw t0, SP_DMA_BUSY(t5) + 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 +} + diff --git a/n64.inc b/n64.inc new file mode 100644 index 0000000..2be051d --- /dev/null +++ b/n64.inc @@ -0,0 +1,267 @@ +// via krom + +//============= +// N64 Include +//============= +// N64 MIPS 4300 CPU Registers +constant r0(0) +constant r1(1) +constant r2(2) +constant r3(3) +constant r4(4) +constant r5(5) +constant r6(6) +constant r7(7) +constant r8(8) +constant r9(9) +constant r10(10) +constant r11(11) +constant r12(12) +constant r13(13) +constant r14(14) +constant r15(15) +constant r16(16) +constant r17(17) +constant r18(18) +constant r19(19) +constant r20(20) +constant r21(21) +constant r22(22) +constant r23(23) +constant r24(24) +constant r25(25) +constant r26(26) +constant r27(27) +constant r28(28) +constant r29(29) +constant r30(30) +constant r31(31) + +constant at(1) +constant v0(2) +constant v1(3) +constant a0(4) +constant a1(5) +constant a2(6) +constant a3(7) +constant t0(8) +constant t1(9) +constant t2(10) +constant t3(11) +constant t4(12) +constant t5(13) +constant t6(14) +constant t7(15) +constant s0(16) +constant s1(17) +constant s2(18) +constant s3(19) +constant s4(20) +constant s5(21) +constant s6(22) +constant s7(23) +constant t8(24) +constant t9(25) +constant k0(26) +constant k1(27) +constant gp(28) +constant sp(29) +constant s8(30) +constant ra(31) + +// N64 MIPS 4300 CP1 Floating Point Unit (FPU) Registers (COP1) +constant f0(0) +constant f1(1) +constant f2(2) +constant f3(3) +constant f4(4) +constant f5(5) +constant f6(6) +constant f7(7) +constant f8(8) +constant f9(9) +constant f10(10) +constant f11(11) +constant f12(12) +constant f13(13) +constant f14(14) +constant f15(15) +constant f16(16) +constant f17(17) +constant f18(18) +constant f19(19) +constant f20(20) +constant f21(21) +constant f22(22) +constant f23(23) +constant f24(24) +constant f25(25) +constant f26(26) +constant f27(27) +constant f28(28) +constant f29(29) +constant f30(30) +constant f31(31) + +// Memory Map +constant RDRAM($A000) // $00000000..$003FFFFF RDRAM Memory 4MB ($00000000..$007FFFFF 8MB With Expansion Pak) + +constant RDRAM_BASE($A3F0) // $03F00000..$03F00027 RDRAM Base Register +constant RDRAM_DEVICE_TYPE($00) // $03F00000..$03F00003 RDRAM: Device Type Register +constant RDRAM_DEVICE_ID($04) // $03F00004..$03F00007 RDRAM: Device ID Register +constant RDRAM_DELAY($08) // $03F00008..$03F0000B RDRAM: Delay Register +constant RDRAM_MODE($0C) // $03F0000C..$03F0000F RDRAM: Mode Register +constant RDRAM_REF_INTERVAL($10) // $03F00010..$03F00013 RDRAM: Ref Interval Register +constant RDRAM_REF_ROW($14) // $03F00014..$03F00017 RDRAM: Ref Row Register +constant RDRAM_RAS_INTERVAL($18) // $03F00018..$03F0001B RDRAM: Ras Interval Register +constant RDRAM_MIN_INTERVAL($1C) // $03F0001C..$03F0001F RDRAM: Minimum Interval Register +constant RDRAM_ADDR_SELECT($20) // $03F00020..$03F00023 RDRAM: Address Select Register +constant RDRAM_DEVICE_MANUF($24) // $03F00024..$03F00027 RDRAM: Device Manufacturer Register + +constant SP_MEM_BASE($A400) // $04000000..$04000FFF SP MEM Base Register +constant SP_DMEM($0000) // $04000000..$04000FFF SP: RSP DMEM (4096 Bytes) +constant SP_IMEM($1000) // $04001000..$04001FFF SP: RSP IMEM (4096 Bytes) + +constant SP_BASE($A404) // $04040000..$0404001F SP Base Register +constant SP_MEM_ADDR($00) // $04040000..$04040003 SP: Master, SP Memory Address Register +constant SP_DRAM_ADDR($04) // $04040004..$04040007 SP: Slave, SP DRAM DMA Address Register +constant SP_RD_LEN($08) // $04040008..$0404000B SP: Read DMA Length Register +constant SP_WR_LEN($0C) // $0404000C..$0404000F SP: Write DMA Length Register +constant SP_STATUS($10) // $04040010..$04040013 SP: Status Register +constant SP_DMA_FULL($14) // $04040014..$04040017 SP: DMA Full Register +constant SP_DMA_BUSY($18) // $04040018..$0404001B SP: DMA Busy Register +constant SP_SEMAPHORE($1C) // $0404001C..$0404001F SP: Semaphore Register + +constant SP_PC_BASE($A408) // $04080000..$04080007 SP PC Base Register +constant SP_PC($00) // $04080000..$04080003 SP: PC Register +constant SP_IBIST_REG($04) // $04080004..$04080007 SP: IMEM BIST Register + +constant DPC_BASE($A410) // $04100000..$0410001F DP Command (DPC) Base Register +constant DPC_START($00) // $04100000..$04100003 DPC: CMD DMA Start Register +constant DPC_END($04) // $04100004..$04100007 DPC: CMD DMA End Register +constant DPC_CURRENT($08) // $04100008..$0410000B DPC: CMD DMA Current Register +constant DPC_STATUS($0C) // $0410000C..$0410000F DPC: CMD Status Register +constant DPC_CLOCK($10) // $04100010..$04100013 DPC: Clock Counter Register +constant DPC_BUFBUSY($14) // $04100014..$04100017 DPC: Buffer Busy Counter Register +constant DPC_PIPEBUSY($18) // $04100018..$0410001B DPC: Pipe Busy Counter Register +constant DPC_TMEM($1C) // $0410001C..$0410001F DPC: TMEM Load Counter Register + +constant DPS_BASE($A420) // $04200000..$0420000F DP Span (DPS) Base Register +constant DPS_TBIST($00) // $04200000..$04200003 DPS: Tmem Bist Register +constant DPS_TEST_MODE($04) // $04200004..$04200007 DPS: Span Test Mode Register +constant DPS_BUFTEST_ADDR($08) // $04200008..$0420000B DPS: Span Buffer Test Address Register +constant DPS_BUFTEST_DATA($0C) // $0420000C..$0420000F DPS: Span Buffer Test Data Register + +constant MI_BASE($A430) // $04300000..$0430000F MIPS Interface (MI) Base Register +constant MI_INIT_MODE($00) // $04300000..$04300003 MI: Init Mode Register +constant MI_VERSION($04) // $04300004..$04300007 MI: Version Register +constant MI_INTR($08) // $04300008..$0430000B MI: Interrupt Register +constant MI_INTR_MASK($0C) // $0430000C..$0430000F MI: Interrupt Mask Register + +constant VI_BASE($A440) // $04400000..$04400037 Video Interface (VI) Base Register +constant VI_STATUS($00) // $04400000..$04400003 VI: Status/Control Register +constant VI_ORIGIN($04) // $04400004..$04400007 VI: Origin Register +constant VI_WIDTH($08) // $04400008..$0440000B VI: Width Register +constant VI_V_INTR($0C) // $0440000C..$0440000F VI: Vertical Interrupt Register +constant VI_V_CURRENT_LINE($10) // $04400010..$04400013 VI: Current Vertical Line Register +constant VI_TIMING($14) // $04400014..$04400017 VI: Video Timing Register +constant VI_V_SYNC($18) // $04400018..$0440001B VI: Vertical Sync Register +constant VI_H_SYNC($1C) // $0440001C..$0440001F VI: Horizontal Sync Register +constant VI_H_SYNC_LEAP($20) // $04400020..$04400023 VI: Horizontal Sync Leap Register +constant VI_H_VIDEO($24) // $04400024..$04400027 VI: Horizontal Video Register +constant VI_V_VIDEO($28) // $04400028..$0440002B VI: Vertical Video Register +constant VI_V_BURST($2C) // $0440002C..$0440002F VI: Vertical Burst Register +constant VI_X_SCALE($30) // $04400030..$04400033 VI: X-Scale Register +constant VI_Y_SCALE($34) // $04400034..$04400037 VI: Y-Scale Register + +constant AI_BASE($A450) // $04500000..$04500017 Audio Interface (AI) Base Register +constant AI_DRAM_ADDR($00) // $04500000..$04500003 AI: DRAM Address Register +constant AI_LEN($04) // $04500004..$04500007 AI: Length Register +constant AI_CONTROL($08) // $04500008..$0450000B AI: Control Register +constant AI_STATUS($0C) // $0450000C..$0450000F AI: Status Register +constant AI_DACRATE($10) // $04500010..$04500013 AI: DAC Sample Period Register +constant AI_BITRATE($14) // $04500014..$04500017 AI: Bit Rate Register + +constant PI_BASE($A460) // $04600000..$04600033 Peripheral Interface (PI) Base Register +constant PI_DRAM_ADDR($00) // $04600000..$04600003 PI: DRAM Address Register +constant PI_CART_ADDR($04) // $04600004..$04600007 PI: Pbus (Cartridge) Address Register +constant PI_RD_LEN($08) // $04600008..$0460000B PI: Read Length Register +constant PI_WR_LEN($0C) // $0460000C..$0460000F PI: Write length register +constant PI_STATUS($10) // $04600010..$04600013 PI: Status Register +constant PI_BSD_DOM1_LAT($14) // $04600014..$04600017 PI: Domain 1 Latency Register +constant PI_BSD_DOM1_PWD($18) // $04600018..$0460001B PI: Domain 1 Pulse Width Register +constant PI_BSD_DOM1_PGS($1C) // $0460001C..$0460001F PI: Domain 1 Page Size Register +constant PI_BSD_DOM1_RLS($20) // $04600020..$04600023 PI: Domain 1 Release Register +constant PI_BSD_DOM2_LAT($24) // $04600024..$04600027 PI: Domain 2 Latency Register +constant PI_BSD_DOM2_PWD($28) // $04600028..$0460002B PI: Domain 2 Pulse Width Register +constant PI_BSD_DOM2_PGS($2C) // $0460002C..$0460002F PI: Domain 2 Page Size Register +constant PI_BSD_DOM2_RLS($30) // $04600030..$04600033 PI: Domain 2 Release Register + +constant RI_BASE($A470) // $04700000..$0470001F RDRAM Interface (RI) Base Register +constant RI_MODE($00) // $04700000..$04700003 RI: Mode Register +constant RI_CONFIG($04) // $04700004..$04700007 RI: Config Register +constant RI_CURRENT_LOAD($08) // $04700008..$0470000B RI: Current Load Register +constant RI_SELECT($0C) // $0470000C..$0470000F RI: Select Register +constant RI_REFRESH($10) // $04700010..$04700013 RI: Refresh Register +constant RI_LATENCY($14) // $04700014..$04700017 RI: Latency Register +constant RI_RERROR($18) // $04700018..$0470001B RI: Read Error Register +constant RI_WERROR($1C) // $0470001C..$0470001F RI: Write Error Register + +constant SI_BASE($A480) // $04800000..$0480001B Serial Interface (SI) Base Register +constant SI_DRAM_ADDR($00) // $04800000..$04800003 SI: DRAM Address Register +constant SI_PIF_ADDR_RD64B($04) // $04800004..$04800007 SI: Address Read 64B Register +//*RESERVED*($08) // $04800008..$0480000B SI: Reserved Register +//*RESERVED*($0C) // $0480000C..$0480000F SI: Reserved Register +constant SI_PIF_ADDR_WR64B($10) // $04800010..$04800013 SI: Address Write 64B Register +//*RESERVED*($14) // $04800014..$04800017 SI: Reserved Register +constant SI_STATUS($18) // $04800018..$0480001B SI: Status Register + +constant CART_DOM2_ADDR1($A500) // $05000000..$0507FFFF Cartridge Domain 2(Address 1) SRAM +constant CART_DOM1_ADDR1($A600) // $06000000..$07FFFFFF Cartridge Domain 1(Address 1) 64DD +constant CART_DOM2_ADDR2($A800) // $08000000..$0FFFFFFF Cartridge Domain 2(Address 2) SRAM +constant CART_DOM1_ADDR2($B000) // $10000000..$18000803 Cartridge Domain 1(Address 2) ROM + +constant PIF_BASE($BFC0) // $1FC00000..$1FC007BF PIF Base Register +constant PIF_ROM($000) // $1FC00000..$1FC007BF PIF: Boot ROM +constant PIF_RAM($7C0) // $1FC007C0..$1FC007FF PIF: RAM (JoyChannel) +constant PIF_HWORD($7C4) // $1FC007C4..$1FC007C5 PIF: HWORD +constant PIF_XBYTE($7C6) // $1FC007C6 PIF: Analog X Byte +constant PIF_YBYTE($7C7) // $1FC007C7 PIF: Analog Y Byte + +constant CART_DOM1_ADDR3($BFD0) // $1FD00000..$7FFFFFFF Cartridge Domain 1 (Address 3) + +constant EXT_SYS_AD($8000) // $80000000..$FFFFFFFF External SysAD Device + +constant VI_NTSC_CLOCK(48681812) // NTSC: Hz = 48.681812 MHz +constant VI_PAL_CLOCK(49656530) // PAL: Hz = 49.656530 MHz +constant VI_MPAL_CLOCK(48628316) // MPAL: Hz = 48.628316 MHz + +macro align(size) { // Align Byte Amount + while (pc() % {size}) { + db 0 + } +} + +macro N64_INIT() { + // enables interrupts on SI and PI. + // must be done else N64 will stop responding. + lui a0,PIF_BASE // A0 = PIF Base Register ($BFC00000) + lli t0,8 + sw t0,PIF_RAM+$3C(a0) +} + +macro DMA(start, end, dest) { // DMA Data Copy Cart->DRAM: Start Cart Address, End Cart Address, Destination DRAM Address + lui a0,PI_BASE // A0 = PI Base Register ($A4600000) + - + lw t0,PI_STATUS(a0) // T0 = Word From PI Status Register ($A4600010) + andi t0,3 // AND PI Status With 3 + bnez t0,- // IF TRUE DMA Is Busy + nop // Delay Slot + + la t0,{dest}&$7FFFFF // T0 = Aligned DRAM Physical RAM Offset ($00000000..$007FFFFF 8MB) + sw t0,PI_DRAM_ADDR(a0) // Store RAM Offset To PI DRAM Address Register ($A4600000) + la t0,$10000000|({start}&$3FFFFFF) // T0 = Aligned Cart Physical ROM Offset ($10000000..$13FFFFFF 64MB) + sw t0,PI_CART_ADDR(a0) // Store ROM Offset To PI Cart Address Register ($A4600004) + la t0,({end}-{start})-1 // T0 = Length Of DMA Transfer In Bytes - 1 + sw t0,PI_WR_LEN(a0) // Store DMA Length To PI Write Length Register ($A460000C) +} diff --git a/n64_gfx.inc b/n64_gfx.inc new file mode 100644 index 0000000..8bdee7b --- /dev/null +++ b/n64_gfx.inc @@ -0,0 +1,523 @@ +// via krom + +//============== +// N64 Graphics +//============== +constant BPP0($0000) // VI Status/Control: Color Depth Blank (No Data Or Sync) (Bit 0..1) +//*RESERVED*($0001) // VI Status/Control: Color Depth Reserved (Bit 0..1) +constant BPP16($0002) // VI Status/Control: Color Depth 16BPP R5/G5/B5/A1 (Bit 0..1) +constant BPP32($0003) // VI Status/Control: Color Depth 32BPP R8/G8/B8/A8 (Bit 0..1) +constant GAMMA_DITHER_EN($00004) // VI Status/Control: Gamma Dither Enable (Requires: Gamma Enable) (Bit 2) +constant GAMMA_EN($00008) // VI Status/Control: Gamma Enable (Gamma Boost For YUV Images) (Bit 3) +constant DIVOT_EN($00010) // VI Status/Control: Divot Enable (Used With Anti-alias) (Bit 4) +constant VBUS_CLK_EN($00020) // VI Status/Control: Video Bus Clock Enable (Bit 5) +constant INTERLACE($00040) // VI Status/Control: Interlace/Serrate (Used With Interlaced Display) (Bit 6) +constant TST_MODE($00080) // VI Status/Control: Test Mode (Bit 7) +constant AA_MODE_0($00000) // VI Status/Control: AA Mode 0 = Anti­-alias & Resample (Always Fetch Extra Lines) (Bit 8..9) +constant AA_MODE_1($00100) // VI Status/Control: AA Mode 1 = Anti­-alias & Resample (Fetch Extra Lines When Needed) (Bit 8..9) +constant AA_MODE_2($00200) // VI Status/Control: AA Mode 2 = Resample Only (Bit 8..9) +constant AA_MODE_3($00300) // VI Status/Control: AA Mode 3 = Replicate Pixels & No Interpolation (Bit 8..9) +constant DIAG_0($00400) // VI Status/Control: Diagnotic 0 (Bit 10..11) +constant DIAG_1($00800) // VI Status/Control: Diagnotic 1 (Bit 10..11) +constant PIXEL_ADV_0($00000) // VI Status/Control: Pixel Advance 0 (Bit 12..15) +constant PIXEL_ADV_1($01000) // VI Status/Control: Pixel Advance 1 (Bit 12..15) +constant PIXEL_ADV_2($02000) // VI Status/Control: Pixel Advance 2 (Bit 12..15) +constant PIXEL_ADV_3($03000) // VI Status/Control: Pixel Advance 3 (Bit 12..15) +constant PIXEL_ADV_4($04000) // VI Status/Control: Pixel Advance 4 (Bit 12..15) +constant PIXEL_ADV_5($05000) // VI Status/Control: Pixel Advance 5 (Bit 12..15) +constant PIXEL_ADV_6($06000) // VI Status/Control: Pixel Advance 6 (Bit 12..15) +constant PIXEL_ADV_7($07000) // VI Status/Control: Pixel Advance 7 (Bit 12..15) +constant PIXEL_ADV_8($08000) // VI Status/Control: Pixel Advance 8 (Bit 12..15) +constant PIXEL_ADV_9($09000) // VI Status/Control: Pixel Advance 9 (Bit 12..15) +constant PIXEL_ADV_A($0A000) // VI Status/Control: Pixel Advance A (Bit 12..15) +constant PIXEL_ADV_B($0B000) // VI Status/Control: Pixel Advance B (Bit 12..15) +constant PIXEL_ADV_C($0C000) // VI Status/Control: Pixel Advance C (Bit 12..15) +constant PIXEL_ADV_D($0D000) // VI Status/Control: Pixel Advance D (Bit 12..15) +constant PIXEL_ADV_E($0E000) // VI Status/Control: Pixel Advance E (Bit 12..15) +constant PIXEL_ADV_F($0F000) // VI Status/Control: Pixel Advance F (Bit 12..15) +constant DITHER_FILTER_EN($10000) // VI Status/Control: Dither Filter Enable (Used With 16BPP Display) (Bit 16) + +macro ScreenNTSC(width,height, status, origin) { + lui a0,VI_BASE // A0 = VI Base Register ($A4400000) + li t0,{status} // T0 = Status/Control + sw t0,VI_STATUS(a0) // Store Status/Control To VI Status Register ($A4400000) + la t0,{origin} // T0 = Origin (Frame Buffer Origin In Bytes) + sw t0,VI_ORIGIN(a0) // Store Origin To VI Origin Register ($A4400004) + lli t0,{width} // T0 = Width (Frame Buffer Line Width In Pixels) + sw t0,VI_WIDTH(a0) // Store Width To VI Width Register ($A4400008) + lli t0,$200 // T0 = Vertical Interrupt (Interrupt When Current Half-Line $200) + sw t0,VI_V_INTR(a0) // Store Vertical Interrupt To VI Interrupt Register ($A440000C) + lli t0,0 // T0 = Current Vertical Line (Current Half-Line, Sampled Once Per Line = 0) + sw t0,VI_V_CURRENT_LINE(a0) // Store Current Vertical Line To VI Current Register ($A4400010) + li t0,$3E52239 // T0 = Video Timing (Start Of Color Burst In Pixels from H-Sync = 3, Vertical Sync Width In Half Lines = 229, Color Burst Width In Pixels = 34, Horizontal Sync Width In Pixels = 57) + sw t0,VI_TIMING(a0) // Store Video Timing To VI Burst Register ($A4400014) + lli t0,$20D // T0 = Vertical Sync (Number Of Half-Lines Per Field = 525) + sw t0,VI_V_SYNC(a0) // Store Vertical Sync To VI V Sync Register ($A4400018) + lli t0,$C15 // T0 = Horizontal Sync (5-bit Leap Pattern Used For PAL only = 0, Total Duration Of A Line In 1/4 Pixel = 3093) + sw t0,VI_H_SYNC(a0) // Store Horizontal Sync To VI H Sync Register ($A440001C) + li t0,$C150C15 // T0 = Horizontal Sync Leap (Identical To H Sync = 3093, Identical To H Sync = 3093) + sw t0,VI_H_SYNC_LEAP(a0) // Store Horizontal Sync Leap To VI Leap Register ($A4400020) + li t0,$6C02EC // T0 = Horizontal Video (Start Of Active Video In Screen Pixels = 108, End Of Active Video In Screen Pixels = 748) + sw t0,VI_H_VIDEO(a0) // Store Horizontal Video To VI H Start Register ($A4400024) + li t0,$2501FF // T0 = Vertical Video (Start Of Active Video In Screen Half-Lines = 37, End Of Active Video In Screen Half-Lines = 511) + sw t0,VI_V_VIDEO(a0) // Store Vertical Video To VI V Start Register ($A4400028) + li t0,$E0204 // T0 = Vertical Burst (Start Of Color Burst Enable In Half-Lines = 14, End Of Color Burst Enable In Half-Lines = 516) + sw t0,VI_V_BURST(a0) // Store Vertical Burst To VI V Burst Register ($A440002C) + lli t0,($100*({width}/160)) // T0 = X-Scale (Horizontal Subpixel Offset In 2.10 Format = 0, 1/Horizontal Scale Up Factor In 2.10 Format) + sw t0,VI_X_SCALE(a0) // Store X-Scale To VI X Scale Register ($A4400030) + lli t0,($100*({height}/60)) // T0 = Y-Scale (Vertical Subpixel Offset In 2.10 Format = 0, 1/Vertical Scale Up Factor In 2.10 Format) + sw t0,VI_Y_SCALE(a0) // Store Y-Scale To VI Y Scale Register ($A4400034) +} + +macro ScreenPAL(width,height, status, origin) { + lui a0,VI_BASE // A0 = VI Base Register ($A4400000) + li t0,{status} // T0 = Status/Control + sw t0,VI_STATUS(a0) // Store Status/Control To VI Status Register ($A4400000) + la t0,{origin} // T0 = Origin (Frame Buffer Origin In Bytes) + sw t0,VI_ORIGIN(a0) // Store Origin To VI Origin Register ($A4400004) + lli t0,{width} // T0 = Width (Frame Buffer Line Width In Pixels) + sw t0,VI_WIDTH(a0) // Store Width To VI Width Register ($A4400008) + lli t0,$200 // T0 = Vertical Interrupt (Interrupt When Current Half-Line $200) + sw t0,VI_V_INTR(a0) // Store Vertical Interrupt To VI Interrupt Register ($A440000C) + lli t0,0 // T0 = Current Vertical Line (Current Half-Line, Sampled Once Per Line = 0) + sw t0,VI_V_CURRENT_LINE(a0) // Store Current Vertical Line To VI Current Register ($A4400010) + li t0,$404233A // T0 = Video Timing (Start Of Color Burst In Pixels from H-Sync = 4, Vertical Sync Width In Half Lines = 04, Color Burst Width In Pixels = 35, Horizontal Sync Width In Pixels = 58) + sw t0,VI_TIMING(a0) // Store Video Timing To VI Burst Register ($A4400014) + lli t0,$271 // T0 = Vertical Sync (Number Of Half-Lines Per Field = 625) + sw t0,VI_V_SYNC(a0) // Store Vertical Sync To VI V Sync Register ($A4400018) + li t0,$150C69 // T0 = Horizontal Sync (5-bit Leap Pattern Used For PAL only = 21: %10101, Total Duration Of A Line In 1/4 Pixel = 3177) + sw t0,VI_H_SYNC(a0) // Store Horizontal Sync To VI H Sync Register ($A440001C) + li t0,$C6F0C6E // T0 = Horizontal Sync Leap (Identical To H Sync = 3183, Identical To H Sync = 3182) + sw t0,VI_H_SYNC_LEAP(a0) // Store Horizontal Sync Leap To VI Leap Register ($A4400020) + li t0,$800300 // T0 = Horizontal Video (Start Of Active Video In Screen Pixels = 128, End Of Active Video In Screen Pixels = 768) + sw t0,VI_H_VIDEO(a0) // Store Horizontal Video To VI H Start Register ($A4400024) + li t0,$5F0239 // T0 = Vertical Video (Start Of Active Video In Screen Half-Lines = 95, End Of Active Video In Screen Half-Lines = 569) + sw t0,VI_V_VIDEO(a0) // Store Vertical Video To VI V Start Register ($A4400028) + li t0,$9026B // T0 = Vertical Burst (Start Of Color Burst Enable In Half-Lines = 9, End Of Color Burst Enable In Half-Lines = 619) + sw t0,VI_V_BURST(a0) // Store Vertical Burst To VI V Burst Register ($A440002C) + lli t0,($100*({width}/160)) // T0 = X-Scale (Horizontal Subpixel Offset In 2.10 Format = 0, 1/Horizontal Scale Up Factor In 2.10 Format) + sw t0,VI_X_SCALE(a0) // Store X-Scale To VI X Scale Register ($A4400030) + lli t0,($100*({height}/60)) // T0 = Y-Scale (Vertical Subpixel Offset In 2.10 Format = 0, 1/Vertical Scale Up Factor In 2.10 Format) + sw t0,VI_Y_SCALE(a0) // Store Y-Scale To VI Y Scale Register ($A4400034) +} + +macro WaitScanline(scanline) { // Wait For RDP To Reach Scanline + lui a0,VI_BASE // A0 = VI Base Register ($A4400000) + lli t0,{scanline} // T0 = Scan Line + - + lw t1,VI_V_CURRENT_LINE(a0) // T1 = Current Scan Line + bne t1,t0,- // IF (Current Scan Line != Scan Line) Wait + nop // ELSE Continue (Delay Slot) +} + +// RDP Commands +macro DPC(start,end) { // Run DPC Command Buffer: Start Address, End Address + lui a0,DPC_BASE // A0 = Reality Display Processer Control Interface Base Register ($A4100000) + la a1,{start} // A1 = DPC Command Start Address + sw a1,DPC_START(a0) // Store DPC Command Start Address To DP Start Register ($A4100000) + la a1,{end} // A1 = DPC Command End Address + sw a1,DPC_END(a0) // Store DPC Command End Address To DP End Register ($A4100004) +} + +// No_Op: No Effect On RDP Command Execution, Useful For Padding Command Buffers + +// Fill_Triangle: lft,level,tile,yl,ym,yh, xl,xlf,dxldy,dxldyf, xh,xhf,dxhdy,dxhdyf, xm,xmf,dxmdy,dxmdyf +// Word 0: Left Major Flag (0=Left Major, 1=Right Major), Number Of Mip-Maps Minus One, Tile ID, Y Coordinate Of Low, Mid Minor, Major Edge (Fixed Point S.11.2) +// Word 1: X Coordinate Of Low Edge Integer, Fraction, DxLDy Inverse Slope Of Low Edge Integer, Fraction +// Word 2: X Coordinate Of Major Edge Integer, Fraction, DxHDy Inverse Slope Of Major Edge Integer, Fraction +// Word 3: X Coordinate Of Middle Edge Integer, Fraction, DxMDy Inverse Slope Of Middle Edge Integer, Fraction + +// Fill_ZBuffer_Triangle: lft,level,tile,yl,ym,yh, xl,xlf,dxldy,dxldyf, xh,xhf,dxhdy,dxhdyf, xm,xmf,dxmdy,dxmdyf +// Word 0: Left Major Flag (0=Left Major, 1=Right Major), Number Of Mip-Maps Minus One, Tile ID, Y Coordinate Of Low, Mid Minor, Major Edge (Fixed Point S.11.2) +// Word 1: X Coordinate Of Low Edge Integer, Fraction, DxLDy Inverse Slope Of Low Edge Integer, Fraction +// Word 2: X Coordinate Of Major Edge Integer, Fraction, DxHDy Inverse Slope Of Major Edge Integer, Fraction +// Word 3: X Coordinate Of Middle Edge Integer, Fraction, DxMDy Inverse Slope Of Middle Edge Integer, Fraction +// Word 4: Z Inverse Depth Integer, Fraction, DzDx Change In Z Per Change In X Coordinate Integer, Fraction (ZBuffer Coefficients) +// Word 5: DzDe Change In Z Along Major Edge Integer, Fraction, DzDy Change In Z Per Change In Y Coordinate Integer, Fraction + +// Texture_Triangle: lft,level,tile,yl,ym,yh, xl,xlf,dxldy,dxldyf, xh,xhf,dxhdy,dxhdyf, xm,xmf,dxmdy,dxmdyf +// Word 0: Left Major Flag (0=Left Major, 1=Right Major), Number Of Mip-Maps Minus One, Tile ID, Y Coordinate Of Low, Mid Minor, Major Edge (Fixed Point S.11.2) +// Word 1: X Coordinate Of Low Edge Integer, Fraction, DxLDy Inverse Slope Of Low Edge Integer, Fraction +// Word 2: X Coordinate Of Major Edge Integer, Fraction, DxHDy Inverse Slope Of Major Edge Integer, Fraction +// Word 3: X Coordinate Of Middle Edge Integer, Fraction, DxMDy Inverse Slope Of Middle Edge Integer, Fraction +// Word 4: S Texture Coordinate Integer, T Texture Coordinate Integer, W Normalized Inverse Depth Integer (Texture Coefficients) +// Word 5: DsDx Change In S, DtDx Change In T, DwDx Change In W Per Change In X Coordinate Integer +// Word 6: S Texture Coordinate Fraction, T Texture Coordinate Fraction, W Normalized Inverse Depth Fraction +// Word 7: DsDx Change In S, DtDx Change In T, DwDx Change In W Per Change In X Coordinate Fraction +// Word 8: DsDe Change In S, DtDe Change In T, DwDe Change In W Along The Edge Integer +// Word 9: DsDy Change In S, DtDy Change In T, DwDy Change In W Per Change In Y Coordinate Integer +// Word 10: DsDe Change In S, DtDe Change In T, DwDe Change In W Along The Edge Fraction +// Word 11: DsDy Change In S, DtDy Change In T, DwDy Change In W Per Change In Y Coordinate Fraction + +// Texture_ZBuffer_Triangle: lft,level,tile,yl,ym,yh, xl,xlf,dxldy,dxldyf, xh,xhf,dxhdy,dxhdyf, xm,xmf,dxmdy,dxmdyf +// Word 0: Left Major Flag (0=Left Major, 1=Right Major), Number Of Mip-Maps Minus One, Tile ID, Y Coordinate Of Low, Mid Minor, Major Edge (Fixed Point S.11.2) +// Word 1: X Coordinate Of Low Edge Integer, Fraction, DxLDy Inverse Slope Of Low Edge Integer, Fraction +// Word 2: X Coordinate Of Major Edge Integer, Fraction, DxHDy Inverse Slope Of Major Edge Integer, Fraction +// Word 3: X Coordinate Of Middle Edge Integer, Fraction, DxMDy Inverse Slope Of Middle Edge Integer, Fraction +// Word 4: S Texture Coordinate Integer, T Texture Coordinate Integer, W Normalized Inverse Depth Integer (Texture Coefficients) +// Word 5: DsDx Change In S, DtDx Change In T, DwDx Change In W Per Change In X Coordinate Integer +// Word 6: S Texture Coordinate Fraction, T Texture Coordinate Fraction, W Normalized Inverse Depth Fraction +// Word 7: DsDx Change In S, DtDx Change In T, DwDx Change In W Per Change In X Coordinate Fraction +// Word 8: DsDe Change In S, DtDe Change In T, DwDe Change In W Along The Edge Integer +// Word 9: DsDy Change In S, DtDy Change In T, DwDy Change In W Per Change In Y Coordinate Integer +// Word 10: DsDe Change In S, DtDe Change In T, DwDe Change In W Along The Edge Fraction +// Word 11: DsDy Change In S, DtDy Change In T, DwDy Change In W Per Change In Y Coordinate Fraction +// Word 12: Z Inverse Depth Integer, Fraction, DzDx Change In Z Per Change In X Coordinate Integer, Fraction (ZBuffer Coefficients) +// Word 13: DzDe Change In Z Along Major Edge Integer, Fraction, DzDy Change In Z Per Change In Y Coordinate Integer, Fraction + +// Shade_Triangle: lft,level,tile,yl,ym,yh, xl,xlf,dxldy,dxldyf, xh,xhf,dxhdy,dxhdyf, xm,xmf,dxmdy,dxmdyf +// Word 0: Left Major Flag (0=Left Major, 1=Right Major), Number Of Mip-Maps Minus One, Tile ID, Y Coordinate Of Low, Mid Minor, Major Edge (Fixed Point S.11.2) +// Word 1: X Coordinate Of Low Edge Integer, Fraction, DxLDy Inverse Slope Of Low Edge Integer, Fraction +// Word 2: X Coordinate Of Major Edge Integer, Fraction, DxHDy Inverse Slope Of Major Edge Integer, Fraction +// Word 3: X Coordinate Of Middle Edge Integer, Fraction, DxMDy Inverse Slope Of Middle Edge Integer, Fraction +// Word 4: Red Color Component Integer, Green Color Component Integer, Blue Color Component Integer, Alpha Color Component Integer (Shade Coefficients) +// Word 5: DrDx Change In Red, DgDx Change In Green, DbDx Change In Blue, DaDx Change In Alpha Per Change In X Coordinate Integer +// Word 6: Red Color Component Fraction, Green Color Component Fraction, Blue Color Component Fraction, Alpha Color Component Fraction +// Word 7: DrDx Change In Red, DgDx Change In Green, DbDx Change In Blue, DaDx Change In Alpha Per Change In X Coordinate Fraction +// Word 8: DrDe Change In Red, DgDe Change In Green, DbDe Change In Blue, DaDe Change In Alpha Along The Edge Integer +// Word 9: DrDy Change In Red, DgDy Change In Green, DbDy Change In Blue, DaDy Change In Alpha Per Change In Y Coordinate Integer +// Word 10: DrDe Change In Red, DgDe Change In Green, DbDe Change In Blue, DaDe Change In Alpha Along The Edge Fraction +// Word 11: DrDy Change In Red, DgDy Change In Green, DbDy Change In Blue, DaDy Change In Alpha Per Change In Y Coordinate Fraction + +// Shade_ZBuffer_Triangle: lft,level,tile,yl,ym,yh, xl,xlf,dxldy,dxldyf, xh,xhf,dxhdy,dxhdyf, xm,xmf,dxmdy,dxmdyf +// Word 0: Left Major Flag (0=Left Major, 1=Right Major), Number Of Mip-Maps Minus One, Tile ID, Y Coordinate Of Low, Mid Minor, Major Edge (Fixed Point S.11.2) +// Word 1: X Coordinate Of Low Edge Integer, Fraction, DxLDy Inverse Slope Of Low Edge Integer, Fraction +// Word 2: X Coordinate Of Major Edge Integer, Fraction, DxHDy Inverse Slope Of Major Edge Integer, Fraction +// Word 3: X Coordinate Of Middle Edge Integer, Fraction, DxMDy Inverse Slope Of Middle Edge Integer, Fraction +// Word 4: Red Color Component Integer, Green Color Component Integer, Blue Color Component Integer, Alpha Color Component Integer (Shade Coefficients) +// Word 5: DrDx Change In Red, DgDx Change In Green, DbDx Change In Blue, DaDx Change In Alpha Per Change In X Coordinate Integer +// Word 6: Red Color Component Fraction, Green Color Component Fraction, Blue Color Component Fraction, Alpha Color Component Fraction +// Word 7: DrDx Change In Red, DgDx Change In Green, DbDx Change In Blue, DaDx Change In Alpha Per Change In X Coordinate Fraction +// Word 8: DrDe Change In Red, DgDe Change In Green, DbDe Change In Blue, DaDe Change In Alpha Along The Edge Integer +// Word 9: DrDy Change In Red, DgDy Change In Green, DbDy Change In Blue, DaDy Change In Alpha Per Change In Y Coordinate Integer +// Word 10: DrDe Change In Red, DgDe Change In Green, DbDe Change In Blue, DaDe Change In Alpha Along The Edge Fraction +// Word 11: DrDy Change In Red, DgDy Change In Green, DbDy Change In Blue, DaDy Change In Alpha Per Change In Y Coordinate Fraction +// Word 12: Z Inverse Depth Integer, Fraction, DzDx Change In Z Per Change In X Coordinate Integer, Fraction (ZBuffer Coefficients) +// Word 13: DzDe Change In Z Along Major Edge Integer, Fraction, DzDy Change In Z Per Change In Y Coordinate Integer, Fraction + +// Shade_Texture_Triangle: lft,level,tile,yl,ym,yh, xl,xlf,dxldy,dxldyf, xh,xhf,dxhdy,dxhdyf, xm,xmf,dxmdy,dxmdyf +// Word 0: Left Major Flag (0=Left Major, 1=Right Major), Number Of Mip-Maps Minus One, Tile ID, Y Coordinate Of Low, Mid Minor, Major Edge (Fixed Point S.11.2) +// Word 1: X Coordinate Of Low Edge Integer, Fraction, DxLDy Inverse Slope Of Low Edge Integer, Fraction +// Word 2: X Coordinate Of Major Edge Integer, Fraction, DxHDy Inverse Slope Of Major Edge Integer, Fraction +// Word 3: X Coordinate Of Middle Edge Integer, Fraction, DxMDy Inverse Slope Of Middle Edge Integer, Fraction +// Word 4: Red Color Component Integer, Green Color Component Integer, Blue Color Component Integer, Alpha Color Component Integer (Shade Coefficients) +// Word 5: DrDx Change In Red, DgDx Change In Green, DbDx Change In Blue, DaDx Change In Alpha Per Change In X Coordinate Integer +// Word 6: Red Color Component Fraction, Green Color Component Fraction, Blue Color Component Fraction, Alpha Color Component Fraction +// Word 7: DrDx Change In Red, DgDx Change In Green, DbDx Change In Blue, DaDx Change In Alpha Per Change In X Coordinate Fraction +// Word 8: DrDe Change In Red, DgDe Change In Green, DbDe Change In Blue, DaDe Change In Alpha Along The Edge Integer +// Word 9: DrDy Change In Red, DgDy Change In Green, DbDy Change In Blue, DaDy Change In Alpha Per Change In Y Coordinate Integer +// Word 10: DrDe Change In Red, DgDe Change In Green, DbDe Change In Blue, DaDe Change In Alpha Along The Edge Fraction +// Word 11: DrDy Change In Red, DgDy Change In Green, DbDy Change In Blue, DaDy Change In Alpha Per Change In Y Coordinate Fraction +// Word 12: S Texture Coordinate Integer, T Texture Coordinate Integer, W Normalized Inverse Depth Integer (Texture Coefficients) +// Word 13: DsDx Change In S, DtDx Change In T, DwDx Change In W Per Change In X Coordinate Integer +// Word 14: S Texture Coordinate Fraction, T Texture Coordinate Fraction, W Normalized Inverse Depth Fraction +// Word 15: DsDx Change In S, DtDx Change In T, DwDx Change In W Per Change In X Coordinate Fraction +// Word 16: DsDe Change In S, DtDe Change In T, DwDe Change In W Along The Edge Integer +// Word 17: DsDy Change In S, DtDy Change In T, DwDy Change In W Per Change In Y Coordinate Integer +// Word 18: DsDe Change In S, DtDe Change In T, DwDe Change In W Along The Edge Fraction +// Word 19: DsDy Change In S, DtDy Change In T, DwDy Change In W Per Change In Y Coordinate Fraction + +// Shade_Texture_Z_Buffer_Triangle: lft,level,tile,yl,ym,yh, xl,xlf,dxldy,dxldyf, xh,xhf,dxhdy,dxhdyf, xm,xmf,dxmdy,dxmdyf +// Word 0: Left Major Flag (0=Left Major, 1=Right Major), Number Of Mip-Maps Minus One, Tile ID, Y Coordinate Of Low, Mid Minor, Major Edge (Fixed Point S.11.2) +// Word 1: X Coordinate Of Low Edge Integer, Fraction, DxLDy Inverse Slope Of Low Edge Integer, Fraction +// Word 2: X Coordinate Of Major Edge Integer, Fraction, DxHDy Inverse Slope Of Major Edge Integer, Fraction +// Word 3: X Coordinate Of Middle Edge Integer, Fraction, DxMDy Inverse Slope Of Middle Edge Integer, Fraction +// Word 4: Red Color Component Integer, Green Color Component Integer, Blue Color Component Integer, Alpha Color Component Integer (Shade Coefficients) +// Word 5: DrDx Change In Red, DgDx Change In Green, DbDx Change In Blue, DaDx Change In Alpha Per Change In X Coordinate Integer +// Word 6: Red Color Component Fraction, Green Color Component Fraction, Blue Color Component Fraction, Alpha Color Component Fraction +// Word 7: DrDx Change In Red, DgDx Change In Green, DbDx Change In Blue, DaDx Change In Alpha Per Change In X Coordinate Fraction +// Word 8: DrDe Change In Red, DgDe Change In Green, DbDe Change In Blue, DaDe Change In Alpha Along The Edge Integer +// Word 9: DrDy Change In Red, DgDy Change In Green, DbDy Change In Blue, DaDy Change In Alpha Per Change In Y Coordinate Integer +// Word 10: DrDe Change In Red, DgDe Change In Green, DbDe Change In Blue, DaDe Change In Alpha Along The Edge Fraction +// Word 11: DrDy Change In Red, DgDy Change In Green, DbDy Change In Blue, DaDy Change In Alpha Per Change In Y Coordinate Fraction +// Word 12: S Texture Coordinate Integer, T Texture Coordinate Integer, W Normalized Inverse Depth Integer (Texture Coefficients) +// Word 13: DsDx Change In S, DtDx Change In T, DwDx Change In W Per Change In X Coordinate Integer +// Word 14: S Texture Coordinate Fraction, T Texture Coordinate Fraction, W Normalized Inverse Depth Fraction +// Word 15: DsDx Change In S, DtDx Change In T, DwDx Change In W Per Change In X Coordinate Fraction +// Word 16: DsDe Change In S, DtDe Change In T, DwDe Change In W Along The Edge Integer +// Word 17: DsDy Change In S, DtDy Change In T, DwDy Change In W Per Change In Y Coordinate Integer +// Word 18: DsDe Change In S, DtDe Change In T, DwDe Change In W Along The Edge Fraction +// Word 19: DsDy Change In S, DtDy Change In T, DwDy Change In W Per Change In Y Coordinate Fraction +// Word 20: Z Inverse Depth Integer, Fraction, DzDx Change In Z Per Change In X Coordinate Integer, Fraction (ZBuffer Coefficients) +// Word 21: DzDe Change In Z Along Major Edge Integer, Fraction, DzDy Change In Z Per Change In Y Coordinate Integer, Fraction + +// Shade_Coefficients: r,g,b,a, drdx,dgdx,dbdx,dadx, rf,gf,bf,af, drdxf,dgdxf,dbdxf,dadxf, drde,dgde,dbde,dade, drdy,dgdy,dbdy,dady, drdef,dgdef,dbdef,dadef, drdyf,dgdyf,dbdyf,dadyf +// Word 0: Red Color Component Integer, Green Color Component Integer, Blue Color Component Integer, Alpha Color Component Integer (Shade Coefficients) +// Word 1: DrDx Change In Red, DgDx Change In Green, DbDx Change In Blue, DaDx Change In Alpha Per Change In X Coordinate Integer +// Word 2: Red Color Component Fraction, Green Color Component Fraction, Blue Color Component Fraction, Alpha Color Component Fraction +// Word 3: DrDx Change In Red, DgDx Change In Green, DbDx Change In Blue, DaDx Change In Alpha Per Change In X Coordinate Fraction +// Word 4: DrDe Change In Red, DgDe Change In Green, DbDe Change In Blue, DaDe Change In Alpha Along The Edge Integer +// Word 5: DrDy Change In Red, DgDy Change In Green, DbDy Change In Blue, DaDy Change In Alpha Per Change In Y Coordinate Integer +// Word 6: DrDe Change In Red, DgDe Change In Green, DbDe Change In Blue, DaDe Change In Alpha Along The Edge Fraction +// Word 7: DrDy Change In Red, DgDy Change In Green, DbDy Change In Blue, DaDy Change In Alpha Per Change In Y Coordinate Fraction + +// Texture_Coefficients: s,t,w, dsdx,dtdx,dwdx, sf,tf,wf, dsdxf,dtdxf,dwdxf, dsde,dtde,dwde, dsdy,dtdy,dwdy, dsdef,dtdef,dwdef, dsdyf,dtdyf,dwdyf +// Word 0: S Texture Coordinate Integer, T Texture Coordinate Integer, W Normalized Inverse Depth Integer +// Word 1: DsDx Change In S, DtDx Change In T, DwDx Change In W Per Change In X Coordinate Integer +// Word 2: S Texture Coordinate Fraction, T Texture Coordinate Fraction, W Normalized Inverse Depth Fraction +// Word 3: DsDx Change In S, DtDx Change In T, DwDx Change In W Per Change In X Coordinate Fraction +// Word 4: DsDe Change In S, DtDe Change In T, DwDe Change In W Along The Edge Integer +// Word 5: DsDy Change In S, DtDy Change In T, DwDy Change In W Per Change In Y Coordinate Integer +// Word 6: DsDe Change In S, DtDe Change In T, DwDe Change In W Along The Edge Fraction +// Word 7: DsDy Change In S, DtDy Change In T, DwDy Change In W Per Change In Y Coordinate Fraction + +// ZBuffer_Coefficients: z,zf,dzdx,dzdxf, dzde,dzdef,dzdy,dzdyf +// Word 0: Z Inverse Depth Integer, Fraction, DzDx Change In Z Per Change In X Coordinate Integer, Fraction (ZBuffer Coefficients) +// Word 1: DzDe Change In Z Along Major Edge Integer, Fraction, DzDy Change In Z Per Change In Y Coordinate Integer, Fraction + +// Texture_Rectangle: xl,yl, tile, xh,yh, s,t, dsdx,dtdy +// Word 0: Bottom Right X/Y, Tile ID, Top Left X/Y (Fixed Point 10.2) +// Word 1: S/T Texture Coordinate Top Left (Fixed Point S.10.5), DsDx Change In S Per Change In X, DtDy Change In T Per Change In Y (Fixed Point S.5.10) + +// Texture_Rectangle_Flip: xl,yl, tile, xh,yh, s,t, dsdx,dtdy ; Same As Texture Rectangle Except Hardware Swaps S/T & DsDx/DtDy +// Word 0: Bottom Right X/Y, Tile ID, Top Left X/Y (Fixed Point 10.2) +// Word 1: S/T Texture Coordinate Top Left (Fixed Point S.10.5), DsDx Change In S Per Change In X, DtDy Change In T Per Change In Y (Fixed Point S.5.10) + +// Sync_Load: Stall Execution Of Load Commands, Until Preceeding Primitives Completely Finish (Usually Preceed Load Commands) + +// Sync_Pipe: Stall Pipeline, Until Preceeding Primitives Completely Finish (Software Can Optimize Usage) + +// Sync_Tile: Allows Synchronization Between Commands That Write To The Same Tile Descriptor That An Immediately Previous Command Is Reading + +// Sync_Full: Stall RDP Until Last DRAM Buffer Is Read Or Written From Any Preceeding Primitive (Needed If Memory Is To Be Reused) + +// Set_Key_GB: wg,wb,cg,sg,cb,sb ; Set The Coefficients Used For Green/Blue Keying, KEY G/B = CLAMP(0.0, -ABS((G/B - CENTER)* SCALE) + WIDTH, 1.0) KEY ALPHA = MINIMUM OF KEY R/G/B +// Word: WIDTH G/B (Size Of Half Key Window Including Soft Edge)*SCALE, CENTER G/B Defines Color Or Intensity At Which Key Is Active (0..255), SCALE GB 1.0/(SIZE OF SOFT EDGE) (0..255) + +// Set_Key_R: wr,cr,sr ; Set The Coefficients Used For Red Keying, KEY R = CLAMP(0.0, -ABS((R - CENTER)* SCALE) + WIDTH, 1.0) KEY ALPHA = MINIMUM OF KEY R/G/B +// Word: WIDTH R (Size Of Half Key Window Including Soft Edge)*SCALE, CENTER R Defines Color Or Intensity At Which Key Is Active (0..255), SCALE R 1.0/(SIZE OF SOFT EDGE) (0..255) + +// Set_Convert: k0,k1,k2,k3,k4,k5 ; Updates The Coefficients For Converting YUV Pixels To RGB, R = C0*(Y-16)+C1*V, G = C0*(Y-16)+C2*U-C3*V, B = C0*(Y-16)+C4*U +// Word: K0, K1, K2, K3, K4, K5 Term Of YUV-RGB Conversion Matrix + +// Set_Scissor: xh,yh,xl,yl,lo ; Set The Scissoring Of Primitives +// Word: Top Left X/Y, Bottom Right X/Y (Fixed Point 10.2), Scissor Field Enable & Scissor Field Even/Odd +constant SCISSOR_EVEN(0) // Set_Scissor O: Field Even (Bit 24) +constant SCISSOR_ODD(1) // Set_Scissor O: Field Odd (Bit 24) +constant SCISSOR_FIELD(1) // Set_Scissor F: Scissor Field Enable (Bit 25) + +// Set_Prim_Depth: pz,pdz ; Set The Depth Of Primitives +// Word: Primitive Z Depth, Primitive Delta Z Depth + +// Set_Other_Modes: Settings ; Set The Other Modes +// Set_Other_Modes LO Word +constant ALPHA_COMPARE_EN($00000000000001) // Set_Other_Modes A: Conditional Color Write On Alpha Compare (Bit 0) +constant DITHER_ALPHA_EN($00000000000002) // Set_Other_Modes B: Use Random Noise In Alpha Compare, Otherwise Use Blend Alpha In Alpha Compare (Bit 1) +constant Z_SOURCE_SEL($00000000000004) // Set_Other_Modes C: Choose Between Primitive Z And Pixel Z (Bit 2) +constant ANTIALIAS_EN($00000000000008) // Set_Other_Modes D: If Not Force Blend, Allow Blend Enable - Use CVG Bits (Bit 3) +constant Z_COMPARE_EN($00000000000010) // Set_Other_Modes E: Conditional Color Write Enable On Depth Comparison (Bit 4) +constant Z_UPDATE_EN($00000000000020) // Set_Other_Modes F: Enable Writing Of Z If Color Write Enabled (Bit 5) +constant IMAGE_READ_EN($00000000000040) // Set_Other_Modes G: Enable Color/CVG Read/Modify/Write Memory Access (Bit 6) +constant COLOR_ON_CVG($00000000000080) // Set_Other_Modes H: Only Update Color On Coverage Overflow (Transparent Surfaces) (Bit 7) +constant CVG_DEST_CLAMP($00000000000000) // Set_Other_Modes I: CVG Destination Clamp (Normal) (Bit 8..9) +constant CVG_DEST_WRAP($00000000000100) // Set_Other_Modes I: CVG Destination Wrap (WAS Assume Full CVG) (Bit 8..9) +constant CVG_DEST_ZAP($00000000000200) // Set_Other_Modes I: CVG Destination Zap (Force To Full CVG) (Bit 8..9) +constant CVG_DEST_SAVE($00000000000300) // Set_Other_Modes I: CVG Destination Save (Don't Overwrite Memory CVG) (Bit 8..9) +constant Z_MODE_OPAQUE($00000000000000) // Set_Other_Modes J: Z Mode Opaque (Bit 10..11) +constant Z_MODE_INTERPENETRATING($00000000000400) // Set_Other_Modes J: Z Mode Interpenetrating (Bit 10..11) +constant Z_MODE_TRANSPARENT($00000000000800) // Set_Other_Modes J: Z Mode Transparent (Bit 10..11) +constant Z_MODE_DECAL($00000000000C00) // Set_Other_Modes J: Z Mode Decal (Bit 10..11) +constant CVG_TIMES_ALPHA($00000000001000) // Set_Other_Modes K: Use CVG Times Alpha For Pixel Alpha And Coverage (Bit 12) +constant ALPHA_CVG_SELECT($00000000002000) // Set_Other_Modes L: Use CVG (Or CVG*Alpha) For Pixel Alpha (Bit 13) +constant FORCE_BLEND($00000000004000) // Set_Other_Modes M: Force Blend Enable (Bit 14) +//*RESERVED*($00000000008000) // Set_Other_Modes N: This Mode Bit Is Not Currently Used, But May Be In The Future (Bit 15) +constant B_M2B_1_0($00000000000000) // Set_Other_Modes O: Blend Modeword, Multiply 2b Input Select 0, Cycle 1 (Bit 16..17) +constant B_M2B_1_1($00000000010000) // Set_Other_Modes O: Blend Modeword, Multiply 2b Input Select 1, Cycle 1 (Bit 16..17) +constant B_M2B_1_2($00000000020000) // Set_Other_Modes O: Blend Modeword, Multiply 2b Input Select 2, Cycle 1 (Bit 16..17) +constant B_M2B_1_3($00000000030000) // Set_Other_Modes O: Blend Modeword, Multiply 2b Input Select 3, Cycle 1 (Bit 16..17) +constant B_M2B_0_0($00000000000000) // Set_Other_Modes P: Blend Modeword, Multiply 2b Input Select 0, Cycle 0 (Bit 18..19) +constant B_M2B_0_1($00000000040000) // Set_Other_Modes P: Blend Modeword, Multiply 2b Input Select 1, Cycle 0 (Bit 18..19) +constant B_M2B_0_2($00000000080000) // Set_Other_Modes P: Blend Modeword, Multiply 2b Input Select 2, Cycle 0 (Bit 18..19) +constant B_M2B_0_3($000000000C0000) // Set_Other_Modes P: Blend Modeword, Multiply 2b Input Select 3, Cycle 0 (Bit 18..19) +constant B_M2A_1_0($00000000000000) // Set_Other_Modes Q: Blend Modeword, Multiply 2a Input Select 0, Cycle 1 (Bit 20..21) +constant B_M2A_1_1($00000000100000) // Set_Other_Modes Q: Blend Modeword, Multiply 2a Input Select 1, Cycle 1 (Bit 20..21) +constant B_M2A_1_2($00000000200000) // Set_Other_Modes Q: Blend Modeword, Multiply 2a Input Select 2, Cycle 1 (Bit 20..21) +constant B_M2A_1_3($00000000300000) // Set_Other_Modes Q: Blend Modeword, Multiply 2a Input Select 3, Cycle 1 (Bit 20..21) +constant B_M2A_0_0($00000000000000) // Set_Other_Modes R: Blend Modeword, Multiply 2a Input Select 0, Cycle 0 (Bit 22..23) +constant B_M2A_0_1($00000000400000) // Set_Other_Modes R: Blend Modeword, Multiply 2a Input Select 1, Cycle 0 (Bit 22..23) +constant B_M2A_0_2($00000000800000) // Set_Other_Modes R: Blend Modeword, Multiply 2a Input Select 2, Cycle 0 (Bit 22..23) +constant B_M2A_0_3($00000000C00000) // Set_Other_Modes R: Blend Modeword, Multiply 2a Input Select 3, Cycle 0 (Bit 22..23) +constant B_M1B_1_0($00000000000000) // Set_Other_Modes S: Blend Modeword, Multiply 1b Input Select 0, Cycle 1 (Bit 24..25) +constant B_M1B_1_1($00000001000000) // Set_Other_Modes S: Blend Modeword, Multiply 1b Input Select 1, Cycle 1 (Bit 24..25) +constant B_M1B_1_2($00000002000000) // Set_Other_Modes S: Blend Modeword, Multiply 1b Input Select 2, Cycle 1 (Bit 24..25) +constant B_M1B_1_3($00000003000000) // Set_Other_Modes S: Blend Modeword, Multiply 1b Input Select 3, Cycle 1 (Bit 24..25) +constant B_M1B_0_0($00000000000000) // Set_Other_Modes T: Blend Modeword, Multiply 1b Input Select 0, Cycle 0 (Bit 26..27) +constant B_M1B_0_1($00000004000000) // Set_Other_Modes T: Blend Modeword, Multiply 1b Input Select 1, Cycle 0 (Bit 26..27) +constant B_M1B_0_2($00000008000000) // Set_Other_Modes T: Blend Modeword, Multiply 1b Input Select 2, Cycle 0 (Bit 26..27) +constant B_M1B_0_3($0000000C000000) // Set_Other_Modes T: Blend Modeword, Multiply 1b Input Select 3, Cycle 0 (Bit 26..27) +constant B_M1A_1_0($00000000000000) // Set_Other_Modes U: Blend Modeword, Multiply 1a Input Select 0, Cycle 1 (Bit 28..29) +constant B_M1A_1_1($00000010000000) // Set_Other_Modes U: Blend Modeword, Multiply 1a Input Select 1, Cycle 1 (Bit 28..29) +constant B_M1A_1_2($00000020000000) // Set_Other_Modes U: Blend Modeword, Multiply 1a Input Select 2, Cycle 1 (Bit 28..29) +constant B_M1A_1_3($00000030000000) // Set_Other_Modes U: Blend Modeword, Multiply 1a Input Select 3, Cycle 1 (Bit 28..29) +constant B_M1A_0_0($00000000000000) // Set_Other_Modes V: Blend Modeword, Multiply 1a Input Select 0, Cycle 0 (Bit 30..31) +constant B_M1A_0_1($00000040000000) // Set_Other_Modes V: Blend Modeword, Multiply 1a Input Select 1, Cycle 0 (Bit 30..31) +constant B_M1A_0_2($00000080000000) // Set_Other_Modes V: Blend Modeword, Multiply 1a Input Select 2, Cycle 0 (Bit 30..31) +constant B_M1A_0_3($000000C0000000) // Set_Other_Modes V: Blend Modeword, Multiply 1a Input Select 3, Cycle 0 (Bit 30..31) +// Set_Other_Modes HI Word +//*RESERVED*($00000F00000000) // Set_Other_Modes: Reserved For Future Use, Default Value Is $F (Bit 32..35) +constant ALPHA_DITHER_SEL_PATTERN($00000000000000) // Set_Other_Modes V1: Alpha Dither Selection Pattern (Bit 36..37) +constant ALPHA_DITHER_SEL_PATTERNB($00001000000000) // Set_Other_Modes V1: Alpha Dither Selection ~Pattern (Bit 36..37) +constant ALPHA_DITHER_SEL_NOISE($00002000000000) // Set_Other_Modes V1: Alpha Dither Selection Noise (Bit 36..37) +constant ALPHA_DITHER_SEL_NO_DITHER($00003000000000) // Set_Other_Modes V1: Alpha Dither Selection No Dither (Bit 36..37) +constant RGB_DITHER_SEL_MAGIC_SQUARE_MATRIX($00000000000000) // Set_Other_Modes V2: RGB Dither Selection Magic Square Matrix (Preferred If Filtered) (Bit 38..39) +constant RGB_DITHER_SEL_STANDARD_BAYER_MATRIX($00004000000000) // Set_Other_Modes V2: RGB Dither Selection Standard Bayer Matrix (Preferred If Not Filtered) (Bit 38..39) +constant RGB_DITHER_SEL_NOISE($00008000000000) // Set_Other_Modes V2: RGB Dither Selection Noise (As Before) (Bit 38..39) +constant RGB_DITHER_SEL_NO_DITHER($0000C000000000) // Set_Other_Modes V2: RGB Dither Selection No Dither (Bit 38..39) +constant KEY_EN($00010000000000) // Set_Other_Modes W: Enables Chroma Keying (Bit 40) +constant CONVERT_ONE($00020000000000) // Set_Other_Modes X: Color Convert Texel That Was The Ouput Of The Texture Filter On Cycle0, Used To Qualify BI_LERP_1 (Bit 41) +constant BI_LERP_1($00040000000000) // Set_Other_Modes Y: 1=BI_LERP, 0=Color Convert Operation In Texture Filter. Used In Cycle 1 (Bit 42) +constant BI_LERP_0($00080000000000) // Set_Other_Modes Z: 1=BI_LERP, 0=Color Convert Operation In Texture Filter. Used In Cycle 0 (Bit 43) +constant MID_TEXEL($00100000000000) // Set_Other_Modes a: Indicates Texture Filter Should Do A 2x2 Half Texel Interpolation, Primarily Used For MPEG Motion Compensation Processing (Bit 44) +constant SAMPLE_TYPE($00200000000000) // Set_Other_Modes b: Determines How Textures Are Sampled: 0=1x1 (Point Sample), 1=2x2. Note That Copy (Point Sample 4 Horizontally Adjacent Texels) Mode Is Indicated By CYCLE_TYPE (Bit 45) +constant TLUT_TYPE($00400000000000) // Set_Other_Modes c: Type Of Texels In Table, 0=16b RGBA(5/5/5/1), 1=IA(8/8) (Bit 46) +constant EN_TLUT($00800000000000) // Set_Other_Modes d: Enable Lookup Of Texel Values From TLUT. Meaningful If Texture Type Is Index, Tile Is In Low TMEM, TLUT Is In High TMEM, And Color Image Is RGB (Bit 47) +constant TEX_LOD_EN($01000000000000) // Set_Other_Modes e: Enable Texture Level Of Detail (LOD) (Bit 48) +constant SHARPEN_TEX_EN($02000000000000) // Set_Other_Modes f: Enable Sharpened Texture (Bit 49) +constant DETAIL_TEX_EN($04000000000000) // Set_Other_Modes g: Enable Detail Texture (Bit 50) +constant PERSP_TEX_EN($08000000000000) // Set_Other_Modes h: Enable Perspective Correction On Texture (Bit 51) +constant CYCLE_TYPE_1_CYCLE($00000000000000) // Set_Other_Modes i: Display Pipeline Cycle Control Mode 1 Cycle (Bit 52..53) +constant CYCLE_TYPE_2_CYCLE($10000000000000) // Set_Other_Modes i: Display Pipeline Cycle Control Mode 2 Cycle (Bit 52..53) +constant CYCLE_TYPE_COPY($20000000000000) // Set_Other_Modes i: Display Pipeline Cycle Control Mode Copy (Bit 52..53) +constant CYCLE_TYPE_FILL($30000000000000) // Set_Other_Modes i: Display Pipeline Cycle Control Mode Fill (Bit 52..53) +//*RESERVED*($40000000000000) // Set_Other_Modes j: This Mode Bit Is Not Currently Used, But May Be In The Future (Bit 54) +constant ATOMIC_PRIM($80000000000000) // Set_Other_Modes k: Force Primitive To Be Written To Frame Buffer Before Read Of Following Primitive + +// Load_Tlut: sl,tl,tile,sh,th ; Used To Initiate A Load From DRAM Of An Indexed Texture Lookup Table (TLUT) (This Table Dereferences Color Indexed Texels Before Texture Filtering) +// Word: Low S Index Into Table (0..255), Low T Normally Zero, Tile ID, High S Index Into Table, High T Normally Zero (Fixed Point 10.2, Fractional Bits Should Be Zero) + +// Set_Tile_Size: sl,tl,tile,sh,th ; Set The Tile Size +// Word: Low S/T Coordinate Of Tile In Image, Tile ID, High S/T Coordinate Of Tile In Image (Fixed Point 10.2) + +// Load_Block: sl,tl,tile,sh,dxt ; Loads A TMEM Tile With A Single Memory "Span" From SL,TL To SH,TL (During Tile Load, T Coordinate Is Incremented By DxT Every 8 TMEM Bytes) +// Word: Low S/T Coordinate Of Tile In Image, Tile ID, High S Coordinate Of Tile In Image (Fixed Point 10.2), Unsigned Increment Value + +// Load_Tile: sl,tl,tile,sh,th ; Loads A TMEM Tile +// Word: Low S/T Coordinate Of Tile In Image, Tile ID, High S/T Coordinate Of Tile In Image (Fixed Point 10.2) + +// Set_Tile: hi,lo ; Set The Tile +// Word: Set Tile Settings +// Set_Tile LO Word +constant SHIFT_S_0($0) // Set_Tile: Shift 0 Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_1($1) // Set_Tile: Shift 1 Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_2($2) // Set_Tile: Shift 2 Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_3($3) // Set_Tile: Shift 3 Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_4($4) // Set_Tile: Shift 4 Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_5($5) // Set_Tile: Shift 5 Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_6($6) // Set_Tile: Shift 6 Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_7($7) // Set_Tile: Shift 7 Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_8($8) // Set_Tile: Shift 8 Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_9($9) // Set_Tile: Shift 9 Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_A($A) // Set_Tile: Shift A Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_B($B) // Set_Tile: Shift B Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_C($C) // Set_Tile: Shift C Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_D($D) // Set_Tile: Shift D Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_E($E) // Set_Tile: Shift E Level Of Detail Shift For S Addresses (Bit 0..3) +constant SHIFT_S_F($F) // Set_Tile: Shift F Level Of Detail Shift For S Addresses (Bit 0..3) +constant MASK_S_0($0) // Set_Tile: Mask 0 For Wrapping/Mirroring In S Direction, Zero = Clamp (Bit 14..17) +constant MASK_S_1($1) // Set_Tile: Mask 1 For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MASK_S_2($2) // Set_Tile: Mask 2 For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MASK_S_3($3) // Set_Tile: Mask 3 For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MASK_S_4($4) // Set_Tile: Mask 4 For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MASK_S_5($5) // Set_Tile: Mask 5 For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MASK_S_6($6) // Set_Tile: Mask 6 For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MASK_S_7($7) // Set_Tile: Mask 7 For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MASK_S_8($8) // Set_Tile: Mask 8 For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MASK_S_9($9) // Set_Tile: Mask 9 For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MASK_S_A($A) // Set_Tile: Mask A For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MASK_S_B($B) // Set_Tile: Mask B For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MASK_S_C($C) // Set_Tile: Mask C For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MASK_S_D($D) // Set_Tile: Mask D For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MASK_S_E($E) // Set_Tile: Mask E For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MASK_S_F($F) // Set_Tile: Mask F For Wrapping/Mirroring In S Direction, Pass (Mask) LSBs Of S Address (Bit 4..7) +constant MIRROR_S(1) // Set_Tile: Mirror Enable For S Direction (Bit 8) +constant CLAMP_S(1) // Set_Tile: Clamp Enable For S Direction (Bit 9) +constant SHIFT_T_0($0) // Set_Tile: Shift 0 Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_1($1) // Set_Tile: Shift 1 Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_2($2) // Set_Tile: Shift 2 Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_3($3) // Set_Tile: Shift 3 Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_4($4) // Set_Tile: Shift 4 Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_5($5) // Set_Tile: Shift 5 Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_6($6) // Set_Tile: Shift 6 Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_7($7) // Set_Tile: Shift 7 Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_8($8) // Set_Tile: Shift 8 Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_9($9) // Set_Tile: Shift 9 Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_A($A) // Set_Tile: Shift A Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_B($B) // Set_Tile: Shift B Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_C($C) // Set_Tile: Shift C Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_D($D) // Set_Tile: Shift D Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_E($E) // Set_Tile: Shift E Level Of Detail Shift For T Addresses (Bit 10..13) +constant SHIFT_T_F($F) // Set_Tile: Shift F Level Of Detail Shift For T Addresses (Bit 10..13) +constant MASK_T_0($0) // Set_Tile: Mask 0 For Wrapping/Mirroring In T Direction, Zero = Clamp (Bit 14..17) +constant MASK_T_1($1) // Set_Tile: Mask 1 For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MASK_T_2($2) // Set_Tile: Mask 2 For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MASK_T_3($3) // Set_Tile: Mask 3 For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MASK_T_4($4) // Set_Tile: Mask 4 For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MASK_T_5($5) // Set_Tile: Mask 5 For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MASK_T_6($6) // Set_Tile: Mask 6 For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MASK_T_7($7) // Set_Tile: Mask 7 For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MASK_T_8($8) // Set_Tile: Mask 8 For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MASK_T_9($9) // Set_Tile: Mask 9 For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MASK_T_A($A) // Set_Tile: Mask A For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MASK_T_B($B) // Set_Tile: Mask B For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MASK_T_C($C) // Set_Tile: Mask C For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MASK_T_D($D) // Set_Tile: Mask D For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MASK_T_E($E) // Set_Tile: Mask E For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MASK_T_F($F) // Set_Tile: Mask F For Wrapping/Mirroring In T Direction, Pass (Mask) LSBs Of T Address (Bit 14..17) +constant MIRROR_T(1) // Set_Tile: Mirror Enable For T Direction (Bit 18) +constant CLAMP_T(1) // Set_Tile: Clamp Enable For T Direction (Bit 19) +constant PALETTE_0($0) // Set_Tile: Palette Number 0 For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_1($1) // Set_Tile: Palette Number 1 For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_2($2) // Set_Tile: Palette Number 2 For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_3($3) // Set_Tile: Palette Number 3 For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_4($4) // Set_Tile: Palette Number 4 For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_5($5) // Set_Tile: Palette Number 5 For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_6($6) // Set_Tile: Palette Number 6 For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_7($7) // Set_Tile: Palette Number 7 For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_8($8) // Set_Tile: Palette Number 8 For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_9($9) // Set_Tile: Palette Number 9 For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_A($A) // Set_Tile: Palette Number A For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_B($B) // Set_Tile: Palette Number B For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_C($C) // Set_Tile: Palette Number C For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_D($D) // Set_Tile: Palette Number D For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_E($E) // Set_Tile: Palette Number E For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +constant PALETTE_F($F) // Set_Tile: Palette Number F For 4Bit Color Indexed Texels, This Number Is The MS 4Bits Of An 8Bit Index (Bit 20..23) +// Set_Tile/Set_Texture_Image/Set_Color_Image HI Word +constant SIZE_OF_PIXEL_4B(0) // Set_Tile/Set_Texture_Image/Set_Color_Image: Size Of Pixel/Texel Color Element 4B (Bit 51..52) +constant SIZE_OF_PIXEL_8B(1) // Set_Tile/Set_Texture_Image/Set_Color_Image: Size Of Pixel/Texel Color Element 8B (Bit 51..52) +constant SIZE_OF_PIXEL_16B(2) // Set_Tile/Set_Texture_Image/Set_Color_Image: Size Of Pixel/Texel Color Element 16B (Bit 51..52) +constant SIZE_OF_PIXEL_32B(3) // Set_Tile/Set_Texture_Image/Set_Color_Image: Size Of Pixel/Texel Color Element 32B (Bit 51..52) +constant IMAGE_DATA_FORMAT_RGBA(0) // Set_Tile/Set_Texture_Image/Set_Color_Image: Image Data Format RGBA (Bit 53..55) +constant IMAGE_DATA_FORMAT_YUV(1) // Set_Tile/Set_Texture_Image/Set_Color_Image: Image Data Format YUV (Bit 53..55) +constant IMAGE_DATA_FORMAT_COLOR_INDX(2) // Set_Tile/Set_Texture_Image/Set_Color_Image: Image Data Format COLOR_INDX (Bit 53..55) +constant IMAGE_DATA_FORMAT_IA(3) // Set_Tile/Set_Texture_Image/Set_Color_Image: Image Data Format IA (Bit 53..55) +constant IMAGE_DATA_FORMAT_I(4) // Set_Tile/Set_Texture_Image/Set_Color_Image: Image Data Format I (Bit 53..55) + +// Fill_Rectangle: xl,yl,xh,yh +// Word: Bottom Right X/Y, Top Left X/Y (Fixed Point 10.2) + +// Set_Fill_Color: Set The Filling Color +// Word: Packed Color: If The Color Image Was Set BE 16B RGBA, Then The Fill Color Would Be Two Horizontally Adjacent 16B RGBA Pixels + +// Set_Fog_Color: Set The Fog Color +// Word: RGBA Color Components + +// Set_Blend_Color: Set The Blending Color +// Word: RGBA Color Components + +// Set_Prim_Color: minlev,levfrac,lo ; Set The Primitive Color +// Word: Prim Min Level: Minimum Clamp For LOD Fraction When In Detail Or Sharpen Texture Modes (Fixed Point 0.5), Prim Level Frac: Level Of Detail Fraction For Primitive, Used Primarily In Multi-Tile Operations For Rectangle Primitives (Fixed Point 0.8), RGBA Color Components + +// Set_Env_Color: Set The Environment Color +// Word: RGBA Color Components + +// Set_Combine_Mode: sub_aR0, mulR0, sub_aA0, mulA0, sub_aR1, mulR1, sub_bR0, sub_bR1, sub_aA1, mulA1, addR0, sub_bA0, addA0, addR1, sub_bA1, addA1 ; Set The Combine Mode +// Word: SUB_A, Multiply Input RGB Components CYCLE 0, SUB_A, Multiply Input ALPHA Components CYCLE 0, SUB_A, Multiply Input RGB Components CYCLE 1, SUB_B, Multiply Input RGB Components CYCLE 0, SUB_B, Multiply Input RGB Components CYCLE 1, SUB_A, Multiply Input ALPHA Components CYCLE 1, Adder Input RGB Components CYCLE 0, SUB_B Input ALPHA Components CYCLE 0, Adder Input ALPHA Components CYCLE 0, Adder Input RGB Components CYCLE 1, SUB_B Input ALPHA Components CYCLE 1, Adder Input ALPHA Components CYCLE 1 + +// Set_Texture_Image: Set The Texture Image +// Word: Image Data Format, Size Of Pixel/Texel Color Element, Width Of Image In Pixels - 1, Base Address (Top Left Corner) Of Image In DRAM + +// Set_Z_Image: Set The Z Buffer Image +// Word: Base Address (Top Left Corner) Of Image In DRAM, In Bytes + +// Set_Color_Image: Set The Color Image +// Word: Image Data Format, Size Of Pixel/Texel Color Element, Width Of Image In Pixels: Image Width=Width+1, Base Address (Top Left Corner) Of Image In DRAM diff --git a/xxd.asm b/xxd.asm new file mode 100644 index 0000000..078de15 --- /dev/null +++ b/xxd.asm @@ -0,0 +1,77 @@ +xxd: + // a0: source address + // a1: source length + // a2: destination (string) address + // a3: destination (string) maximum length + // v0: error code (0 is OK) + beqz a1, xxdExit + lli v0, 0 // delay slot + lli v1, 0x20 // ascii space + +xxdLoop: + lbu t0, 0(a0) + subiu a1, a1, 1 + addiu a0, a0, 1 + + // split byte into nybbles + srl t1, t0, 4 + andi t0, t0, 0xF + // convert nybbles to ascii bytes + sltiu at, t0, 0xA + bnez at,+ + addiu t2, t0, 0x30 // (delay slot) + addiu t2, t0, 0x41 - 0xA ++ + sltiu at, t1, 0xA + bnez at,+ + addiu t3, t1, 0x30 // (delay slot) + addiu t3, t1, 0x41 - 0xA ++ + + subiu a3, a3, 3 + blezl a3, xxdExit + lli v0, 1 + + sb v1, 0(a2) // write space + sb t3, 1(a2) // write high nybble + sb t2, 2(a2) // write low nybble + addiu a2, a2, 3 + + // pretty-printing: + andi at, a0, 0xF + bnez at,+ + lli t9, 0x0A // (delay slot) ascii newline + subiu a3, a3, 1 + blezl a3, xxdExit + lli v0, 1 + sb t9, 0(a2) // write newline + b ++ + addiu a2, a2, 1 // delay slot ++ + andi at, a0, 0x3 + bnez at,+ + nop // delay slot + subiu a3, a3, 1 + blezl a3, xxdExit + lli v0, 1 + sb v1, 0(a2) // write extra space + addiu a2, a2, 1 ++ + + bnez a1, xxdLoop + nop // delay slot + + beqz a3, xxdExit + nop // delay slot + +xxdZero: + // fill the remaining bytes with nulls + sb r0, 0(a2) + subiu a3, a3, 1 + bnez a3, xxdZero + addiu a2, a2, 1 // delay slot + +xxdExit: + jr ra + nop // delay slot +