aboutsummaryrefslogtreecommitdiff
path: root/autorun.s
blob: af3b1d954e7c37fa3978521ca359062e9694e7c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
; autorun.s - display an intro screen and a menu from which the user
; can launch dla.xex or dla2csv.xex, or exit to DOS.

; I was *going* to write this in C, using cc65's exec()... but it
; turns out to only be implemented on XDOS, which is a rather uncommon
; DOS. MyDOS has XIO 40 (execute binary file), which is a lot easier
; to deal with in asm. Other DOSes might support XIO 40, and/or this
; might support other DOSes someday... Or I could write my own xex
; file loader (rather not).

; SDX 4.41 manual says: XIO 40,#IOCB,4,X,"Dd:[path]fname.ext" where
; X=0 for load and execute (X=128 is load only, we don't want that).
; manual also says it works the same way in Sparta 3.2.

; MyDOS 4.50 technical manual says XIO 39 and 40 are identical, and
; that AUX1 should be 4 to load & execute the program (AUX2 doesn't
; do anything). MyDOS 4.30 only documents 39, but I don't care about
; versions older than 4.50.

; So for all 3 DOSes, XIO 40,#x,4,0,"filename" works... XXX: except it
; doesn't, quite. MyDOS and Sparta 3.2 can load & run both dla.xex and
; dla2csv.xex. SDX 4.42 will load & run dla2csv.xex, but fails with
; error 150 for dla.xex (error 150 is "path not found", no idea what's
; going on here). This autorun.sys only has to work on MyDOS, which
; it does...

; Eventually I should send the cc65 devs a patch to implement exec()
; on MyDOS and Sparta.

 .include "atari.inc"
 .include "xex.inc"

 .bss
 .org $80

old_sdlstl: .res 1
old_sdlsth: .res 1
old_color2: .res 1
old_color1: .res 1
keycode:    .res 1

 .code

 ; this doesn't have to be aligned on a 4K boundary, but it should
 ; be aligned to 1K.
loadaddr = $3000

 xex_org loadaddr
screendata:
 .incbin "about.dat" ; generated from ABOUT.txt, by text2screen.pl

 ; 960 bytes is exactly one GR.0 screen (40x24)
 .if ((* - screendata) <> 960)
   .error .sprintf("%c*** about.dat is %d bytes (should be 960)", 10, * - screendata)
 .endif

 ; bog-standard GRAPHICS 0 display list (except the LMS address)
dlist:
 .byte DL_BLK8, DL_BLK8, DL_BLK8
 .byte DL_CHR40x8x1 | DL_LMS
 .word screendata
 .repeat 23
  .byte DL_CHR40x8x1
 .endrep
 .byte DL_JVB
 .word dlist

 .if ((* / 1024) <> (screendata / 1024))
  .error .sprintf("%c*** screendata and dlist cross a 1K boundary!", 10)
 .endif

 .include "io.s"
 .include "printint.s"

main:
 ; fix things so the Reset key doesn't do a coldstart, see
 ; BOOT? and COLDST in Mapping.
 ldx #0
 stx COLDST
 inx
 stx BOOTQ

 ; save the OS's colors and display list.
 lda SDLSTL
 sta old_sdlstl
 lda SDLSTH
 sta old_sdlsth
 lda COLOR1
 sta old_color1
 lda COLOR2
 sta old_color2

 ; use our own colors and display list (displays our message).
 lda #$90
 sta COLOR2
 lda #$0e
 sta COLOR1
 lda #<dlist
 sta SDLSTL
 lda #>dlist
 sta SDLSTH

 ; wait for a keypress
keyloop:
 lda CH
 cmp #KEY_NONE
 beq keyloop

 sta keycode ; got a keypress, save it for later

 ; clear keypress so the loaded program won't see it
 lda #$ff
 sta CH

 ; restore OS's colors and display list (back to regular E:)
 lda old_sdlstl
 sta SDLSTL
 lda old_sdlsth
 sta SDLSTH
 lda old_color1
 sta COLOR1
 lda old_color2
 sta COLOR2

 ; see what key was hit
 ldy #0
keytabloop:
 lda keytab,y   ; get table entry
 cmp #KEY_NONE  ; did we hit the end of the table with no match?
 beq exit       ; yes, we're done
 cmp keycode    ; no, see if this table entry matches
 beq load_file  ; yes, use it
 iny            ; no, look at next entry
 bne keytabloop ; branch always

 ; load and run the file (Y is index into filename table)
load_file:
 ; first print a "Loading D1:whatever" message.
 sty keycode
 lda #<loadingmsg
 ldx #>loadingmsg
 jsr printmsg
 ldy keycode
 lda fntab_l,y
 ldx fntab_h,y
 jsr printmsg
 ldy keycode

 ; now we can set up the IOCB and call CIO to load the file.
 ldx #$10 ; IOCB #1
 lda #$28 ; MyDOS, Sparta 3.2, and SDX all support this XIO
 sta ICCOM,x
 lda fntab_l,y  ; filename
 sta ICBAL,x
 lda fntab_h,y
 sta ICBAH,x
 lda fnlentab,y ; filename length
 sta ICBLL,x
 lda #0
 sta ICBLH,x
 sta ICAX2,x    ; AUX1=0: On Sparta means "load & run", on MyDOS ignored.
 lda #4
 sta ICAX1,x    ; AUX2=4: On MyDOS means "load & run", on Sparta 4 is required.
 jsr CIOV       ; pull the trigger

 ; CIOV should never return on success, so if we get here, give up.
 tya
 pha ; save CIO return status (aka error number)
 lda #<diskerrmsg
 ldx #>diskerrmsg
 jsr printmsg ; print error message
 pla
 jsr printdecb ; print error number
 lda #<presskeymsg
 ldx #>presskeymsg
 jsr printmsg  ; press a key...

 ; wait for a keypress, to give the user a chance to read the
 ; error message.
keyloop2:
 lda CH
 cmp #KEY_NONE
 beq keyloop2
 lda #KEY_NONE
 sta CH
exit:
 rts

 ; SDX insists these must be D1:, not just D:. There's probably
 ; a good reason...
dla_filename: .byte "D1:DLA.XEX"
dla_fn_len = * - dla_filename
 .byte 0 ; null terminate for printmsg

csv_filename: .byte "D1:DLA2CSV.XEX"
csv_fn_len = * - csv_filename
 .byte 0

; these tables only have 2 entries, but could have many more if
; we ever need them (up to 255).
fntab_l:  .byte <dla_filename, <csv_filename
fntab_h:  .byte >dla_filename, >csv_filename

fnlentab: .byte dla_fn_len, csv_fn_len

; KEY_NONE marks the end of this table.
keytab: .byte KEY_1, KEY_2, KEY_NONE

diskerrmsg:  .byte "I/O Error ",0
presskeymsg: .byte $9b,"Press any key...",0
loadingmsg:  .byte "Loading ",0

xex_run main