gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/libc/targets/z80/msxdos/crt0.s
1 .include "global.s"
2
3 .title "Runtime"
4 .module Runtime
5
6 .ez80
7
8 ;; Ordering of segments for the linker.
9 .area _CODE
10 .area _CODE_0
11 .area _HOME
12 .area _BASE
13 .area _LIT
14 .area _GSINIT
15 .area _GSFINAL
16 .area _INITIALIZER
17
18 .area _DATA
19 .area _INITIALIZED
20 .area _BSEG
21 .area _BSS
22 .area _HEAP
23 .area _HEAP_END
24
25 ; program startup code
26 .area _CODE
27 .start::
28 ei
29 call .save_int_vector
30 call .gsinit
31
32 ld a, (___overlay_count)
33 and a
34 call nz, .load_overlays
35 jp c, .exit_error
36
37 call .setup_video_mode
38
39 ld hl, #.LS_FILE_BUFFER
40 xor a
41 ld b, a
42 ld c, (hl)
43 or c
44 jr z, 1$
45
46 add hl, bc
47 inc hl
48 xor a
49 ld (hl), a
50 ld c, a ; param counter
51
52 ld hl, #(.LS_FILE_BUFFER + 1)
53 3$:
54 ld a, (hl)
55 or a
56 jr z, 6$
57 cp #0x20
58 jr nz, 6$
59 inc hl
60 jr 3$
61 6$:
62 jr z, 2$
63
64 inc c
65 push hl
66 4$:
67 inc hl
68 ld a, (hl)
69 or a
70 jr z, 2$
71 cp #0x20
72 jr nz, 4$
73 5$:
74 ld (hl), #0
75 inc hl
76 jr 3$
77 2$:
78 ld hl, #0
79 add hl, sp
80 push hl ; push pointer to argv array on stack
81 1$:
82 ld b, #0
83 push bc ; push argc
84 ; reverse argv order
85 ld e, c
86 srl e
87 jr z, 7$ ; only 1 parameter
88
89 dec c
90 ld ixh, b
91 ld ixl, c
92 add ix, ix
93 ld b, h
94 ld c, l
95 add ix, bc
96 8$:
97 ld d, (hl)
98 ld a, 0 (ix)
99 ld 0 (ix), d
100 ld (hl), a
101 inc hl
102 ld d, (hl)
103 ld a, 1 (ix)
104 ld 1 (ix), d
105 ld (hl), a
106 inc hl
107 dec ix
108 dec ix
109 dec e
110 jr nz, 8$
111 7$:
112 call _main
113 .exit:
114 push hl
115 ld l, #0
116 call _SWITCH_ROM
117 call .restore_int_vector
118 pop hl
119 ld b, l
120 CALL_BDOS #_TERM ; try terminate usind MSX DOS 2 function
121 JP_BDOS #_TERM0
122 _exit::
123 pop hl
124 pop hl
125 jr .exit
126
127 .exit_error:
128 ld hl, #1$
129 push hl
130 call _puts
131 JP_BDOS #_TERM0
132 1$:
133 .asciz "LOAD ERROR!\r\n"
134
135 ;; fills memory at HL of length BC with A, clobbers DE
136 .memset_simple::
137 ld e, a
138 ld a, c
139 or b
140 ret z
141 ld (hl), e
142 dec bc
143 ld d, h
144 ld e, l
145 inc de
146
147 ;; copies BC bytes from HL into DE
148 .memcpy_simple::
149 ld a, c
150 or b
151 ret z
152 ldir
153 ret
154
155 ;; put some internal data here, to save bytes wasted for the alignment of __banks_remap_table
156
157 ___overlay_count::
158 .db 0
159 .overlay_fcb:
160 .db 0 ; drive
161 ___overlay_name::
162 .ascii "OVERLAYS" ; filename
163 .overlay_fcb_ext::
164 .ascii "000" ; extension
165 .overlay_fcb_extent:
166 .db 0 ; extent
167 .db 0 ; attributes
168 .overlay_fcb_record_size:
169 .db 0 ; extent ; msx-dos1: record size low byte
170 .overlay_fbc_record_cont:
171 .db 0 ; record count ; msx-dos1: record size high byte
172 .overlay_fcb_file_size:
173 .db 0, 0, 0, 0 ; file size
174 .db 0, 0, 0, 0 ; volume id
175 .ds 8 ; internal
176 .overlay_fcb_position:
177 .db 0 ; current record within extent
178 .overlay_fcb_random_pos:
179 .db 0, 0, 0, 0 ; Random record number
180 .overlay_fcb_end:
181
182 __memman_present::
183 .db 0
184 __rammapper_table::
185 .dw 0
186
187 .rammapper_hiwater:
188 .db 4 ; 7 segments for 128K config
189 .rammapper_alloc_hiwater:
190 .db 1 ; allocation starts from bank 1
191
192 .mapper_page_alloc::
193 ld hl, #.rammapper_hiwater
194 ld a, (hl)
195 inc (hl)
196 or a ; never fail
197 ret
198
199 _SWITCH_ROM:: ; Z88DK_FASTCALL : uint8_t parameter in l
200 ld a, l
201 ld (__current_bank), a
202 ld h, #>__banks_remap_table
203 ld l, a
204 ld a, (hl)
205 .mapper_page_set:: ; must preserve C
206 out (.MAP_FRAME1), a
207 ret
208
209 .mapper_page_get::
210 in a, (.MAP_FRAME1)
211 __mapper_page_mask = .+1
212 .globl __mapper_page_mask
213 and #0x00 ; zero ram size, will be patched
214 ret
215
216 __current_bank::
217 .db 0
218
219 ; --- 256 byte boundary ---------------------------------------
220
221 .bndry 0x100
222 __banks_remap_table::
223 .ds 100
224 l__banks_remap_table = .-__banks_remap_table
225
226 __mapper_bank_alloc::
227 ld hl, #.rammapper_alloc_hiwater
228 ld a, (hl)
229 inc (hl)
230 ld h, #>__banks_remap_table
231 ld l, a
232 ld a, #0xff
233 cp (hl)
234 jr nz, 1$
235
236 xor a
237 ld b, a
238 push hl
239 call .mapper_page_alloc
240 pop hl
241 ret c ; return if no memory
242 ld (hl), a ; set segment number for the bank number
243 1$:
244 or a
245 ret ; allocated bank returns in l
246
247 .macro TRANSFER_POINTER ofs dest
248 ld hl, #dest
249 ld (hl), #0xc3
250 inc hl
251 ld a, ofs (ix)
252 ld (hl), a
253 inc hl
254 ld a, ofs+1 (ix)
255 ld (hl), a
256 .endm
257
258 .initialize_ram_mapper::
259 ; detect mapper capacity
260 in a, (.MAP_FRAME1)
261 ld e, a
262 xor a
263 out (.MAP_FRAME1), a
264 in a, (.MAP_FRAME1)
265 cpl
266 ld (__mapper_page_mask), a
267 and e
268 ld hl, #__banks_remap_table
269 ld (hl), a
270 inc hl
271 ld (hl), a ; bank 0 == bank 1
272
273 xor a
274 ld de,#0401 ; get routines info table
275 call .EXTBIO
276 ld (__rammapper_table), hl
277
278 xor a
279 ld de, #0x0402 ; populate ram mapper routines table
280 call .EXTBIO
281 or a
282 jr nz, 1$
283 scf
284 ret
285 1$:
286 push hl
287 pop ix
288
289 TRANSFER_POINTER 0x01, .mapper_page_alloc
290 TRANSFER_POINTER 0x1f, .mapper_page_set
291 TRANSFER_POINTER 0x22, .mapper_page_get
292
293 ld a, #1
294 ld (__memman_present), a
295
296 or a ; return ok
297 ret
298
299 ;; Wait for VBL interrupt to be finished
300 .wait_vbl_done::
301 _wait_vbl_done::
302 _vsync::
303 ld a, (_shadow_VDP_R1)
304 and #.R1_DISP_ON
305 ret z
306
307 xor a
308 ld (.vbl_done), a
309 1$:
310 halt
311 ld a, (.vbl_done)
312 or a
313 jr z, 1$
314 ret
315
316 ; --- 256 byte boundary ---------------------------------------
317
318 .bndry 256
319 _shadow_OAM::
320 .ds 0x80
321
322 ;; load overlays, count in A
323 .load_overlays:
324 ld b, a
325 ld a, (__memman_present)
326 or a
327 jr nz, 3$
328 ld a, (__mapper_page_mask)
329 sub #3 ; ram segments used for DOS
330 inc a
331 cp b
332 ret c ; not sufficient ram to load overlays
333 3$:
334 ld c, #1
335 1$:
336 push bc
337 call .load_overlay
338 pop bc
339 ret c ; error loading overlay
340
341 ld a, c
342 cp b
343 jr z, 2$ ; all loaded - return
344
345 inc c ; next overlay
346 ld a, #(l__banks_remap_table - 1)
347 cp c
348 ret c ; more than 99 overlays are not allowed
349
350 jr 1$
351 2$:
352 xor a
353 call _SWITCH_ROM
354 ret
355
356 .load_overlay:
357 push bc
358 call __mapper_bank_alloc
359 pop bc
360 ret c ; no free segments
361
362 call _SWITCH_ROM ; switch bank to l
363
364 ld b, #8
365 xor a
366 1$:
367 rlc c
368 adc a
369 daa
370 djnz 1$
371 ; result in a, max 99 overlays
372 ld c, a
373 ld b, #0x0f
374 ld e, #'0'
375 ld hl, #(.overlay_fcb_ext + 1)
376 rra
377 rra
378 rra
379 rra
380 and b
381 add e
382 ld (hl), a
383 inc hl
384 ld a, c
385 and b
386 add e
387 ld (hl), a
388
389 xor a
390 ld bc, #(.overlay_fcb_end - .overlay_fcb_extent)
391 ld hl, #.overlay_fcb_extent
392 call .memset_simple ; initialize fcb
393
394 ld de, #.overlay_fcb
395 CALL_BDOS #_FOPEN
396 rrca
397 ret c ; file not found
398
399 ld de, #0x4000
400 3$:
401 CALL_BDOS #_SETDTA
402
403 push de
404 ld de, #.overlay_fcb
405 CALL_BDOS #_RDSEQ
406 pop de
407
408 rrca
409 jr c, 2$ ; EOF reached
410
411 ld a, #128
412 ADD_A_REG16 d, e
413
414 ld a, #0xc0
415 cp d
416 jr z, 2$ ; end of page1 reached
417
418 jr 3$
419 2$:
420 ld de, #.overlay_fcb
421 CALL_BDOS #_FCLOSE
422
423 or a ; return ok
424 ret
425
426 .restore_int_vector:
427 ld hl, #__old_int_vector
428 ld de, #.LS_INT_VECTOR
429 jr .restore_ldir
430 .save_int_vector:
431 ld hl, #.LS_INT_VECTOR
432 ld de, #__old_int_vector
433 .restore_ldir:
434 ld bc, #0x0005
435 di
436 ldir
437 ei
438 ret
439
440 .setup_video_mode:
441 di
442 ;; Initialize VDP
443 ld c, #.VDP_CMD
444 ld b, #(.shadow_VDP_end - .shadow_VDP)
445 ld hl,#(.shadow_VDP_end - 1)
446 1$:
447 outd
448 jr 3$ ; delay
449 3$:
450 ld a, b
451 or #.VDP_REG_MASK
452 out (c), a
453
454 ld a, b
455 or a
456 jr nz, 1$
457
458 ei
459 ret
460
461 .shadow_VDP:
462 _shadow_VDP_R0::
463 .db #(.R0_DEFAULT | .R0_SCR_MODE2)
464 _shadow_VDP_R1::
465 .db #(.R1_DEFAULT | .R1_DISP_ON | .R1_IE | .R1_SCR_MODE2 | .R1_SPR_8X8)
466 _shadow_VDP_R2::
467 .db .R2_MAP_0x1C00
468 _shadow_VDP_R3::
469 .db 0xFF ; tiledata attr from 0x2000
470 _shadow_VDP_R4::
471 .db 0x03 ; tiledata from 0x0000
472 _shadow_VDP_R5::
473 .db .R5_SAT_0x1B00
474 _shadow_VDP_R6::
475 .db 0x07
476 _shadow_VDP_R7::
477 _shadow_VDP_RBORDER::
478 .db 0x01
479 .shadow_VDP_end::
480
481 .sys_time::
482 _sys_time::
483 .dw 0x0000
484 .vbl_done::
485 __vbl_done::
486 .db 0
487 __shadow_OAM_base::
488 .db #>_shadow_OAM
489 __shadow_OAM_OFF::
490 .db 0
491 .mode::
492 .ds .T_MODE_INOUT ; Current mode
493 __SYSTEM::
494 .db .SYSTEM_NTSC ; Detection not implemented yet
495 __old_int_vector::
496 .ds 5
497
498 .area _GSINIT
499 .gsinit::
500 ;; initialize static storage
501 xor a
502 ld bc, #l__DATA
503 ld hl, #s__DATA
504 call .memset_simple ; initialize variables in RAM with zero
505
506 ;; initialize static storage variables
507 ld bc, #l__INITIALIZER
508 ld hl, #s__INITIALIZER
509 ld de, #s__INITIALIZED
510 call .memcpy_simple
511
512 ;; initialize ram mapper
513 call .initialize_ram_mapper
514
515 .area _GSFINAL
516 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.