217 lines
5.6 KiB
NASM
217 lines
5.6 KiB
NASM
// 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"
|