-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathddos2f.asm
More file actions
executable file
·6437 lines (5199 loc) · 199 KB
/
ddos2f.asm
File metadata and controls
executable file
·6437 lines (5199 loc) · 199 KB
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
;
; DragonDos 1.0, Copyright (C) 1982, Dragon Data Ltd.
;
; Disassembled 2020-03-09, P.Harvey-Smith.
;
use cpudefs.asm
use dgndefs.asm
use dosdefs.asm
use romdefs.asm
use basictokens.asm
use basicdefs.asm
use samdefs.asm
use wddefs.asm
* Dragon Alpha has a third PIA at FF24, this is used for
* Drive select / motor control, and provides FIRQ from the
* disk controler.
DPPIADA EQU DPPIA2DA
DPPIACRA EQU DPPIA2CRA
DPPIADB EQU DPPIA2DB
DPPIACRB EQU DPPIA2CRB
PIADA EQU DPPIADA+IO ; Side A Data/DDR
PIACRA EQU DPPIACRA+IO ; Side A Control.
PIADB EQU DPPIADB+IO ; Side A Data/DDR
PIACRB EQU DPPIACRB+IO ; Side A Control.
;WD2797 Floppy disk controler, used in Alpha Note registers in reverse order !
DPCmdReg EQU DPCmdRegA ; command/status
DPTrkReg EQU DPTrkRegA ; Track register
DPSecReg EQU DPSecRegA ; Sector register
DPDataReg EQU DPDataRegA ; Data register
CmdReg EQU DPCmdReg+IO ; command/status
TrkReg EQU DPTrkReg+IO ; Track register
SecReg EQU DPSecReg+IO ; Sector register
DataReg EQU DPDataReg+IO ; Data register
NextResJump EQU BasStub2+StubResJumpOfs ; Jump to reserved word handler of user table
NextFuncsJump EQU BasStub2+StubFuncsJumpOfs ; Jump to functions handler of user table
org $C000
; Disk controler ID, if a cartrage starts with the chars 'DK', then the basic rom routines
; will do a JMP to $C002 to init the cartrage.
DosBegin
FCC /DK/ ; Disk cartrage auto-init identifier.
LC002 BRA DosInit
; Indirect jump table, these are probably the official DragonData entry
; points to be called with jsr [entry]
FDB DOSLowLevel ; Low Level disk IO routine
FDB DosCommand ; Address of data table for low level command
FDB DOSValidFilename ; Validate filename & copy to disk block.
FDB DOSOpenFile ; Open A file.
FDB DOSCreateFile ; Create file (make backup)
FDB DOSGetFLen ; Get file length
FDB DOSCloseAll ; Close all open files
FDB DOSCloseFile ; Close file
FDB DOSFRead ; Read data from file
FDB DOSFWrite ; Write data to file
FDB DOSGetFree ; Get free space on a disk
FDB DOSDeleteFile ; Delete a file
ifdef PGSFix
FDB DOSProtectMC ; Protect/unprotect file
FDB DOSRenameMC ; Rename a file
else
FDB DOSProtectMC ; Protect/unprotect file
FDB DOSRename ; Rename a file
endc
FDB DOSGetDirEntry ; Get a directory entry
FDB DOSFindAndRead ; Find free buffer and read sector
FDB DOSSyncDir ; Copy updated sectors from track 20 to 16 (sync direcories)
FDB DOSReadAbsSector ; Read absolute sector
FDB DOSWriteAbsSector ; Write absolute sector (no verify)
;
; Init Dos
;
DosInit LDX #DosAreaStart ; Point to bottom of dos vars area
TFR X,Y
LC02F CLR ,X+ ; Clear a byte, increment X
LEAY -1,Y ; decrement counter
BNE LC02F ; loop again if more to do
; X now points to the top of the dos variable area
TFR X,D
TFR A,B
ADDB #$18
STB <BasStartProg ; Setup new begining of basic
JSR >BasLocateScreen
LDA <GrDisplayStartAddr ; Adjust graphics ram pages
ADDA #$06
STA <GrLastDisplayAddr
;
; Init various low ram stuff, interrupt vectors, basic stub etc
;
LDX #NewVectorTable ; Point to rom copy of data to copy
LC049 LDB ,X+ ; Get byte count byte
BEQ LC054 ; zero= end of table, exit copy
LDU ,X++ ; Get destination address
JSR >UtilCopyBXtoU ; do copy
BRA LC049 ; do next
LC054 LDB #$00 ; Set hardware control mask
; Was $20 for DDv1
STB DosHWMaskFF48
COM DosVerifyFlag ; function unknown
LDX #DosNewUSRTable ; Adjust usr vector base
STX <BasUSRTableAddr
LDU #BasFCError ; Setup the 10 usr vectors to point to BasFCError
LDB #$0A ; do 10
LC066 STU ,X++ ; setup vector
DECB ; decrement count
BNE LC066 ; loop again if more to do
INC DosDefDriveNo
BSR DosReset
LDX #VectBase ; Point to ram hooks
LDY #RamHookTable ; Point to ram hook table in rom
LDD #$137E ; load A with number of vectors B with opcode for JMP
LC07A STB ,X+ ; setup jump
LDU ,Y++ ; setup vector
STU ,X++
DECA ; decrement counter
BNE LC07A ; Loop again if more to do
LDX #$4549 ; Look for DK at $E000
CMPX $E000
LBEQ $E002 ; Found it, call it's init routine
EIEND LDX #ResetVector ; Setup new reset vector
STX <IndVecReset
LDA #$55
STA <WarmStartFlag
andcc #~(FlagIRQ+FlagFIRQ) ; reenable inturrupts
LDX #BasSignonMess ; Print staandard Basic signon message
JSR >TextOutString
INC <DosDriveNo
LDX #$8000 ; delay counter
CLRA
LC0A4 MUL ; take some time....
LEAX -1,X ; decrement count
BNE LC0A4 ; loop again....
JSR >DosDoRestore
JSR >TextCls ; clear screen
LDX #DosSignonMess-1 ; Print dos signon message
JSR >TextOutString
JMP >BasCmdMode ; Jump to normal basic command mode
DosReset
LDA #WDCmdForceInt ; Force WD2797 to interrupt & reset
STA CmdReg
ifdef PGSFix
LDX #DosD0Online ; Clear drive online flags
else
LDX #DosD0Online-1 ; Clear drive online flags
endc
CLR ,X ; initialize drive info tables
CLR 1,X
CLR 2,X
CLR 3,X
LDX #Drv0Details+DrvDetUseCnt ; Clear drive in use counts
CLR ,X
CLR 6,X
CLR 12,X
CLR $12,X
CLR <DosIOInProgress ; Flag to check for timeout
LDX #DosDirSecStatus ; Clear Dirctory status, FCBs etc
LC0D9 CLR ,X+
CMPX #DosFCBEnd
BNE LC0D9
LDB #$04 ; Count of buffers to process
LDX #Buff1Details ; Setup disk buffer initial values
LDU #$0800 ; addr of buffer
LC0E8 CLR 2,X
STB 4,X
STU 5,X
LEAU $0100,U ; Increment addr for next buffer
LEAX 7,X ; do next buffer
DECB ; done all ?
BNE LC0E8 ; no : do next
RTS
;
; The following code is quite clever, there are actually multiple code paths.
; This involves having a 2 byte instruction encoded as the oprand to a 3
; byte instruction eg :-
;
; L00FA CMPX #$C605
;
; CMPX is one byte long, so a jump to L00DB, will execute the oprand to the
; CMPX, which decodes as LDB #$05 this saves a few bytes by not having LDB #xx,
; BRA label.
;
; There are several examples of this in the Dos ROM !
;
DosDoReadAddr
LDB #DosFnReadAddr ; Read address
FCB Skip2
DosDoWriteTrack
LDB #DosFnWriteTrack ; Write track
FCB Skip2
DosDoWriteSecN
LDB #DosFnWriteSecN ; Write sector no verify
FCB Skip2
DosDoWriteSecV
LDB #DosFnWriteSecV ; Write sector verify
FCB Skip2
DosDoReadSec
LDB #DosFnReadSec ; Read sector
DosDoFuncinB
PSHS A
LEAS -2,S ; Make room on stack
CLR Thrash ; clear work byte
LC10D LDA #$03 ; retry count ?
STD ,S ; save on stack
LC111 BSR DosDoSeek ; Try to seek to track
BCS LC11E ; Error ?
LDB 1,S ; No error, get dos op code
STB <DosCommand ; Save operation to perform
JSR >DOSLowLevel
BCC LC15A ; No error
LC11E CMPB #ErrWP ; Write protect ?, no point in retrying !
BEQ LC149
DEC ,S ; Dec retry count
BEQ LC13B ; Any retries left ?
LDB ,S ; get retry count
LSRB ; gety lsbit
BCC LC133 ; on even numbered retry, do recal
INC <DskTrackNo ; step out a track
BSR DosDoSeek
DEC <DskTrackNo ; step back in when retrying
BRA LC111
LC133 LDA <DskTrackNo ; Save Track no whilst doing restore
BSR DosDoRestore ; Restore & Recalibrate
STA <DskTrackNo ; Put track no back
BRA LC111 ; Try again
; We come here when all reties exhausted
LC13B CMPB #ErrNR ; Not ready ?
BNE LC157
TST DosAreaStart
BNE LC157
COM DosAreaStart
BRA LC153
; Something to do with dir track ? Make sure same op done to both copies of Dir
LC149 LDA <DskTrackNo ; Get track number
CMPA #DirPrimary ; Track 20 ?
BNE LC157 ; no : error
LDA #DirBackup ; set track to 16
STA <DskTrackNo
LC153 LDB 1,S ; Get Dos op code
BRA LC10D ; So same to track 16
LC157 ORCC #FlagCarry ; Flag error
FCB Skip1 ; opcocode for BRN
LC15A CLRB ; Flag no error
LEAS 2,S ; Drop bytes from stack
PULS A,PC ; restore & return
;
; Another LDB, enbeded in CMPX sequence....
;
DosDoReadSec2
LDB #DosFnReadSec2 ; Read sector 2 (just first 2 chars)
FCB Skip2
DosDoSeek
LDB #DosFnSeek
FCB Skip2 ; Seek to a track
DosDoRestore
LDB #DosFnRestore ; Restore to track 0
STB <DosCommand ; save in hardware byte
;
; Disk I/O.
;
; This is the main Disk I/O entry point.
; All registers are preserved except the condition codes and B on the
; return. (error code).
;
; Call :
; DosDriveNo = drive number
; DskSectorNo = sector number
; DskTrackNo = track number
; DiskBuffPtr = buffer pointer
; DosCommand = Dos function to execute (see below)
;
; DosFnRestore ($00), Restore to track 0
; DosFnSeek ($01), Seek to a track
; DosFnReadSec ($02), Read a sector
; DosFnWriteSecV ($03), Write a sector with verify
; DosFnWriteSecN ($04), Write a sector no verify
; DosFnWriteTrack ($05), Write (format) track
; DosFnReadAddr ($06), Read address mark
; DosFnReadSec2 ($07), Read first two bytes of a sector
;
; Exit conditions :
;
; DosDiskError = WD2797 status register, or zero if no error.
; B = error code for basic or zero if no error.
; CC.carry = 0 if no error, 1 if error.
;
DOSLowLevel
PSHS CC,A,DP,X,Y,U
ORCC #(FlagIRQ+FlagFIRQ) ; Disable interrupts
ROR ,S
CLR <DosDiskError ; Flag no disk error
LDA <DosCommand ; get HW byte
CMPA #$07 ; Valid op
BLS LC179 ; yes : do it !
BRA LC181 ; No: error
LC179 JSR >ResetAndStartDrive
BCC LC18C ; Error ?
LDB #$FD ; yes flag error
FCB Skip2 ; Andothe CMPX saving.....
LC181 LDB #$FC ; Set error code
ORCC #FlagCarry ; and carry bit
ROL ,S
STB <DosDiskError ; Flag disk error
LBRA LC230
LC18C LDX #PIA0CRA ; Point to PIA CR A
; roughly equivilent to SetPIA in DDv1
; gets the control registers of PIA0 and PIA1, saves them on the stack
; and then disables interrupts from those PIAs, to prevent them interfereing
; with the disk system.
SavePIAs
LDA ,X ; get PIA control register
PSHS A ; save it on the stack
ANDA #$FC ; disable interrupts from PIAxA
STA ,X++ ; save it, move to CRB
LDA ,X ; get CRB
PSHS A ; save on stack
ANDA #$FC ; disable interrupts from PIAxB
STA ,X ; save it
LEAX 30,X ; move to next PIA
CMPX #$FF23 ; reached PIA2 yet?
BLO SavePIAs ; nope, keep going
LDA PIA2CRB ; get control register B of PIA2
ORA #$03 ; enable interrupt, rishing edge
STA PIA2CRB ; save back to PIA
LDA #$03
PSHS A
LDA <DskSectorNo ; Get disk sector no
CMPA #SectorsPerTrack ; >$12, therefore on second side
BLS LC1B5 ; no: don't adjust
SUBA #SectorsPerTrack ; Calculate sector number on second side
LDB #$02 ; Flag as side 2 (Dragon WD2797 only)
ORB DosHWMaskFF40
STB DosHWMaskFF40
LC1B5 STA SecReg
STA <DosSectorSeek
LC1B8 LDY <DBZero
LDX <DiskBuffPtr ; Point to buffer
LDB <DosCommand ; Get hardware byte (function code)
LSLB ; Calculate offset in table
LDU #DosFunctionTable ; Point to function dispatch table
LDA <DosSectorSeek ; get sector seeking to
CMPA SecRegA ; Compare to sector register
BNE LC1B5 ; not same write again
LDA #$FF ; Set DP=$FF, to make IO quicker
TFR A,DP
JSR [B,U] ; Jump to function handler
STA <DosDiskError ; Save error code
BCC LC1E6 ; No error : check verify
BRA LC214
LC1E6 ANDA DosErrorMask ; Mask out error bits we are not interested in
STA <DosDiskError ; save errors for later use
BEQ LC1FB
LDA <DosCommand ; Get operation code
CMPA #DosFnReadSec2 ; ReadSec2 command ?
BEQ LC1F7 ; yes
DEC ,S ; Dec retry count
BNE LC1B8 ; retry, if tries remaining
LC1F7 ORCC #FlagCarry ; Flag error
BRA LC214
LC1FB TST DosErrorMask ; is this write sector ?
BPL LC214 ; no : jump ahead
LDA <DskTrackNo ; Get track number
CMPA #DirPrimary ; Primary Dir track ?
BEQ LC211 ; yep
CMPA #DirBackup ; Secondary dir track ?
BEQ LC211
TST DosVerifyFlag ; should we verify?
ANDCC #~(FlagCarry) ; Flag no carry
BPL LC214 ; no, skip ahead
LC211 LBSR DosDoReadSec2 ; verify the write
LC214 LEAS 1,S
ROL 4,S
LDX #DosD0Track-1 ; Point to drive track table
LDB <DosDriveNo ; Get last used drive
ABX ; get pointer to track for current drive
LDA TrkReg ; Get current track number from WD
CMPA <DskTrackNo ; Same as current track no ?
BEQ LC236
LDB DosErrorMask ; is this a seek ?
CMPB #$19
BNE LC236
LDB #ErrSFF ; Error code : no error
STB <DosDiskError
ROR 4,S
ORCC #FlagCarry ; flag error
ROL 4,S
LC236 STA ,X ; update track table
; Restore PIA control registers saved in SavePIAs above.
LDX #$FF23 ; point at PIA1 CRB
LC23B PULS A ; get CRB value
STA ,X ; write it to PIA
PULS A ; get CRA value
STA ,--X ; write it to PIA, move pointer
LEAX -30,X ; point to previous PIA
CMPX #$FF01 ; done all ?
BHI LC23B ; nope loop again
CLR DosHWMaskFF40 ; Clear hardware mask
LC24E
LC230 CLRB ; Flag no error
PULS CC,A,DP,X,Y,U ; Restore regs
BHS LC28A ; no error, exit
LDB <DosDiskError ; get last error code
BEQ LC28A ; no error, exit
BPL LC279
;
; Work out the dragon error code that coresponds to the hardware
; error reported by WD.
;
CMPB #$FC
BNE LC261
LDB #ErrPR ; parameter
BRA LC288
LC261
CMPB #$FD
BNE LC269
LDB #BErrDN ; Device Number
BRA LC288
LC269
CMPB #$FE
BNE LC271
LDB #ErrNR ; not ready
BRA LC288
LC271
CMPB #$FF
BNE LC286
LDB #ErrSK ; seek
BRA LC288
LC279 TFR B,A
LDB #$82
ROLA
LC27E ADDB #$02
ROLA
TSTA
BLO LC288
BNE LC27E
LC286 LDB #ErrUD ; undefined
LC288 ORCC #FlagCarry
LC28A RTS
;
; Reset controler chip, and spin up drive.
;
ResetAndStartDrive
LDA #WDCmdForceInt ; Force interrupt
STA CmdReg
LDA <DosDriveNo ; Get last active drive no
BEQ LC27C
CMPA #$04 ; Drive valid ?
BLS LC29B
LC27C ORCC #FlagCarry ; Flag error
DosHookRetDevParam
RTS
; Generate Alpha drive mask from drive number, do drive no
; left shifts to get the correct mask
LC29B LDB #$01 ; initialize mask at 1
LC29D LSLB ; shift it left
DECA ; decrement drive no
BNE LC29D ; keep going until zero
LSRB ; compensate for one shift too many
ORB #MotorOnA ; turn on motor
PSHS B ; save it
LDA DosHWMaskFF48 ; get saved hw mask
ANDA #~DriveMaskA ; mask drives off in HW mask
ORA ,S+ ; combine with drive we want
STA DosHWMaskFF48 ; re-save hardware mask
LBSR AlphaDskCtl ; send it to AY-8912, turn on drives etc
LDA PIA2CRA ; get control register of PIA2 side A
ORA #$38 ; set CA2 high (enable NMI?)
STA PIA2CRA ;
LDX #DosD0Track-1 ; Point to current track table
LDA <DosDriveNo ; Get active drive
LDA A,X ; Get drive current track
STA TrkReg ; Write to controler
LDA #$D2 ; set timeout
STA DosTimeout
CLRB ; no error ?
RTS
;
; Dos function 0 restore
;
DosFunctionRestore
CLRA ; zero track no
STA >DskTrackNo ; Save Track number
BRA LC2B9
;
; Dos function 1 seek
;
DosFunctionSeek
LDA >DskTrackNo ; Get current track no
CMPA DPTrkReg ; Are we over it ?
BNE SeekTrackinA ; no : seek to it
CLRA
STA DosErrorMask ; Turn off verify
TFR A,DP ; Reset DP
RTS
;
; Seek to a track, routine will exit either with an error, or via NMI.
; On entry A contains track to seek to.
;
SeekTrackinA
STA <DPDataReg ; <Eval43 ;DataReg
LDA #WDCmdSeek ; Seek command
LC2B9 LDB #$19
STB DosErrorMask
LDX #DosD0StepRate-1 ; Point to step rate table
LDB >DosDriveNo ; Get active drive
ORA B,X ; Mask in that drive's step rate
STA DPCmdReg ; save in command reg
LC2C8 MUL ; burn up CPU time waiting....
MUL ; NMI will exit this loop
LEAY -1,Y ; decrement timeout counter
BNE LC2C8 ; count exhausted ? : no keep going
BRA DosHWError ; yes : error
;
; Dos function 6 : Read address mark (Dragon)
;
DosFunctionReadAddr
LDA #WDCmdReadAddr ; Read address mark
FCB Skip2 ; CMPX again :)
;
; Dos function 2 : Read sector (Dragon/Cumana)
;
DosFunctionReadSec
LDA #WDCmdReadSec ; Read a sector
LDB #WDDefErrMask ; set error mask
STB DosErrorMask
LDB #$05 ; try 5x$FFFF for timeout
ORA DosHWMaskFF40 ; Mask in side etc
STA DPCmdReg
LC2E1
LDA DPPIACRB ; Check for INT from WD
BMI LC2F3 ; yes : start reading bytes
LEAY -1,Y ; decrement timeout count
BNE LC2E1 ; check for int again, if no timeout
LDA DPPIADB
ifdef PGSFix
BRN LC2F2
else
BMI LC2F2
endc
DECB ; decrement retry wait count
BNE LC2E1 ; count=0 ?, no continue waiting
BRA DosHWError ; yes : error and exit
;
; Read sector/address mark loop, exits with NMI.
;
LC2F2 SYNC
LC2F3 LDB DPPIADB ; clear interrupt
LDA DPDataReg ; read byte from WD
STA ,X+ ; save in buffer
BRA LC2F2 ; do next byte
;
; Dos function 7 read first two bytes of a sector, used by BOOT command.
;
DosFunctionReadSec2
LDX #$004F
LDA #WDDefErrMask ; Set error mask
STA DosErrorMask
;
; Code to wait for DRQ when using Dragon/Cumana controlers.
;
LDB #$05 ; Wait 5x$FFFF
LDA #WDCmdReadSec ; Read sector command
ORA DosHWMaskFF40 ; mask in heads etc
STA DPCmdReg ; write it to WD
LC30C
LDA DPPIACRB ; Check for Int from WD
BMI LC327 ; yes : start reading
LEAY -1,Y ; decrement timeout
BNE LC30C ; check again
LDA DPPIADB ; try clearing int
ifdef PGSFix
BRN LC327
else
BMI LC327
endc
DECB ; decrement outer count
BNE LC30C
DosHWError
LDA #WDCmdForceInt ; Force the WD to abort
STA DPCmdReg
CLRA ; Reset DP to page 0
TFR A,DP
LDA #$FE ; return error
ORCC #FlagCarry
RTS
;
; Read data from WD, as normal exited with NMI
;
; Read bytes code when using Dragon/Cumana controlers.
;
LC327 LDA DPDataReg ; read byte from WD
TST DPPIADB ; clear interrupt
STA ,X+ ; save in memory
SYNC ; wait for next
LDA DPDataReg ; get next byte
TST DPPIADB ; clear interrupt
STA ,X ; save byte
LC334 SYNC
TST DPPIADB ; clear interrupt
LDA DPDataReg ; read byte
BRA LC334
;
; Dos function 4 Write sector no verify
;
DosFunctionWriteSec2
LDA #WDErrMask5F ; set error mask
FCB Skip2
;
; Dos function 3 Write sector with verify
;
DosFunctionWriteSec
LDA #WDErrMaskDF ; set error mask
STA DosErrorMask
BSR DosSetPrecomp ; Setup write precomp
;
; Write sector for Dragon/Cumana controlers.
;
LDA #WDCmdWriteSec ; Write sector
ORA DosHWMaskFF40 ; Mask in side etc
STA DPCmdReg ; write to WD
LDA ,X+ ; fetch first byte to write
LC34E
LDB DPPIACRB ; Int from WD ?
BMI LC35B ; yes : start writing
LEAY -1,Y ; decrement timeout
BNE LC34E ; if not timed out continue waiting
BRA DosHWError ; timout, abort, and return error
; Write sector loop, NMI breaks out of here
LC358 LDA ,X+ ; get byte to write
SYNC ; wait for WD
LC35B STA DPDataReg ; write byte to WD
LDA DPPIADB ; clear interrupt
BRA LC358
;
; Dos function 5 write track.
;
; Will return WTErr if N.F.G.
;
; The format of the write buffer is somewhat strange for this routine.
; The reason for this is so that we can format a diskette without hosing
; the poor user's basic program.
; The method of run length coding only requires $22B bytes instead of
; the normale $0000 bytes.
;
DosFunctionWriteTrack
LDA #WDErrMaskFormat ; set error mask
STA DosErrorMask
BSR DosSetPrecomp ; Set write precomp
LDA #WDCmdWriteTrack ; Write (format) track
ORA DosHWMaskFF40 ; Mask in head etc
STA DPCmdReg
LC36F LDD ,X++ ; Get bytes to write A=count, B=byte
LC371 SYNC ; Wait for WD
CMPA DPPIADB ; Clear interrupt
STB DPDataReg ; Write a byte on track
DECA ; decrement byte count
BNE LC371 ; continue until count=0
LDA ,X+ ; get next
SYNC
CMPA DPPIADB ; Clear int
STA DPDataReg ; write to wd
BRA LC36F
;
; Set write precompensation based on track
;
DosSetPrecomp
LDA DPTrkReg ; Get track
CMPA #TrackPrecomp ; track < 16
BLS LC38F ; no : no write precomp
LDA DosHWMaskFF48 ; Enable precomp
ORA #WPCEnA
BRA LC394
LC38F LDA DosHWMaskFF48 ; Turn off precomp
ANDA #~WPCEnA ;#$EF
LC394
LBSR AlphaDskCtl ; Write control reg
RTS
ENDC
;
; BOOTDSK dispatch routine
;
; Syntax is the same as for DSKINIT below.
;
CmdBootdsk
PSHS CC ; save flags
DEC <DosMakeSysDsk ; flag that we are making a system disk
PULS CC ; recover flags fall through to DSKINIT
;
; Dskinit dispatch routine
;
; Syntax :
; DSKINIT (default drive,sides,tracks)
; DSKINIT drive (specified drive, default sides,tracks)
; DSKINIT drive,sides (specified drive,sides default tracks)
; DSKINIT drive,sides,tracks (specified drive,sides,tracks)
;
CmdDskInit
BEQ LC3BC ; No parameters : use defaults
JSR >GetDriveNoInB ; Get drive no
STB <DosDriveNo ; save it
JSR >GetCommaThen8Bit ; Get comma, and then no of sides
BEQ LC3C1 ; Error, use default sides & tracks
DECB ; Convert sides to zero base
CMPB #$01 ; > 1 sides specified : error & exit
BHI LC3B9 ; Error : use default tracks
STB <DosRecLenFlag ; Save sides
JSR >GetCommaThen8Bit ; Get comman, then tracks
BEQ LC3C3 ; Error : use default tracks
CMPB #$28 ; 40 tracks ?
BEQ LC3C5 ; Yes skip on
NEG <DosRecLenFlag
CMPB #$50 ; 80 tracks ?
BEQ LC3C5 ; yes, skip on
LC3B9 JMP >DosPRError
;
; Set defaults for format : disk=1,sides=1,tracks=40
;
LC3BC LDB DosDefDriveNo ; use default drive
STB <DosDriveNo ; save in last used
LC3C1 CLR <DosRecLenFlag
LC3C3 LDB #FmtDefTracksA ; no of tracks to format by default
LC3C5 STB <DosDSKINITraks
;
; <DosDSKINITraks = tracks to format
; <DosRecLenFlag = sides-1 so singlesided = 0, double sided = 1
;
JSR >DosCloseAllFiles ; close all files error if can't
LBNE DosJmpToSysError
LDX #DosDiskBuffBase ; Point to the buffer base
STX <DiskBuffPtr
JSR >DosDoRestore ; Restore to track 0
BNE DosJmpToSysError ; error : exit
LDA #$01 ; start at sector 1
STA <DskSectorNo
JSR >DosDoReadSec2 ; try reading it
CMPB #$80
BEQ DosJmpToSysError
LC3E5 CLR <DosDSKINIHead ; do head 0
CLR <DskSectorNo ; start at sector 0
JSR >SetupTrackLayout ; setup track layout in ram
JSR >DosDoWriteTrack ; write the track
BCS DosJmpToSysError ; error : exit
TST <DosRecLenFlag ; is this a double sided disk ?
BEQ LC404 ; nope skip
LDA #$01 ; do side 1
STA <DosDSKINIHead
NEGA
STA <DskSectorNo
JSR >SetupTrackLayout ; setup track layout in ram
JSR >DosDoWriteTrack ; write the track
BCS DosJmpToSysError ; error : exit
LC404 INC <DskTrackNo ; increment track
LDA <DskTrackNo
CMPA <DosDSKINITraks ; have we done all yet ?
BCS LC3E5 ; nope do next track
JSR >DosDoRestore ; finished formatting, restore to track 0
BCS DosJmpToSysError
LC411 JSR >DosDoSeek ; seek to track
BCS DosJmpToSysError ; error : exit
CLRA
JSR >CmdDskInitVerifyTrack ; verify current track
INC <DskTrackNo ; move to next track
LDA <DskTrackNo
CMPA <DosDSKINITraks ; done all ?
BCS LC411 ; nope : do next track
LDX <DiskBuffPtr ; point at disk buffer
LDD <DBZero ; d=0
LC426 STD ,X++ ; fill buffer with zeros
CMPX #DskInitBuffer+(3*256) ; end of buffer?
BNE LC426 ; nope keep filling
LDA #$01 ; sector 0
STA <DskSectorNo
LDA #DirPrimary ; Directory track
BSR BuildAndWriteBAM ; build and write BAM
DEC <DskSectorNo ; Point back at first BAM block
DEC <DiskBuffPtr
LDA #DirBackup ; Directory backup track
BSR WriteBAM ; Write BAM sectors
BRA MakeBlankDir
BuildAndWriteBAM
PSHS A
BSR BuildBAM ; Build BAM and geometry info
PULS A
WriteBAM
STA <DskTrackNo ; Write sector to track
JSR >DosDoWriteSecV
BCS DosJmpToSysError ; error : exit
INC <DskSectorNo ; do sector 2
INC <DiskBuffPtr
JSR >DosDoWriteSecV ; Write sector to track
BCS DosJmpToSysError ; error : exit
RTS
;
; Exit with error, allow basic to handle it.
;
DosJmpToSysError
CLR >DosMakeSysDsk
JMP >DosHookSysError ; Jump to basic error handler
; Fill in a blank directory sector, setting default attributes.
; Bug : this seems to only fill in the backup track, as the call
; to Lc489 will never return !
MakeBlankDir
INC <DiskBuffPtr ; Increment buff pointer by 1 page
LDX <DiskBuffPtr
LDD #(AttrAtFormat*256)+DirEntPerSec ; Get default attribute & number of entries
LC460 STA ,X ; Fill in attributes
LEAX DirEntryLen,X ; move to next entry
DECB ; any more : continue
BNE LC460
BSR WriteNewDir