2
2
; Title: BBC Basic for AGON - Interrupts
3
3
; Author: Dean Belfield
4
4
; Created: 06/05/2022
5
- ; Last Updated: 06/05/2022
5
+ ; Last Updated: 23/03/2023
6
6
;
7
7
; Modinfo:
8
+ ; 23/03/2023: Added VBLANK_INIT and VBLANK_HANDLER
8
9
9
10
.ASSUME ADL = 0
10
11
12
+ INCLUDE "macros.inc"
11
13
INCLUDE "equs.inc"
14
+ INCLUDE "mos_api.inc" ; In MOS/src
12
15
13
16
SEGMENT CODE
14
17
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
31
37
RET
32
-
33
- .ASSUME ADL = 1
34
38
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
35
60
61
+ ;
36
62
; Interrupts in mixed mode always run in ADL mode
37
63
;
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
40
78
0 commit comments