]> git.sur5r.net Git - cc65/blobdiff - libsrc/runtime/condes.s
Optimized the condes routine, because it is used to schedule interrupt
[cc65] / libsrc / runtime / condes.s
index 099c3e4bf8049fd992c85fb79bfef6f5d4598329..99c4a6b85d312b5c7e1424e70c538a39061b8a8d 100644 (file)
@@ -4,44 +4,79 @@
 ; CC65 runtime: Support for calling module constructors/destructors
 ;
 ; The condes routine must be called with the table address in a/x and the
-; number of vectors in the table in y. The current implementation limits
-; the table size to 128 bytes (64 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
+; code.
 
-               .export condes
-               .import jmpvec
+
+               .export initlib, donelib, condes
+
+               .import __CONSTRUCTOR_TABLE__, __CONSTRUCTOR_COUNT__
+       .import __DESTRUCTOR_TABLE__, __DESTRUCTOR_COUNT__
+
+        .macpack        cpu
 
 .code
 
-condes:        sta     getbyt+1
-       stx     getbyt+2
-       sty     index
+; --------------------------------------------------------------------------
+; Initialize library modules
 
-loop:  ldy     index
-       beq     done
-       dey
-       jsr     getbyt
-       sta     jmpvec+2
-       dey
-       jsr     getbyt
-       sta     jmpvec+1
-       sty     index
-       jsr     jmpvec
-       jmp     loop
+.proc  initlib
+
+       ldy     #<(__CONSTRUCTOR_COUNT__*2)
+               beq     exit
+       lda     #<__CONSTRUCTOR_TABLE__
+       ldx     #>__CONSTRUCTOR_TABLE__
+        jmp     condes
+exit:   rts
+
+.endproc
 
-done:  rts
 
 ; --------------------------------------------------------------------------
-; Data. The getbyte routine is placed in the data segment cause it's patched
-; at runtime.
+; Cleanup library modules
+
+.proc  donelib
 
-.bss
+       ldy     #<(__DESTRUCTOR_COUNT__*2)
+       beq     initlib::exit
+       lda     #<__DESTRUCTOR_TABLE__
+       ldx     #>__DESTRUCTOR_TABLE__
+       jmp     condes
 
-index: .byte   0
+.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 ...
+; NOTE: The routine must not be called if the table is empty!
 
 .data
 
-getbyt:        lda     $FFFF,y
-       rts
+.proc  condes
+
+       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
+fetch2: lda     $FFFF,y                 ; Patched at runtime
+        sta     jmpvec+1
+               sty     index+1
+jmpvec: jsr            $FFFF                   ; Patched at runtime
+index:         ldy     #$FF                    ; Patched at runtime
+               bne     loop
+        rts
+
+.endproc
+