2 ; Startup code for cc65 (Plus/4 version)
4 ; This must be the *first* file on the linker command line
10 .import condes, initlib, donelib
11 .import push0, _main, zerobss
12 .import __IRQFUNC_TABLE__, __IRQFUNC_COUNT__
14 .include "zeropage.inc"
18 ; ------------------------------------------------------------------------
21 IRQInd = $500 ; JMP $0000 - used as indirect IRQ vector
23 ; ------------------------------------------------------------------------
24 ; Place the startup code in a special segment to cope with the quirks of
29 .word Head ; Load address
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
36 ; ------------------------------------------------------------------------
39 sei ; No interrupts since we're banking out the ROM
43 sta zpsave,x ; save the zero page locations we need
53 ; Switch to second charset
58 ; Setup the IRQ vector in the banked RAM and switch off the ROM
60 sei ; No ints, handler not yet in place
63 sta $FFFE ; Install interrupt handler
66 cli ; Allow interrupts
72 ; Save system stuff and setup the stack. The stack starts at the top of the
76 stx spsave ; save system stk ptr
83 ; Call module constructors
87 ; If we have IRQ functions, chain our stub into the IRQ vector
89 lda #<__IRQFUNC_COUNT__
102 ; Pass an empty command line
104 NoIRQ1: jsr push0 ; argc
107 ldy #4 ; Argument size
108 jsr _main ; call the users code
110 ; Back from main (this is also the _exit entry). Reset the IRQ vector if
113 _exit: lda #<__IRQFUNC_COUNT__
122 ; Run module destructors.
124 NoIRQ2: jsr donelib ; Run module destructors
126 ; Restore system stuff
131 ; Copy back the zero page stuff
139 ; Enable the ROM, reset changed vectors and return to BASIC
145 ; ------------------------------------------------------------------------
153 tsx ; Get the stack pointer
154 lda $0103,x ; Get the saved status register
156 and #$10 ; Test for BRK bit
158 lda #>irq_ret ; Push new return address
164 sta ENABLE_ROM ; Switch to ROM
165 jmp ($FFFE) ; Jump to kernal irq handler
168 sta ENABLE_RAM ; Switch back to RAM
175 lda brk_jmp+2 ; Check high byte of address
177 jmp brk_jmp ; Jump to the handler
179 ; No break handler installed, jump to ROM
183 pha ; ROM handler expects Y on stack
185 jmp (BRKVec) ; Jump indirect to the break vector
187 ; ------------------------------------------------------------------------
188 ; Stub for the IRQ chain. Is used only if there are IRQs defined. Needed in
189 ; low memory because of the banking.
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
201 jmp IRQInd ; Jump to the saved IRQ vector
203 ; ------------------------------------------------------------------------