sms_int.s (3931B)
1 .include "global.s" 2 3 .title "INT Handler" 4 .module INTHandler 5 6 .globl .sys_time, .vbl_done 7 .globl .OUTI128, .OUTI64, __shadow_OAM_base 8 9 .area _HOME 10 11_INT_ISR:: 12 push af 13 push bc 14 push de 15 push hl 16 push iy 17 push ix 18 19 in a, (.VDP_STAT) 20 and #.STATF_INT_VBL 21 jp z, 2$ 22 ;; handle VBlank 23 24 ld hl, (.sys_time) 25 inc hl 26 ld (.sys_time), hl 27 28 ld a, #1 29 ld (.vbl_done), a 30 31 ;; transfer shadow OAM 32 ld a, (__shadow_OAM_OFF) ; check transfer is OFF 33 or a 34 jp nz, 1$ 35 ld hl, #__shadow_OAM_base 36 ld h, (hl) 37 ld l, a ; a == 0 here 38 or h 39 jp z, 1$ 40 41 ld c, #.VDP_CMD 42 ld a, #<.VDP_SAT 43 out (c), a 44 ld a, #>.VDP_SAT 45 out (c), a 46 dec c ; c == .VDP_DATA 47 call .OUTI64 48 inc c ; c == .VDP_CMD 49 ld a, #<(.VDP_SAT + 0x80) 50 out (c), a 51 ld a, #>(.VDP_SAT + 0x80) 52 out (c), a 53 dec c ; c == .VDP_DATA 54 call .OUTI128 551$: 56 57 ;; call user-defined VBlank handlers 58 ld hl, (.VBLANK_HANDLER0) 59 ld a, h 60 or l 61 jp z, 3$ 62 CALL_HL 63 64 ld hl, (.VBLANK_HANDLER1) 65 ld a, h 66 or l 67 jp z, 3$ 68 CALL_HL 69 70 ld hl, (.VBLANK_HANDLER2) 71 ld a, h 72 or l 73 jp z, 3$ 74 CALL_HL 75 jp 3$ 76 77 ;; handle HBlank 782$: 79 ld hl, (.HBLANK_HANDLER0) 80 CALL_HL 81 823$: 83 pop ix 84 pop iy 85 pop hl 86 pop de 87 pop bc 88 pop af 89 ei 90 reti 91 92; void remove_LCD (int_handler h) __z88dk_fastcall __preserves_regs(b, c, iyh, iyl); 93_remove_LCD:: 94.remove_LCD:: 95 ld hl, #.empty_function 96 97; void add_LCD (int_handler h) __z88dk_fastcall __preserves_regs(b, c, iyh, iyl); 98_add_LCD:: 99.add_LCD:: 100 ld (.HBLANK_HANDLER0), hl 101 ret 102 103; void add_VBL(int_handler h) __z88dk_fastcall __preserves_regs(d, e, iyh, iyl); 104_add_VBL:: 105 ld b, h 106 ld c, l 107 108.add_VBL:: 109 ld hl, #.VBLANK_HANDLER0 110 111 ;; Add interrupt routine in BC to the interrupt list in HL 112.add_int:: 1131$: 114 ld a, (hl) 115 inc hl 116 or (hl) 117 jr z, 2$ 118 inc hl 119 jr 1$ 1202$: 121 ld (hl), b 122 dec hl 123 ld (hl), c 124 ret 125 126; void remove_VBL(int_handler h) __z88dk_fastcall __preserves_regs(iyh, iyl); 127_remove_VBL:: 128 ld b, h 129 ld c, l 130 131 ;; Remove interrupt routine in BC from the VBL interrupt list 132 ;; falldown to .remove_int 133.remove_VBL:: 134 ld hl, #.VBLANK_HANDLER0 135 136 ;; Remove interrupt BC from interrupt list HL if it exists 137 ;; Abort if a 0000 is found (end of list) 138.remove_int:: 1391$: 140 ld e, (hl) 141 inc hl 142 ld d, (hl) 143 inc hl 144 ld a, e 145 or d 146 ret z ; No interrupt found 147 148 ld a, e 149 cp c 150 jr nz, 1$ 151 152 ld a, d 153 cp b 154 jr nz, 1$ 155 156 ld d, h 157 ld e, l 158 dec de 159 dec de 160 161 ;; Now do a memcpy from here until the end of the list 1622$: 163 ld a, (hl) 164 ldi 165 or (hl) 166 ldi 167 jr nz, 2$ 168 ret 169 170_remove_TIM:: 171_remove_SIO:: 172_remove_JOY:: 173_add_TIM:: 174_add_SIO:: 175_add_JOY:: 176.empty_function: 177 ret 178 179 .area _INITIALIZED 180 181.HBLANK_HANDLER0: 182 .ds 0x02 183.VBLANK_HANDLER0: 184 .ds 0x02 185.VBLANK_HANDLER1: 186 .ds 0x02 187.VBLANK_HANDLER2: 188 .ds 0x02 189 .ds 0x02 190 191 .area _INITIALIZER 192 193 .dw .empty_function 194 .dw 0x0000 195 .dw 0x0000 196 .dw 0x0000 197 .dw 0x0000