File: condes.s

package info (click to toggle)
cc65 2.19-2
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,268 kB
  • sloc: ansic: 117,151; asm: 66,339; pascal: 4,248; makefile: 1,009; perl: 607
file content (84 lines) | stat: -rw-r--r-- 2,158 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
;
; Ullrich von Bassewitz, 20.11.2000
;
; 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 (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 initlib, donelib, condes

        .import __CONSTRUCTOR_TABLE__, __CONSTRUCTOR_COUNT__
        .import __DESTRUCTOR_TABLE__, __DESTRUCTOR_COUNT__

        .macpack        cpu

; --------------------------------------------------------------------------
; Initialize library modules

.segment        "ONCE"

.proc   initlib

        ldy     #<(__CONSTRUCTOR_COUNT__*2)
        beq     exit
        lda     #<__CONSTRUCTOR_TABLE__
        ldx     #>__CONSTRUCTOR_TABLE__
        jmp     condes
exit:   rts

.endproc


; --------------------------------------------------------------------------
; Cleanup library modules

.code

.proc   donelib

        ldy     #<(__DESTRUCTOR_COUNT__*2)
        beq     exit
        lda     #<__DESTRUCTOR_TABLE__
        ldx     #>__DESTRUCTOR_TABLE__
        jmp     condes
exit:   rts

.endproc


; --------------------------------------------------------------------------
; 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

.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