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