homebrew/main.asm
2018-08-16 23:06:31 +02:00

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 "debug.asm" // assumes gp is set to CI base
SetupScreen:
// NTSC: 640x480, 32BPP, Interlace, Resample Only, DRAM Origin VIDEO_BUFFER
ScreenNTSC(640, 480, BPP32|INTERLACE|AA_MODE_2, VIDEO_BUFFER | UNCACHED)
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_BASE << 16) | BLAH_DLIST_JUMPER) & ADDR_MASK // initial DList
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"