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