crt0.s (11082B)
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) 533$: 54 ld a, (hl) 55 or a 56 jr z, 6$ 57 cp #0x20 58 jr nz, 6$ 59 inc hl 60 jr 3$ 616$: 62 jr z, 2$ 63 64 inc c 65 push hl 664$: 67 inc hl 68 ld a, (hl) 69 or a 70 jr z, 2$ 71 cp #0x20 72 jr nz, 4$ 735$: 74 ld (hl), #0 75 inc hl 76 jr 3$ 772$: 78 ld hl, #0 79 add hl, sp 80 push hl ; push pointer to argv array on stack 811$: 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 968$: 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$ 1117$: 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 1321$: 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:: 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 224l__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 2431$: 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 2851$: 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 ld a, (_shadow_VDP_R1) 303 and #.R1_DISP_ON 304 ret z 305 306 xor a 307 ld (.vbl_done), a 3081$: 309 halt 310 ld a, (.vbl_done) 311 or a 312 jr z, 1$ 313 ret 314 315; --- 256 byte boundary --------------------------------------- 316 317 .bndry 256 318_shadow_OAM:: 319 .ds 0x80 320 321 ;; load overlays, count in A 322.load_overlays: 323 ld b, a 324 ld a, (__memman_present) 325 or a 326 jr nz, 3$ 327 ld a, (__mapper_page_mask) 328 sub #3 ; ram segments used for DOS 329 inc a 330 cp b 331 ret c ; not sufficient ram to load overlays 3323$: 333 ld c, #1 3341$: 335 push bc 336 call .load_overlay 337 pop bc 338 ret c ; error loading overlay 339 340 ld a, c 341 cp b 342 jr z, 2$ ; all loaded - return 343 344 inc c ; next overlay 345 ld a, #(l__banks_remap_table - 1) 346 cp c 347 ret c ; more than 99 overlays are not allowed 348 349 jr 1$ 3502$: 351 xor a 352 call _SWITCH_ROM 353 ret 354 355.load_overlay: 356 push bc 357 call __mapper_bank_alloc 358 pop bc 359 ret c ; no free segments 360 361 call _SWITCH_ROM ; switch bank to l 362 363 ld b, #8 364 xor a 3651$: 366 rlc c 367 adc a 368 daa 369 djnz 1$ 370 ; result in a, max 99 overlays 371 ld c, a 372 ld b, #0x0f 373 ld e, #'0' 374 ld hl, #(.overlay_fcb_ext + 1) 375 rra 376 rra 377 rra 378 rra 379 and b 380 add e 381 ld (hl), a 382 inc hl 383 ld a, c 384 and b 385 add e 386 ld (hl), a 387 388 xor a 389 ld bc, #(.overlay_fcb_end - .overlay_fcb_extent) 390 ld hl, #.overlay_fcb_extent 391 call .memset_simple ; initialize fcb 392 393 ld de, #.overlay_fcb 394 CALL_BDOS #_FOPEN 395 rrca 396 ret c ; file not found 397 398 ld de, #0x4000 3993$: 400 CALL_BDOS #_SETDTA 401 402 push de 403 ld de, #.overlay_fcb 404 CALL_BDOS #_RDSEQ 405 pop de 406 407 rrca 408 jr c, 2$ ; EOF reached 409 410 ld a, #128 411 ADD_A_REG16 d, e 412 413 ld a, #0xc0 414 cp d 415 jr z, 2$ ; end of page1 reached 416 417 jr 3$ 4182$: 419 ld de, #.overlay_fcb 420 CALL_BDOS #_FCLOSE 421 422 or a ; return ok 423 ret 424 425.restore_int_vector: 426 ld hl, #__old_int_vector 427 ld de, #.LS_INT_VECTOR 428 jr .restore_ldir 429.save_int_vector: 430 ld hl, #.LS_INT_VECTOR 431 ld de, #__old_int_vector 432.restore_ldir: 433 ld bc, #0x0005 434 ld a, i 435 push af 436 di 437 ldir 438 pop af 439 jp po, 1$ 440 ei 4411$: 442 ret 443 444.setup_video_mode: 445 ld a, i 446 push af 447 di 448 ;; Initialize VDP 449 ld c, #.VDP_CMD 450 ld b, #(.shadow_VDP_end - .shadow_VDP) 451 ld hl,#(.shadow_VDP_end - 1) 4521$: 453 outd 454 jr 3$ ; delay 4553$: 456 ld a, b 457 or #.VDP_REG_MASK 458 out (c), a 459 460 ld a, b 461 or a 462 jr nz, 1$ 463 464 pop af 465 jp po, 2$ 466 ei 4672$: 468 ret 469 470.shadow_VDP: 471_shadow_VDP_R0:: 472 .db #(.R0_DEFAULT | .R0_SCR_MODE2) 473_shadow_VDP_R1:: 474 .db #(.R1_DEFAULT | .R1_DISP_ON | .R1_IE | .R1_SCR_MODE2 | .R1_SPR_8X8) 475_shadow_VDP_R2:: 476 .db .R2_MAP_0x1C00 477_shadow_VDP_R3:: 478 .db 0xFF ; tiledata attr from 0x2000 479_shadow_VDP_R4:: 480 .db 0x03 ; tiledata from 0x0000 481_shadow_VDP_R5:: 482 .db .R5_SAT_0x1B00 483_shadow_VDP_R6:: 484 .db 0x07 485_shadow_VDP_R7:: 486_shadow_VDP_RBORDER:: 487 .db 0x01 488.shadow_VDP_end:: 489 490.sys_time:: 491_sys_time:: 492 .dw 0x0000 493.vbl_done:: 494 .db 0 495__shadow_OAM_base:: 496 .db #>_shadow_OAM 497__shadow_OAM_OFF:: 498 .db 0 499.mode:: 500 .ds .T_MODE_INOUT ; Current mode 501__old_int_vector:: 502 .ds 5 503 504 .area _GSINIT 505.gsinit:: 506 ;; initialize static storage 507 xor a 508 ld bc, #l__DATA 509 ld hl, #s__DATA 510 call .memset_simple ; initialize variables in RAM with zero 511 512 ;; initialize static storage variables 513 ld bc, #l__INITIALIZER 514 ld hl, #s__INITIALIZER 515 ld de, #s__INITIALIZED 516 call .memcpy_simple 517 518 ;; initialize ram mapper 519 call .initialize_ram_mapper 520 521 .area _GSFINAL 522 ret