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/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.