gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/libc/targets/sm83/duck/crt0.s
1 .include "global.s"
2
3 ;; ****************************************
4 ;; Beginning of module
5 ;; BANKED: checked
6 .title "Runtime"
7 .module Runtime
8 .area _HEADER (ABS)
9
10 ;; RST vectors
11 .org 0x00 ; MEGADUCK entry point/reset
12 JP .code_start
13
14 ; .org 0x08 ; --profile handler utilized by emu_debug.h
15
16 ; .org 0x10 ; empty
17
18 ; .org 0x18 ; empty
19
20 .org 0x20 ; RST 0x20 == call HL
21 .call_hl::
22 JP (HL)
23
24 .org 0x28 ; zero up to 256 bytes in C pointed by HL
25 .MemsetSmall::
26 LD (HL+),A
27 DEC C
28 RET Z
29 LD (HL+), A
30 DEC C
31 JR NZ,.MemsetSmall
32 ret
33
34 .org 0x30 ; copy up to 256 bytes in C from DE to HL
35 .MemcpySmall::
36 LD A, (DE)
37 LD (HL+), A
38 INC DE
39 DEC C
40 JR NZ,.MemcpySmall
41 RET
42
43 ; .org 0x38 ; crash handler utilized by crash_handler.h
44
45 ;; Hardware interrupt vectors
46 .org 0x40 ; VBL
47 .int_VBL:
48 PUSH AF
49 PUSH HL
50 LD HL,#.int_0x40
51 JP .int
52
53 ; .org 0x48 ; LCD
54
55 ; .org 0x50 ; TIM
56
57 ; .org 0x58 ; SIO
58
59 ; .org 0x60 ; JOY
60
61 ; .org 0x70
62 ;; space for drawing.s bit table
63
64 .org 0x80
65 .int::
66 PUSH BC
67 PUSH DE
68 1$:
69 LD A,(HL+)
70 OR (HL)
71 JR Z,.int_tail
72 PUSH HL
73 LD A,(HL-)
74 LD L,(HL)
75 LD H,A
76 RST 0x20 ; .call_hl
77 POP HL
78 INC HL
79 JR 1$
80 _wait_int_handler::
81 ADD SP,#4
82 .int_tail:
83 POP DE
84 POP BC
85 POP HL
86
87 ;; we return at least at the beginning of mode 2
88 WAIT_STAT
89
90 POP AF
91 RETI
92
93 ;; VBlank default interrupt routine
94 __standard_VBL_handler::
95 .std_vbl:
96 LD HL,#.sys_time
97 INC (HL)
98 JR NZ,2$
99 INC HL
100 INC (HL)
101 2$:
102 LD A, #1
103 LDH (.vbl_done),A
104
105 JP .refresh_OAM
106
107 _refresh_OAM::
108 WAIT_STAT
109 LD A, #>_shadow_OAM
110 JP .refresh_OAM_DMA
111
112 .clear_WRAM:
113 XOR A
114 LD BC, #l__DATA
115 LD HL, #s__DATA
116 CALL .memset_simple
117
118 LD A, #>_shadow_OAM
119 LDH (__shadow_OAM_base), A
120 LD H, A
121 XOR A
122 LD L, A
123 LD C, #(40 << 2) ; 40 entries 4 bytes each
124 JP .MemsetSmall
125
126 _set_interrupts::
127 DI
128 LDH (.IE),A
129 XOR A
130 EI
131 LDH (.IFL),A ; Clear pending interrupts
132 RET
133
134 ;; Copy OAM data to OAM RAM
135 .start_refresh_OAM:
136 LDH A,(__shadow_OAM_base)
137 OR A
138 RET Z
139 .start_refresh_OAM_DMA:
140 LDH (.DMA),A ; Put A into DMA registers
141 LD A,#0x28 ; We need to wait 160 ns
142 1$:
143 DEC A
144 JR NZ,1$
145 RET
146 .end_refresh_OAM:
147
148 .org .MODE_TABLE
149 ;; Jump table for modes
150 RET
151
152 .org 0x150
153
154 ;; soft reset: falldown to .code_start
155 .reset::
156 _reset::
157
158 ;; Initialization code
159 .code_start::
160 DI ; Disable interrupts
161 ;; Initialize the stack
162 LD SP, #.STACK
163
164 PUSH DE
165 ;; Turn the screen off
166 CALL .display_off
167 ;; Clear the static storage
168 CALL .clear_WRAM
169 POP DE
170
171
172 ;; Store CPU type
173 LD A, #.DMG_TYPE ; MEGADUCK is always a DMG
174 LD (__cpu), A
175 XOR A
176 ; LD (__is_GBA), A ; and it is never GBA ; clearing (__is_GBA) is performed when clearing RAM
177 ; LD (.mode),A ; clearing (.mode) is performed when clearing RAM
178
179 ;; Initialize the display
180 LDH (.SCY),A
181 LDH (.SCX),A
182 LDH (.STAT),A
183 LDH (.WY),A
184 LD A,#0x07
185 LDH (.WX),A
186
187 ;; Copy refresh_OAM routine to HRAM
188 LD DE,#.start_refresh_OAM ; source
189 LD HL,#.refresh_OAM ; dest
190 LD C,#(.end_refresh_OAM - .start_refresh_OAM) ; size
191 RST 0x30 ; call .MemcpySmall
192
193 ;; Clear the OAM by calling refresh_OAM
194 CALL .refresh_OAM
195
196 ;; Install interrupt routines
197 LD DE,#.std_vbl
198 CALL .add_VBL
199
200 ;; Standard color palettes
201 LD A,#0b11100100 ; Grey 3 = 11 (Black)
202 ; Grey 2 = 10 (Dark grey)
203 ; Grey 1 = 01 (Light grey)
204 ; Grey 0 = 00 (Transparent)
205 LDH (.BGP),A
206 LDH (.OBP0),A
207 LD A,#0b00011011
208 LDH (.OBP1),A
209
210 ;; Turn the screen on
211 LD A,#(LCDCF_ON | LCDCF_WIN9C00 | LCDCF_WINOFF | LCDCF_BG8800 | LCDCF_BG9800 | LCDCF_OBJ8 | LCDCF_OBJOFF | LCDCF_BGOFF)
212 LDH (.LCDC),A
213
214 LD A,#.VBL_IFLAG ; switch on VBlank interrupt only
215 LDH (.IE),A
216
217 XOR A
218 LDH (.IFL),A
219
220 LD HL,#.sys_time
221 LD (HL+),A
222 LD (HL),A
223
224 LDH (.NR52),A ; Turn sound off
225
226 INC A
227 LDH (__current_bank),A ; current bank is 1 at startup
228
229 CALL gsinit
230
231 EI ; Enable interrupts
232
233 ;; Call the main function
234 CALL _main
235 _exit::
236 99$:
237 HALT
238 NOP
239 JR 99$ ; Wait forever
240
241 ;; Wait for VBL interrupt to be finished
242 .wait_vbl_done::
243 _wait_vbl_done::
244 _vsync::
245 ;; Check if the screen is on
246 LDH A,(.LCDC)
247 AND #LCDCF_ON
248 RET Z ; Return if screen is off
249 XOR A
250 LDH (.vbl_done),A ; Clear any previous sets of vbl_done
251 1$:
252 HALT ; Wait for any interrupt
253 NOP ; HALT sometimes skips the next instruction
254 LDH A,(.vbl_done) ; Was it a VBlank interrupt?
255 ;; Warning: we may lose a VBlank interrupt, if it occurs now
256 OR A
257 JR Z,1$ ; No: back to sleep!
258 RET
259
260 ;; Remove interrupt routine in DE from the VBL interrupt list
261 ;; falldown to .remove_int
262 _remove_VBL::
263 .remove_VBL::
264 LD HL,#.int_0x40
265
266 ;; Remove interrupt DE from interrupt list HL if it exists
267 ;; Abort if a 0000 is found (end of list)
268 .remove_int::
269 1$:
270 LD A,(HL+)
271 LD C,A
272 LD A,(HL+)
273 LD B,A
274 OR C
275 RET Z ; No interrupt found
276
277 LD A,E
278 CP C
279 JR NZ,1$
280 LD A,D
281 CP B
282 JR NZ,1$
283
284 LD B,H
285 LD C,L
286 DEC BC
287 DEC BC
288
289 ;; Now do a memcpy from here until the end of the list
290 2$:
291 LD A,(HL+)
292 LD (BC),A
293 INC BC
294 LD D,A
295 LD A,(HL+)
296 LD (BC),A
297 INC BC
298 OR D
299 JR NZ, 2$
300 RET
301
302 ;; Add interrupt routine in BC to the VBL interrupt list
303 ;; falldown to .add_int
304 _add_VBL::
305 .add_VBL::
306 LD HL,#.int_0x40
307
308 ;; Add interrupt routine in BC to the interrupt list in HL
309 .add_int::
310 1$:
311 LD A,(HL+)
312 OR (HL)
313 JR Z,2$
314 INC HL
315 JR 1$
316 2$:
317 LD A,D
318 LD (HL-),A
319 LD (HL),E
320 RET
321
322 ;; ****************************************
323
324 ;; Ordering of segments for the linker
325 ;; Code that really needs to be in bank 0
326 .area _HOME
327 ;; Similar to _HOME
328 .area _BASE
329 ;; Code
330 .area _CODE
331 ;; #pragma bank 0 workaround
332 .area _CODE_0
333 ;; Constant data
334 .area _LIT
335 ; ;; since _CODE_1 area base address is pre-defined in the linker from 0x4000,
336 ; ;; that moves initializer code and tables out of bank 0
337 ; .area _CODE_1
338 ;; Constant data, used to init _DATA
339 .area _INITIALIZER
340 ;; Code, used to init _DATA
341 .area _GSINIT
342 .area _GSFINAL
343 ;; Uninitialised ram data
344 .area _DATA
345 .area _BSS
346 ;; Initialised in ram data
347 .area _INITIALIZED
348 ;; For malloc
349 .area _HEAP
350 .area _HEAP_END
351 ;; High RAM area
352 .area _HRAM
353
354 .area _DATA
355 __cpu::
356 .ds 0x01 ; GB type (GB, PGB, CGB)
357 __is_GBA::
358 .ds 0x01 ; detect GBA
359 .mode::
360 .ds 0x01 ; Current mode
361 .sys_time::
362 _sys_time::
363 .ds 0x02 ; System time in VBL units
364 .int_0x40::
365 .blkw 0x06 ; 5 interrupt handlers: 1 built-in + 4 user-defined
366
367 .area _HRAM
368 .refresh_OAM::
369 .ds (.start_refresh_OAM_DMA - .start_refresh_OAM)
370 .refresh_OAM_DMA:
371 .ds (.end_refresh_OAM - .start_refresh_OAM_DMA)
372
373 .bndry 0x10
374
375 __current_bank::
376 .ds 0x01 ; Current bank
377 .vbl_done:
378 __vbl_done::
379 .ds 0x01 ; Is VBL interrupt finished?
380 __shadow_OAM_base::
381 .ds 0x01
382
383 ;; Runtime library
384 .area _GSINIT
385
386 gsinit::
387 ;; initialize static storage variables
388 LD BC, #l__INITIALIZER
389 LD HL, #s__INITIALIZER
390 LD DE, #s__INITIALIZED
391 CALL .memcpy_simple
392
393 .area _GSFINAL
394
395 RET
396
397 .area _HOME
398
399 ;; fills memory at HL of length BC with A, clobbers DE
400 .memset_simple::
401 LD E, A
402 LD A, B
403 OR C
404 RET Z
405 LD (HL), E
406 DEC BC
407 LD D, H
408 LD E, L
409 INC DE
410
411 ;; copies BC bytes from HL into DE
412 .memcpy_simple::
413 LD A, B
414 OR C
415 RET Z
416
417 SRL B
418 RR C
419 JR NC,3$
420 LD A, (HL+)
421 LD (DE), A
422 INC DE
423 3$:
424 INC B
425 INC C
426 JR 2$
427 1$:
428 LD A, (HL+)
429 LD (DE), A
430 INC DE
431 LD A, (HL+)
432 LD (DE), A
433 INC DE
434 2$:
435 DEC C
436 JR NZ,1$
437 DEC B
438 JR NZ,1$
439 4$:
440 RET
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.