]> git.sur5r.net Git - cc65/blob - libsrc/apple2/exec.s
Removed (pretty inconsistently used) tab chars from source code base.
[cc65] / libsrc / apple2 / exec.s
1 ;
2 ; Oliver Schmidt, 2011-01-26
3 ;
4 ; int __fastcall__ exec (const char* progname, const char* cmdline);
5 ;
6
7         .export         _exec
8         .import         pushname, popname
9         .import         popax, done, _exit
10
11         .include        "zeropage.inc"
12         .include        "errno.inc"
13         .include        "apple2.inc"
14         .include        "mli.inc"
15
16         ; Wrong file type
17 typerr: lda     #$4A            ; "Incompatible file format"
18
19         ; Cleanup name
20 oserr:  jsr     popname         ; Preserves A
21         
22         ; Set __oserror
23         jmp     __mappederrno
24
25 _exec:
26         ; Get and push name
27         jsr     popax
28         jsr     pushname
29         bne     oserr
30
31         ; Set pushed name
32         lda     sp
33         ldx     sp+1
34         sta     mliparam + MLI::INFO::PATHNAME
35         stx     mliparam + MLI::INFO::PATHNAME+1
36
37         ; Get file_type and aux_type
38         lda     #GET_INFO_CALL
39         ldx     #GET_INFO_COUNT
40         jsr     callmli
41         bcs     oserr
42
43         ; If we get here the program file at least exists so we copy
44         ; the loader stub right now and patch it later to set params
45         ldx     #size - 1
46 :       lda     source,x
47         sta     target,x
48         dex
49         bpl     :-
50
51         ; Check program file type
52         lda     mliparam + MLI::INFO::FILE_TYPE
53         cmp     #$FF            ; SYS file?
54         bne     binary          ; No, check for BIN file
55
56         ; ProDOS TechRefMan, chapter 5.1.5.1:
57         ; "The complete or partial pathname of the system program
58         ;  is stored at $280, starting with a length byte."
59         ldy     #$00
60         lda     (sp),y
61         tay
62 :       lda     (sp),y
63         sta     $0280,y
64         dey
65         bpl     :-
66         
67         ; SYS programs replace BASIC.SYSTEM so set in the ProDOS system bit map
68         ; protection for pages $80 - $BF just in case BASIC.SYSTEM is there now
69         ldx     #$0F            ; Start with protection for pages $B8 - $BF
70         lda     #%00000001      ; Protect only system global page
71 :       sta     $BF60,x         ; Set protection for 8 pages
72         lda     #$00            ; Protect no page
73         dex
74         bpl     :-
75         bmi     prodos          ; Branch always
76
77 binary: cmp     #$06            ; BIN file?
78         bne     typerr          ; No, wrong file type
79
80         ; Set BIN program load addr
81         lda     mliparam + MLI::INFO::AUX_TYPE
82         ldx     mliparam + MLI::INFO::AUX_TYPE+1
83         sta     data_buffer
84         stx     data_buffer+1
85
86         ; Check ProDOS system bit map for presence of BASIC.SYSTEM
87         lda     $BF6F           ; Protection for pages $B8 - $BF
88         cmp     #%00000001      ; Exactly system global page is protected
89         beq     setvec
90
91         ; Get highest available mem addr from BASIC.SYSTEM
92         ldx     HIMEM+1         ; High byte
93         bne     setbuf          ; Branch always
94
95         ; BIN programs are supposed to quit through one of the two DOS
96         ; vectors so we set up those to point to the ProDOS dispatcher
97 setvec: ldx     #$03 - 1        ; Size of JMP opcode
98 :       lda     dosvec,x
99         sta     DOSWARM,x       ; DOS warm start
100         sta     DOSWARM + 3,x   ; DOS cold start
101         dex
102         bpl     :-
103
104         ; No BASIC.SYSTEM so use addr of ProDOS system global page
105 prodos: ldx     #>$BF00         ; High byte
106
107         ; The I/O buffer needs to be page aligned
108 setbuf: lda     #$00            ; Low byte
109
110         ; The I/O buffer needs four pages
111         dex
112         dex
113         dex
114         dex
115         
116         ; Set I/O buffer
117         sta     mliparam + MLI::OPEN::IO_BUFFER
118         stx     mliparam + MLI::OPEN::IO_BUFFER+1
119
120         ; PATHNAME already set
121         .assert MLI::OPEN::PATHNAME = MLI::INFO::PATHNAME, error
122
123         ; Lower file level to avoid program file
124         ; being closed by C libary shutdown code
125         ldx     LEVEL
126         stx     level
127         beq     :+
128         dec     LEVEL
129         
130         ; Open file
131 :       lda     #OPEN_CALL
132         ldx     #OPEN_COUNT
133         jsr     callmli
134
135         ; Restore file level
136         ldx     level
137         stx     LEVEL
138         bcc     :+
139         jmp     oserr
140
141         ; Get and save fd
142 :       lda     mliparam + MLI::OPEN::REF_NUM
143         sta     read_ref
144         sta     close_ref
145
146         .ifdef  __APPLE2ENH__
147         ; Calling the 80 column firmware needs the ROM switched
148         ; in, otherwise it copies the F8 ROM to the LC (@ $CEF4)
149         bit     $C082
150
151         ; ProDOS TechRefMan, chapter 5.3.1.3:
152         ; "80-column text cards -- and other Apple IIe features -- can
153         ;  be turned off using the following sequence of instructions:"
154         lda     #$15
155         jsr     $C300
156
157         ; Switch in LC bank 2 for R/O
158         bit     $C080
159         .endif
160
161         ; Call loader stub after C libary shutdown
162         lda     #<target
163         ldx     #>target
164         sta     done
165         stx     done+1
166
167         ; Initiate C libary shutdown
168         jmp     _exit
169
170         .bss
171
172 level : .res    1
173
174         .rodata
175
176         ; Read whole program file
177 source: jsr     $BF00
178         .byte   READ_CALL
179         .word   read_param
180         bcs     :+
181
182         ; Close program file
183         jsr     $BF00
184         .byte   CLOSE_CALL
185         .word   close_param
186         bcs     :+
187
188         ; Go for it ...
189         jmp     (data_buffer)
190
191 read_param      = * - source + target
192         .byte   $04             ; PARAM_COUNT
193 read_ref        = * - source + target
194         .byte   $00             ; REF_NUM
195 data_buffer     = * - source + target
196         .addr   $2000           ; DATA_BUFFER
197         .word   $FFFF           ; REQUEST_COUNT
198         .word   $0000           ; TRANS_COUNT
199
200 close_param     = * - source + target
201         .byte   $01             ; PARAM_COUNT
202 close_ref       = * - source + target
203         .byte   $00             ; REF_NUM
204
205         ; Quit to ProDOS dispatcher
206 quit            = * - source + target
207 :       jsr     $BF00
208         .byte   $65             ; QUIT
209         .word   quit_param
210
211 quit_param      = * - source + target
212         .byte   $04             ; PARAM_COUNT
213         .byte   $00             ; QUIT_TYPE
214         .word   $0000           ; RESERVED
215         .byte   $00             ; RESERVED
216         .word   $0000           ; RESERVED
217
218 size            = * - source
219
220 target          = DOSWARM - size
221
222 dosvec: jmp     quit