From 526b10147d909af14f277fcb624e97d929086b21 Mon Sep 17 00:00:00 2001 From: cuz Date: Sun, 4 Apr 2004 14:15:45 +0000 Subject: [PATCH] Added a specialized callirq routine git-svn-id: svn://svn.cc65.org/cc65/trunk@2968 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- libsrc/runtime/Makefile | 1 + libsrc/runtime/callirq.s | 53 ++++++++++++++++++++++++++++++++++++++++ libsrc/runtime/condes.s | 5 ++-- 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 libsrc/runtime/callirq.s diff --git a/libsrc/runtime/Makefile b/libsrc/runtime/Makefile index 6226d3521..b42a5bba9 100644 --- a/libsrc/runtime/Makefile +++ b/libsrc/runtime/Makefile @@ -41,6 +41,7 @@ OBJS = add.o \ bneg.o \ bpushbsp.o \ call.o \ + callirq.o \ callmain.o \ compl.o \ condes.o \ diff --git a/libsrc/runtime/callirq.s b/libsrc/runtime/callirq.s new file mode 100644 index 000000000..9254d71b8 --- /dev/null +++ b/libsrc/runtime/callirq.s @@ -0,0 +1,53 @@ +; +; 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 + + diff --git a/libsrc/runtime/condes.s b/libsrc/runtime/condes.s index 99c4a6b85..2a2692a7b 100644 --- a/libsrc/runtime/condes.s +++ b/libsrc/runtime/condes.s @@ -52,9 +52,8 @@ exit: rts ; -------------------------------------------------------------------------- -; 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