git.y1.nz

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.