2 ; Oliver Schmidt, 2009-09-15
4 ; Startup code for cc65 (Apple2 version)
7 .export _exit, done, return
8 .export __STARTUP__ : absolute = 1 ; Mark as startup
10 .import initlib, donelib
12 .import __LC_START__, __LC_LAST__ ; Linker generated
13 .import __INIT_RUN__, __INIT_SIZE__ ; Linker generated
14 .import __ZPSAVE_RUN__ ; Linker generated
16 .include "zeropage.inc"
21 ; ProDOS TechRefMan, chapter 5.2.1:
22 ; "For maximum interrupt efficiency, a system program should not
23 ; use more than the upper 3/4 of the stack."
25 txs ; Init stack pointer
27 ; Switch in LC bank 2 for W/O.
31 ; Set the source start address.
32 lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__)
33 ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__)
37 ; Set the source last address.
38 lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__)
39 ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__)
43 ; Set the destination last address.
49 ; Call into the Applesoft Block Transfer Utility -- which handles zero-
50 ; sized blocks well -- to move the content of the LC memory area.
53 ; Set the source start address.
59 ; Set the source last address.
60 lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__)
61 ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__)
65 ; Set the destination last address.
66 lda #<(__INIT_RUN__ + __INIT_SIZE__)
67 ldy #>(__INIT_RUN__ + __INIT_SIZE__)
71 ; Call into the Applesoft Block Transfer Utility -- which handles moving
72 ; overlapping blocks upwards well -- to move the INIT segment.
75 ; Delegate all further processing, to keep the STARTUP segment small.
78 ; Avoid a re-entrance of donelib. This is also the exit() entry.
81 jsr reset ; Setup RESET vector
83 ; Switch in ROM, in case it wasn't already switched in by a RESET.
86 ; Call the module destructors.
89 ; Restore the original RESET vector.
96 ; Copy back the zero-page stuff.
103 ; ProDOS TechRefMan, chapter 5.2.1:
104 ; "System programs should set the stack pointer to $FF at the
105 ; warm-start entry point."
107 txs ; Re-init stack pointer
114 ; Save the zero-page locations that we need.
121 ; Clear the BSS data.
124 ; Save the original RESET vector.
131 ; ProDOS TechRefMan, chapter 5.3.5:
132 ; "Your system program should place in the RESET vector the
133 ; address of a routine that ... closes the files."
136 jsr reset ; Setup RESET vector
139 ldy $BF00 ; MLI call entry point
140 cpy #$4C ; Is MLI present? (JMP opcode)
143 ; Check the ProDOS system bit map.
144 lda $BF6F ; Protection for pages $B8 - $BF
145 cmp #%00000001 ; Exactly system global page is protected
148 ; No BASIC.SYSTEM; so, quit to the ProDOS dispatcher instead.
154 ; No BASIC.SYSTEM; so, use the addr of the ProDOS system global page.
157 bne :+ ; Branch always
159 ; Get the highest available mem addr from the BASIC interpreter.
163 ; Set up the C stack.
167 ; Call the module constructors.
170 ; Switch in LC bank 2 for R/O.
173 ; Push the command-line arguments; and, call main().
178 ; Set up the RESET vector.
185 ; Quit to the ProDOS dispatcher.
186 quit: jsr $BF00 ; MLI call entry point
192 ; MLI parameter list for quit
193 q_param:.byte $04 ; param_count
194 .byte $00 ; quit_type
195 .word $0000 ; reserved
197 .word $0000 ; reserved
201 ; Final jump when we're done
202 done: jmp DOSWARM ; Potentially patched at runtime