This repository has been archived by the owner on Jul 24, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.asm
281 lines (229 loc) · 5.62 KB
/
main.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
arch n64.cpu
endian msb
include "inc/util.inc"
include "inc/n64.inc"
include "inc/64drive.inc"
include "inc/main.inc"
include "inc/kernel.inc"
output "test.z64", create
fill 1052672 // ROM size
origin 0
base 0x80000000
include "header.asm"
insert "bin/6102.bin"
if origin() != 0x1000 {
error "bad header or bootcode; combined size should be exactly 0x1000"
}
include "kernel.asm"
Main:
lui s0, MAIN_BASE
jal LoadFont16
lui a0, FONT_BASE
if MAIN_DECOMP_IMAGE {
DecompImage:
nop; nop; nop; nop
mfc0 t0, CP0_Count
sw t0, MAIN_COUNTS+0(s0)
// 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
mfc0 t0, CP0_Count
nop; nop; nop; nop
lw t1, MAIN_COUNTS+0x0(s0)
sw t0, MAIN_COUNTS+0x4(s0)
subu t1, t0, t1
sw t1, MAIN_COUNTS+0xC(s0)
jal PokeDataCache
nop
lui a0, MAIN_BASE
jal MainDumpWrite
lli a1, 0x20
}
Test3D:
// write the jump to our actual commands
lui a0, MAIN_BASE
lui t0, 0xDE01 // jump (no push)
ori t1, a0, MAIN_DLIST
sw t0, MAIN_DLIST_JUMPER+0(a0)
sw t1, MAIN_DLIST_JUMPER+4(a0)
jal SetupScreen
nop
lli s1, 1 // s1: which color buffer we're writing to (1: alt)
Start3D:
mfc0 t0, CP0_Status
mtc0 t0, CP0_Status
ori a0, s0, MAIN_DLIST
jal WriteDList
or a1, s1, r0
jal PokeDataCache
nop
DisableInt()
// prepare RSP
lui a0, SP_BASE
lli t0, SP_TASKDONE_CLR | SP_YIELDED_CLR | SP_YIELD_CLR | SP_HALT_SET
sw t0, SP_STATUS(a0)
// 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)
jal PushVideoTask
ori a0, s0, MAIN_SP_TASK
jal LoadRSPBoot
nop
// clear all flags that would halt RSP (i.e. tell it to run!)
lui a0, SP_BASE
lli t0, SP_INT_ON_BREAK_SET | SP_SINGLE_STEP_CLR | SP_BREAK_CLR | SP_HALT_CLR
sw t0, SP_STATUS(a0)
EnableInt()
MainLoop:
mfc0 s2, CP0_Count
WriteString(S_SP_Wait)
-
mfc0 t0, CP0_Status
mtc0 t0, CP0_Status
//
lui a0, SP_BASE
lw t0, SP_STATUS(a0)
andi t0, SP_HALT
beqz t0,-
nop
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
}
// 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
+
// wait on VI too
WriteString(S_VI_Wait)
lui a0, VI_BASE
-
lw t0, VI_V_CURRENT_LINE(a0)
// until half-line <= 2
sltiu at, t0, 2 + 1
beqz at,-
nop
WriteString(SNewFrame)
j Start3D
nop
SetupScreen:
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
nop
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:
mfc0 t0, CP0_Status
mtc0 t0, CP0_Status
j Die
nop
KSL(S_SP_Wait, "now waiting on SP")
KSL(S_VI_Wait, "now waiting on VI")
KSL(SNewFrame, "next frame")
if MAIN_DECOMP_IMAGE {
include "lzss.baku.unsafe.asm"
align(16); insert LZ_BAKU, "res/Image.baku.lzss"
}
include "dlist.asm"
include "task.asm"
include "font.8x16.asm"
if pc() > (MAIN_BASE << 16) {
error "ran out of memory for code and data"
}