]> git.sur5r.net Git - cc65/blob - libsrc/apple2/crt0.s
Fixed _textcolor definition.
[cc65] / libsrc / apple2 / crt0.s
1 ;
2 ; Oliver Schmidt, 2009-09-15
3 ;
4 ; Startup code for cc65 (Apple2 version)
5 ;
6
7         .export         _exit, done, return
8         .export         __STARTUP__ : absolute = 1      ; Mark as startup
9
10         .import         initlib, donelib
11         .import         zerobss, callmain
12         .import         __ONCE_LOAD__, __ONCE_SIZE__    ; Linker generated
13         .import         __LC_START__, __LC_LAST__       ; Linker generated
14
15         .include        "zeropage.inc"
16         .include        "apple2.inc"
17
18 ; ------------------------------------------------------------------------
19
20         .segment        "STARTUP"
21
22         ; ProDOS TechRefMan, chapter 5.2.1:
23         ; "For maximum interrupt efficiency, a system program should not
24         ;  use more than the upper 3/4 of the stack."
25         ldx     #$FF
26         txs                     ; Init stack pointer
27
28         ; Save space by putting some of the start-up code in the ONCE segment,
29         ; which can be re-used by the BSS segment, the heap and the C stack.
30         jsr     init
31
32         ; Clear the BSS data.
33         jsr     zerobss
34
35         ; Push the command-line arguments; and, call main().
36         jsr     callmain
37
38         ; Avoid a re-entrance of donelib. This is also the exit() entry.
39 _exit:  ldx     #<exit
40         lda     #>exit
41         jsr     reset           ; Setup RESET vector
42
43         ; Switch in ROM, in case it wasn't already switched in by a RESET.
44         bit     $C082
45
46         ; Call the module destructors.
47         jsr     donelib
48
49         ; Restore the original RESET vector.
50 exit:   ldx     #$02
51 :       lda     rvsave,x
52         sta     SOFTEV,x
53         dex
54         bpl     :-
55
56         ; Copy back the zero-page stuff.
57         ldx     #zpspace-1
58 :       lda     zpsave,x
59         sta     sp,x
60         dex
61         bpl     :-
62
63         ; ProDOS TechRefMan, chapter 5.2.1:
64         ; "System programs should set the stack pointer to $FF at the
65         ;  warm-start entry point."
66         ldx     #$FF
67         txs                     ; Re-init stack pointer
68
69         ; We're done
70         jmp     done
71
72 ; ------------------------------------------------------------------------
73
74         .segment        "ONCE"
75
76         ; Save the zero-page locations that we need.
77 init:   ldx     #zpspace-1
78 :       lda     sp,x
79         sta     zpsave,x
80         dex
81         bpl     :-
82
83         ; Save the original RESET vector.
84         ldx     #$02
85 :       lda     SOFTEV,x
86         sta     rvsave,x
87         dex
88         bpl     :-
89
90         ; Check for ProDOS.
91         ldy     $BF00           ; MLI call entry point
92         cpy     #$4C            ; Is MLI present? (JMP opcode)
93         bne     basic
94
95         ; Check the ProDOS system bit map.
96         lda     $BF6F           ; Protection for pages $B8 - $BF
97         cmp     #%00000001      ; Exactly system global page is protected
98         bne     basic
99
100         ; No BASIC.SYSTEM; so, quit to the ProDOS dispatcher instead.
101         lda     #<quit
102         ldx     #>quit
103         sta     done+1
104         stx     done+2
105
106         ; No BASIC.SYSTEM; so, use the addr of the ProDOS system global page.
107         lda     #<$BF00
108         ldx     #>$BF00
109         bne     :+              ; Branch always
110
111         ; Get the highest available mem addr from the BASIC interpreter.
112 basic:  lda     HIMEM
113         ldx     HIMEM+1
114
115         ; Set up the C stack.
116 :       sta     sp
117         stx     sp+1
118
119         ; ProDOS TechRefMan, chapter 5.3.5:
120         ; "Your system program should place in the RESET vector the
121         ;  address of a routine that ... closes the files."
122         ldx     #<_exit
123         lda     #>_exit
124         jsr     reset           ; Setup RESET vector
125
126         ; Call the module constructors.
127         jsr     initlib
128
129         ; Switch in LC bank 2 for W/O.
130         bit     $C081
131         bit     $C081
132
133         ; Set the source start address.
134         ; Aka __LC_LOAD__ iff segment LC exists.
135         lda     #<(__ONCE_LOAD__ + __ONCE_SIZE__)
136         ldy     #>(__ONCE_LOAD__ + __ONCE_SIZE__)
137         sta     $9B
138         sty     $9C
139
140         ; Set the source last address.
141         ; Aka __LC_LOAD__ + __LC_SIZE__ iff segment LC exists.
142         lda     #<((__ONCE_LOAD__ + __ONCE_SIZE__) + (__LC_LAST__ - __LC_START__))
143         ldy     #>((__ONCE_LOAD__ + __ONCE_SIZE__) + (__LC_LAST__ - __LC_START__))
144         sta     $96
145         sty     $97
146
147         ; Set the destination last address.
148         ; Aka __LC_RUN__ + __LC_SIZE__ iff segment LC exists.
149         lda     #<__LC_LAST__
150         ldy     #>__LC_LAST__
151         sta     $94
152         sty     $95
153
154         ; Call into Applesoft Block Transfer Up -- which handles zero-
155         ; sized blocks well -- to move the content of the LC memory area.
156         jsr     $D39A           ; BLTU2
157
158         ; Switch in LC bank 2 for R/O and return.
159         bit     $C080
160         rts
161
162 ; ------------------------------------------------------------------------
163
164         .code
165
166         ; Set up the RESET vector.
167 reset:  stx     SOFTEV
168         sta     SOFTEV+1
169         eor     #$A5
170         sta     PWREDUP
171 return: rts
172
173         ; Quit to the ProDOS dispatcher.
174 quit:   jsr     $BF00           ; MLI call entry point
175         .byte   $65             ; Quit
176         .word   q_param
177
178 ; ------------------------------------------------------------------------
179
180         .rodata
181
182         ; MLI parameter list for quit
183 q_param:.byte   $04             ; param_count
184         .byte   $00             ; quit_type
185         .word   $0000           ; reserved
186         .byte   $00             ; reserved
187         .word   $0000           ; reserved
188
189 ; ------------------------------------------------------------------------
190
191         .data
192
193         ; Final jump when we're done
194 done:   jmp     DOSWARM         ; Potentially patched at runtime
195
196 ; ------------------------------------------------------------------------
197
198         .segment        "INIT"
199
200 zpsave: .res    zpspace
201 rvsave: .res    3