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