homebrew/main.asm

247 lines
5.9 KiB
NASM
Raw Normal View History

2018-08-16 10:53:31 -07:00
// built on the N64 ROM template by krom
arch n64.cpu
endian msb
2018-08-20 19:40:25 -07:00
2018-08-20 20:10:06 -07:00
include "inc/util.inc"
2018-08-18 08:31:58 -07:00
include "inc/n64.inc"
include "inc/64drive.inc"
2018-08-20 19:40:25 -07:00
include "inc/main.inc"
include "inc/kernel.inc"
2018-08-16 10:53:31 -07:00
output "test.z64", create
fill 1052672 // ROM size
2018-08-16 10:53:31 -07:00
origin 0x00000000
base 0x80000000
include "header.asm"
2018-08-18 08:31:58 -07:00
insert "bin/6102.bin"
2018-08-20 22:02:37 -07:00
if origin() != 0x1000 {
error "bad header or bootcode; combined size should be exactly 0x1000"
2018-08-20 22:02:37 -07:00
}
2018-08-16 10:53:31 -07:00
include "kernel.asm"
2018-08-16 10:53:31 -07:00
Main:
2018-08-24 17:25:56 -07:00
lui s0, MAIN_BASE
2018-08-31 03:54:48 -07:00
if 0 {
nop; nop; nop; nop
mfc0 t0, CP0_Count
2018-08-24 17:25:56 -07:00
sw t0, MAIN_COUNTS+0(s0)
2018-08-16 10:53:31 -07:00
// decompress our picture
la a0, LZ_BAKU + 4
lw a3, -4(a0) // load uncompressed size from the file itself
li a1, LZ_BAKU.size - 4
li a2, VIDEO_C_IMAGE
jal LzDecomp
nop
2018-08-16 10:53:31 -07:00
mfc0 t0, CP0_Count
nop; nop; nop; nop
2018-08-24 17:25:56 -07:00
lw t1, MAIN_COUNTS+0x0(s0)
sw t0, MAIN_COUNTS+0x4(s0)
subu t1, t0, t1
2018-08-24 17:25:56 -07:00
sw t1, MAIN_COUNTS+0xC(s0)
2018-08-16 10:53:31 -07:00
2018-08-20 19:40:25 -07:00
jal PokeDataCache
nop
2018-08-31 03:54:48 -07:00
}
2018-08-20 19:40:25 -07:00
2018-08-24 17:25:56 -07:00
lui a0, MAIN_BASE
2018-08-16 10:53:31 -07:00
lli a1, 0x20
2018-08-24 17:25:56 -07:00
ori a2, a0, MAIN_XXD
2018-08-18 07:39:57 -07:00
jal DumpAndWrite
2018-08-16 10:53:31 -07:00
lli a3, 0x20 * 4
2018-08-23 23:24:01 -07:00
WriteString(KS_Newline)
2018-08-16 10:53:31 -07:00
2018-08-20 19:40:25 -07:00
Test3D:
// write the jump to our actual commands
2018-08-24 17:25:56 -07:00
lui a0, MAIN_BASE
lui t0, 0xDE01 // jump (no push)
2018-08-24 17:25:56 -07:00
ori t1, a0, MAIN_DLIST
sw t0, MAIN_DLIST_JUMPER+0(a0)
sw t1, MAIN_DLIST_JUMPER+4(a0)
jal SetupScreen
2018-08-20 19:40:25 -07:00
nop
lli s1, 1 // s1: which color buffer we're writing to (1: alt)
Start3D:
2018-08-24 17:25:56 -07:00
lui a0, MAIN_BASE
ori a0, MAIN_DLIST
jal WriteDList
or a1, s1, r0
jal PokeDataCache
nop
ClearIntMask()
2018-08-20 19:40:25 -07:00
// prepare RSP
lui a0, SP_BASE
2018-08-31 03:54:48 -07:00
lli t0, SP_SG2_CLR | SP_SG1_CLR | SP_SG0_CLR | SP_INT_ON_BREAK_SET
sw t0, SP_STATUS(a0)
2018-08-31 03:54:48 -07:00
SP_HALT_WAIT()
2018-08-20 19:40:25 -07:00
// set RSP PC to IMEM+$0
lui a0, SP_PC_BASE
// only the lowest 12 bits are used, so 00000000 is equivalent to 04001000.
sw r0, SP_PC(a0)
2018-08-24 17:25:56 -07:00
lui a0, MAIN_BASE
2018-08-20 19:40:25 -07:00
jal PushVideoTask
2018-08-24 17:25:56 -07:00
ori a0, a0, MAIN_SP_TASK
2018-08-20 19:40:25 -07:00
2018-08-31 03:54:48 -07:00
SP_DMA_WAIT()
2018-08-20 19:40:25 -07:00
jal LoadRSPBoot
nop
2018-08-31 03:54:48 -07:00
SP_DMA_WAIT()
2018-08-20 19:40:25 -07:00
// clear all flags that would halt RSP (i.e. tell it to run!)
lui a0, SP_BASE
2018-08-31 03:54:48 -07:00
lli t0, SP_INT_ON_BREAK_SET | SP_SINGLE_STEP_CLR | SP_BREAK_CLR | SP_HALT_CLR
sw t0, SP_STATUS(a0)
nop
SetIntMask()
2018-08-16 10:53:31 -07:00
MainLoop:
2018-08-31 03:54:48 -07:00
SP_HALT_WAIT()
WriteString(SPreFrame)
// wait on VI too
-
lui t0, VI_BASE
lw t0, VI_V_CURRENT_LINE(t0)
// until line <= 3
sltiu t0, 4 // larger values seem to die on N64 (cen64 has no problem)
beqz t0,-
nop
2018-08-23 23:24:01 -07:00
WriteString(SNewFrame)
// swap buffers
lui a0, VI_BASE
beqz s1, SwitchToAlt
2018-08-23 20:09:34 -07:00
nop
SwitchToMain:
la t0, VIDEO_C_IMAGE_ALT
sw t0, VI_ORIGIN(a0)
j Start3D
lli s1, 0
SwitchToAlt:
la t0, VIDEO_C_IMAGE
sw t0, VI_ORIGIN(a0)
j Start3D
lli s1, 1
2018-08-16 10:53:31 -07:00
2018-08-31 03:54:48 -07:00
KSL(SPreFrame, "now waiting for VI")
KSL(SNewFrame, "next frame")
2018-08-16 10:53:31 -07:00
SetupScreen:
2018-08-23 20:09:34 -07:00
if HICOLOR {
ScreenNTSC(WIDTH, HEIGHT, BPP32|INTERLACE|AA_MODE_2, VIDEO_C_IMAGE | UNCACHED)
2018-08-23 20:09:34 -07:00
} else {
ScreenNTSC(WIDTH, HEIGHT, BPP16|AA_MODE_2, VIDEO_C_IMAGE | UNCACHED)
2018-08-23 20:09:34 -07:00
}
2018-08-16 10:53:31 -07:00
jr ra
nop
PushVideoTask:
// a0: Task RDRAM Pointer (size: 0x40) (should probably be row-aligned)
subiu sp, sp, 0x18
sw ra, 0x10(sp)
2018-08-16 10:53:31 -07:00
lli t0, 1 // mode: video
lli t1, TASK_DP_WAIT // flags
li t2, UCODE_BOOT // does not need masking (not actually used?)
li t3, UCODE_BOOT.size
2018-08-16 10:53:31 -07:00
li t4, F3DZEX_IMEM & ADDR_MASK
2018-08-20 19:40:25 -07:00
li t5, F3DZEX_IMEM.size
2018-08-16 10:53:31 -07:00
li t6, F3DZEX_DMEM & ADDR_MASK
2018-08-20 19:40:25 -07:00
li t7, F3DZEX_DMEM.size
2018-08-16 10:53:31 -07:00
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 // used for DList calls and returns?
2018-08-16 10:53:31 -07:00
li t1, VIDEO_STACK_SIZE
li t2, VIDEO_OUTPUT & ADDR_MASK
// most commercial games re-use the yield pointer, so i assume it's fine:
li t3, VIDEO_YIELD & ADDR_MASK // stores output buffer size
2018-08-24 17:25:56 -07:00
li t4, ((MAIN_BASE << 16) | MAIN_DLIST_JUMPER) & ADDR_MASK // initial DList
2018-08-20 19:40:25 -07:00
lli t5, 8 // size of one jump command. this is ignored and 0xA8 is used instead
2018-08-16 10:53:31 -07:00
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)
// tell data cache to write itself out
cache 0x19, 0x00(a0)
cache 0x19, 0x10(a0)
cache 0x19, 0x20(a0)
cache 0x19, 0x30(a0)
li t9, ADDR_MASK
jal PushRSPTask
and a0, a0, t9
2018-08-16 10:53:31 -07:00
lw ra, 0x10(sp)
2018-08-16 10:53:31 -07:00
jr ra
addiu sp, sp, 0x18
2018-08-16 10:53:31 -07:00
PushRSPTask:
lli t3, 0x40 - 1 // DMA quirk
2018-08-31 03:54:48 -07:00
or t4, a0, r0
SP_DMA_WAIT() // clobbers t0, a0
la t1, 0xA4000FC0
2018-08-31 03:54:48 -07:00
sw t1, SP_MEM_ADDR(a0)
sw t4, SP_DRAM_ADDR(a0)
sw t3, SP_RD_LEN(a0) // pull data from RDRAM into DMEM/IMEM
2018-08-16 10:53:31 -07:00
jr ra
nop
2018-08-20 19:40:25 -07:00
LoadRSPBoot:
la t2, UCODE_BOOT & ADDR_MASK
li t3, UCODE_BOOT.size
2018-08-20 19:40:25 -07:00
subiu t3, t3, 1 // DMA quirk
2018-08-31 03:54:48 -07:00
SP_DMA_WAIT() // clobbers t0, a0
2018-08-20 19:40:25 -07:00
la t1, 0xA4001000
2018-08-31 03:54:48 -07:00
sw t1, SP_MEM_ADDR(a0)
sw t2, SP_DRAM_ADDR(a0)
sw t3, SP_RD_LEN(a0) // pull data from RDRAM into DMEM/IMEM
2018-08-20 19:40:25 -07:00
jr ra
nop
include "lzss.baku.unsafe.asm"
include "dlist.asm"
align(16); insert UCODE_BOOT, "bin/common.boot.bin"
2018-08-18 08:31:58 -07:00
align(16); insert F3DZEX_IMEM, "bin/F3DZEX2.bin"
align(16); insert F3DZEX_DMEM, "bin/F3DZEX2.data.bin"
//align(16); insert FONT, "res/dwarf.1bpp"
//align(16); insert LZ_BAKU, "res/Image.baku.lzss"
2018-08-24 17:25:56 -07:00
if pc() > (MAIN_BASE << 16) {
2018-08-24 17:18:40 -07:00
error "ran out of memory for code and data"
}