cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

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