2 ; Oliver Schmidt, 2011-01-26
4 ; int __fastcall__ exec (const char* progname, const char* cmdline);
8 .import pushname, popname
9 .import popax, done, _exit
11 .include "zeropage.inc"
17 typerr: lda #$4A ; "Incompatible file format"
20 oserr: jsr popname ; Preserves A
35 ; ProDOS TechRefMan, chapter 5.1.5.1:
36 ; "The complete or partial pathname of the system program
37 ; is stored at $280, starting with a length byte."
38 ; In fact BASIC.SYSTEM does the same for BLOAD and BRUN of
39 ; binary programs so we should do the same too in any case
40 ; especially as _we_ rely on it in mainargs.s for argv[0]
52 sta mliparam + MLI::INFO::PATHNAME
53 stx mliparam + MLI::INFO::PATHNAME+1
55 ; Get file_type and aux_type
61 ; If we get here the program file at least exists so we copy
62 ; the loader stub right now and patch it later to set params
69 ; Check program file type
70 lda mliparam + MLI::INFO::FILE_TYPE
72 bne binary ; No, check for BIN file
73 sta file_type ; Save file type for cmdline handling
75 ; SYS programs replace BASIC.SYSTEM so set in the ProDOS system bit map
76 ; protection for pages $80 - $BF just in case BASIC.SYSTEM is there now
77 ldx #$0F ; Start with protection for pages $B8 - $BF
78 lda #%00000001 ; Protect only system global page
79 : sta $BF60,x ; Set protection for 8 pages
80 lda #%00000000 ; Protect no page
83 bmi prodos ; Branch always
85 binary: cmp #$06 ; BIN file?
86 bne typerr ; No, wrong file type
88 ; Set BIN program load addr
89 lda mliparam + MLI::INFO::AUX_TYPE
90 ldx mliparam + MLI::INFO::AUX_TYPE+1
94 ; Check ProDOS system bit map for presence of BASIC.SYSTEM
95 lda $BF6F ; Protection for pages $B8 - $BF
96 cmp #%00000001 ; Exactly system global page is protected
99 ; Get highest available mem addr from BASIC.SYSTEM
100 ldx HIMEM+1 ; High byte
101 bne setbuf ; Branch always
103 ; BIN programs are supposed to quit through one of the two DOS
104 ; vectors so we set up those to point to the ProDOS dispatcher
105 setvec: ldx #$03 - 1 ; Size of JMP opcode
107 sta DOSWARM,x ; DOS warm start
108 sta DOSWARM + 3,x ; DOS cold start
112 ; No BASIC.SYSTEM so use addr of ProDOS system global page
113 prodos: ldx #>$BF00 ; High byte
115 ; The I/O buffer needs to be page aligned
116 setbuf: lda #$00 ; Low byte
118 ; The I/O buffer needs four pages
125 sta mliparam + MLI::OPEN::IO_BUFFER
126 stx mliparam + MLI::OPEN::IO_BUFFER+1
128 ; PATHNAME already set
129 .assert MLI::OPEN::PATHNAME = MLI::INFO::PATHNAME, error
131 ; Lower file level to avoid program file
132 ; being closed by C libary shutdown code
150 : lda mliparam + MLI::OPEN::REF_NUM
155 ; Calling the 80 column firmware needs the ROM switched
156 ; in, otherwise it copies the F8 ROM to the LC (@ $CEF4)
159 ; ProDOS TechRefMan, chapter 5.3.1.3:
160 ; "80-column text cards -- and other Apple IIe features -- can
161 ; be turned off using the following sequence of instructions:"
165 ; Switch in LC bank 2 for R/O
169 ; Reset stack as we already passed
170 ; the point of no return anyway
174 ; Store up to 127 chars of cmdline (if any)
175 ; including terminating zero in stack page
178 beq :++ ; Yes, store as '\0'
181 beq :+ ; '\0' stored, done
186 beq :- ; Branch always
188 ; Call loader stub after C libary shutdown
194 ; Initiate C libary shutdown
203 ; Read whole program file
215 ; Check for cmdline handling
216 lda $0100 ; Valid cmdline?
217 beq jump ; No, jump to program right away
218 ldx file_type ; SYS file?
219 bne system ; Yes, check for startup filename
221 ; Store REM and cmdline in BASIC input buffer
223 bne :++ ; Branch always
228 beq jump ; Branch always
230 ; Check for startup filename support
231 ; ProDOS TechRefMan, chapter 5.1.5.1:
232 ; "$2000 is a jump instruction. $2003 and $2004 are $EE."
242 ; Store cmdline in startup filename buffer
248 cpx $2005 ; Buffer full?
249 bcc :- ; No, continue
251 stx $2006 ; Store cmdline length
254 jump: jmp (data_buffer)
256 file_type = * - source + target
259 read_param = * - source + target
260 .byte $04 ; PARAM_COUNT
261 read_ref = * - source + target
263 data_buffer = * - source + target
264 .addr $2000 ; DATA_BUFFER
265 .word $FFFF ; REQUEST_COUNT
266 .word $0000 ; TRANS_COUNT
268 close_param = * - source + target
269 .byte $01 ; PARAM_COUNT
270 close_ref = * - source + target
273 ; Quit to ProDOS dispatcher
274 quit = * - source + target
279 quit_param = * - source + target
280 .byte $04 ; PARAM_COUNT
281 .byte $00 ; QUIT_TYPE
282 .word $0000 ; RESERVED
284 .word $0000 ; RESERVED
288 target = DOSWARM - size