]> git.sur5r.net Git - cc65/blob - libsrc/c64/crt0.s
Added an interrupt facility similar to that on the C128 and Plus/4
[cc65] / libsrc / c64 / crt0.s
1 ;
2 ; Startup code for cc65 (C64 version)
3 ;
4 ; This must be the *first* file on the linker command line
5 ;
6
7         .export         _exit
8         .import         initlib, donelib, condes
9         .import         zerobss, push0
10         .import         callmain
11         .import         RESTOR, BSOUT, CLRCH
12         .import         __IRQFUNC_TABLE__, __IRQFUNC_COUNT__
13         .import         __RAM_START__, __RAM_SIZE__     ; Linker generated
14
15         .include        "zeropage.inc"
16         .include        "c64.inc"
17
18
19 ; ------------------------------------------------------------------------
20 ; Place the startup code in a special segment.
21
22 .segment        "STARTUP"
23
24 ; BASIC header with a SYS call
25
26         .word   Head            ; Load address
27 Head:   .word   @Next
28         .word   .version        ; Line number
29         .byte   $9E,"2061"      ; SYS 2061
30         .byte   $00             ; End of BASIC line
31 @Next:  .word   0               ; BASIC end marker
32
33 ; ------------------------------------------------------------------------
34 ; Actual code
35
36         ldx     #zpspace-1
37 L1:     lda     sp,x
38         sta     zpsave,x        ; Save the zero page locations we need
39         dex
40         bpl     L1
41
42 ; Close open files
43
44         jsr     CLRCH
45
46 ; Switch to second charset
47
48         lda     #14
49         jsr     BSOUT
50
51 ; Switch off the BASIC ROM
52
53         lda     $01
54         pha                     ; Remember the value
55         and     #$F8
56         ora     #$06            ; Enable kernal+I/O, disable basic
57         sta     $01
58
59 ; Clear the BSS data
60
61         jsr     zerobss
62
63 ; Save system settings and setup the stack
64
65         pla
66         sta     mmusave         ; Save the memory configuration
67
68         tsx
69         stx     spsave          ; Save the system stack ptr
70
71         lda     #<(__RAM_START__ + __RAM_SIZE__)
72         sta     sp
73         lda     #>(__RAM_START__ + __RAM_SIZE__)
74         sta     sp+1            ; Set argument stack ptr
75
76 ; Call module constructors
77
78         jsr     initlib
79
80 ; If we have IRQ functions, chain our stub into the IRQ vector
81
82         lda     #<__IRQFUNC_COUNT__
83         beq     NoIRQ1
84         lda     IRQVec
85         ldx     IRQVec+1
86         sta     IRQInd+1
87         stx     IRQInd+2
88         lda     #<IRQStub
89         ldx     #>IRQStub
90         sei
91         sta     IRQVec
92         stx     IRQVec+1
93         cli
94
95 ; Push arguments and call main
96
97 NoIRQ1: jsr     callmain
98
99 ; Back from main (This is also the _exit entry). Reset the IRQ vector if we
100 ; chained it.
101
102 _exit:  pha                     ; Save the return code on stack
103         lda     #<__IRQFUNC_COUNT__
104         beq     NoIRQ2
105         lda     IRQInd+1
106         ldx     IRQInd+2
107         sei
108         sta     IRQVec
109         stx     IRQVec+1
110         cli
111
112 ; Run module destructors
113
114 NoIRQ2: jsr     donelib
115
116 ; Copy back the zero page stuff
117
118         ldx     #zpspace-1
119 L2:     lda     zpsave,x
120         sta     sp,x
121         dex
122         bpl     L2
123
124 ; Place the program return code into ST
125
126         pla
127         sta     ST
128
129 ; Restore system stuff
130
131         ldx     spsave
132         txs                     ; Restore stack pointer
133         ldx     mmusave
134         stx     $01             ; Restore memory configuration
135
136 ; Reset changed vectors, back to basic
137
138         jmp     RESTOR
139
140 ; ------------------------------------------------------------------------
141 ; The IRQ vector jumps here, if condes routines are defined with type 2.
142
143 IRQStub:
144         cld                             ; Just to be sure
145         ldy     #<(__IRQFUNC_COUNT__*2)
146         lda     #<__IRQFUNC_TABLE__
147         ldx     #>__IRQFUNC_TABLE__
148         jsr     condes                  ; Call the functions
149         jmp     IRQInd                  ; Jump to the saved IRQ vector
150
151 ; ------------------------------------------------------------------------
152 ; Data
153
154 .data
155
156 zpsave: .res    zpspace
157 IRQInd: jmp     $0000
158
159 .bss
160
161 spsave: .res    1
162 mmusave:.res    1