2 ; Startup code for cc65 (Apple2 version)
4 ; This must be the *first* file on the linker command line
9 .import initlib, donelib
10 .import callmain, callirq
12 .import __STARTUP_LOAD__, __BSS_LOAD__ ; Linker generated
13 .import __INTERRUPTOR_COUNT__ ; Linker generated
15 .include "zeropage.inc"
19 ; ------------------------------------------------------------------------
23 .addr __STARTUP_LOAD__ ; Start address
24 .word __BSS_LOAD__ - __STARTUP_LOAD__ ; Size
26 ; ------------------------------------------------------------------------
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."
34 txs ; Init stack pointer
36 ; Delegate all further processing to keep STARTUP small
39 ; Avoid re-entrance of donelib. This is also the _exit entry
42 jsr reset ; Setup RESET vector
44 ; Call module destructors
47 ; Check for valid interrupt vector table entry number
51 ; Deallocate interrupt vector table entry
52 dec params ; Adjust parameter count
54 .byte $41 ; Dealloc interrupt
57 ; Restore the original RESET vector
64 ; Copy back the zero page stuff
71 ; ProDOS TechRefMan, chapter 5.2.1:
72 ; "System programs should set the stack pointer to $FF at the
73 ; warm-start entry point."
75 txs ; Re-init stack pointer
80 ; ------------------------------------------------------------------------
84 ; Save the zero page locations we need
91 ; Save the original RESET vector
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."
103 jsr reset ; Setup RESET vector
112 sta sp+1 ; Set argument stack ptr
114 ; Check for interruptors
115 lda #<__INTERRUPTOR_COUNT__
120 cmp #$4C ; Is MLI present? (JMP opcode)
123 ; Allocate interrupt vector table entry
125 .byte $40 ; Alloc interrupt
129 ; Enable interrupts as old ProDOS versions (i.e. 1.1.1)
130 ; jump to SYS and BIN programs with interrupts disabled
133 ; Call module constructors
136 ; Push arguments and call main()
139 ; Print error message and return
140 prterr: ldx #msglen-1
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
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
163 ; ------------------------------------------------------------------------
167 ; ProDOS TechRefMan, chapter 6.2:
168 ; "Each installed routine must begin with a CLD instruction."
171 ; Call interruptors and check for success
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."
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 ..."
187 ; ------------------------------------------------------------------------
198 ; ------------------------------------------------------------------------
206 params: .byte $02 ; Parameter count
207 intnum: .byte $00 ; Interrupt number
208 .addr intrpt ; Interrupt handler