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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
|
; 20221210 bkw: reverse-engineered "source" for setmem.xex.
; originally created with da65 (cc65's disassembler), then
; hand-edited to make it (hopefully) more human-readable.
; By default, this builds the original setmem.xex, 877 bytes,
; md5sum f7834eaf50e8b5d5314a20f6a5d83a0d.
; I've added a couple of optional defines:
; reverse_logic - For upgrades that have 256K/compy as the default.
; coldstart - Reboot the Atari instead of exiting to DOS. For use
; with SpartaDOS X, which crashes if we exit to DOS
; after changing the mode.
; See the Makefile for build options.
.include "atari.inc"
.include "xex.inc"
.include "inv.inc"
; 2 byte ZP pointer used for printing text.
msgptr = $cc
; "Magic" hardware register. On an un-upgraded Atari, $d3f3 is just
; a "mirror" of $d303 (aka PBCTL). It's special on the tfhh upgrade
; though: changing it to $d303 here results in a non-functional setmem.xex.
; Also note that writing to $d3f3 only affects the upgrade if the
; Start key is pressed... and even when Start is pressed, writing
; to $d3f3 still changes PBCTL.
magic_register = $d3f3
loadaddress = $3000
xex_org loadaddress
entrypoint:
cld ; unnecessary.
lda #$08
sta CONSOL ; clicks the consol speaker (no idea why).
lda #$00
sta choice ; choice = 0 (but it immediately gets inc'd to 1).
next_choice:
inc choice ; choice++;
lda choice
cmp #$03
bne choice_ok
lda #$00 ; if(choice == 3) choice = 0;
sta choice
choice_ok:
lda #<banner_msg
sta msgptr
lda #>banner_msg
sta msgptr+1
jsr print_msg
lda choice
clc
asl a
asl a
tay ; Y = choice * 4;
lda msg0,y
sta msgptr
lda msg0+1,y
sta msgptr+1
lda magicbits_0,y
sta magic_bits
jsr print_msg
read_consol:
lda CONSOL
and #$07
cmp #$03
beq option_pressed
cmp #$06
beq start_pressed
cmp #$05
bne read_consol
select_pressed:
lda CONSOL
and #$07
cmp #$07
bne select_pressed
beq next_choice
option_pressed:
lda #<no_change_msg
sta msgptr
lda #>no_change_msg
sta msgptr+1
print_and_exit:
jsr print_msg
lda #$00
tax
tay
rts
; apply the current choice to the hardware
start_pressed:
sei ; disable IRQs
lda #$00
sta NMIEN ; disable NMIs
lda magic_register
and #$FC
ora magic_bits
sta magic_register
wait_consol_release:
lda CONSOL
and #$07
cmp #$07
bne wait_consol_release
lda #$40
sta NMIEN ; re-enable NMIs
cli ; re-enable IRQs
.ifdef coldstart
jmp COLDSV
.else
lda #<mode_set_msg ; "Mode was set...."
sta msgptr
lda #>mode_set_msg
sta msgptr+1
jmp print_and_exit
.endif
; print null-terminated ATASCII message pointed to by (msgptr).
print_msg:
lda #$00
tax
tay
sta ICBLL,x
sta ICBLH,x
lda #PUTCHR
sta ICCOM,x
lda msgptr
sta ICBAL,x
lda msgptr+1
sta ICBAH,x
nextchar:
lda (msgptr),y
beq call_cio
iny
bne zptr_hi_ok
inc msgptr+1
zptr_hi_ok:
inc ICBLL,x
bne nextchar
inc ICBLH,x
bne nextchar
call_cio:
jmp CIOV
; R/W data (2 bytes):
choice: .byte $00 ; Currently chosen option (default 1, range 0 to 2).
; This gets set to one of disable_magic, compy_magic, or rambo_magic.
; Bits 0 and 1 will get ORed into magic_register.
magic_bits: .byte $00
; R/O data (rest of file):
disable_magic = $01
.ifdef reverse_logic
compy_magic = $00
rambo_magic = $02
.else
compy_magic = $02
rambo_magic = $00
.endif
; Table of 3 4-byte entries, one per choice. 4th byte is filler (always 0).
msg0: .addr disable_msg
magicbits_0: .byte disable_magic
filler_0: .byte 0
msg1: .addr compy_msg
magicbits_1: .byte compy_magic
filler_1: .byte 0
msg2: .addr rambo_msg
magicbits_2: .byte rambo_magic
filler_2: .byte 0
; Rest of the data is messages to be printed to IOCB#0 by print_msg.
; These are null-terminated.
banner_msg:
.byte CLS
.byte EOL
inverse " Setup tool for tfhh SRAM expansions "
.byte EOL,EOL
.ifdef reverse_logic
inverse "Reverse Logic"
.byte " - This"
.else
.byte "20210614"
.byte " - This tool"
.endif
.byte " works with:"
.byte EOL,EOL
.byte "- 512 KB SRAM memory expansion "
inverse "V4.5"
.byte EOL
.byte " (please check revision number!)"
.byte EOL,EOL
.byte "- 576 KB SRAM memory expansion "
inverse "V2"
.byte EOL
.byte " (only for the Atari 600XL, please"
.byte EOL
.byte " check the presence of "
.byte '"', "V2", '"', " printed", EOL
.byte " on the PCB)"
.byte EOL,EOL
.byte "Use console key "
inverse " SELECT "
.byte " to change"
.byte EOL
.byte "the desired mode, press "
inverse " OPTION "
.byte " to"
.byte EOL
.byte "quit this tool without any change"
.byte EOL
.byte "or press "
inverse " START "
.byte " to setup the SRAM"
.byte EOL
.byte "memory expansion as shown and"
.byte EOL
.ifdef coldstart
inverse "reboot"
.byte " the Atari."
.else
.byte "return to DOS."
.endif
.byte EOL,EOL
.byte "Expansion will be set to: "
.byte EOL,EOL
.byte "==> "
.byte 0
disable_msg:
inverse " Memory Expansion switched off"
.byte 0
compy_msg:
inverse " 256 KByte Compy-Shop/XE mode"
.byte 0
rambo_msg:
inverse " 512 KByte RAMBO mode"
.byte 0
mode_set_msg:
inverse " "
.byte EOL,EOL
.byte "Mode was set. Program terminated."
.byte EOL,EOL,0
no_change_msg:
inverse " "
.byte EOL,EOL
.byte "Nothing changed. Programm terminated."
.byte EOL,EOL,0
xex_run entrypoint
|