homebrew/inc/n64.inc

426 lines
18 KiB
PHP

// by krom, edited by notwa
//=============
// 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 fp(30)
constant ra(31)
constant s8(30) // alias of fp
// 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)
// Coprocessor 0 registers
constant CP0_Index(0)
constant CP0_Random(1)
constant CP0_EntryLo0(2)
constant CP0_EntryLo1(3)
constant CP0_Context(4)
constant CP0_PageMask(5)
constant CP0_Wired(6)
constant CP0_Reserved_1(7)
constant CP0_BadVAddr(8)
constant CP0_Count(9)
constant CP0_EntryHi(10)
constant CP0_Compare(11)
constant CP0_Status(12)
constant CP0_Cause(13)
constant CP0_EPC(14)
constant CP0_PRid(15)
constant CP0_Config(16)
constant CP0_LLAddr(17)
constant CP0_WatchLo(18)
constant CP0_WatchHi(19)
constant CP0_XContext(20)
constant CP0_Reserved_2(21)
constant CP0_Reserved_3(22)
constant CP0_Reserved_4(23)
constant CP0_Reserved_5(24)
constant CP0_Reserved_6(25)
constant CP0_PErr(26) // unused
constant CP0_CacheErr(27) // unused
constant CP0_TagLo(28)
constant CP0_TagHi(29) // reserved
constant CP0_ErrorPC(30)
constant CP0_Reserved_7(31)
constant CP0_STATUS_IE($0001) // Interrupt Enable
constant CP0_STATUS_EXL($0002) // Exception Level
constant CP0_STATUS_ERL($0004) // Error Level
constant CP0_STATUS_IM0($0100) // Interrupt Mask 0 (Software)
constant CP0_STATUS_IM1($0200) // Interrupt Mask 1 (Software)
constant CP0_STATUS_IM2($0400) // Interrupt Mask 2 (External)
constant CP0_STATUS_IM3($0800) // Interrupt Mask 3 (External)
constant CP0_STATUS_IM4($1000) // Interrupt Mask 4 (External)
constant CP0_STATUS_IM5($2000) // Interrupt Mask 5 (External)
constant CP0_STATUS_IM6($4000) // Interrupt Mask 6 (External)
constant CP0_STATUS_IM7($8000) // Interrupt Mask 7 (External)
constant CP0_STATUS_IM_ALL($FF01) // enable all interrupts
// note that these are all masks.
constant CP0_CAUSE_CODE($007C) // actually supposed to be called ExcCode
constant CP0_CAUSE_IP0($0100) // Interrupt Pending 0 (Software)
constant CP0_CAUSE_IP1($0200) // Interrupt Pending 1 (Software)
constant CP0_CAUSE_IP2($0400) // Interrupt Pending 2 (External)
constant CP0_CAUSE_IP3($0800) // Interrupt Pending 3 (External)
constant CP0_CAUSE_IP4($1000) // Interrupt Pending 4 (External)
constant CP0_CAUSE_IP5($2000) // Interrupt Pending 5 (External)
constant CP0_CAUSE_IP6($4000) // Interrupt Pending 6 (External)
constant CP0_CAUSE_IP7($8000) // Interrupt Pending 7 (External)
// upper halfword:
constant CP0_CAUSE_CE($30000000) // Coprocessor Error
constant CP0_CAUSE_BD($80000000) // Branch Delay (not an exception, just info)
// note that these constants are shifted left 2 into the Cause register,
// so you must unshift the value from the register before comparing them.
constant CP0_CODE_INT(0) // Interrupt
constant CP0_CODE_MOD(1) // TLB modification exception
constant CP0_CODE_TLBL(2) // TLB Exception (Load or instruction fetch)
constant CP0_CODE_TLBS(3) // TLB Exception (Store)
constant CP0_CODE_ADEL(4) // Address Error Exception (Load or instruction fetch)
constant CP0_CODE_ADES(5) // Address Error Exception (Store)
constant CP0_CODE_IBE(6) // Bus Error Exception (instruction fetch)
constant CP0_CODE_DBE(7) // Bus Error Exception (data reference: load or store)
constant CP0_CODE_SYS(8) // SysCall Exception
constant CP0_CODE_BP(9) // Breakpoint Exception
constant CP0_CODE_RI(10) // Reserved instruction Exception
constant CP0_CODE_CPU(11) // Coprocessor Unusable Exception
constant CP0_CODE_OV(12) // Arithmetic Overflow Exception
constant CP0_CODE_TR(13) // Trap Exception
constant CP0_CODE_RESERVED_14(14)
constant CP0_CODE_FPE(15) // Floating Point Exception
constant CP0_CODE_RESERVED_16(16)
constant CP0_CODE_RESERVED_17(17)
constant CP0_CODE_RESERVED_18(18)
constant CP0_CODE_RESERVED_19(19)
constant CP0_CODE_RESERVED_20(20)
constant CP0_CODE_RESERVED_21(21)
constant CP0_CODE_RESERVED_22(22)
constant CP0_CODE_WATCH(23) // Reference to WatchHi/WatchLo address
constant CP0_CODE_RESERVED_24(24)
constant CP0_CODE_RESERVED_25(25)
constant CP0_CODE_RESERVED_26(26)
constant CP0_CODE_RESERVED_27(27)
constant CP0_CODE_RESERVED_28(28)
constant CP0_CODE_RESERVED_29(29)
constant CP0_CODE_RESERVED_30(30)
constant CP0_CODE_RESERVED_31(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
// SP_STATUS Read Flags:
constant RSP_HLT($0001) // Halt
constant RSP_BRK($0002) // Break
constant RSP_BSY($0004) // DMA Busy
constant RSP_FUL($0008) // DMA Full
constant RSP_IOF($0010) // IO Full
constant RSP_STP($0020) // Single Step
constant RSP_IOB($0040) // Interrupt On Break
constant RSP_SG0($0080) // Signal 0 Set
constant RSP_SG1($0100) // Signal 1 Set
constant RSP_SG2($0200) // Signal 2 Set
constant RSP_SG3($0400) // Signal 3 Set
constant RSP_SG4($0800) // Signal 4 Set
constant RSP_SG5($1000) // Signal 5 Set
constant RSP_SG6($2000) // Signal 6 Set
constant RSP_SG7($4000) // Signal 7 Set
// SP_STATUS Write Flags:
constant CLR_HLT($00000001) // Clear Halt
constant SET_HLT($00000002) // Set Halt
constant CLR_BRK($00000004) // Clear Broke
constant CLR_INT($00000008) // Clear Interrupt
constant SET_INT($00000010) // Set Interrupt
constant CLR_STP($00000020) // Clear Single Step
constant SET_STP($00000040) // Set Single Step
constant CLR_IOB($00000080) // Clear Interrupt On Break
constant SET_IOB($00000100) // Set Interrupt On Break
constant CLR_SG0($00000200) // Clear Signal 0
constant SET_SG0($00000400) // Set Signal 0
constant CLR_SG1($00000800) // Clear Signal 1
constant SET_SG1($00001000) // Set Signal 1
constant CLR_SG2($00002000) // Clear Signal 2
constant SET_SG2($00004000) // Set Signal 2
constant CLR_SG3($00008000) // Clear Signal 3
constant SET_SG3($00010000) // Set Signal 3
constant CLR_SG4($00020000) // Clear Signal 4
constant SET_SG4($00040000) // Set Signal 4
constant CLR_SG5($00080000) // Clear Signal 5
constant SET_SG5($00100000) // Set Signal 5
constant CLR_SG6($00200000) // Clear Signal 6
constant SET_SG6($00400000) // Set Signal 6
constant CLR_SG7($00800000) // Clear Signal 7
constant SET_SG7($01000000) // Set Signal 7
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 MI_INTR_SP($01)
constant MI_INTR_SI($02)
constant MI_INTR_AI($04)
constant MI_INTR_VI($08)
constant MI_INTR_PI($10)
constant MI_INTR_DP($20)
constant MI_INTR_ALL($3F)
// TODO: SET and CLR rather than just MASK
constant MI_INTR_MASK_SP($002)
constant MI_INTR_MASK_SI($008)
constant MI_INTR_MASK_AI($020)
constant MI_INTR_MASK_VI($080)
constant MI_INTR_MASK_PI($200)
constant MI_INTR_MASK_DP($800)
constant MI_INTR_MASK_ALL($AAA)
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)
}