forked from mist64/cbmsrc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
burstc.src
1459 lines (1242 loc) · 30.5 KB
/
burstc.src
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
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
.messg "burstc"
.subttl "burstc"
.page
logical_err
lda #%10001101
jmp fail
logical_rd
lda dkoramask
bmi logical_err
ldx #0 ; job #0
lda cmdbuf+3 ; get track
sta hdrs,x
lda cmdbuf+4 ; get sector
sta hdrs+1,x
lda #read_dv ; read
jsr stbctl
jsr upinst ; update controller status
bit switch ; check E
bvs lerror_sw
cmp #2 ; error
bcc lerror_sw
jmp fail
lerror_sw
jsr hskstat ; handshake on state of clkin
ldy #0 ; even page
sty bufpnt
lda #>buff0
sta bufpnt+1 ; pointer to data
1$ lda (bufpnt),y ; get data
jsr hskrd ; handshake on state
iny
bne 1$
dec cmdbuf+5 ; any more sectors
beq 2$
jsr lsectnx ; next sector
jmp logical_rd ; read next
2$ jmp lchksee ; next track
.page
nchnl lda #%00001011 ; no channel
.byte skip2
ndkrd lda #%01001111 ; no drive
fail jsr upinst ; update dkmode
jsr statqy ; wait for state handshake
final lda burst_stat
cmp #2
bcs exbad
rts
exbad and #15 ; bits 0-3 only
ldx #0 ; jobnum
jmp error ; controller error entry
.page
; (1) FAST READ
fstrd lda wpsw ; disk change?
bne nchnl ; br, bad
fstread jsr fspout ; output mode
lda switch ; check for L
bmi logical_rd
ldx #0 ; job #0
lda cmdbuf+3 ; get track
sta hdrs,x
lda cmdbuf+4 ; get sector
sta hdrs+1,x
lda switch
and #bit4
sta sids,x
lda #tpread_dv ; read
jsr stbctl
jsr upinst ; update controller status
bit switch ; check E
bvs error_sw
cmp #2 ; error
bcs fail
error_sw
jsr hskstat ; handshake on state of clkin
buffer_sw
ldy #0 ; even page
sty bufpnt
lda cacheoff,y
and #all-bit7
clc
adc cache+1
sta bufpnt+1 ; pointer to data
ldx psectorsiz
cpx #3
bne 1$
inx
1$ lda (bufpnt),y ; get data
jsr hskrd ; handshake on state
iny
bne 1$
dex
beq trans_sw
inc bufpnt+1
bne 1$ ; bra
trans_sw
dec cmdbuf+5 ; any more sectors ?
beq 1$
jsr sectnx ; next sector
jmp fstread ; more to do
1$ jmp chksee ; next track ?
.page
; (2) FAST WRITE
logical_werr
lda #%10001101
sta burst_stat
lda switch ; set internal abort switch
ora #%00001000
sta switch
bne lfstwrite ; bra
logical_wrt
lda dkoramask
bmi logical_werr
lfstwrite
ldy #0
sty bufpnt
lda #>buff0
sta bufpnt+1
1$ lda pb ; debounce
eor #clkout ; toggle state of clock
bit icr ; clear pending
sta pb
lda #8
2$ bit pb
bmi 3$ ; br, attn low
bit icr ; wait for byte
beq 2$
lda sdr ; get data
sta (bufpnt),y ; put away data
iny
bne 1$ ; more ?
beq ltrans_sw1 ; bra
3$ jsr tstatn
jmp 2$ ; if it comes back then ok
labort_sw
lda burst_stat
jmp fail ; abort
ltrans_sw1
jsr clkhi ; release clock
lda switch ; check internal abort switch
and #%00001000
bne labort_sw ; br, ok...
ldx #0 ; job #0
lda cmdbuf+3 ; get track
sta hdrs,x
lda cmdbuf+4 ; get sector
sta hdrs+1,x
lda #wrtsd_dv ; get write job
jsr stbctl
jsr upinst ; update status
jsr statqb ; send status
bit switch ; check error ignore switch
bvs 1$
lda burst_stat
cmp #2 ; error on job ?
bcc 1$
jmp exbad
1$ dec cmdbuf+5 ; any more sectors
beq 2$
jsr lsectnx ; next sector
jmp logical_wrt
2$ jmp lchksee ; next track
.page
wnochnl lda #%00001011 ; no channel
.byte skip2
ndkwrt lda #%01001111 ; no drv 1
sta burst_stat
jmp fstwrt1 ; bra
fstwrt lda wpsw ; disk change
bne wnochnl
lda switch ; check for logical
bpl 1$
jmp logical_wrt
1$ ldx #0 ; job #0
lda switch
and #bit4
sta sids,x
lda cmdbuf+3 ; get track
sta hdrs,x
lda cmdbuf+4 ; get sector
sta hdrs+1,x
lda #tpwrt_dv ; get write job
jsr stbctl
jsr upinst ; update status
cmp #2
bcc fstwrite
lda #0
sta dirty ; clear dirty flag
fstwrt1 lda switch ; set internal abort switch
ora #%00001000
sta switch
fstwrite
jsr cachepoint ; set pointer to cache buffer
ldx psectorsiz
cpx #3
bne 1$
inx
1$ lda pb ; debounce
eor #clkout ; toggle state of clock
bit icr ; clear pending
sta pb
lda #8
2$ bit pb
bmi 3$ ; br, attn low
bit icr ; wait for byte
beq 2$
lda sdr ; get data
sta (bufpnt),y ; put away data
iny
bne 1$ ; more ?
inc bufpnt+1
dex
bne 1$
beq trans_sw1 ; bra
3$ jsr tstatn
jmp 2$ ; if it comes back then ok
abort_sw
lda burst_stat
jmp fail ; abort
trans_sw1
jsr clkhi ; release clock
lda switch ; check internal abort switch
and #%00001000
bne abort_sw ; br, ok...
jsr statqb ; send status
bit switch ; check error ignore switch
bvs buffer_sw1
lda burst_stat
cmp #2 ; error on job ?
bcc buffer_sw1
jmp exbad
buffer_sw1
dec cmdbuf+5 ; more sectors ?
beq 1$
jsr sectnx ; increment sector
jmp fstwrt
1$ jmp chksee ; next track ?
cachepoint
ldy #0 ; even page
sty bufpnt
lda cmdbuf+4 ; sector
sec
sbc pstartsec
ldx psectorsiz ; multiply by sector size
1$ dex
beq 2$
asl a
jmp 1$
2$ clc
adc cache+1 ; add offset
sta bufpnt+1
rts
.page
; (3) FAST SEEK
fstsek lda cmdbuf+2 ; check drive number
and #1
bne 1$ ; drive 1 - error
ldx #0
stx dkmode
lda #restore_dv
jsr stbctl ; restore head
php
cli
lda #bit7
sta xjobrtn ; return
jsr jintdsk ; init new dsk
jsr initdr ; read in appropiate info
asl xjobrtn ; clear
plp
lda switch
and #bit4
lsr a
lsr a
lsr a
lsr a
sta sids,x
lda #side_dv ; select side
jsr strobe_controller
lda #seekhd_dv ; seek
jsr stbctl
.byte skip2 ; return status
1$ lda #%01001111 ; no drv 1
2$ jsr fail ; update status
lda #1
sta minsek
sta pstartsec
ldx header+3
lda nsecks,x ; get max #
beq 3$ ; br, error
sta pnumsec
sta pendsec
sta maxsek
rts
3$ lda #$0e
bne 2$ ; bra, not supported
nsecks .byte 0,16,10,5
.page
nonedr lda #%01001111 ; no drive one
jsr upinst ; update status
jmp final ; finish up ...
; (4) BURST FORMAT MFM/GCR
fstfmt lda cmdbuf+2 ; check drive number
and #1
bne nonedr
lda cmdbuf+2 ; format gcr or mfm ?
bpl usenew
; (4) FORMAT DISK
; 0 1 2 3 4 5 6 7 8 9 + cmdbuf
; ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
; "U" + "0" + N + SZ + LT + NS + ST + FL + SS + GP
lda cmdsiz ; setup default parms
sec
sbc #3 ; less mandatory + 1
tay
beq sz00 ; not sz
lda cmdbuf+3
sta psectorsiz
dey
beq lt00 ; sz only, not lt
dey
beq ns00 ; sz, lt only, not ns
dey
beq st00 ; sz, lt, ns only, not st
dey
beq fl00 ; sz, lt, ns, st only, not fl
dey
beq ss00 ; sz, lt, ns, st ,fl only, not ss
lda cmdbuf+8
sta pstartsec
dey
beq gap00 ; sz, lt, ns, st ,fl,ss only, not gp
lda cmdbuf+9
sta gap3
jmp startfmt
fmtfil .byte 'N0:COPYRIGHT CBM,86',$0D
flenf=*-fmtfil
usenew
ldy #flenf-1
1$ lda fmtfil,y
sta cmdbuf,y ; transfer filename to cmd buffer
dey
bpl 1$
lda #20
sta cmdsiz
lda #17
sta filtbl+1 ; set dskid
lda #1
sta filtbl
ldx #0
jmp jnew ; new it
.page
cp00
sz00 lda #sysiz ; 512 byte sectors
sta psectorsiz
lt00 lda #79 ; last track is #79, 80 tracks total
sta cmdbuf+4 ; *** pmaxtrk ***
ns00 ldx psectorsiz
lda nsecks,x ; x=sector size index for # of sectors per track
sta cmdbuf+5 ; *** pnumsec ***
st00 lda #0 ; default track #0 start
sta cmdbuf+6 ; *** startrk - 1 ***
fl00 lda #$e5 ; default block fill
sta cmdbuf+7 ; *** fillbyte ***
ss00 lda #1
sta pstartsec
gap00 ldx psectorsiz
lda gp3,x ; get gap
sta gap3
.page
startfmt
lda startrk
pha
lda fillbyte
pha
lda pmaxtrk
pha
lda cmdbuf+4
sta pmaxtrk ; maximum track
lda cmdbuf+5 ; # of sectors
sta pnumsec
clc
adc pstartsec
sec
sbc #1 ; get ending sector and maximum sector
sta pendsec
sta maxsek
ldy cmdbuf+6 ; store logical
iny
sty startrk
lda cmdbuf+7
sta fillbyte
lda startrk
sta track
lda #0
sta sector
jsr seth ; set header
lda #restore_dv
jsr strobe_controller
lda #formatdk_dv
jsr strobe_controller
cmp #2
bcs c_801
c_802 lda #0
.byte skip2
c_801 lda #6
jsr upinst
pla
sta pmaxtrk
pla
sta fillbyte
pla
sta startrk
jmp final
gp3 .byte 14,22,38,68
.page
; (5) SOFT INTERLEAVE NOT SUPPORTED
cpmint
lda #%00001110 ; syntax error
jsr upinst ; update dkmode
lda #badcmd
jmp cmderr
.page
; (6) QUERY DISK FORMAT
querdk jsr fstsek ; send initial
ldx #0
stx tmp+5
lda #restore_dv
jsr strobe_controller
cmp #2
bcs 2$
bit switch ; seek to n-track ?
bpl 1$
lda cmdbuf+3
sta hdrs2 ; goto this track
lda #seek_dv
jsr strobe_controller
cmp #2
bcs 2$
1$ lda header
sta pstartrk ; physical starting track
lda switch
and #bit4
lsr a
lsr a
lsr a
lsr a
sta sids,x
lda #side_dv
jsr strobe_controller
lda #seekhd_dv ; read a header
jsr strobe_controller
cmp #2
bcs 2$
lda header+2 ; sector is?
sta tmp+6 ; this is where we stop
3$ ldx #0
lda #seekhd_dv
jsr strobe_controller
cmp #2
bcs 2$
lda header+2 ; get next sector
ldy tmp+5
sta cmdbuf+11,y
inc tmp+5 ; inc sector count
cpy #31 ; went too far ?
bcs 5$
cmp tmp+6 ; done yet ?
bne 3$ ; wait for rap...
lda tmp+5
sta pnumsec ; physical
lda #0
.byte skip2
5$ lda #2
2$ jsr upinst
cmp #2
bcc 4$
jmp fail
4$ jsr maxmin ; determine low/high sector
jsr spout ; serial port output
lda minsek
sta pstartsec
lda maxsek ; send max.
sta pendsec
jsr hskstat ; send status
lda pnumsec ; get number of sectors
jsr hskrd ; send it
lda header ; get logical track number
jsr hskrd ; send track
lda minsek
jsr hskrd ; wait for handshake
lda maxsek ; send max.
jsr hskrd ; wait for handshake
lda #1
jsr hskrd ; interleave
lda #bit5
bit switch
beq 7$
ldy #0
6$ lda cmdbuf+11,y
jsr hskrd ; send back sector table
iny
cpy pnumsec ; done?
bne 6$
7$ rts
.page
; (7) QUERY/INIT STATUS
inqst bit switch ; read/write op ?
bpl wrstat
statqy jsr fspout ; serial port out
jsr hskstat ; send status
jmp fspinp ; serial port input
wrstat lda cmdbuf+3 ; new value
sta dkmode
lda #bit5
bit switch ; M mask?
beq 1$
lda cmdbuf+4 ; new value
sta dkoramask
lda cmdbuf+5 ; new value
sta dkandmask
1$ bit switch ; clear wp-latch the hard way
bvc 2$
php
cli
lda #bit7
sta xjobrtn ; return
jsr jintdsk ; init new disk
jsr initdr ; read in appropiate info
asl xjobrtn ; clear
plp
rts
2$ lda #bit1
sta wpsw
jmp jintdsk ; clear it default
.page
; (8) BACKUP DISK
duplc1 ldx #%00001110
jsr upinst ; update dkmode
lda #badcmd
jmp cmderr
.page
; (9) DUMP BUFFER
dumpbuf lda cmdbuf+2 ; check drive number
tay ; save it
and #1
bne 2$ ; drive 1 - error
ldx #0 ; job 0
tya ; retrieve
bpl 1$ ; force bit on?
and #bit6 ; extract side
lsr a
lsr a
lsr a
lsr a
lsr a
lsr a
and #bit0 ; got this bit correct!!!
sta cacheside
lda cmdbuf+3
sta cachetrk
lda #bit7
sta dirty
1$ lda dirty ; dirty?
bpl 3$
lda #detwp_dv ; wp?
jsr strobe_controller
sta wpstat
bne 4$ ; br, wp
lda #bit7
sta xjobrtn
jsr jdumptrk ; dump it now!!!
asl xjobrtn
.byte skip2 ; return status
2$ lda #%01001111 ; no drv 1
.byte skip2
3$ lda #0
4$ jmp fail ; update status
.page
; SUBROUTINES
lchksee
dec cmdbuf+6
chksee lda cmdsiz ; chk for next track
cmp #7
bcc 1$
ldx #0
lda cmdbuf+6 ; next track
sta hdrs,x
lda #pseek_dv
jmp strobe_controller
1$ rts
;******************************************************
statqb jsr fspout ; serial port out
jsr hskstat ; send status
jsr burst ; other side
jmp fspinp ; serial port input
;******************************************************
upinst sta burst_stat
ldx psectorsiz
lda dkmode ; update main status w/ controller status
and #%10000000 ; clear old controller status
ora burst_stat
ora shftsiz,x ; mask in sector size
and dkandmask ; mask status
ora dkoramask ; *
sta dkmode ; updated
lda burst_stat
rts
shftsiz .byte $00,$10,$20,$30
;******************************************************
hsktst jmp tstatn ; test for atn
hskrd pha
1$ lda pb ; debounce
cmp pb
bne 1$
and #$ff ; set/clr neg flag
bmi hsktst ; br, attn low
eor fsflag ; wait for state chg
and #4
beq 1$
hsksnd pla ; retrieve data
sta sdr ; send it
lda fsflag
eor #clkin ; change state of clk
sta fsflag
lda #8
1$ bit icr ; wait transmission time
beq 1$
rts
;******************************************************
hskstat
lda dkmode ; get status and send it
jmp hskrd ; transmit status
;******************************************************
stbctl
pha
lda #bit6
sta jobrtn ; no check t&s, vernum
pla
stbctr php
cli ; let controller run free
sta cmd ; save cmd for later
jsr strobe_controller
cmp #2 ; was there an error ?
bcc 1$ ; br, nope
jsr stbret ; let DOS retry
1$ lda #0
sta jobrtn
lda jobs,x ; get error
plp ; restore status
rts
;******************************************************
stbret lda jobrtn
ora #bit7
sta jobrtn ; set error recovery on
stx jobnum ; set job #
lda cmd ; set for dos
sta lstjob,x ; set last job
jsr strobe_controller
jmp watjob ; let dos clean it up
;******************************************************
dumptrk lda #trkwrt_dv
sta lstjob,x
lda cachetrk
sta track
lda pstartsec
sta sector ; sector
stx jobnum
txa
jsr seth
ldx jobnum
lda revcnt
and #$3f
sta cmd ; set retry
jsr firstdump ; first dump
bcc 3$
1$ jsr retrydump ; retry dump
bcc 3$
dec cmd
bne 1$
bit xjobrtn
bmi 3$ ; ok return
bit jobrtn
bmi 3$ ; ok return
jmp quit2
3$ rts
;******************************
retrydump
lda #bit7
sta dirty
firstdump ; Ah .. Oh .. Eh
lda track
sta cachetrk ; set track
ldy #1
jmp dorec1 ; go for it
;******************************************************
burtst jsr tstatn ; test for atn
burst
1$ lda pb ; debounce
cmp pb
bne 1$ ; same ?
and #$ff ; set/clr neg flag
bmi burtst ; br, attn low
eor fsflag ; wait for state chg
and #4
beq 1$
eor fsflag
sta fsflag ; state change
rts
;******************************************************
sectnx sec
lda minsek
beq 1$
sbc #2
.byte skip2
1$ sbc #1
sta tmp+5 ; save min sector - 1, -2
lda cmdbuf+4 ; get original sector
cmp maxsek
beq 2$ ; equal to or
clc
adc #1 ; next sector
jmp 5$
2$ lda switch ; check side
tay
eor #bit4 ; invert side
sta switch
tya
and #bit4
beq 4$ ; bra
3$ inc cmdbuf+3 ; next track
4$ lda pstartsec
bcs 6$ ; bra ... here or there
5$ bcc 6$ ; less than
sbc maxsek ; rap around
clc
adc tmp+5 ; add min now
6$ sta cmdbuf+4 ; next sector for controller
rts
;******************************************************
lsectnx
lda numsec
sec
sbc #1
sta tmp+5 ; last logical sector number
lda cmdbuf+4 ; get original sector
cmp tmp+5
beq 1$ ; equal to or
clc
adc #1 ; next sector
jmp 2$
1$ inc cmdbuf+3 ; next track
lda #0
2$ sta cmdbuf+4
rts
;******************************************************
.page
;******************************************************
maxmin ldy pnumsec ; get ns
dey ; one less
lda #255 ; as small as min can get
minim cmp cmdbuf+11,y
bcc no_min ; br, no change
lda cmdbuf+11,y
no_min dey
bpl minim
sta minsek ; save min
ldy pnumsec
dey ; one less
lda #0 ; as small as max can get
maxim cmp cmdbuf+11,y
bcs no_max ; br, no change
lda cmdbuf+11,y
no_max dey
bpl maxim
sta maxsek ; save max
rts
;******************************************************
.page
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;BURST CMD ONE - READ
;
; BYTE BIT 7 6 5 4 3 2 1 0
;============================================================================
; 00 0 1 0 1 0 1 0 1
;----------------------------------------------------------------------------