]> git.sur5r.net Git - cc65/blob - targetutil/apple2/loader.s
ab4ae44e3aa74065a00a08e7a9b8af8a3a17f8a0
[cc65] / targetutil / apple2 / loader.s
1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;                                                                              ;
3 ; Apple][ ProDOS 8 system program for loading binary programs (Oliver Schmidt) ;
4 ;                                                                              ;
5 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
7 A1L             := $3C
8 A1H             := $3D
9 HIMEM           := $73
10 STACK           := $0100
11 BUF             := $0200
12 PATHNAME        := $0280
13 DOSWARM         := $03D0
14 DOSCOLD         := $03D3
15 SOFTEV          := $03F2
16 PWREDUP         := $03F4
17 MLI             := $BF00
18 MEMTABL         := $BF58
19 RESET           := $FA62
20 VERSION         := $FBB3
21 RDKEY           := $FD0C
22 PRBYTE          := $FDDA
23 COUT            := $FDED
24
25 QUIT_CALL          = $65
26 GET_FILE_INFO_CALL = $C4
27 OPEN_CALL          = $C8
28 READ_CALL          = $CA
29 CLOSE_CALL         = $CC
30 FILE_NOT_FOUND_ERR = $46
31
32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
33
34         .import __CODE_0300_SIZE__, __DATA_0300_SIZE__
35         .import __CODE_0300_LOAD__, __CODE_0300_RUN__
36
37 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38
39 .segment        "DATA_2000"
40
41 GET_FILE_INFO_PARAM:
42                 .byte   $0A             ;PARAM_COUNT
43                 .addr   PATHNAME        ;PATHNAME
44                 .byte   $00             ;ACCESS
45                 .byte   $00             ;FILE_TYPE
46 FILE_INFO_ADDR: .word   $0000           ;AUX_TYPE
47                 .byte   $00             ;STORAGE_TYPE
48                 .word   $0000           ;BLOCKS_USED
49                 .word   $0000           ;MOD_DATE
50                 .word   $0000           ;MOD_TIME
51                 .word   $0000           ;CREATE_DATE
52                 .word   $0000           ;CREATE_TIME
53
54 OPEN_PARAM:
55                 .byte   $03             ;PARAM_COUNT
56                 .addr   PATHNAME        ;PATHNAME
57                 .addr   MLI - 1024      ;IO_BUFFER
58 OPEN_REF:       .byte   $00             ;REF_NUM
59
60 LOADING:
61                 .byte   $0D
62                 .asciiz "Loading "
63
64 ELLIPSES:
65                 .byte   " ...", $0D, $0D, $00
66
67 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
68
69 .segment        "DATA_0300"
70
71 READ_PARAM:
72                 .byte   $04             ;PARAM_COUNT
73 READ_REF:       .byte   $00             ;REF_NUM
74 READ_ADDR:      .addr   $0000           ;DATA_BUFFER
75                 .word   $FFFF           ;REQUEST_COUNT
76                 .word   $0000           ;TRANS_COUNT
77
78 CLOSE_PARAM:
79                 .byte   $01             ;PARAM_COUNT
80 CLOSE_REF:      .byte   $00             ;REF_NUM
81
82
83 .ifndef         REBOOT
84
85 QUIT_PARAM:
86                 .byte   $04             ;PARAM_COUNT
87                 .byte   $00             ;QUIT_TYPE
88                 .word   $0000           ;RESERVED
89                 .byte   $00             ;RESERVED
90                 .word   $0000           ;RESERVED
91
92 .endif
93
94 FILE_NOT_FOUND:
95                 .asciiz "... File Not Found"
96                                 
97 ERROR_NUMBER:
98                 .asciiz "... Error $"
99
100 PRESS_ANY_KEY:
101                 .asciiz " - Press Any Key "
102
103 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
104
105 .segment        "CODE_2000"
106
107         jmp     :+
108         .byte   $EE
109         .byte   $EE
110         .byte   65
111 STARTUP:.res    65
112
113         ; Reset stack
114 :       ldx     #$FF
115         txs
116
117         ; Relocate CODE_0300 and DATA_0300
118         ldx     #<(__CODE_0300_SIZE__ + __DATA_0300_SIZE__)
119 :       lda     __CODE_0300_LOAD__ - 1,x
120         sta     __CODE_0300_RUN__ - 1,x
121         dex
122         bne     :-
123
124 .ifndef         REBOOT
125
126         ; Jump to dispatcher on program exit
127         ldy     #$4C            ; jmp
128         lda     #<EXIT
129         ldx     #>EXIT
130         sty     DOSWARM
131         sta     DOSWARM + 1
132         stx     DOSWARM + 2
133         sty     DOSCOLD
134         sta     DOSCOLD + 1
135         stx     DOSCOLD + 2
136
137         ; Jump to dispatcher on RESET
138         sta     SOFTEV
139         stx     SOFTEV + 1
140         txa
141         eor     #$A5
142         sta     PWREDUP
143
144 .else
145
146         ; Jump to RESET on program exit
147         ldy     #$4C            ; jmp
148         lda     #<RESET
149         ldx     #>RESET
150         sty     DOSWARM
151         sta     DOSWARM + 1
152         stx     DOSWARM + 2
153         sty     DOSCOLD
154         sta     DOSCOLD + 1
155         stx     DOSCOLD + 2
156         
157         ; Reboot on RESET
158         inc     PWREDUP
159
160 .endif
161
162         ; That's what it's all about !
163         lda     #<MLI
164         ldx     #>MLI
165         sta     HIMEM
166         stx     HIMEM + 1
167
168         ; Overwrite the whole system bit map
169         ldx     #($C0 / 8) - 1
170
171         ; Set protection for pages $B8 - $BF
172         lda     #%00000001
173         sta     MEMTABL,x
174         dex
175
176         ; Set protection for pages $08 - $B7
177         lda     #%00000000
178 :       sta     MEMTABL,x
179         dex
180         bne     :-
181
182         ; Set protection for pages $00 - $07
183         lda     #%11011111      ; include page $03
184         sta     MEMTABL,x
185
186         ; Remove ".SYSTEM" from pathname
187         lda     PATHNAME
188         sec
189         sbc     #.strlen(".SYSTEM")
190         sta     PATHNAME
191
192         ; Add trailing '\0' to pathname
193         tax
194         lda     #$00
195         sta     PATHNAME + 1,x
196
197         ; Copy ProDOS startup filename and trailing '\0' to stack
198         ldx     STARTUP
199         lda     #$00
200         beq     :++             ; bra
201 :       lda     STARTUP + 1,x
202 :       sta     STACK,x
203         dex
204         bpl     :--     
205
206         ; Provide some user feedback
207         lda     #<LOADING
208         ldx     #>LOADING
209         jsr     PRINT
210         lda     #<(PATHNAME + 1)
211         ldx     #>(PATHNAME + 1)
212         jsr     PRINT
213         lda     #<ELLIPSES
214         ldx     #>ELLIPSES
215         jsr     PRINT
216
217         jsr     MLI
218         .byte   GET_FILE_INFO_CALL
219         .word   GET_FILE_INFO_PARAM
220         bcc     :+
221         jmp     ERROR
222
223 :       jsr     MLI
224         .byte   OPEN_CALL
225         .word   OPEN_PARAM
226         bcc     :+
227         jmp     ERROR
228
229         ; Copy file reference number
230 :       lda     OPEN_REF
231         sta     READ_REF
232         sta     CLOSE_REF
233
234         ; Get load address from aux-type
235         lda     FILE_INFO_ADDR
236         ldx     FILE_INFO_ADDR + 1
237         sta     READ_ADDR
238         stx     READ_ADDR + 1
239
240         ; It's high time to leave this place
241         jmp     __CODE_0300_RUN__
242
243 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
244
245 .segment        "CODE_0300"
246
247         jsr     MLI
248         .byte   READ_CALL
249         .word   READ_PARAM
250         bcs     ERROR
251
252         jsr     MLI
253         .byte   CLOSE_CALL
254         .word   CLOSE_PARAM
255         bcs     ERROR
256
257         ; Copy REM token and startup filename to BASIC input buffer
258         ldx     #$00
259         lda     #$B2
260         bne     :++             ; bra
261 :       inx
262         lda     a:STACK - 1,x
263 :       sta     BUF,x
264         bne     :--
265         
266         ; Go for it ...
267         jmp     (READ_ADDR)
268
269 PRINT:
270         sta     A1L
271         stx     A1H
272         ldx     VERSION
273         ldy     #$00
274 :       lda     (A1L),y
275         beq     :++
276         cpx     #$06            ; //e ?
277         beq     :+
278         cmp     #$60            ; lowercase ?
279         bcc     :+
280         and     #$5F            ; -> uppercase
281 :       ora     #$80
282         jsr     COUT
283         iny
284         bne     :--             ; bra
285 :       rts
286
287 ERROR:
288         cmp     #FILE_NOT_FOUND_ERR
289         bne     :+
290         lda     #<FILE_NOT_FOUND
291         ldx     #>FILE_NOT_FOUND
292         jsr     PRINT
293         beq     :++             ; bra
294 :       pha
295         lda     #<ERROR_NUMBER
296         ldx     #>ERROR_NUMBER
297         jsr     PRINT
298         pla
299         jsr     PRBYTE
300 :       lda     #<PRESS_ANY_KEY
301         ldx     #>PRESS_ANY_KEY
302         jsr     PRINT
303         jsr     RDKEY
304
305 .ifndef         REBOOT
306
307 EXIT:
308         ; Reset stack
309         ldx     #$FF
310         txs
311
312         jsr     MLI
313         .byte   QUIT_CALL
314         .word   QUIT_PARAM
315         
316 .endif
317
318 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;