2 ; Christian Groessler, 12-Jun-2016
4 ; int __fastcall__ exec (const char* progname, const char* cmdline);
6 ; supports only XDOS at the moment
14 .import excexit ; from crt0.s
15 .import SP_save ; from crt0.s
21 .include "zeropage.inc"
25 ; area $0100 to $0128 might be in use (e.g. Hias' high speed patch)
26 CMDLINE_BUFFER = $0129 ; put progname + cmdline as one single string there
28 ;CMDLINE_BUFFER = $0480 ; put progname + cmdline as one single string there
29 CMDLINE_MAX = 40+3 ; max. length of drive + progname + cmdline
33 notsupp:lda #ENOSYS ; "unsupported system call"
34 .byte $2C ; bit opcode, eats the next 2 bytes
35 noiocb: lda #EMFILE ; "too many open files"
36 jsr incsp2 ; clean up stack
37 seterr: jmp __directerrno
54 stx tmp4 ; remember IOCB index
65 sty tmp2 ; set flag for ucase_fn
68 invret: lda #EINVAL ; file name is too long
71 .endif ; defined UCASE_FILENAME
73 ; copy program name and arguments to CMDLINE_BUFFER
75 sta ptr4 ; ptr4: pointer to program name
78 ; TODO: check stack ptr and and use min(CMDLINE_MAX,available_stack)
86 ; programe name too long
89 .ifndef UCASE_FILENAME
94 ; file name copied, check for args
96 copypd: tya ; put Y into X (index into CMDLINE_BUFFER)
99 ora ptr3+1 ; do we have arguments?
102 lda (ptr3),y ; get first byte of cmdline parameter
103 beq copycd ; nothing there...
104 lda #' ' ; add a space btw. progname and cmdline
112 copyc1: sta CMDLINE_BUFFER,x
116 ; progname + arguments too long
126 ; open the program file, read the first two bytes and compare them to $FF
128 ldx tmp4 ; get IOCB index
129 lda ptr4 ; ptr4 points to progname
133 lda #OPNIN ; open for input
141 .ifdef UCASE_FILENAME
143 jsr addysp ; free used space on the stack
144 ; the following 'bpl' depends on 'addysp' restoring A as last command before 'rts'
145 .endif ; defined UCASE_FILENAME
148 pha ; remember error code
149 jsr close ; close the IOCB (required even if open failed)
150 pla ; put error code back into A
151 setmerr:jmp __mappederrno ; update errno from OS specific error code in A
154 sta ICBAH,x ; set buffer address
157 lda #0 ; set buffer length
161 lda #GETCHR ; iocb command code
164 bmi invexe ; read operation failed, return error
166 lda ICBLL,x ; # of bytes read
169 lda #$FF ; check file format (need $FFFF at the beginning)
175 jsr close ; close program file
177 ; program file appears to be available and good
178 ; here's the point of no return
181 txs ; reset stack pointer to what it was at program entry
182 lda tmp4 ; get IOCB index
183 pha ; and save it ('excexit' calls destructors and they might destroy tmp4)
184 jsr excexit ; on atarixl this will enable the ROM again, making all high variables inaccessible
186 tax ; IOCB index in X
189 sta ICBAL,x ; address
193 sta ICBLL,x ; length shouldn't be random, but 0 is ok
197 lda #80 ; XDOS: run DUP command
199 jmp CIOV_org ; no way to display an error message in case of failure, and we will return to DOS
202 ; close IOCB, index in X
206 jmp CIOV ; close IOCB