-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinterrupt.s
More file actions
119 lines (85 loc) · 2.42 KB
/
interrupt.s
File metadata and controls
119 lines (85 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
;
; 2012-01-18, Oliver Schmidt
; 2015-08-22, Greg King
;
; void __fastcall__ set_irq (irq_handler f, void *stack_addr, size_t stack_size);
; void reset_irq (void);
;
.export _set_irq, _reset_irq
.interruptor clevel_irq, 1 ; Export as low priority IRQ handler
.import popax, __ZP_START__, jmpvec
.include "zeropage.inc"
.macpack generic
; ---------------------------------------------------------------------------
.data
irqvec: jmp $00FF ; Patched at runtime
; ---------------------------------------------------------------------------
.bss
irqsp: .res 2
zpsave: .res zpsavespace
; ---------------------------------------------------------------------------
.code
.proc _set_irq
; Keep clevel_irq from being called right now
sei
; Set irq stack pointer to stack_addr + stack_size
sta irqsp
stx irqsp+1
jsr popax
add irqsp
sta irqsp
txa
adc irqsp+1
sta irqsp+1
; Set irq vector to irq_handler
jsr popax
sta irqvec+1
stx irqvec+2 ; Set the user vector
; Restore interrupt requests and return
cli
rts
.endproc
.proc _reset_irq
lda #$00
sta irqvec+2 ; High byte is enough
rts
.endproc
.proc clevel_irq
; Is C level interrupt request vector set?
lda irqvec+2 ; High byte is enough
bne @L1
clc ; Interrupt not handled
rts
; Save our zero page locations
@L1: ldx #.sizeof(::zpsave)-1
@L2: lda <__ZP_START__,x
sta zpsave,x
dex
bpl @L2
; Save jmpvec
lda jmpvec+1
pha
lda jmpvec+2
pha
; Set C level interrupt stack
lda irqsp
ldx irqsp+1
sta sp
stx sp+1
; Call C level interrupt request handler
jsr irqvec
; Mark interrupt handled / not handled
lsr
; Restore our zero page content
ldx #.sizeof(::zpsave)-1
@L3: lda zpsave,x
sta <__ZP_START__,x
dex
bpl @L3
; Restore jmpvec and return
pla
sta jmpvec+2
pla
sta jmpvec+1
rts
.endproc