]> git.sur5r.net Git - cc65/blob - libsrc/runtime/callirq.s
Fixed _textcolor definition.
[cc65] / libsrc / runtime / callirq.s
1 ;
2 ; Ullrich von Bassewitz, 2004-04-04
3 ;
4 ; CC65 runtime: Support for calling special irq routines declared as condes
5 ; type 2.
6 ;
7 ; There are two reasons, why this is a separate routine, and the generic
8 ; condes routine in condes.s is not used:
9 ;
10 ;   1. Speed. Having several things hardcoded makes it faster. This is
11 ;      important if it is called in each interrupt.
12 ;
13 ;   2. Reentrancy. The condes routines must use self modyfiying code, which
14 ;      means it is not reentrant. An IRQ using condes, that interrupts
15 ;      another use of condes will cause unpredicatble behaviour. The current
16 ;      code avoids this by using locking mechanisms, but it's complex and
17 ;      has a size and performance penalty.
18 ;
19 ;   3. Special semantics: An interruptor called by callirq must tell by
20 ;      setting or resetting the carry flag if the interrupt has been handled
21 ;      (which means that the interrupt is no longer active at the interrupt
22 ;      source). callirq will call no other interruptors if this happens. To
23 ;      simplify code, all interrupt routines will be called with carry clear
24 ;      on entry.
25 ;
26 ; As the normal condes routine, this one has the limitation of 127 table
27 ; entries.
28 ;
29
30         .export         callirq
31         .export         callirq_y       ; Same but with Y preloaded
32         .export         __CALLIRQ__ : absolute = 1
33         .constructor    irq_init, 10
34         .destructor     irq_done, 10
35
36         .import         __INTERRUPTOR_TABLE__, __INTERRUPTOR_COUNT__
37         .import         initirq
38         .import         doneirq
39
40         irq_init :=     initirq
41         irq_done :=     doneirq
42
43 ; --------------------------------------------------------------------------
44 ; Call all IRQ routines. The function needs to use self modifying code and
45 ; is thereforce placed in the data segment. It will return carry set if the
46 ; interrupt was handled and carry clear if not. The caller may choose to
47 ; ignore this at will.
48 ; NOTE: The routine must not be called if the table is empty!
49
50 .data
51
52 callirq:
53         ldy     #.lobyte(__INTERRUPTOR_COUNT__*2)
54 callirq_y:
55         clc                             ; Preset carry flag
56 loop:   dey
57         lda     __INTERRUPTOR_TABLE__,y
58         sta     jmpvec+2                ; Modify code below
59         dey
60         lda     __INTERRUPTOR_TABLE__,y
61         sta     jmpvec+1                ; Modify code below
62         sty     index+1                 ; Modify code below
63 jmpvec: jsr     $FFFF                   ; Patched at runtime
64         bcs     done                    ; Bail out if interrupt handled
65 index:  ldy     #$FF                    ; Patched at runtime
66         bne     loop
67 done:   rts