]> git.sur5r.net Git - cc65/blob - libsrc/apple2/crt0.s
Apple 2 mouse driver and other stuff from Oliver Schmidt
[cc65] / libsrc / apple2 / crt0.s
1 ;
2 ; Startup code for cc65 (Apple2 version)
3 ;
4 ; This must be the *first* file on the linker command line
5 ;
6
7         .export         _exit
8         .import         zerobss
9         .import         initlib, donelib
10         .import         callmain, callirq
11         .import         COUT
12         .import         __STARTUP_LOAD__, __BSS_LOAD__  ; Linker generated
13         .import         __INTERRUPTOR_COUNT__           ; Linker generated
14
15         .include        "zeropage.inc"
16         .include        "apple2.inc"
17         .include        "mli.inc"
18
19 ; ------------------------------------------------------------------------
20
21         .segment        "EXEHDR"
22
23         .addr           __STARTUP_LOAD__                ; Start address
24         .word           __BSS_LOAD__ - __STARTUP_LOAD__ ; Size
25
26 ; ------------------------------------------------------------------------
27
28         .segment        "STARTUP"
29
30         ; ProDOS TechRefMan, chapter 5.2.1:
31         ; "For maximum interrupt efficiency, a system program should not
32         ;  use more than the upper 3/4 of the stack."
33         ldx     #$FF
34         txs                     ; Init stack pointer
35
36         ; Delegate all further processing to keep STARTUP small
37         jsr     init
38
39         ; Avoid re-entrance of donelib. This is also the _exit entry
40 _exit:  ldx     #<exit
41         lda     #>exit
42         jsr     reset           ; Setup RESET vector
43
44         ; Call module destructors
45         jsr     donelib
46
47         ; Check for valid interrupt vector table entry number
48         lda     intnum
49         beq     exit
50
51         ; Deallocate interrupt vector table entry
52         dec     params          ; Adjust parameter count
53         jsr     ENTRY
54         .byte   $41             ; Dealloc interrupt
55         .addr   params
56
57         ; Restore the original RESET vector
58 exit:   ldx     #$02
59 :       lda     rvsave,x
60         sta     SOFTEV,x
61         dex
62         bpl     :-
63
64         ; Copy back the zero page stuff
65         ldx     #zpspace-1
66 :       lda     zpsave,x
67         sta     sp,x
68         dex
69         bpl     :-
70
71         ; ProDOS TechRefMan, chapter 5.2.1:
72         ; "System programs should set the stack pointer to $FF at the
73         ;  warm-start entry point."
74         ldx     #$FF
75         txs                     ; Re-init stack pointer
76
77         ; Back to DOS
78         jmp     DOSWARM
79
80 ; ------------------------------------------------------------------------
81
82         .segment        "INIT"
83
84         ; Save the zero page locations we need
85 init:   ldx     #zpspace-1
86 :       lda     sp,x
87         sta     zpsave,x
88         dex
89         bpl     :-
90
91         ; Save the original RESET vector
92         ldx     #$02
93 :       lda     SOFTEV,x
94         sta     rvsave,x
95         dex
96         bpl     :-
97
98         ; ProDOS TechRefMan, chapter 5.3.5:
99         ; "Your system program should place in the RESET vector the
100         ;  address of a routine that ... closes the files."
101         ldx     #<_exit
102         lda     #>_exit
103         jsr     reset           ; Setup RESET vector
104                 
105         ; Clear the BSS data
106         jsr     zerobss
107
108         ; Setup the stack
109         lda     HIMEM
110         sta     sp
111         lda     HIMEM+1
112         sta     sp+1            ; Set argument stack ptr
113
114         ; Check for interruptors
115         lda     #<__INTERRUPTOR_COUNT__
116         beq     :+
117
118         ; Check for ProDOS
119         lda     ENTRY
120         cmp     #$4C            ; Is MLI present? (JMP opcode)
121         bne     prterr
122
123         ; Allocate interrupt vector table entry
124         jsr     ENTRY
125         .byte   $40             ; Alloc interrupt
126         .addr   params
127         bcs     prterr
128
129         ; Enable interrupts as old ProDOS versions (i.e. 1.1.1)
130         ; jump to SYS and BIN programs with interrupts disabled
131         cli
132
133         ; Call module constructors
134 :       jsr     initlib
135
136         ; Push arguments and call main()
137         jmp     callmain
138
139         ; Print error message and return
140 prterr: ldx     #msglen-1
141 :       lda     errmsg,x
142         jsr     COUT
143         dex
144         bpl     :-
145         rts
146
147 errmsg: .ifdef  __APPLE2ENH__
148         .byte   $8D,     't'|$80, 'p'|$80, 'u'|$80, 'r'|$80, 'r'|$80
149         .byte   'e'|$80, 't'|$80, 'n'|$80, 'i'|$80, ' '|$80, 'c'|$80
150         .byte   'o'|$80, 'l'|$80, 'l'|$80, 'a'|$80, ' '|$80, 'o'|$80
151         .byte   't'|$80, ' '|$80, 'd'|$80, 'e'|$80, 'l'|$80, 'i'|$80
152         .byte   'a'|$80, 'F'|$80, $8D
153         .else
154         .byte   $8D,     'T'|$80, 'P'|$80, 'U'|$80, 'R'|$80, 'R'|$80
155         .byte   'E'|$80, 'T'|$80, 'N'|$80, 'I'|$80, ' '|$80, 'C'|$80
156         .byte   'O'|$80, 'L'|$80, 'L'|$80, 'A'|$80, ' '|$80, 'O'|$80
157         .byte   'T'|$80, ' '|$80, 'D'|$80, 'E'|$80, 'L'|$80, 'I'|$80
158         .byte   'A'|$80, 'F'|$80, $8D
159         .endif
160
161 msglen = * - errmsg
162
163 ; ------------------------------------------------------------------------
164
165         .segment        "LOWCODE"
166
167         ; ProDOS TechRefMan, chapter 6.2:
168         ; "Each installed routine must begin with a CLD instruction."
169 intrpt: cld
170
171         ; Call interruptors and check for success
172         jsr     callirq
173         bcc     :+
174
175         ; ProDOS TechRefMan, chapter 6.2:
176         ; "When the routine that can process the interrupt is called, it
177         ;  should ... return (via an RTS) with the carry flag clear."
178         clc
179         rts
180
181         ; ProDOS TechRefMan, chapter 6.2:
182         ; "When a routine that cannot process the interrupt is called,
183         ;  it should return (via an RTS) with the cary flag set ..."
184 :       sec
185         rts
186
187 ; ------------------------------------------------------------------------
188
189         .code
190
191         ; Setup RESET vector
192 reset:  stx     SOFTEV
193         sta     SOFTEV+1
194         eor     #$A5
195         sta     PWREDUP
196         rts
197
198 ; ------------------------------------------------------------------------
199
200         .data
201
202 zpsave: .res    zpspace
203
204 rvsave: .res    3
205
206 params: .byte   $02             ; Parameter count
207 intnum: .byte   $00             ; Interrupt number
208         .addr   intrpt          ; Interrupt handler