-
Notifications
You must be signed in to change notification settings - Fork 0
/
fallback.asm
290 lines (237 loc) · 5.08 KB
/
fallback.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
; fallback
; this is the only place where you can flash the drive from SIO
; other than that - flash and ram commands are unavailable
; so you won't accidentally brick the drive when doing normal SIO stuff.
; the only way to get here is at the beginning of the drive boot.
; procedure
; 1. power off the drive
; 2. remove any disks
; 3. CLOSE THE DRIVE DOOR (!!!IMPORTANT!!!)
; 4. power on the drive.
; 5. OPEN THE DOOR
; 6. run flasher.
.local fallback
riot equ 0x700 ; riot base address
porta equ riot ; data register port a
portb equ riot+0x02 ; data register port b
tim64 equ riot+0x16 ; timer : 64
t1024i equ riot+0x1f ; timer : 1024 interrupt enable
rambank_select equ 0x0600 ;xram bank select register
xram equ 0x0800 ;banked xram window
jumper equ $61 ;(2); $62
ztmp equ $f0 ; (3) $f1 $f2
error equ $f3 ; (1)
where equ $f4 ; (2) $f5
count equ $f7 ; (1)
cksum equ $f8 ; (1)
;reg_a equ $f9 ; (1)
cmd_frame equ $fa ; (5) $fb $fc $fd $fe $ff
dunit equ cmd_frame
dcommand equ cmd_frame+1
daux1 equ cmd_frame+2
;daux2 equ cmd_frame+3
;crc equ cmd_frame+4
main jsr getcmd
jmp main
getcmd lda #2
bit portb
bne ret
bmi *+3
ret rts
mva #4 count
mwa #cmd_frame where
jsr read_from_serial ; read 4 bytes with time out
wait_end bit portb ; wait until command on zero
bmi wait_end
bit error
bvs chksumerr
lda porta
and #3 ; drive number
tax ; to x reg
lda drvnr,x ; drive number same
cmp dunit ;cmd_buf ; as in command frame[0]
bne notme ; no, error
ldx #0
search lda cmds,x
cmp dcommand ;cmd_buf+1
beq execute
inx
cpx #cmds_len
bcc search
lda status
ora #1
sta status
jsr send_nak ;lda status
notme rts
execute lda lows,x
sta jumper
lda highs,x
sta jumper+1
jmp (jumper)
chksumerr lda status
ora #2
sta status
rts
go_putmem;rombank #0
jsr put_memory
rts
go_run ;rombank #0
jsr run_memory
rts
drvnr .byte $33,$32,$34,$31,$ff,$00
;
cmds dta b($f0),b($f2)
cmds_len equ (*-cmds)
;
lows dta l(go_putmem),l(go_run)
highs dta h(go_putmem),h(go_run)
put_memory bit daux1
bpl dalej ; cmp #$80; bcc dalej
jsr send_nak
rts
;
dalej jsr send_ack
lda daux1 ; podzielimy przez 8 da nam nr banku
lsr @
lsr @
lsr @
sta rambank_select
;
lda daux1 ; page moze byc od 0 do 7
and #%00000111
clc
adc >xram
sta where+1
mva <xram where ; where now points to bank+page[0]
mva #0 count
jsr read_from_serial
wait900us
;
bit error
bvs errrr
;
jsr send_ack
jsr send_compl
rts
errrr; status_cksum_err
jsr send_error
rts
; run program @adr in ram
; daux1,daux2 = lsb,msb
run_memory jsr send_ack
jmp (daux1)
rts
; stock serial routine
.align $100,$ff
sendbyte sta ztmp ; save char
sty ztmp+1 ; save checksum
stx ztmp+2 ; save x
ldy #8 ; send 8 bits
lda #$fe ; set start bit
and portb ; ...and send
sta portb
inc ztmp+2 ; delay
sbyte1 ror ztmp ; next data bit
bcc sbit0 ; send '0' bit
lda #1 ; send '1' bit if carry set
ora portb
bne sbit ; send bit
sbit0 lda #$fe ; send '0' bit
and portb
nop ; keep synchronous
sbit ldx #5 ; send bit
dex ; delay
bne *-1
sta portb ; to port
dey ; done?
bne sbyte1
ldx #6 ; delay for last bit
dex
bne *-1
nop
dec ztmp+2 ; delay
lda #1 ; send stop bit
ora portb
sta portb
ldx #5 ; delay for stop bit
dex
bne *-1
ldx ztmp+2 ; restore x
ldy ztmp+1 ; and y
lda ztmp ; and a
rts ; done
readbyte sty ztmp+2 ; save x reg
wsb bit porta ; wait for start bit
bvc err1 ; data interrupt from floppy?
bit portb ; or data in at port 6 high?
bvc wsb ; no
sec ; otherwise
lda #$80 ; bit 7 mark for end
ldx #6 ; wait 0.5 bit time
dex
bne *-1
w32b ldx #6 ; wait 2/3 bit time
dex ; to get first bit in the middle
bne *-1
nop
nop
nop
bit portb ; bit 1 or 0?
bvc bit1
clc ; got a zero
bcc nxtbit
bit1 sec ; got a one
nop ; keep in same tempo as bcc
nxtbit ror @ ; roll bit in result
bcc w32b ; already 8 bits?
ldy ztmp+2 ; restore x reg
rts
err1 pla
pla
jmp errstat
read_from_serial timeout #$ff ;lda #$ff
mva #0 ztmp ;lda #0 ; reset checksum
tay
; sta ztmp
; data byte
rnxtb jsr readbyte ; read byte
sta (where),y ; and store it
clc ; add to checksum
lda ztmp
adc (where),y
adc #0
sta ztmp
iny ; buffer pointer + 1
dec count ; job done?
bne rnxtb ; no, continue
; chksum
jsr readbyte ; yes, read checksum
sta cksum ;(where),y ; store
lda ztmp ; and compare with accumulated value
eor cksum ;(where),y
beq norerr ; br if ok
errstat lda #$40
norerr sta error
lda tim64 ; reset timeout counter
rts
send_ack lda #'A'
jsr sendbyte
rts
send_nak lda #'N'
jsr sendbyte
rts
send_compl lda #'C'
jsr sendbyte
rts
send_error lda #'E'
jsr sendbyte
rts
delay1 ldy #$12
dey
bne *-1
dex
nop
nop
bne delay1
rts
.endl