-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathbootstrap.asm
317 lines (286 loc) · 8.21 KB
/
bootstrap.asm
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
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
include "SYSVARS.asm"
org &a0
.cpsrc equw &0000
.cpdst equw &0000
.cplen equb &00
.ourrom equb &00
.dstrom equb &00
org &8000
; The included MMFS ROM is added to &4000 bytes (&3600 code, &A00 workspace)
; The guard is &CA00 as the workspace is allowed to "overflow"
guard &CA00
; A fixed buffer is now used for the copying code, as it's now self modifying
; and thus contains absolute addresses.
; Page &09 (9) - Envelope, Serial output, Speech, transient command buffer
; ========================================================================
; &0900-&09BF RS423 output buffer
; &09C0-&09FF Speech buffer
; &0900-&09FF CFS/RFS BPUT sequential output buffer (nb, *not* used by SAVE)
; &0900-&09BF ENVELOPES 5 to 16
;
; this area is reasonable safe to use in the reset sequence
code_buffer = &0900
; Page &0A (10) - Serial input, transient command buffer
; ======================================================
; &0A00-&0AFF Cassette/RS423 input buffer (nb: *not* used by LOAD)
;
; this area is reasonable safe to use in the reset sequence
copy_buffer = &0a00
; Macros to page in the ROM in the X register
;
; The Electron version is compicated by the need to
; do a double-write if the current ROM is 0x8-0xB
;
; As these slots correspond to Basic and the Keyboard
; they will not be used in the copy. So a faster version
; of the macro is used there.
;
; On the Beeb both versions are the same
IF _ELECTRON_
MACRO page_rom_x
pha
lda #&0F
sta &f4
sta &fe05
pla
stx &f4
stx &fe05
ENDMACRO
MACRO page_rom_x_fast
stx &f4
stx &fe05
ENDMACRO
ELSE
MACRO page_rom_x
stx &f4
stx &fe30
ENDMACRO
MACRO page_rom_x_fast
page_rom_x
ENDMACRO
ENDIF
.start equs "MRB"
jmp serv
equb %10000010
equb copyr-&8000
equb &01
equs "MMFS Bootstrap"
equb &00
equs "1.1"
.copyr equb &00
equs "(C) Martin Mathers, David Banks, Steven Fosdick"
equb &00
.serv cmp #&01
beq absws
rts
.absws tya
pha
lda #&fd ; get the last BREAK type.
ldx #&00
ldy #&ff
jsr OSBYTE
cpx #&00
beq docmp
.docopy lda #<copyst
sta cpsrc
lda #>copyst
sta cpsrc+1
lda #copyen-copyst
sta cplen
bne common
.docmp lda #<cmpst
sta cpsrc
lda #>cmpst
sta cpsrc+1
lda #cmpen-cmpst
sta cplen
.common
ldy #0
.loop1 lda (cpsrc),Y ; copy the copy routine into main ram.
sta code_buffer, Y
iny
cpy cplen
bne loop1
lda &f4 ; including the source ROM - this one.
sta ourrom
jmp code_buffer ; points to the RAM copy of the copy routine.
.romfai
ldx #&00
lda faimsg
.failp jsr OSWRCH
inx
lda faimsg,x
bne failp
lda cpdst+1
jsr hexbyt
lda cpdst
jsr hexbyt
jsr OSNEWL
jsr OSNEWL
jmp docopy
.hexbyt pha
lsr a
lsr a
lsr a
lsr a
jsr hexnyb
pla
.hexnyb and #&0f
cmp #&0a
bcc lten
adc #&06
.lten adc #'0'
jmp OSWRCH
.faimsg equs "MMFS RAM/ROM comparison failed at "
equb &00
.noram ldx #&00
lda normsg
.norlp jsr OSWRCH
inx
lda normsg,x
bne norlp
pla
tay
lda #&01 ; and dont "claim" this call - others ROMS
ldx ourrom ; restore the current ROM number in X
rts ; can claim workspace (we don't).
.normsg equs "No sideways RAM found for MMFS"
equb &0d,&0a,&00
;; The following is copied into RAM. It is relocatable code
;; so there is no need to change it on the fly.
MACRO csetup mode
.base
ldx #&0f ; find the highest free sideways RAM slot.
.romlp
cpx ourrom ; don't write to ourrom in case it's FLASH
beq romnxt
page_rom_x
;; Step 1: Test if candidate slot already contains a rom image
;; so we don't clobber any pre-existing ROM images
ldy &8007
lda &8000, Y
bne testram
lda &8001, Y
cmp #'('
bne testram
lda &8002, Y
cmp #'C'
bne testram
lda &8003, Y
cmp #')'
bne testram
;; Step 2: Test if that pre-existing rom image is SWMMFS
;; so we re-use the same slot again and again
lda &b5fe
cmp #MAGIC0
bne romnxt
lda &b5ff
cmp #MAGIC1
bne romnxt
;; Step 3: Check if slot is RAM
.testram
lda &8006
eor #&FF
sta &8006
cmp &8006
php
eor #&FF
sta &8006
plp
beq testdone
.romnxt
dex
bpl romlp
.testdone
stx dstrom
ldx ourrom ; page back in the source ROM
page_rom_x
.wait
lda &8000 ; some FLASH devices vanish for a while after being written to
cmp #'M' ; MRB is a signature for for the source ROM
bne wait
lda &8001
cmp #'R'
bne wait
lda &8002
cmp #'B'
bne wait
ldx dstrom ; X=FF if no RAM found
bpl gotram
jmp noram
.gotram
lda #>romst ; set the embedded MMFS ROM as thes ource of the copy
sta code_buffer + patch1 + 2 - base
lda #&80 ; set copy destination as the start the sideways RAM bank
sta code_buffer + patch2 + 2 - base
.cploop
ldx ourrom
page_rom_x_fast
ldy #&00
.cploop1
.patch1
lda romst, y ; 4
sta copy_buffer, y ; 5
iny ; 2
bne cploop1 ; 3
ldx dstrom
page_rom_x_fast
.cploop2
lda copy_buffer, y ; 4
.patch2
IF mode=1
cmp &8000, y ; 4
bne fail ; 2
ELSE
sta &8000, y ; 5
ENDIF
iny ; 2
bne cploop2 ; 3
inc code_buffer + patch1 + 2 - base
inc code_buffer + patch2 + 2 - base
lda code_buffer + patch2 + 2 - base
cmp #&b6
bne cploop
IF mode=1
beq exit ; success: exit with Z=0
.fail
sty cpdst
lda code_buffer + patch2 + 2 - base
sta cpdst + 1 ; fail: exit with Z=1
ENDIF
.exit
ENDMACRO
align &100
.copyst csetup 0
lda #&aa ; Find the ROM info table.
ldx #&00
ldy #&ff
jsr OSBYTE
stx cpdst
sty cpdst+1
lda &8006 ; copy the MMFS ROM type into the table
ldy dstrom ; entry for the RAM copy.
sta (cpdst),Y
pla
tay
lda #&01 ; and dont "claim" this call - others ROMS
ldx ourrom ; restore the current ROM number in X
page_rom_x
rts ; can claim workspace (we don't).
.copyen
align &100
.cmpst csetup 1
bne cmpfai
pla
tay
lda #&01 ; and dont "claim" this call - others ROMS
ldx ourrom ; restore the current ROM number in X
page_rom_x
rts ; can claim workspace (we don't).
.cmpfai ldx ourrom
page_rom_x
jmp romfai
.cmpen
; Page align the included MMFS ROM which will follow
; This avoids any penalties with page crossing during the copy
align &100