]> git.sur5r.net Git - cc65/blob - libsrc/common/interrupt.s
Merge pull request #369 from groessler/something_to_pull
[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__
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         ; Set C level interrupt stack
88         lda     irqsp
89         ldx     irqsp+1
90         sta     sp
91         stx     sp+1
92
93         ; Call C level interrupt request handler
94         jsr     irqvec
95
96         ; Copy back our zero page content
97         ldx     #.sizeof(::zpsave)-1
98 @L3:    ldy     zpsave,x
99         sty     <__ZP_START__,x
100         dex
101         bpl     @L3
102
103         ; Mark interrupt handled / not handled and return
104         lsr
105         rts
106
107 .endproc