2018-08-16 10:53:31 -07:00
|
|
|
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
|
2018-08-29 17:58:09 -07:00
|
|
|
fill 1052672 // ROM size
|
2018-08-16 10:53:31 -07:00
|
|
|
|
2018-10-01 19:49:09 -07:00
|
|
|
origin 0
|
2018-08-16 10:53:31 -07:00
|
|
|
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 {
|
2018-08-29 17:58:09 -07:00
|
|
|
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
|
|
|
|
2018-08-16 23:02:25 -07:00
|
|
|
include "kernel.asm"
|
2018-08-16 10:53:31 -07:00
|
|
|
|
2018-08-16 23:02:25 -07:00
|
|
|
Main:
|
2018-08-31 03:54:48 -07:00
|
|
|
|
2018-10-23 07:29:25 -07:00
|
|
|
lui s0, MAIN_BASE
|
|
|
|
|
|
|
|
jal LoadFont16
|
|
|
|
lui a0, FONT_BASE
|
|
|
|
|
2018-09-28 22:07:44 -07:00
|
|
|
if MAIN_DECOMP_IMAGE {
|
2018-09-28 01:40:22 -07:00
|
|
|
DecompImage:
|
|
|
|
|
2018-08-18 15:22:24 -07:00
|
|
|
nop; nop; nop; nop
|
2018-08-16 23:02:25 -07:00
|
|
|
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
|
|
|
|
2018-08-18 15:22:24 -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
|
2018-08-29 17:58:09 -07:00
|
|
|
li a2, VIDEO_C_IMAGE
|
|
|
|
jal LzDecomp
|
2018-08-18 15:22:24 -07:00
|
|
|
nop
|
2018-08-16 10:53:31 -07:00
|
|
|
|
2018-08-16 23:02:25 -07:00
|
|
|
mfc0 t0, CP0_Count
|
2018-08-18 15:22:24 -07:00
|
|
|
nop; nop; nop; nop
|
|
|
|
|
2018-08-24 17:25:56 -07:00
|
|
|
lw t1, MAIN_COUNTS+0x0(s0)
|
|
|
|
sw t0, MAIN_COUNTS+0x4(s0)
|
2018-08-18 15:22:24 -07:00
|
|
|
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-24 17:25:56 -07:00
|
|
|
lui a0, MAIN_BASE
|
2018-09-28 01:40:22 -07:00
|
|
|
jal MainDumpWrite
|
2018-08-16 10:53:31 -07:00
|
|
|
lli a1, 0x20
|
2018-09-28 01:40:22 -07:00
|
|
|
}
|
2018-08-16 10:53:31 -07:00
|
|
|
|
2018-08-20 19:40:25 -07:00
|
|
|
Test3D:
|
2018-08-29 17:58:09 -07:00
|
|
|
// write the jump to our actual commands
|
2018-08-24 17:25:56 -07:00
|
|
|
lui a0, MAIN_BASE
|
2018-08-19 17:13:11 -07:00
|
|
|
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)
|
2018-08-19 17:13:11 -07:00
|
|
|
|
2018-08-24 17:04:19 -07:00
|
|
|
jal SetupScreen
|
2018-08-20 19:40:25 -07:00
|
|
|
nop
|
2018-08-19 17:13:11 -07:00
|
|
|
|
2018-08-24 17:04:19 -07:00
|
|
|
lli s1, 1 // s1: which color buffer we're writing to (1: alt)
|
|
|
|
|
|
|
|
Start3D:
|
2018-10-01 20:13:49 -07:00
|
|
|
mfc0 t0, CP0_Status
|
|
|
|
mtc0 t0, CP0_Status
|
|
|
|
|
2018-10-23 07:29:25 -07:00
|
|
|
ori a0, s0, MAIN_DLIST
|
2018-08-24 17:04:19 -07:00
|
|
|
jal WriteDList
|
|
|
|
or a1, s1, r0
|
|
|
|
jal PokeDataCache
|
2018-08-23 23:20:43 -07:00
|
|
|
nop
|
|
|
|
|
2018-10-01 20:13:49 -07:00
|
|
|
DisableInt()
|
2018-08-20 19:40:25 -07:00
|
|
|
|
2018-08-24 17:04:19 -07:00
|
|
|
// prepare RSP
|
2018-08-19 17:13:11 -07:00
|
|
|
lui a0, SP_BASE
|
2018-10-01 20:13:49 -07:00
|
|
|
lli t0, SP_TASKDONE_CLR | SP_YIELDED_CLR | SP_YIELD_CLR | SP_HALT_SET
|
2018-08-19 17:13:11 -07:00
|
|
|
sw t0, SP_STATUS(a0)
|
|
|
|
|
|
|
|
// set RSP PC to IMEM+$0
|
|
|
|
lui a0, SP_PC_BASE
|
2018-08-24 17:04:19 -07:00
|
|
|
// only the lowest 12 bits are used, so 00000000 is equivalent to 04001000.
|
|
|
|
sw r0, SP_PC(a0)
|
2018-08-19 17:13:11 -07:00
|
|
|
|
2018-08-20 19:40:25 -07:00
|
|
|
jal PushVideoTask
|
2018-10-23 07:29:25 -07:00
|
|
|
ori a0, s0, MAIN_SP_TASK
|
2018-08-20 19:40:25 -07:00
|
|
|
|
|
|
|
jal LoadRSPBoot
|
|
|
|
nop
|
|
|
|
|
|
|
|
// clear all flags that would halt RSP (i.e. tell it to run!)
|
2018-08-19 17:13:11 -07:00
|
|
|
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
|
2018-08-19 17:13:11 -07:00
|
|
|
sw t0, SP_STATUS(a0)
|
|
|
|
|
2018-10-01 20:13:49 -07:00
|
|
|
EnableInt()
|
2018-08-19 17:13:11 -07:00
|
|
|
|
2018-08-16 10:53:31 -07:00
|
|
|
MainLoop:
|
2018-10-23 07:29:25 -07:00
|
|
|
mfc0 s2, CP0_Count
|
|
|
|
|
2018-09-28 22:27:36 -07:00
|
|
|
WriteString(S_SP_Wait)
|
2018-10-01 20:13:49 -07:00
|
|
|
-
|
|
|
|
mfc0 t0, CP0_Status
|
|
|
|
mtc0 t0, CP0_Status
|
|
|
|
//
|
|
|
|
lui a0, SP_BASE
|
|
|
|
lw t0, SP_STATUS(a0)
|
|
|
|
andi t0, SP_HALT
|
|
|
|
beqz t0,-
|
|
|
|
nop
|
2018-08-31 03:54:48 -07:00
|
|
|
|
2018-10-23 07:29:25 -07:00
|
|
|
mfc0 s3, CP0_Count
|
|
|
|
subu s3, s2
|
|
|
|
addiu s3, COUNT_RATE / (60 * 200) // for rounding
|
|
|
|
li t9, COUNT_RATE / (60 * 100)
|
|
|
|
divu s3, t9
|
|
|
|
mflo s2 // s2: frame budget spent in (integer) percent
|
|
|
|
|
|
|
|
// there are faster ways, but i'll prefer smaller codesize for now.
|
|
|
|
lli t9, 10
|
|
|
|
divu s2, t9
|
|
|
|
mfhi s3 // s3: (RTL) first digit
|
|
|
|
mflo t0
|
|
|
|
divu t0, t9
|
|
|
|
mfhi s4 // s4: (RTL) second digit
|
|
|
|
mflo t0
|
|
|
|
divu t0, t9
|
|
|
|
mfhi s5 // s5: (RTL) third digit
|
|
|
|
|
|
|
|
if !HICOLOR {
|
|
|
|
|
|
|
|
if HIRES {
|
|
|
|
lli s6, 64 // s6: X position
|
|
|
|
lli s7, 48 // s7: Y position
|
|
|
|
} else {
|
|
|
|
lli s6, 32 // s6: X position
|
|
|
|
lli s7, 24 // s7: Y position
|
|
|
|
}
|
|
|
|
|
|
|
|
la s8, VIDEO_C_IMAGE // s8: output image buffer
|
|
|
|
beqz s1,+
|
|
|
|
nop
|
|
|
|
la s8, VIDEO_C_IMAGE_ALT
|
|
|
|
+
|
|
|
|
|
|
|
|
beqz s5,+
|
|
|
|
lui a0, FONT_BASE
|
|
|
|
addiu a1, s5, '0'
|
|
|
|
sll a2, s7, 16
|
|
|
|
or a2, s6
|
|
|
|
move a3, s8
|
|
|
|
jal DrawChar16
|
|
|
|
+
|
|
|
|
addiu s6, FONT_WIDTH
|
|
|
|
|
|
|
|
or at, s5, s6
|
|
|
|
beqz at,+
|
|
|
|
lui a0, FONT_BASE
|
|
|
|
addiu a1, s4, '0'
|
|
|
|
sll a2, s7, 16
|
|
|
|
or a2, s6
|
|
|
|
move a3, s8
|
|
|
|
jal DrawChar16
|
|
|
|
+
|
|
|
|
addiu s6, FONT_WIDTH
|
|
|
|
|
|
|
|
lui a0, FONT_BASE
|
|
|
|
addiu a1, s3, '0'
|
|
|
|
sll a2, s7, 16
|
|
|
|
or a2, s6
|
|
|
|
move a3, s8
|
|
|
|
jal DrawChar16
|
|
|
|
addiu s6, FONT_WIDTH
|
|
|
|
|
|
|
|
lui a0, FONT_BASE
|
|
|
|
addiu a1, r0, '%'
|
|
|
|
sll a2, s7, 16
|
|
|
|
or a2, s6
|
|
|
|
move a3, s8
|
|
|
|
jal DrawChar16
|
|
|
|
addiu s6, FONT_WIDTH
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-10-21 08:31:03 -07:00
|
|
|
// queue buffers to swap
|
|
|
|
lui a0, K_BASE
|
|
|
|
beqz s1, SwapToMain
|
|
|
|
nop
|
|
|
|
SwapToAlt:
|
|
|
|
la t0, VIDEO_C_IMAGE_ALT | UNCACHED
|
|
|
|
sw t0, KV_ORIGIN(a0)
|
|
|
|
b +
|
|
|
|
lli s1, 0
|
|
|
|
SwapToMain:
|
|
|
|
la t0, VIDEO_C_IMAGE | UNCACHED
|
|
|
|
sw t0, KV_ORIGIN(a0)
|
|
|
|
lli s1, 1
|
|
|
|
+
|
|
|
|
|
2018-08-24 17:04:19 -07:00
|
|
|
// wait on VI too
|
2018-10-21 08:31:03 -07:00
|
|
|
WriteString(S_VI_Wait)
|
2018-10-01 20:13:49 -07:00
|
|
|
lui a0, VI_BASE
|
2018-08-24 17:04:19 -07:00
|
|
|
-
|
2018-10-01 20:13:49 -07:00
|
|
|
lw t0, VI_V_CURRENT_LINE(a0)
|
|
|
|
// until half-line <= 2
|
|
|
|
sltiu at, t0, 2 + 1
|
|
|
|
beqz at,-
|
2018-08-23 23:20:43 -07:00
|
|
|
nop
|
|
|
|
|
2018-08-23 23:24:01 -07:00
|
|
|
WriteString(SNewFrame)
|
2018-08-23 23:20:43 -07:00
|
|
|
|
2018-08-24 17:04:19 -07:00
|
|
|
j Start3D
|
2018-10-21 08:31:03 -07:00
|
|
|
nop
|
2018-08-16 10:53:31 -07:00
|
|
|
|
|
|
|
SetupScreen:
|
2018-10-21 08:31:03 -07:00
|
|
|
if WIDTH == 640 {
|
|
|
|
lli a0, RES_640_480
|
|
|
|
} else if WIDTH == 576 {
|
|
|
|
lli a0, RES_576_432
|
|
|
|
} else if WIDTH == 512 {
|
|
|
|
lli a0, RES_512_448
|
|
|
|
} else if WIDTH == 320 {
|
|
|
|
lli a0, RES_320_240
|
|
|
|
} else if WIDTH == 288 {
|
|
|
|
lli a0, RES_288_216
|
|
|
|
} else if WIDTH == 256 {
|
|
|
|
lli a0, RES_256_224
|
|
|
|
}
|
|
|
|
|
|
|
|
li a1, VIDEO_MODE
|
|
|
|
la a2, VIDEO_C_IMAGE | UNCACHED
|
|
|
|
j K_SetScreenNTSC // tail-call
|
2018-08-16 10:53:31 -07:00
|
|
|
nop
|
|
|
|
|
2018-09-28 01:40:22 -07:00
|
|
|
MainDumpWrite:
|
|
|
|
subiu sp, 0x18
|
|
|
|
sw ra, 0x10(sp)
|
|
|
|
|
|
|
|
lui a2, MAIN_BASE
|
|
|
|
ori a2, MAIN_XXD
|
|
|
|
jal DumpAndWrite // a0,a1 passthru
|
|
|
|
lli a3, 0x200
|
|
|
|
WriteString(KS_Newline)
|
|
|
|
|
|
|
|
lw ra, 0x10(sp)
|
|
|
|
jr ra
|
|
|
|
addiu sp, 0x18
|
|
|
|
|
|
|
|
Die:
|
2018-10-21 08:31:03 -07:00
|
|
|
mfc0 t0, CP0_Status
|
|
|
|
mtc0 t0, CP0_Status
|
2018-09-28 01:40:22 -07:00
|
|
|
j Die
|
|
|
|
nop
|
|
|
|
|
2018-09-28 22:27:36 -07:00
|
|
|
KSL(S_SP_Wait, "now waiting on SP")
|
|
|
|
KSL(S_VI_Wait, "now waiting on VI")
|
|
|
|
KSL(SNewFrame, "next frame")
|
2018-09-28 22:07:44 -07:00
|
|
|
|
|
|
|
if MAIN_DECOMP_IMAGE {
|
|
|
|
include "lzss.baku.unsafe.asm"
|
|
|
|
align(16); insert LZ_BAKU, "res/Image.baku.lzss"
|
|
|
|
}
|
2018-08-24 17:04:19 -07:00
|
|
|
include "dlist.asm"
|
2018-08-31 04:01:27 -07:00
|
|
|
include "task.asm"
|
2018-10-23 07:29:25 -07:00
|
|
|
include "font.8x16.asm"
|
2018-08-29 17:58:09 -07:00
|
|
|
|
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"
|
2018-08-24 17:04:19 -07:00
|
|
|
}
|