22; Title: BBC Basic for AGON - Interrupts
33; Author: Dean Belfield
44; Created: 06/05/2022
5- ; Last Updated: 06/05/2022
5+ ; Last Updated: 23/03/2023
66;
77; Modinfo:
8+ ; 23/03/2023: Added VBLANK_INIT and VBLANK_HANDLER
89
910 .ASSUME ADL = 0
1011
12+ INCLUDE "macros.inc"
1113 INCLUDE "equs.inc"
14+ INCLUDE "mos_api.inc" ; In MOS/src
1215
1316 SEGMENT CODE
1417
15- XDEF INIT_IM2
16-
17- ; Initialise IM2
18- ; HL: Address of vector table (must be on page boundary)
19- ;
20- INIT_IM2: DI
21- LD DE , INV_DUMMY
22- LD L , 0
23- $$: LD (HL) , E
24- INC L
25- LD (HL) , D
26- INC L
27- JR NZ , $ B
28- LD A , H
29- IM 2 ; Set the interrupt mode
30- LD I , A
18+ XDEF VBLANK_INIT
19+ XDEF VBLANK_HANDLER
20+
21+ XREF ESCSET
22+ XREF KEYDOWN ; In ram.asm
23+ XREF KEYASCII ; In ram.asm
24+
25+ ; Hook into the MOS VBLANK interrupt
26+ ;
27+ VBLANK_INIT: DI
28+ LD E , 32h ; Set up the VBLANK interrupt
29+ LD HL , VBLANK_HANDLER
30+ MOSCALL mos_setintvector
31+ EX DE , HL ; DEU: Address of previous interrupt handler
32+ LD HL , VBLANK_HANDLER_JP + 1 ; This is a 16-bit address within this segment
33+ LD A , MB ; Get the current segment
34+ CALL SET_AHL16 ; Convert to an absolute 24-bit address
35+ LD.LIL (HL) , DE ; Self-modify the code
36+ EI
3137 RET
32-
33- .ASSUME ADL = 1
3438
39+ ; Set the MSB of HL (U) to A
40+ ;
41+ SET_AHL16: PUSH .LIL HL
42+ LD.LIL HL , 2
43+ ADD .LIL HL , SP
44+ LD.LIL (HL) , A
45+ POP .LIL HL
46+ RET
47+
48+ ; A safe LIS call to ESCSET
49+ ;
50+ DO_KEYBOARD: MOSCALL mos_sysvars ; Get the system variables
51+ LD.LIL A , (IX + sysvar_vkeydown) ; Fetch key down value (1 = key down, 0 = key up)
52+ LD (KEYDOWN) , A ; Store locally
53+ OR A
54+ JR Z , $ F ; If it is key up, then skip to next bit
55+ LD.LIL A , (IX + sysvar_keyascii) ; Fetch key ASCII value
56+ $$: LD (KEYASCII) , A ; Store locally
57+ CP 1Bh ; Is it escape?
58+ CALL Z , ESCSET ; Yes, so set the escape flags
59+ RET .LIS ; Return to the interrupt handler
3560
61+ ;
3662; Interrupts in mixed mode always run in ADL mode
3763;
38- INV_DUMMY: EI
39- RETI.L
64+ .ASSUME ADL = 1
65+
66+ VBLANK_HANDLER: DI
67+ PUSH AF
68+ PUSH IX
69+ CALL .LIS DO_KEYBOARD
70+ POP IX
71+ POP AF
72+ ;
73+ ; Finally jump to the MOS interrupt
74+ ;
75+ VBLANK_HANDLER_JP: JP 0 ; This is self-modified by VBLANK_INIT
76+
77+ .ASSUME ADL = 0
4078
0 commit comments