crt0.s (5810B)
1 .include "global.s" 2 3 .title "Runtime" 4 .module Runtime 5 .area _HEADER (ABS) 6 7 .globl _set_default_palette 8 9 .org 0x00 ; Reset 00h 10 di ; disable interrupt 11 im 1 ; interrupt mode 1 (this won't change) 12 jp .init 13 14; .org 0x08 ; --profile handler 15 16 .org 0x10 ; RST 0x10: VDP_WRITE_CMD 17 18_WRITE_VDP_CMD:: 19 VDP_WRITE_CMD h, l 20 ret 21 22; .org 0x18 ; unusable 23 24 .org 0x20 ; RST 0x20: VDP_WRITE_DATA 25 26_WRITE_VDP_DATA:: 27 VDP_WRITE_DATA h, l 28 ret 29 30; .org 0x28 ; unusable 31 32 .org 0x30 ; RST 0x30: call HL 33.call_hl:: 34 jp (HL) 35 36 .org 0x38 ; handle IRQ 37 jp _INT_ISR 38 39 .org 0x66 ; handle NMI 40 jp _NMI_ISR 41 42 .org 0x80 43 44.init:: 45 ld sp, #.STACK ; set stack pointer at end of RAM 46 47 ld a, (#.BIOS) 48 push af 49 50 xor a 51 ld bc, #l__DATA 52 ld hl, #s__DATA 53 call .memset_simple ; initialize veriables in RAM with zero 54 55 pop af 56 ld (#__BIOS), a ; save BIOS value 57 58 ld hl, #_shadow_OAM 59 ld de, #(_shadow_OAM + 1) 60 ld bc, #64 61 ld (hl), #0xc0 62 ldir 63 ld (hl), #0 64 ld bc, #(128 - 1) 65 ldir 66 67 ld hl,#0x0000 ; initialize mappers 68 ld (#.RAM_CONTROL),hl ; [.RAM_CONTROL]=$00, [.MAP_FRAME0]=$00 69 ld hl,#0x0201 70 ld (#.MAP_FRAME1),hl ; [.MAP_FRAME1]=$01, [.MAP_FRAME2]=$02 71 72 ;; Initialise global variables 73 call .gsinit 74 75 ;; Initialize VDP 76 ld c, #.VDP_CMD 77 ld b, #(.shadow_VDP_end - .shadow_VDP) 78 ld hl,#(.shadow_VDP_end - 1) 791$: 80 outd 81 82 ld a, b 83 or #.VDP_REG_MASK 84 out (c), a 85 86 ld a, b 87 or a 88 jr nz, 1$ 89 90 ;; detect PAL/NTSC 91 ld c, #.VDP_VCOUNTER 922$: in a, (c) 93 cp #0x80 94 jr nz, 2$ 953$: ld b, a 96 in a, (c) 97 cp b 98 jr nc, 3$ 99 100 ld a, b 101 cp #0xE8 102 ld a, #.SYSTEM_NTSC 103 jr c, 4$ 104 ld a, #.SYSTEM_PAL 1054$: 106 ld (#__SYSTEM), a 107 108 call .clear_VRAM 109 110 call _set_default_palette 111 112 VDP_CANCEL_INT 113 114 ei ; re-enable interrupts before going to main() 115 call _main 11610$: 117 halt 118 jr 10$ 119 120 ;; Ordering of segments for the linker. 121 .area _HOME 122 .area _BASE 123 .area _CODE 124 .area _CODE_0 125 .area _LIT 126 .area _INITIALIZER 127 .area _GSINIT 128 .area _GSFINAL 129 130 .area _DATA 131 .area _INITIALIZED 132 .area _BSEG 133 .area _BSS 134 .area _HEAP 135 .area _HEAP_END 136 137 .area _CODE 138 .area _GSINIT 139.gsinit:: 140 ;; initialize static storage variables 141 ld bc, #l__INITIALIZER 142 ld hl, #s__INITIALIZER 143 ld de, #s__INITIALIZED 144 call .memcpy_simple 145 146 .area _GSFINAL 147 ret 148 149 .area _HOME 150 151.clear_VRAM: 152 ld a, #<.VDP_VRAM 153 out (#.VDP_CMD), a 154 ld a, #>.VDP_VRAM 155 out (#.VDP_CMD), a 156 xor a 157 ld bc, #0x4101 158 jr 6$ 1595$: 160 out (.VDP_DATA), a 1616$: 162 dec c 163 jr nz, 5$ 164 dec b 165 jr nz, 5$ 166 ret 167 168 ;; fills memory at HL of length BC with A, clobbers DE 169.memset_simple:: 170 ld e, a 171 ld a, c 172 or b 173 ret z 174 ld (hl), e 175 dec bc 176 ld d, h 177 ld e, l 178 inc de 179 180 ;; copies BC bytes from HL into DE 181.memcpy_simple:: 182 ld a, c 183 or b 184 ret z 185 ldir 186 ret 187 188 ;; Wait for VBL interrupt to be finished 189.wait_vbl_done:: 190_wait_vbl_done:: 191 ld a, (_shadow_VDP_R1) 192 and #.R1_DISP_ON 193 ret z 194 195 xor a 196 ld (.vbl_done), a 1971$: 198 halt 199 ld a, (.vbl_done) 200 or a 201 jr z, 1$ 202 ret 203 204 .area _DATA 205 206.start_crt_globals: 207__BIOS:: 208 .ds 0x01 ; GB type (GB, PGB, CGB) 209__SYSTEM:: 210 .ds 0x01 ; PAL/NTSC 211.end_crt_globals: 212 213 .area _INITIALIZED 214.shadow_VDP: 215_shadow_VDP_R0:: 216 .ds 0x01 217_shadow_VDP_R1:: 218 .ds 0x01 219_shadow_VDP_R2:: 220 .ds 0x01 221_shadow_VDP_R3:: 222 .ds 0x01 223_shadow_VDP_R4:: 224 .ds 0x01 225_shadow_VDP_R5:: 226 .ds 0x01 227_shadow_VDP_R6:: 228 .ds 0x01 229_shadow_VDP_R7:: 230_shadow_VDP_RBORDER:: 231 .ds 0x01 232_shadow_VDP_R8:: 233_shadow_VDP_RSCX:: 234 .ds 0x01 235_shadow_VDP_R9:: 236_shadow_VDP_RSCY:: 237 .ds 0x01 238_shadow_VDP_R10:: 239 .ds 0x01 240.shadow_VDP_end:: 241 242.sys_time:: 243_sys_time:: 244 .ds 0x02 245.vbl_done:: 246 .ds 0x01 247_VDP_ATTR_SHIFT:: 248.vdp_shift:: 249 .ds 0x01 250__shadow_OAM_base:: 251 .ds 0x01 252__shadow_OAM_OFF:: 253 .ds 0x01 254.mode:: 255 .ds 0x01 ; Current mode 256 257 .area _INITIALIZER 258 259 .db .R0_DEFAULT 260 .db #(.R1_DEFAULT | .R1_DISP_ON | .R1_IE) ; VBLANK 261 .db .R2_MAP_0x3800 262 .db 0xFF 263 .db 0xFF 264 .db .R5_SAT_0x3F00 265 .db .R6_DATA_0x2000 266 .db #(0 | .R7_COLOR_MASK) 267 .db 0 ; SCX 268 .db 0 ; SCY 269 .db .R10_INT_OFF 270 .dw 0x0000 ; .sys_time 271 .db 0 ; .vbl_done 272 .db 0 ; _VDP_ATTR_SHIFT 273 .db #>_shadow_OAM ; __shadow_OAM_base 274 .db 0 ; __shadow_OAM_OFF 275 .db .T_MODE_INOUT ; .mode