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
|
; 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).
.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:
ldx #$10 ; IOCB #1
lda #$28 ; MyDOS XIO 40. 39 also works (same thing?), neither works on SDX
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
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
dla_filename: .byte "D:DLA.XEX"
dla_fn_len = * - dla_filename
csv_filename: .byte "D:DLA2CSV.XEX"
csv_fn_len = * - csv_filename
; 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
xex_run main
|