From e4554505d6f2f3cacc6f14b0c24531ca20f3adbc Mon Sep 17 00:00:00 2001 From: cuz Date: Thu, 25 Mar 2004 07:58:58 +0000 Subject: [PATCH] Optimized the condes routine, because it is used to schedule interrupt handlers on many platforms, so too many cycles are evil. git-svn-id: svn://svn.cc65.org/cc65/trunk@2962 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- libsrc/runtime/condes.s | 77 +++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 46 deletions(-) diff --git a/libsrc/runtime/condes.s b/libsrc/runtime/condes.s index c9e373277..99c4a6b85 100644 --- a/libsrc/runtime/condes.s +++ b/libsrc/runtime/condes.s @@ -4,9 +4,9 @@ ; CC65 runtime: Support for calling module constructors/destructors ; ; The condes routine must be called with the table address in a/x and the -; size of the table in y. The current implementation limits the table size -; to 254 bytes (127 vectors) but this shouldn't be problem for now and may -; be changed later. +; size of the table (which must not be zero!) in y. The current implementation +; limits the table size to 254 bytes (127 vectors) but this shouldn't be +; problem for now and may be changed later. ; ; libinit and libdone call condes with the predefined module constructor and ; destructor tables, they must be called from the platform specific startup @@ -27,11 +27,12 @@ .proc initlib + ldy #<(__CONSTRUCTOR_COUNT__*2) + beq exit lda #<__CONSTRUCTOR_TABLE__ ldx #>__CONSTRUCTOR_TABLE__ - ldy #<(__CONSTRUCTOR_COUNT__*2) - bne condes - rts + jmp condes +exit: rts .endproc @@ -41,57 +42,41 @@ .proc donelib - lda #<__DESTRUCTOR_TABLE__ - ldx #>__DESTRUCTOR_TABLE__ - ldy #<(__DESTRUCTOR_COUNT__*2) - bne condes - rts + ldy #<(__DESTRUCTOR_COUNT__*2) + beq initlib::exit + lda #<__DESTRUCTOR_TABLE__ + ldx #>__DESTRUCTOR_TABLE__ + jmp condes .endproc ; -------------------------------------------------------------------------- -; Generic table call handler. We cannot use callax here, since condes is also -; used for interrupt handlers, and callax clobbers ptr1. +; 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 ... +; NOTE: The routine must not be called if the table is empty! -.proc condes +.data - sta getbyt+1 - stx getbyt+2 - sty index +.proc condes -loop: ldy index - beq done - dey - jsr getbyt + sta fetch1+1 + stx fetch1+2 + sta fetch2+1 + stx fetch2+2 +loop: dey +fetch1: lda $FFFF,y ; Patched at runtime sta jmpvec+2 - dey - jsr getbyt + dey +fetch2: lda $FFFF,y ; Patched at runtime sta jmpvec+1 - sty index - jsr jmpvec -.if (.cpu .bitand ::CPU_ISET_65SC02) - bra loop -.else - jmp loop -.endif - -done: rts + sty index+1 +jmpvec: jsr $FFFF ; Patched at runtime +index: ldy #$FF ; Patched at runtime + bne loop + rts .endproc -; -------------------------------------------------------------------------- -; Data. The getbyte and jmpvec routines are placed in the data segment -; cause they're patched at runtime. - -.bss - -index: .byte 0 - -.data - -getbyt: lda $FFFF,y - rts - -jmpvec: jmp $0000 -- 2.39.5