--- /dev/null
+;
+; Ullrich von Bassewitz, 2004-04-04
+;
+; CC65 runtime: Support for calling special irq routines declared as condes
+; type 2.
+;
+; There are two reasons, why this is a separate routine, and the generic
+; condes routine in condes.s is not used:
+;
+; 1. Speed. Having several things hardcoded makes it faster. This is
+; important if it is called in each interrupt.
+;
+; 2. Reentrancy. The condes routines must use self modyfiying code, which
+; means it is not reentrant. An IRQ using condes, that interrupts
+; another use of condes will cause unpredicatble behaviour. The current
+; code avoids this by using locking mechanisms, but it's complex and
+; has a size and performance penalty.
+;
+; As the normal condes routine, this one has the limitation of 127 table
+; entries.
+;
+
+ .export callirq
+
+ .import __IRQFUNC_TABLE__, __IRQFUNC_COUNT__
+
+.code
+
+; --------------------------------------------------------------------------
+; Call all IRQ routines. The function needs to use self modifying code and
+; is thereforce placed in the data segment.
+; NOTE: The routine must not be called if the table is empty!
+
+.data
+
+.proc callirq
+
+ ldy #.lobyte(__IRQFUNC_COUNT__)
+loop: dey
+ lda __IRQFUNC_TABLE__+1,y
+ sta jmpvec+2 ; Modify code below
+ dey
+ lda __IRQFUNC_TABLE__+0,y
+ sta jmpvec+1 ; Modify code below
+ sty index+1 ; Modify code below
+jmpvec: jsr $FFFF ; Patched at runtime
+index: ldy #$FF ; Patched at runtime
+ bne loop
+ rts
+
+.endproc
+
+
; --------------------------------------------------------------------------
-; Generic table call handler. Since the routine is also used to call a table
-; of interrupt handlers, it uses heavily self modifying code for performance
-; reasons. It will go into the data segment for this reason ...
+; Generic table call handler. The code uses self modifying code and goes
+; into the data segment for this reason.
; NOTE: The routine must not be called if the table is empty!
.data