aboutsummaryrefslogtreecommitdiff
path: root/setmem.s
blob: 0b53c616452b1077aca7246b0215d580b580c1cf (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
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