2 ; Startup code for cc65 (CBM 600/700 version)
4 ; This must be the *first* file on the linker command line
8 .exportzp crtc, sid, IPCcia, cia, acia, tpi1, tpi2, ktab1
9 .exportzp ktab2, ktab3, ktab4, time, RecvBuf, SendBuf
11 .import initlib, donelib
13 .import __BSS_RUN__, __BSS_SIZE__
15 .import k_irq, k_nmi, k_plot, k_udtim, k_scnkey
17 .include "zeropage.inc"
21 ; ------------------------------------------------------------------------
22 ; BASIC header and a small BASIC program. Since it is not possible to start
23 ; programs in other banks using SYS, the BASIC program will write a small
24 ; machine code program into memory at $100 and start that machine code
25 ; program. The machine code program will then start the machine language
26 ; code in bank 1, which will initialize the system by copying stuff from
27 ; the system bank, and start the application.
29 ; Here's the basic program that's in the following lines:
36 ; 60 data 120,169,1,133,0
38 ; The machine program in the data lines is:
42 ; sta $00 <-- Switch to bank 1 after this command
44 ; Initialization is not only complex because of the jumping from one bank
45 ; into another. but also because we want to save memory, and because of
46 ; this, we will use the system memory ($00-$3FF) for initialization stuff
47 ; that is overwritten later.
52 ; To make things more simple, make the code of this module absolute.
55 Head: .byte $03,$00,$11,$00,$0a,$00,$81,$20,$49,$b2,$30,$20,$a4,$20,$34,$00
56 .byte $19,$00,$14,$00,$87,$20,$4a,$00,$27,$00,$1e,$00,$97,$20,$32,$35
57 .byte $36,$aa,$49,$2c,$4a,$00,$2f,$00,$28,$00,$82,$20,$49,$00,$39,$00
58 .byte $32,$00,$9e,$20,$32,$35,$36,$00,$4f,$00,$3c,$00,$83,$20,$31,$32
59 .byte $30,$2c,$31,$36,$39,$2c,$31,$2c,$31,$33,$33,$2c,$30,$00,$00,$00
61 ; Since we need some vectors to access stuff in the system bank for our own,
62 ; we will include them here, starting from $60:
78 RecvBuf: .word $0100 ; RS232 received buffer
79 SendBuf: .word $0200 ; RS232 send buffer
82 ; The code in the target bank when switching back will be put at the bottom
83 ; of the stack. We will jump here to switch segments. The range $F2..$FF is
84 ; not used by any kernal routine.
92 ; The following code is a copy of the code that is poked in the system bank
93 ; memory by the basic header program, it's only for documentation and not
100 ; This is the actual starting point of our code after switching banks for
101 ; startup. Beware: The following code will get overwritten as soon as we
102 ; use the stack (since it's in page 1)!
105 stx spsave ; Save the system stackpointer
107 txs ; Set up our own stack
109 ; Set the interrupt, NMI and other vectors
117 ; Switch the indirect segment to the system bank
122 ; Copy the kernal zero page ($90-$F2) from the system bank
134 ; Copy the page 3 vectors in place
143 ; Copy the rest of page 3 from the system bank
154 ; Set the indirect segment to bank we're executing in
159 ; Zero the BSS segment. We will do that here instead calling the routine
160 ; in the common library, since we have the memory anyway, and this way,
177 inc ptr1+1 ; Next page
181 ; Clear the remaining page
183 Z2: ldx #<__BSS_SIZE__
198 ; We expect to be in page 2 now
208 .error "Code range invalid"
211 ; This code is in page 2, so we may now start calling subroutines safely,
212 ; since the code we execute is no longer in the stack page.
213 ; Call module constructors
217 ; Create the (empty) command line for the program
222 ; Execute the program code
226 ; ------------------------------------------------------------------------
227 ; Additional data that we need for initialization and that's overwritten
241 jmp k_scnkey ; SCNKEY
250 jmp k_setlfs ; SETLFS
251 jmp k_setnam ; SETNAM
261 jmp k_settim ; SETTIM
267 jmp k_screen ; SCREEN
269 jmp k_iobase ; IOBASE
274 .word 0 ; Reset - not used
276 vectable_size = * - vectable
279 .word k_irq ; IRQ user vector
280 .word k_brk ; BRK user vector
281 .word k_nmi ; NMI user vector
282 p3vectable_size = * - p3vectable
285 ; ------------------------------------------------------------------------
286 ; This is the program code after setup. It starts at $400
298 ldy #4 ; Argument size
299 jsr _main ; call the users code
301 ; Call module destructors. This is also the _exit entry.
303 _exit: jsr donelib ; Run module destructors
305 ; Clear the start of the zero page, since it will be interpreted as a
306 ; (garbage) BASIC program otherwise. This is also the default entry for
316 ; Setup the welcome code at the stack bottom in the system bank. Use
317 ; the F4/F5 vector to access the system bank
332 ; ------------------------------------------------------------------------
333 ; Code that is copied into the system bank at $100 when switching back
336 jmp $8000 ; BASIC cold start
337 reset_size = * - reset
339 ; ------------------------------------------------------------------------
340 ; Code for a few simpler kernal calls goes here
384 ; -------------------------------------------------------------------------
385 ; Data area - switch back to relocatable mode