start work on interrupt handler; refactor
This commit is contained in:
parent
d05169fcbc
commit
ab2896cec6
4 changed files with 339 additions and 58 deletions
260
kernel.asm
Normal file
260
kernel.asm
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
// not really a kernel,
|
||||||
|
// just handling some low-level stuff like interrupts.
|
||||||
|
|
||||||
|
Start:
|
||||||
|
lui k0, K_BASE
|
||||||
|
|
||||||
|
// copy our interrupt handlers into place.
|
||||||
|
lui t0, 0x8000
|
||||||
|
la t1, _InterruptStart
|
||||||
|
la t2, _InterruptEnd
|
||||||
|
-
|
||||||
|
ld t3, 0(t1)
|
||||||
|
ld t4, 8(t1)
|
||||||
|
addiu t1, t1, 0x10
|
||||||
|
ld t3, 0(t0)
|
||||||
|
sd t4, 8(t0)
|
||||||
|
addiu t0, t0, 0x10
|
||||||
|
bne t1, t2,-
|
||||||
|
cache 1, 0(t0) // not sure if this is necessary, but it doesn't hurt.
|
||||||
|
|
||||||
|
// enable SI and PI interrupts.
|
||||||
|
lui a0, PIF_BASE
|
||||||
|
lli t0, 8
|
||||||
|
sw t0, PIF_RAM+0x3C(a0)
|
||||||
|
|
||||||
|
// SP defaults to RSP instruction memory: 0xA4001FF0
|
||||||
|
// we can do better than that.
|
||||||
|
lui sp, K_STACK_INIT_BASE
|
||||||
|
// SP should always be 8-byte aligned
|
||||||
|
// so that SD and LD instructions don't fail on it.
|
||||||
|
subiu sp, sp, 8
|
||||||
|
|
||||||
|
// TODO: just wipe a portion of RAM?
|
||||||
|
sw r0, K_64DRIVE_MAGIC(k0)
|
||||||
|
sw r0, K_REASON(k0)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
Drive64TryExtended:
|
||||||
|
lui gp, CI_BASE_EXTENDED
|
||||||
|
lw t1, CI_HW_MAGIC(gp)
|
||||||
|
bne t1, t2, Drive64Done
|
||||||
|
nop
|
||||||
|
|
||||||
|
Drive64Confirmed:
|
||||||
|
sw t2, K_64DRIVE_MAGIC(k0)
|
||||||
|
sw gp, K_CI_BASE(k0)
|
||||||
|
|
||||||
|
// enable writing to cartROM (SDRAM) for USB writing later
|
||||||
|
lli t1, 0xF0
|
||||||
|
|
||||||
|
CI_WAIT()
|
||||||
|
sw t1, CI_COMMAND(gp) // send our command
|
||||||
|
CI_WAIT()
|
||||||
|
|
||||||
|
Drive64Done:
|
||||||
|
|
||||||
|
// clear internal exception/interrupt value
|
||||||
|
ori k1, r0, r0
|
||||||
|
|
||||||
|
// load up most registers with a dummy value for debugging
|
||||||
|
lui at, 0xCAFE
|
||||||
|
ori at, r0, 0xBABE
|
||||||
|
dsllv at, 32
|
||||||
|
// attempting to use this as an address should trigger an interrupt
|
||||||
|
ori at, r0, 0xDEAD
|
||||||
|
dsllv at, 16
|
||||||
|
ori at, r0, 0xBEEF
|
||||||
|
|
||||||
|
// k0, k1, sp intentionally absent
|
||||||
|
daddu v0, at, r0
|
||||||
|
daddu v1, at, r0
|
||||||
|
daddu a0, at, r0
|
||||||
|
daddu a1, at, r0
|
||||||
|
daddu a2, at, r0
|
||||||
|
daddu a3, at, r0
|
||||||
|
daddu t0, at, r0
|
||||||
|
daddu t1, at, r0
|
||||||
|
daddu t2, at, r0
|
||||||
|
daddu t3, at, r0
|
||||||
|
daddu t4, at, r0
|
||||||
|
daddu t5, at, r0
|
||||||
|
daddu t6, at, r0
|
||||||
|
daddu t7, at, r0
|
||||||
|
daddu s0, at, r0
|
||||||
|
daddu s1, at, r0
|
||||||
|
daddu s2, at, r0
|
||||||
|
daddu s3, at, r0
|
||||||
|
daddu s4, at, r0
|
||||||
|
daddu s5, at, r0
|
||||||
|
daddu s6, at, r0
|
||||||
|
daddu s7, at, r0
|
||||||
|
daddu t8, at, r0
|
||||||
|
daddu t9, at, r0
|
||||||
|
daddu gp, at, r0
|
||||||
|
daddu fp, at, r0
|
||||||
|
daddu ra, at, r0
|
||||||
|
|
||||||
|
j Main
|
||||||
|
nop
|
||||||
|
|
||||||
|
align(0x10)
|
||||||
|
_InterruptStart: // for copying purposes
|
||||||
|
pushvar base
|
||||||
|
|
||||||
|
// note that we jump to the handler by jr instead of j
|
||||||
|
// because we want to change the PC to cached memory,
|
||||||
|
// which depends on the higher bits that j cannot change.
|
||||||
|
|
||||||
|
base 0x80000000
|
||||||
|
InterruptTBLRefill:
|
||||||
|
la k0, InterruptHandler
|
||||||
|
jr k0
|
||||||
|
lli k1, K_INT_TLB_REFILL
|
||||||
|
|
||||||
|
nops(0x80000080)
|
||||||
|
InterruptXTLBRefill:
|
||||||
|
la k0, InterruptHandler
|
||||||
|
jr k0
|
||||||
|
lli k1, K_INT_XTLB_REFILL
|
||||||
|
|
||||||
|
nops(0x80000100)
|
||||||
|
InterruptCacheError: // A0000100?
|
||||||
|
la k0, InterruptHandler
|
||||||
|
jr k0
|
||||||
|
lli k1, K_INT_CACHE_ERROR
|
||||||
|
|
||||||
|
nops(0x80000180)
|
||||||
|
InterruptOther:
|
||||||
|
la k0, InterruptHandler
|
||||||
|
jr k0
|
||||||
|
lli k1, K_INT_OTHER
|
||||||
|
|
||||||
|
nops(0x80000200)
|
||||||
|
pullvar base
|
||||||
|
_InterruptEnd: // for copying purposes
|
||||||
|
|
||||||
|
InterruptHandler:
|
||||||
|
lui k0, K_BASE
|
||||||
|
sw k1, K_REASON(k0)
|
||||||
|
|
||||||
|
sd at, K_DUMP+0x08(k0)
|
||||||
|
|
||||||
|
// disable interrupts, clear exception and error level bits:
|
||||||
|
mfc0 at, CP0_Status
|
||||||
|
sw at, K_STATUS(k0) // TODO: restored later
|
||||||
|
addiu at, r0, 0xFFFC
|
||||||
|
and k1, k1, at
|
||||||
|
mtc0 k1, CP0_Status
|
||||||
|
|
||||||
|
mfc0 k1, CP0_Cause
|
||||||
|
sw k1, K_CAUSE(k0)
|
||||||
|
|
||||||
|
// TODO: option to only store clobbered registers
|
||||||
|
// TODO: option to dump COP1 registers too
|
||||||
|
|
||||||
|
sd r0, K_DUMP+0x00(k0) // intentional (it'd be weird if
|
||||||
|
// r0 showed as nonzero in memory dumps)
|
||||||
|
sd v0, K_DUMP+0x10(k0)
|
||||||
|
sd v1, K_DUMP+0x18(k0)
|
||||||
|
sd a0, K_DUMP+0x20(k0)
|
||||||
|
sd a1, K_DUMP+0x28(k0)
|
||||||
|
sd a2, K_DUMP+0x30(k0)
|
||||||
|
sd a3, K_DUMP+0x38(k0)
|
||||||
|
sd t0, K_DUMP+0x40(k0)
|
||||||
|
sd t1, K_DUMP+0x48(k0)
|
||||||
|
sd t2, K_DUMP+0x50(k0)
|
||||||
|
sd t3, K_DUMP+0x58(k0)
|
||||||
|
sd t4, K_DUMP+0x60(k0)
|
||||||
|
sd t5, K_DUMP+0x68(k0)
|
||||||
|
sd t6, K_DUMP+0x70(k0)
|
||||||
|
sd t7, K_DUMP+0x78(k0)
|
||||||
|
sd s0, K_DUMP+0x80(k0)
|
||||||
|
sd s1, K_DUMP+0x88(k0)
|
||||||
|
sd s2, K_DUMP+0x90(k0)
|
||||||
|
sd s3, K_DUMP+0x98(k0)
|
||||||
|
sd s4, K_DUMP+0xA0(k0)
|
||||||
|
sd s5, K_DUMP+0xA8(k0)
|
||||||
|
sd s6, K_DUMP+0xB0(k0)
|
||||||
|
sd s7, K_DUMP+0xB8(k0)
|
||||||
|
sd t8, K_DUMP+0xC0(k0)
|
||||||
|
sd t9, K_DUMP+0xC8(k0)
|
||||||
|
sd k0, K_DUMP+0xD0(k0)
|
||||||
|
sd k1, K_DUMP+0xD8(k0)
|
||||||
|
sd gp, K_DUMP+0xE0(k0)
|
||||||
|
sd sp, K_DUMP+0xE8(k0)
|
||||||
|
sd fp, K_DUMP+0xF0(k0)
|
||||||
|
sd ra, K_DUMP+0xF8(k0)
|
||||||
|
|
||||||
|
mfhi t0
|
||||||
|
mflo t1
|
||||||
|
sd t0, K_DUMP+0x100(k0)
|
||||||
|
sd t1, K_DUMP+0x108(k0)
|
||||||
|
|
||||||
|
// free to modify any GPR here
|
||||||
|
|
||||||
|
lui k0, K_BASE
|
||||||
|
ld t0, K_DUMP+0x100(k0)
|
||||||
|
ld t1, K_DUMP+0x108(k0)
|
||||||
|
mthi t0
|
||||||
|
mtlo t1
|
||||||
|
|
||||||
|
ld at, K_DUMP+0x08(k0)
|
||||||
|
ld v0, K_DUMP+0x10(k0)
|
||||||
|
ld v1, K_DUMP+0x18(k0)
|
||||||
|
ld a0, K_DUMP+0x20(k0)
|
||||||
|
ld a1, K_DUMP+0x28(k0)
|
||||||
|
ld a2, K_DUMP+0x30(k0)
|
||||||
|
ld a3, K_DUMP+0x38(k0)
|
||||||
|
ld t0, K_DUMP+0x40(k0)
|
||||||
|
ld t1, K_DUMP+0x48(k0)
|
||||||
|
ld t2, K_DUMP+0x50(k0)
|
||||||
|
ld t3, K_DUMP+0x58(k0)
|
||||||
|
ld t4, K_DUMP+0x60(k0)
|
||||||
|
ld t5, K_DUMP+0x68(k0)
|
||||||
|
ld t6, K_DUMP+0x70(k0)
|
||||||
|
ld t7, K_DUMP+0x78(k0)
|
||||||
|
ld s0, K_DUMP+0x80(k0)
|
||||||
|
ld s1, K_DUMP+0x88(k0)
|
||||||
|
ld s2, K_DUMP+0x90(k0)
|
||||||
|
ld s3, K_DUMP+0x98(k0)
|
||||||
|
ld s4, K_DUMP+0xA0(k0)
|
||||||
|
ld s5, K_DUMP+0xA8(k0)
|
||||||
|
ld s6, K_DUMP+0xB0(k0)
|
||||||
|
ld s7, K_DUMP+0xB8(k0)
|
||||||
|
ld t8, K_DUMP+0xC0(k0)
|
||||||
|
ld t9, K_DUMP+0xC8(k0)
|
||||||
|
ld gp, K_DUMP+0xE0(k0)
|
||||||
|
ld sp, K_DUMP+0xE8(k0)
|
||||||
|
ld fp, K_DUMP+0xF0(k0)
|
||||||
|
ld ra, K_DUMP+0xF8(k0)
|
||||||
|
|
||||||
|
lw k1, K_CAUSE(k0)
|
||||||
|
andi k1, k1, 0x2000 // check if this was a trap exception
|
||||||
|
mfc0 k0, CP0_EPC
|
||||||
|
beqz k1, ReturnFromInterrupt
|
||||||
|
sw k0, K_EPC(k0)
|
||||||
|
|
||||||
|
ReturnFromTrap:
|
||||||
|
addiu k0, k0, 4
|
||||||
|
|
||||||
|
ReturnFromInterrupt:
|
||||||
|
// restore interrupts
|
||||||
|
mfc0 k1, CP0_Status
|
||||||
|
ori k1, k1, 1
|
||||||
|
mtc0 k1, CP0_Status
|
||||||
|
|
||||||
|
// wait, shouldn't this be ERET?
|
||||||
|
rfe
|
||||||
|
jr k0
|
||||||
|
or k1, r0, r0
|
||||||
|
|
||||||
|
nops((K_BASE << 16) + 0x10000)
|
68
main.asm
68
main.asm
|
@ -18,68 +18,28 @@ insert "6102.bin"
|
||||||
|
|
||||||
include "main.inc"
|
include "main.inc"
|
||||||
|
|
||||||
Start:
|
include "kernel.asm"
|
||||||
N64_INIT() // enable interrupts
|
|
||||||
|
|
||||||
// SP defaults to RSP instruction memory: 0xA4001FF0
|
nops(0x80010000)
|
||||||
// we can do better than that.
|
|
||||||
lui sp, BLAH_BASE
|
Main:
|
||||||
// SP should always be 8-byte aligned
|
lui t0, K_BASE
|
||||||
// so that SD and LD instructions don't fail on it.
|
lw gp, K_CI_BASE(t0)
|
||||||
subiu sp, sp, 8
|
|
||||||
|
|
||||||
lui s0, BLAH_BASE
|
lui s0, BLAH_BASE
|
||||||
|
|
||||||
Drive64Init:
|
mfc0 t0, CP0_Count
|
||||||
lui gp, CI_BASE
|
mfc0 t1, CP0_Status+0
|
||||||
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)
|
sw t0, BLAH_COUNTS+0(s0)
|
||||||
mfc0 t0, 0x9 // move cycle Count register from COP 0
|
sw t1, 8(s0)
|
||||||
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
|
// decompress our picture
|
||||||
include "lz.asm"
|
include "lz.asm"
|
||||||
|
|
||||||
mfc0 t0, 0x9
|
mfc0 t0, CP0_Count
|
||||||
sw t0, BLAH_COUNTS+8(s0)
|
sw t0, BLAH_COUNTS+8(s0)
|
||||||
lw t1, BLAH_CONFIRMED(s0)
|
lui t0, K_BASE
|
||||||
|
lw t1, K_64DRIVE_MAGIC(t0)
|
||||||
beqz t1, InitVideo
|
beqz t1, InitVideo
|
||||||
nop // delay slot
|
nop // delay slot
|
||||||
|
|
||||||
|
@ -112,7 +72,7 @@ InitVideo: // currently 80001190 (this comment is likely out of date)
|
||||||
jal SetupScreen
|
jal SetupScreen
|
||||||
nop
|
nop
|
||||||
|
|
||||||
mfc0 t0, 0x9 // move cycle Count register from COP 0
|
mfc0 t0, CP0_Count
|
||||||
sw t0, BLAH_COUNTS+0xC(s0)
|
sw t0, BLAH_COUNTS+0xC(s0)
|
||||||
|
|
||||||
MainLoop:
|
MainLoop:
|
||||||
|
@ -175,7 +135,7 @@ PushVideoTask:
|
||||||
sw t5, 0x14(a0)
|
sw t5, 0x14(a0)
|
||||||
sw t6, 0x18(a0)
|
sw t6, 0x18(a0)
|
||||||
sw t7, 0x1C(a0)
|
sw t7, 0x1C(a0)
|
||||||
li t0, VIDEO_STACK & ADDR_MASK // ?
|
li t0, VIDEO_STACK & ADDR_MASK // used for DList calls and returns?
|
||||||
li t1, VIDEO_STACK_SIZE
|
li t1, VIDEO_STACK_SIZE
|
||||||
li t2, VIDEO_BUFFER & ADDR_MASK
|
li t2, VIDEO_BUFFER & ADDR_MASK
|
||||||
li t3, (VIDEO_BUFFER & ADDR_MASK) + VIDEO_BUFFER_SIZE // end pointer (not size!)
|
li t3, (VIDEO_BUFFER & ADDR_MASK) + VIDEO_BUFFER_SIZE // end pointer (not size!)
|
||||||
|
|
29
main.inc
29
main.inc
|
@ -1,13 +1,32 @@
|
||||||
constant UNCACHED(0xA0000000)
|
constant UNCACHED(0xA0000000)
|
||||||
constant ADDR_MASK(0x1FFFFFFF)
|
constant ADDR_MASK(0x1FFFFFFF)
|
||||||
|
|
||||||
|
// "kernel" constants:
|
||||||
|
constant K_BASE(0x8000) // k0 is set to this.
|
||||||
|
constant K_DUMP(0x0400) // we save registers and state here
|
||||||
|
// when handling interrupts
|
||||||
|
constant K_REASON(0x0600)
|
||||||
|
constant K_CAUSE(0x0604)
|
||||||
|
constant K_STATUS(0x0608)
|
||||||
|
constant K_EPC(0x060C)
|
||||||
|
constant K_64DRIVE_MAGIC(0x0800)
|
||||||
|
constant K_CI_BASE(0x0804)
|
||||||
|
|
||||||
|
constant K_STACK_INIT_BASE(0x803F) // note that this gets subtracted by 8
|
||||||
|
// and that the stack grows *backwards.*
|
||||||
|
|
||||||
|
// internal interrupt enum: (0 means no known interrupt/exception)
|
||||||
|
constant K_INT_TLB_REFILL(1)
|
||||||
|
constant K_INT_XTLB_REFILL(2)
|
||||||
|
constant K_INT_CACHE_ERROR(3)
|
||||||
|
constant K_INT_OTHER(4)
|
||||||
|
|
||||||
constant BLAH_BASE(0x803F)
|
constant BLAH_BASE(0x803F)
|
||||||
constant BLAH_CONFIRMED(0x0000)
|
|
||||||
constant BLAH_CI_BASE(0x0004)
|
|
||||||
constant BLAH_COUNTS(0x0010)
|
constant BLAH_COUNTS(0x0010)
|
||||||
constant BLAH_SP_TASK(0x0040)
|
constant BLAH_SP_TASK(0x0040)
|
||||||
constant BLAH_DLIST_JUMPER(0x0080)
|
constant BLAH_DLIST_JUMPER(0x0080)
|
||||||
constant BLAH_XXD(0x0100)
|
constant BLAH_XXD(0x0100)
|
||||||
|
|
||||||
constant VIDEO_BUFFER(0x80100000)
|
constant VIDEO_BUFFER(0x80100000)
|
||||||
constant VIDEO_BUFFER_SIZE(640 * 480 * 4)
|
constant VIDEO_BUFFER_SIZE(640 * 480 * 4)
|
||||||
constant VIDEO_STACK(VIDEO_BUFFER + VIDEO_BUFFER_SIZE)
|
constant VIDEO_STACK(VIDEO_BUFFER + VIDEO_BUFFER_SIZE)
|
||||||
|
@ -15,6 +34,12 @@ constant VIDEO_STACK_SIZE(0x400)
|
||||||
constant VIDEO_YIELD(VIDEO_STACK + VIDEO_STACK_SIZE)
|
constant VIDEO_YIELD(VIDEO_STACK + VIDEO_STACK_SIZE)
|
||||||
constant VIDEO_YIELD_SIZE(0xC00)
|
constant VIDEO_YIELD_SIZE(0xC00)
|
||||||
|
|
||||||
|
macro nops(new_pc) {
|
||||||
|
while (pc() < {new_pc}) {
|
||||||
|
nop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro PI_WAIT() {
|
macro PI_WAIT() {
|
||||||
lui t5, PI_BASE
|
lui t5, PI_BASE
|
||||||
-
|
-
|
||||||
|
|
40
n64.inc
40
n64.inc
|
@ -1,4 +1,4 @@
|
||||||
// via krom
|
// by krom, edited by notwa
|
||||||
|
|
||||||
//=============
|
//=============
|
||||||
// N64 Include
|
// N64 Include
|
||||||
|
@ -66,9 +66,11 @@ constant k0(26)
|
||||||
constant k1(27)
|
constant k1(27)
|
||||||
constant gp(28)
|
constant gp(28)
|
||||||
constant sp(29)
|
constant sp(29)
|
||||||
constant s8(30)
|
constant fp(30)
|
||||||
constant ra(31)
|
constant ra(31)
|
||||||
|
|
||||||
|
constant s8(30) // alias of fp
|
||||||
|
|
||||||
// N64 MIPS 4300 CP1 Floating Point Unit (FPU) Registers (COP1)
|
// N64 MIPS 4300 CP1 Floating Point Unit (FPU) Registers (COP1)
|
||||||
constant f0(0)
|
constant f0(0)
|
||||||
constant f1(1)
|
constant f1(1)
|
||||||
|
@ -103,6 +105,40 @@ constant f29(29)
|
||||||
constant f30(30)
|
constant f30(30)
|
||||||
constant f31(31)
|
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)
|
||||||
|
|
||||||
// Memory Map
|
// Memory Map
|
||||||
constant RDRAM($A000) // $00000000..$003FFFFF RDRAM Memory 4MB ($00000000..$007FFFFF 8MB With Expansion Pak)
|
constant RDRAM($A000) // $00000000..$003FFFFF RDRAM Memory 4MB ($00000000..$007FFFFF 8MB With Expansion Pak)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue