-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcartprg.6502
252 lines (215 loc) · 6.14 KB
/
cartprg.6502
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
\ MiniProg: A barebones programmer tool for MultiROM flash cartridge.
\ Compatible with both Master and Electron (modifies itself at runtime to use
\ appropriate ROMSEL address). Suitable for MODE 6 and PAGE <= &1D00. Loads
\ entire ROM image into buffer at once with OSFILE &FF, should be able to load
\ from tape without motor control.
\ In theory, should be able to program any SST39SF010 sideways ROM hardware, so
\ long as it maps A0-A13 directly, and A14 to the low bit of ROMSEL.
\ If set, bundle a ROM image to create a 'self-contained' installer
ROM_IMAGE =? ""
\ Friendly name for bundled ROM image, shown at startup. Defaults to ROM image filename.
ROM_IMAGE_NAME =? ""
INCLUDE "tools/common.6502"
ORG &1D00
GUARD &6000
.begin
\ Check that we have enough free memory for the buffer
\ We need up to &5FFF
OSCALL_A osbyte, &84 \ OSBYTE &84: read start of screen memory into XY
CPY #&60:BCS ram_ok \ Check high byte to make sure screen memory starts at >=&6000
LDA #&16:JSR osasci:LDA #&06:JSR osasci \ Switch into a suitable mode
.ram_ok
\ Make sure we're not running on a second processor
OSCALL_AXY osbyte, &EA, &00, &FF \ OSBYTE &EA - get/set tube presence byte
TXA:BEQ tube_ok
BRK:EQUS 0, "Tube not supported", 0
.exit
RTS \ Just a convenient place to put this, we branch to it in checks below
.tube_ok
\ Check if we're running on an Electron, and if so, patch the address of the
\ ROM selection register
OSCALL_AX osbyte, &00, &01 \ OSBYTE &00,&01: return host type in X
CPX #0:BNE not_elk \ Are we running on an Electron?
LDA #LO(elk_romsel):STA romsel_sta+1 \ Yes, patch ROMSEL address
.not_elk
LDX #(str_header - strings)
JSR print_string
\ Prompt for filename and load into buffer
IF ROM_IMAGE = ""
LDX #(str_file_prompt - strings):JSR print_string
\ OSWORD &00 - read line from console
OSCALL_WORD osword, &00, ctl_filename_prompt
BCS exit \ Escape pressed? get outta here
LDA strbuf
CMP #&0D
BNE load_file \ Got filename, try to load it
\ Filename was blank, erase ROM only
LDA #0:PHA \ push zeroed 'program enable' flag onto stack
BEQ rom_prompt \ always taken
.load_file
OSCALL_WORD osfile, &FF, ctl_file_load
JSR osfile
ENDIF
LDA #&FF:PHA \ Always set program-enable flag with bundled ROM
\ Prompt for ROM number to program
.rom_prompt
LDX #(str_rom_prompt - strings):JSR print_string
\ OSWORD &00 - read line from console
OSCALL_WORD osword, &00, ctl_rom_prompt
BCS exit \ Escape pressed? get outta here
LDA strbuf:CMP #&0D:BEQ rom_prompt \ Blank line? try again
\ Convert a single hex digit
\ Constraints (set in control block):
\ - only 1 character
\ - >= '0'
\ - <= 'f'
CMP #'9'+1:BPL char
SEC:SBC #'0':BCS convert_done
.char
AND #&DF:SEC:SBC #'A'-&0A
CMP #&0A:BMI rom_prompt \ exclude chars < A
CMP #&10:BCS rom_prompt \ exclude chars > F
.convert_done
PHA
{
\ Check for valid flash chip
TAX:JSR read_id
CMP #&BF:BNE not_flash \ Mfg ID &BF = SST
CPY #&B5:BNE unknown:BEQ is_flash \ Product ID &B5 = SST39SF010
.not_flash
\ read_id returns an invalid manufacturer ID of &00 if ID cannot be read
CMP #0
BNE unknown \ Unknown nonzero manufacturer ID. Bail out!
CPY #0
BNE ram \ &00,&01 - writeable memory, probably sideways RAM
BRK \ &00,&00 - no ID, not writeable, probably real ROM
EQUS 0, "Can't: ROM", 0
.ram
BRK
EQUS 0, "Can't: SWRAM", 0
.unknown
BRK
EQUS 0, "Unknown chip", 0
.is_flash
}
\ Erase selected ROM in preparation for programming
PLA:TAX
JSR erase_rom
PLA:BEQ finished \ pull 'program enable' flag off stack, skip programming if clear
\ Program contents of buffer into selected ROM
LDA #LO(buffer):STA bufptr
LDA #HI(buffer):STA bufptr+1
LDA #&00:STA romptr
LDA #&80:STA romptr+1
LDY #0
{
.loop
LDA (bufptr),Y
JSR write_byte
INY
BNE loop
LDA #1:BIT romptr+1:BNE skipprint
LDA #'*'
JSR osasci
.skipprint
INC romptr+1:INC bufptr+1
LDA romptr+1:CMP #&C0:BNE loop
}
JSR osnewl
\ Verify programmed ROM against buffer
LDA #LO(buffer):STA bufptr
LDA #HI(buffer):STA bufptr+1
LDA #&00:STA romptr
LDA #&80:STA romptr+1
LDY #0
{
.loop
JSR read_byte
CMP (bufptr), Y
BEQ ok
BRK
EQUS 0, "Verify failed", 0
.ok
INY
BNE loop
LDA #1:BIT romptr+1:BNE skipprint
LDA #'#'
JSR osasci
.skipprint
INC romptr+1:INC bufptr+1
LDA romptr+1:CMP #&C0:BNE loop
}
JSR osnewl
.finished
LDX #(str_done - strings)
\ Fall through to print_string and exit
\ Print a null-terminated string
\ Arguments: X - offset of string to print from 'strings' label
\ Destroys: A, X
\ Preserves: Y
.print_string
{
LDA strings, X
BEQ done
JSR osasci
INX
JMP print_string
.done
RTS
}
ENABLE_ERASE_ROM=TRUE
ENABLE_WRITE_BYTE=TRUE
ENABLE_READ_ID=TRUE
ENABLE_READ_BYTE=TRUE
INCLUDE "tools/flashio.6502"
.strings
.str_header
EQUS "MultiROM Cartridge Programmer", &0D
IF ROM_IMAGE <> ""
EQUS "Preloaded with "
IF ROM_IMAGE_NAME <> ""
EQUS ROM_IMAGE_NAME
ELSE
EQUS ROM_IMAGE
ENDIF
EQUB &0D
ENDIF
EQUB 0
IF ROM_IMAGE = ""
.str_file_prompt
EQUS "ROM Filename (blank to erase)? ", 0
ENDIF
.str_rom_prompt
EQUS "ROM # to program (0-F)? ", 0
.str_done
EQUS "Done.", &0D, 0
.ctl_rom_prompt
EQUW strbuf \ Read string to strbuf
EQUB 1 \ Maximum length 1 char
EQUB '0' \ Reject characters < '0'
EQUB 'f' \ Reject characters > 'f'
IF ROM_IMAGE = ""
.ctl_filename_prompt
EQUW strbuf \ Read string to strbuf
EQUB 255 \ Max length 255 chars
EQUB &20,&7E \ Accept any printable character
EQUB &7E
.ctl_file_load
EQUW strbuf \ Get filename from strbuf
EQUD buffer \ Load file to buffer
EQUD &0000
EQUD &0000
EQUD &0000
EQUD &0000
ENDIF
.buffer
PRINT "Buffer starts at ", ~buffer
PRINT &2000-buffer, "bytes free."
IF ROM_IMAGE <> ""
INCBIN ROM_IMAGE
.end
ELSE
.end
SKIP 16384
ENDIF
SAVE begin, end, begin