]> git.sur5r.net Git - cc65/blob - libsrc/plus4/crt0.s
Added joystick drivers for C16 and Atari
[cc65] / libsrc / plus4 / crt0.s
1 ;
2 ; Startup code for cc65 (Plus/4 version)
3 ;
4 ; This must be the *first* file on the linker command line
5 ;
6
7         .export         _exit
8         .export         brk_jmp
9
10         .import         condes, initlib, donelib
11         .import         push0, _main, zerobss
12         .import         __IRQFUNC_TABLE__, __IRQFUNC_COUNT__
13
14         .include        "zeropage.inc"
15         .include        "plus4.inc"
16
17
18 ; ------------------------------------------------------------------------
19 ; Constants
20
21 IRQInd          = $500  ; JMP $0000 - used as indirect IRQ vector
22
23 ; ------------------------------------------------------------------------
24 ; Place the startup code in a special segment to cope with the quirks of
25 ; plus/4 banking.
26
27 .segment        "STARTUP"
28
29         .word   Head            ; Load address
30 Head:   .word   @Next
31         .word   1000            ; Line number
32         .byte   $9E,"4109"      ; SYS 4109
33         .byte   $00             ; End of BASIC line
34 @Next:  .word   0               ; BASIC end marker
35
36 ; ------------------------------------------------------------------------
37 ; Actual code
38
39         sei                     ; No interrupts since we're banking out the ROM
40         sta     ENABLE_RAM
41         ldx     #zpspace-1
42 L1:     lda     sp,x
43         sta     zpsave,x        ; save the zero page locations we need
44         dex
45         bpl     L1
46         sta     ENABLE_ROM
47         cli
48
49 ; Close open files
50
51         jsr     $FFCC           ; CLRCH
52
53 ; Switch to second charset
54
55         lda     #14
56         jsr     $FFD2           ; BSOUT
57
58 ; Setup the IRQ vector in the banked RAM and switch off the ROM
59
60         sei                     ; No ints, handler not yet in place
61         sta     ENABLE_RAM
62         lda     #<IRQ
63         sta     $FFFE           ; Install interrupt handler
64         lda     #>IRQ
65         sta     $FFFF
66         cli                     ; Allow interrupts
67
68 ; Clear the BSS data
69
70         jsr     zerobss
71
72 ; Save system stuff and setup the stack. The stack starts at the top of the
73 ; usable RAM.
74
75         tsx
76         stx     spsave          ; save system stk ptr
77
78         lda     #<$FD00
79         sta     sp
80         lda     #>$FD00
81         sta     sp+1
82
83 ; Call module constructors
84
85         jsr     initlib
86
87 ; If we have IRQ functions, chain our stub into the IRQ vector
88
89         lda     #<__IRQFUNC_COUNT__
90         beq     NoIRQ1
91         lda     IRQVec
92         ldx     IRQVec+1
93         sta     IRQInd+1
94         stx     IRQInd+2
95         lda     #<IRQStub
96         ldx     #>IRQStub
97         sei
98         sta     IRQVec
99         stx     IRQVec+1
100         cli
101
102 ; Pass an empty command line
103
104 NoIRQ1: jsr     push0           ; argc
105         jsr     push0           ; argv
106
107         ldy     #4              ; Argument size
108         jsr     _main           ; call the users code
109
110 ; Back from main (this is also the _exit entry). Reset the IRQ vector if
111 ; we chained it.
112
113 _exit:  lda     #<__IRQFUNC_COUNT__
114         beq     NoIRQ2
115         lda     IRQInd+1
116         ldx     IRQInd+2
117         sei
118         sta     IRQVec
119         stx     IRQVec+1
120         cli
121
122 ; Run module destructors.
123
124 NoIRQ2: jsr     donelib         ; Run module destructors
125
126 ; Restore system stuff
127
128         ldx     spsave
129         txs
130
131 ; Copy back the zero page stuff
132
133         ldx     #zpspace-1
134 L2:     lda     zpsave,x
135         sta     sp,x
136         dex
137         bpl     L2
138
139 ; Enable the ROM, reset changed vectors and return to BASIC
140
141         sta     ENABLE_ROM
142         jmp     $FF8A           ; RESTOR
143
144
145 ; ------------------------------------------------------------------------
146 ; IRQ handler
147
148 .segment        "LOWCODE"
149
150 IRQ:    pha
151         txa
152         pha
153         tsx                     ; Get the stack pointer
154         lda     $0103,x         ; Get the saved status register
155         tax                     ; Save for later
156         and     #$10            ; Test for BRK bit
157         bne     dobreak
158         lda     #>irq_ret       ; Push new return address
159         pha
160         lda     #<irq_ret
161         pha
162         txa
163         pha
164         sta     ENABLE_ROM      ; Switch to ROM
165         jmp     ($FFFE)         ; Jump to kernal irq handler
166
167 irq_ret:
168         sta     ENABLE_RAM      ; Switch back to RAM
169         pla
170         tax
171         pla
172         rti
173
174 dobreak:
175         lda     brk_jmp+2       ; Check high byte of address
176         beq     nohandler
177         jmp     brk_jmp         ; Jump to the handler
178
179 ; No break handler installed, jump to ROM
180
181 nohandler:
182         tya
183         pha                     ; ROM handler expects Y on stack
184         sta     ENABLE_ROM
185         jmp     (BRKVec)        ; Jump indirect to the break vector
186
187 ; ------------------------------------------------------------------------
188 ; Stub for the IRQ chain. Is used only if there are IRQs defined. Needed in
189 ; low memory because of the banking.
190
191 .segment        "LOWCODE"
192
193 IRQStub:
194         cld                     ; Just to be sure
195         sta     ENABLE_RAM      ; Switch to RAM
196         ldy     #<(__IRQFUNC_COUNT__*2)
197         lda     #<__IRQFUNC_TABLE__
198         ldx     #>__IRQFUNC_TABLE__
199         jsr     condes                  ; Call the IRQ functions
200         sta     ENABLE_ROM
201         jmp     IRQInd                  ; Jump to the saved IRQ vector
202
203 ; ------------------------------------------------------------------------
204 ; Data
205
206 .data
207 zpsave:         .res    zpspace
208
209 ; BRK handling
210 brk_jmp:        jmp     $0000
211
212 .bss
213 spsave:         .res    1
214
215
216