aboutsummaryrefslogtreecommitdiff
path: root/autorun.s
blob: dc0f5dd468fa5cfbb63bbc857913f6252dc5bd18 (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
; 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