This is done by having 4 bytes of self modifying code in wram.
It offers enough space for a call and a reti instruction.
Currently it is simply hard-set to the default handler, but if a custom handler is ever needed
it can be put there.
; vblank 0x40
;=============
vec_vblank:
- call vblank
+ jp vblank_jp
reti
.fill 0, 0x48 - $
xor a, a
ld [unit_sprite], a
ret
+
+ ; writes default vblank jmp vector
+setup_vblank_jp_smc:
+ ld hl, vblank_jp
+
+ ; write instruction
+ ld a, 0xCD ; call
+ ld [hl+], a
+
+ ; write address
+ ld a, vblank LO
+ ld [hl+], a
+ ld a, vblank HI
+ ld [hl+], a
+
+ ; write reti
+ ld a, 0xD9 ; reti
+ ld [hl], a
+ ret
ld bc, 1024
ld d, UI_WINDOW_BACKGROUND
call memset
+
+ ; setup vblank jp
+ call setup_vblank_jp_smc
ret
; status text buffer
status_text: .adv 32
+ ; self modifying code
+ ; the vblank interrupt jumps here
+ ; this should be enough memory for
+ ; a jp + address
+ ; and a reti instruction
+vblank_jp: .adv 4
+
; ptr to demo inputs
; provides one byte of inputs per frame
; if all buttons are held (value is 0xFF) it indicates the end