comparison 3rdparty/drivers/burke/hdcmd.src @ 91:c10820aa211b

Added
author boisy
date Wed, 03 Jul 2002 03:41:59 +0000
parents
children
comparison
equal deleted inserted replaced
90:6aa54d3691e5 91:c10820aa211b
1 *******************************************
2 *** ***
3 *** HDCMD.SRC ***
4 *** ***
5 *** COPYRIGHT BURKE & BURKE 1987 ***
6 *** ALL RIGHTS RESERVED ***
7 *** ***
8 *** COPYRIGHT BURKE & BURKE 1992 ***
9 *** ALL RIGHTS RESERVED ***
10 *** ***
11 *******************************************
12
13 *
14 * This is the routine that executes controller commands, and
15 * its support routines.
16 *
17 * Modification History
18 * --------------------
19 *
20 * Date Who Description
21 * -------- --- ------------------------------------
22 * 12/20/87 CJB Modified GetDat and PutDat to call
23 * SNOOZE routine if not ready for data.
24 * This causes the driver to sleep
25 * during disk seeks.
26 * Modified s25flg stuff for generic
27 * 32x4x?? drives.
28 * 02/07/88 CJB Added CMEXIN to process special drive
29 * parameters during formatting
30 *
31 * 04/17/88 cjb Added WaitIdl, which waits for controller
32 * ready to receive a command.
33 * Added call to Snooze in WaitIdl.
34 * 04/21/88 cjb Added code to OR RetryEn into step rate
35 * byte. This allows retries to be disabled
36 * by RetryEn = $80.
37 * 05/18/88 cjb Checked all paths for proper handling of
38 * premature command termination
39 * 06/12/88 cjb Added WaitId2 to assure sleep for at least
40 * one tick.
41 * Fixed DrvCmd to check for WX$XIN opcode
42 * if formatting enabled.
43 * 07/01/88 cjb Fixed bug in CMESTS -- changed "<" to ">"
44 * 10/10/88 cjb Modified to save error track if format enabled
45 * 02/01/89 cjb Fixed bug in error routine -- now dumps
46 * cache on any uncorrectable error
47 * Fixed bug in error routine to save
48 * error track # correctly
49 * 05/05/90 cjb Added kludge for ST11R in WAIRDY
50 * Added support for drives in multiple slots
51 * 04/15/92 cjb Fixed bug in location of DBLRDD - caused
52 * driver to hang up on an error message.
53 * Lenghtened a bit for speed, and to allow
54 * easy 6309E overlays.
55 *
56
57 page
58 *
59 * Byte saver.
60 *
61 * Call here to send command in Reg-A to drive in Reg-B,
62 * with 0's as the rest of the command.
63 *
64 * Note that this command sets the step rate to 3 ms!
65 *
66 DrvCmd pshs y,x,a ;Save registers same as CmExec
67 sts AbtStk,U ;Save stack pointer for error recovery
68
69 * Enter here to send WX$STS -- stack etc. already set up
70
71 DrvCm2 bsr WAIRDY ;Wait for ready for command -- preserves B
72 lda ,S ; recover reg-A
73
74 ifne fmtflg
75 bsr ChkCmd ; translate cmd. if necessary
76 endc
77
78 ifne (Drives-1) ;If multiple drives,
79 andb #$01 ; 2 drives per controller, different slots
80 aslb
81 aslb
82 aslb ;convert drive # to controller's format
83 aslb
84 aslb
85 else
86 clrb ;drive # is always 0
87 endc
88
89 bsr PutCm2 ;Send command & drive #
90
91 * Send the rest of the command as 0's (including step rate . . . 3ms)
92 * Note that RetryEn is ignored here.
93
94 clra
95 clrb
96 bsr PutCm2
97 bsr PutCm2 ;Send 4 zeros for rest of command
98
99 * Pass control to dispatch routine, and wait for end when done
100
101 bra CmDisp
102
103 page
104 *
105 * Put Reg-D to controller as command bytes
106 *
107 * Assumes AbtStk is valid.
108 *
109 ifne icdflg ;If ignoring C/D status bit
110
111 PutCm2 lbra PutDt2
112
113 else
114
115 PutCm2 bsr PutCmd
116 tfr B,A ;Fall through to PutCm2
117
118 endc
119
120 *
121 * Wait for controller to indicate it is ready to receive
122 * a command byte, then send it from Reg-A.
123 *
124 * Assumes AbtStk,U has been set to the error recovery
125 * stack pointer.
126 * If the command aborts, the stack is cleaned and control
127 * passed to CmdDun.
128 *
129 ifne icdflg ;If ignoring C/D status bit
130
131 PutCmd lbra PutDat
132
133 else
134
135 PutCmd pshs A
136
137 PCM0 bsr ChkAbt ;Get status, check for abort
138 cmpa #%00001101 ;Check for command request
139 bne PCM0
140
141 * Ready. Put the data
142
143 puls A
144 sta >HDDATA
145 rts
146
147 endc
148
149 *
150 * Get status of hard disk controller, and abort command in
151 * progress if controller says so.
152 *
153 * Assumes AbtStk,U has been set to the error recovery
154 * stack pointer.
155 * If the command aborts, the stack is cleaned and control
156 * passed to CmdDun.
157 *
158 ChkAbt lda >HDSTAT
159 cmpa >HDSTAT ;Data must be stable
160 bne ChkAbt
161
162 anda #%00001111
163 cmpa #%00001111 ;Check for abort
164 bne CKA9
165
166 * Well, the command is complete. This normally means it
167 * aborted. Pass control to CmdDun
168
169 lds AbtStk,U ;Clean stack
170 bra CmdDun
171
172 * Not done yet. Return current status to caller
173
174 CKA9 rts
175
176 ifne fmtflg ;If formatting allowed,
177 *
178 * Convert command op-code before transmission to controller
179 * if necessary.
180 *
181 * The special initialization code WX$XIN is not a real controller
182 * op-code.
183 *
184 ChkCmd cmpa #WX$XIN ;Check for bogus INITIALIZE PARAMETERS
185 bne CCM9
186 lda #WX$INI ; convert to real INITIALIZE PARAMETERS
187 CCM9 rts
188 endc
189
190 *
191 * Wait for controller ready to receive a command, then
192 * get its attention. Blows away Reg-A.
193 *
194 * Does not time out.
195 *
196 WAIRDY bsr WaitIdl ;Wait for controller idle
197 clr >HDATTN ;Get attention of controller
198 rts
199
200 * Wait for controller ready to receive a command
201
202 WaitIdl lda >HDSTAT
203 * anda #%00001111
204 anda #%00001001 ;Special mask works for ST11R, too
205 cmpa #%00000000 ; (all bits must be clear if ready)
206 beq WaitId9
207
208 * Enter here to sleep for at least one tick.
209 * Waste time while waiting for HD.
210
211 WaitId2 lbsr Snooze ;Give up slot, sleep.
212 bra WaitIdl
213
214 WaitId9 rts
215
216 page
217 *
218 * Command execution module for CoCo XT.
219 *
220 * Enter with:
221 *
222 * Command op-code in Reg-A
223 * Buffer pointer in Reg-X (points to buffer for data part of cmd)
224 * Command image set up at IMAGE,U
225 * Reg-Y points to real or bogus path descriptor (for drive # and
226 * step rate).
227 * Slot 3 is assumed to be selected, with interrupts disabled.
228 *
229 * Exits w/ carry clear if success, otherwise carry set and
230 * error code in Reg-B.
231 *
232 CMEXEC pshs y,x,a ;Save caller's registers
233 sts AbtStk,U ;Save stack pointer for error recovery
234
235 * Wait for drive ready to accept a command
236
237 bsr WaiRdy
238
239 * Point to the command block
240
241 leax IMAGE,U
242
243 * Issue the command . . . op-code 1st
244 * PutCmd and PutCm2 will automatically abort the command
245 * if the controller indicates that this is necessary.
246
247 lda 0,S ;Recover command op-code
248
249 ifne fmtflg
250 bsr ChkCmd ;Translate command op-code if needed
251 endc
252
253 CMX1 bsr PutCmd
254
255 ldd ,X++ ; (send head & sector)
256 bsr PutCm2
257
258 ldd ,X++ ; (send cylinder & block count)
259 bsr PutCm2
260
261 lda PD.STP,Y ; (send step rate)
262 ora RetryEn,U ; (and send retry flag)
263 bsr PutCmd
264
265 * Now dispatch the command based on it's op-code. If a command
266 * isn't explicitly checked for in this loop, it is assumed that
267 * the command has no data arguments and is now executing.
268
269 CmDisp equ *
270
271 * Command in progress. Dispatch to service routine.
272 * Note that the service routine must check for premature
273 * command termination via CHKABT.
274
275 ldx 1,S ;Recover possible data pointer
276 lda 0,S ;Recover op-code
277
278 cmpa #WX$RDD ;READ SECTOR
279 beq CMERDD
280
281 cmpa #WX$WRT ;WRITE SECTOR
282 beq CMEWRT
283
284 cmpa #WX$INI ;SET DRIVE PARAMETERS
285 lbeq CMEINI
286
287 ifne fmtflg
288 cmpa #WX$WBF ;WRITE SECTOR BUFFER (for format)
289 lbeq CMEWBF
290
291 cmpa #WX$XIN ;Bogus SET DRIVE PARAMETERS
292 lbeq CMEXIN
293 endc
294
295 cmpa #WX$STS ;DETAILED STATUS REQUEST
296 lbeq CMESTS
297
298 * Wait for end of command execution. Then get completion status
299 * byte and decode any errors encountered.
300
301 WaiEnd bsr ewait ;Wait for command done
302
303 * Get completion status byte
304 * Stack pointer and ABTSTK,U match
305
306 CmdDun clrb ;Clear carry, assume no error
307
308 lda >HDDATA
309 bita #%00000010
310 beq NoErr
311
312 * Error bit is set -- note this could still be a "null" error
313 * or a correctable error, so we have to get the status packet.
314
315 lda 0,S ;Check op-code
316 cmpa #WX$STS ;Was it an error status request?
317 bne GetErr
318
319 * Unknown error, or error while trying to determine error.
320
321 NotRdy comb
322 ldb #E$Read ;Report it as a "read" error
323
324 * Generic exit
325
326 NoErr equ *
327 CMEXIT puls a,x,y,pc
328
329 * Issue command to read error from controller. This command
330 * will return the error code in Reg-B w/ carry set.
331
332 GetErr lda #WX$STS ;Recurse to get detailed status (implicit bfr)
333
334 ifne Drives-1 ;If more than 1 drive,
335 ldb PD.DRV,Y
336 endc
337
338 lds AbtStk,U ;Recover stack pointer
339 sta 0,S ;Put command on stack
340 lbra DrvCm2 ;Go try again.
341
342 * Wait for command to terminate
343
344 ewait lda >HDSTAT
345 anda #%00000111 ;NOTE: IGNORE BUSY BIT
346 cmpa #%00000111 ; (all bits set for command completion byte)
347 beq ewx
348
349 * Not done. Sleep for the rest of this tick, then try again.
350
351 lbsr Snooze ;Give up slot, sleep, get back slot
352 bra ewait
353
354 * Exit
355
356 ewx rts
357
358 page
359 *
360 * Handle tail end of sector read.
361 * Get the data to the caller's buffer.
362 *
363 CMERDD lda secnum,u
364 bita #1
365 bne CMRODD
366
367 * Read even logical sector on track -- 1st half of physical sector
368 * Save 2nd half if necessary.
369
370 bsr keep256
371
372 ifne cchflg ;If read cache supported,
373
374 tst BFRFLG,U
375 beq CMRE1
376
377 * Copy 2nd half of sector to verify buffer (possible cache)
378 leax vrfbuf,U
379 bsr keep256
380 bra WaiEnd
381
382 endc
383
384 * Discard 2nd half of sector
385 CMRE1 bsr dump256
386 bra WAIEND
387
388 * Read odd logical sector on track -- 2nd half of physical sector
389 * Throw away the 1st half
390 CMRODD bsr dump256
391 bsr keep256
392 bra WAIEND
393
394 page
395 *
396 * Handle tail end of sector write.
397 * Get the data from the caller's buffer.
398 *
399 CMEWRT lda secnum,u
400 bita #1
401 bne CMWODD
402
403 * Write even lsn on track -- uses 1st half, get 2nd half from verify bfr
404 bsr writ256
405 bsr copy256
406 bra WAIEND
407
408 * Write odd lsn on track -- uses 2nd half, get 1st half from verify bfr
409 CMWODD bsr copy256
410 bsr writ256
411 bra WAIEND
412
413 ifne fmtflg ;If hard formatting enabled,
414
415 page
416 *
417 * Process command to fill sector buffer with (A).
418 *
419 * This is only used at the beginning of a FORMAT command.
420 *
421 CMEWBF ldd #$E600 ; ($00 -> 256 iterations)
422 bsr CMF0
423 bsr CMF0 ; Reg-B is still 0 from previous iteration
424 lbra WAIEND
425
426 CMF0 bsr PutDat ;Fill 256 bytes of sector buffer with (A)
427 decb
428 bne CMF0
429
430 rts
431
432 endc
433
434 page
435 *
436 * Copy 256 bytes from sector buffer to (X)
437 *
438
439 ifne fstflg ;If fast transfers,
440
441 Keep256 bsr GetDat ;Full handshake on 1st byte
442 sta ,X+
443 ifne tboflg ;If 2 MHz for transfers,
444 clr >$FFD9
445 endc
446 bsr GetDat ;Get 2nd (quick move goes in pairs)
447 sta ,X+
448 ldb #$7F ;pair count
449 pshs B
450
451 RDD1 lda >HDDATA ;Read the rest of the block w/o handshake
452 ldb >HDDATA
453 std ,X++
454 dec ,S
455 bne RDD1
456
457 ifne tboflg ;If 2 MHz for transfers,
458 clr >$FFD8
459 endc
460
461 puls A,PC ;Flush counter
462
463 else ;If slow transfers,
464
465 Keep256 clrb ;Copy 256 bytes
466 ifne tboflg ;If 2 MHz for transfers,
467 clr >$FFD9
468 endc
469
470 RDD1 bsr GetDat ;Full handshake on every byte
471 sta ,X+
472 decb
473 bne RDD1
474
475 ifne tboflg ;If 2 MHz for transfers,
476 clr >$FFD8
477 endc
478
479 rts
480
481 endc
482
483 *
484 * Copy 256 bytes from sector buffer to bit bucket
485 *
486
487 ifne fstflg ;If fast transfers,
488
489 Dump256 bsr GetDat ;Full handshake on 1st byte
490 ifne tboflg ;If 2 MHz for transfers,
491 clr >$FFD9
492 endc
493 bsr GetDat ;Quick dump goes in pairs
494 ldb #$7F
495
496 RDD2 lda >HDDATA ;Read the rest of the block w/o handshake
497 lda >HDDATA
498 decb
499 bne RDD2
500
501 ifne tboflg ;If 2 MHz for transfers,
502 clr >$FFD8
503 endc
504 rts
505
506 else ;If slow transfers,
507
508 Dump256 clrb ;Copy 256 bytes
509 ifne tboflg ;If 2 MHz for transfers,
510 clr >$FFD9
511 endc
512
513 RDD2 bsr GetDat ;Full handshake on every byte
514 decb
515 bne RDD2
516
517 ifne tboflg ;If 2 MHz for transfers,
518 clr >$FFD8
519 endc
520 rts
521
522 endc
523
524 *
525 * Wait for controller to indicate it is ready to transmit
526 * a data byte, then get it to Reg-A.
527 *
528 * Assumes AbtStk,U has been set to the error recovery
529 * stack pointer.
530 * If the command aborts, the stack is cleaned and control
531 * passed to CmdDun.
532 *
533 GetDat equ *
534
535 GDT0 lbsr ChkAbt ;Get status, check for abort
536 ifne icdflg ;If ignoring C/D bit,
537 anda #%00001011
538 endc
539 cmpa #%00001011 ;Check for data request
540 beq GDT1 ; (branch if request present)
541
542 * New -- sleep if controller not ready (D.DMAReq only)
543
544 lbsr Snooze
545 bra GDT0
546
547 * Ready. Get the data
548
549 GDT1 lda >HDDATA
550 rts
551
552 page
553 *
554 * Copy 256 bytes from (X) to sector buffer
555 *
556
557 ifne fstflg ;If fast transfers,
558
559 Writ256 ldd ,X++
560 bsr PutDt2 ;Full handshake on 1st byte pair
561 ifne tboflg ;If 2 MHz for transfers,
562 clr >$FFD9
563 endc
564 ldb #$7F
565 pshs B
566
567 WRT1 ldd ,X++
568 sta >HDDATA ;Write the rest of the block w/o handshake
569 stb >HDDATA
570 dec ,S
571 bne WRT1
572
573 ifne tboflg ;If 2 MHz for transfers,
574 clr >$FFD8
575 endc
576 puls A,PC ;clean up counter
577
578 else ;If slow transfers,
579
580 Writ256 clrb ;Copy 256 bytes
581 ifne tboflg ;If 2 MHz for transfers,
582 clr >$FFD9
583 endc
584
585 WRT1 lda ,X+
586 bsr PutDat ;Full handshake on every byte
587 decb
588 bne WRT1
589
590 ifne tboflg ;If 2 MHz for transfers,
591 clr >$FFD8
592 endc
593 rts
594
595 endc
596
597 *
598 * Copy 256 bytes from verify buffer to sector buffer
599 *
600
601 copy256 pshs X
602
603 leax vrfbuf,u ;Get verify buffer pointer
604 bsr writ256
605
606 puls X,PC
607
608 *
609 * Put Reg-D to controller as data bytes
610 *
611 * Assumes AbtStk is valid.
612 *
613 PutDt2 bsr PutDat
614 tfr B,A ;Fall through to PutCm2
615
616 *
617 * Wait for controller to indicate it is ready to receive
618 * a data byte, then send it from Reg-A.
619 *
620 * Assumes AbtStk,U has been set to the error recovery
621 * stack pointer.
622 * If the command aborts, the stack is cleaned and control
623 * passed to CmdDun.
624 *
625 PutDat pshs A
626
627 PDT0 lbsr ChkAbt ;Get status, check for abort
628 ifne icdflg ;If ignoring C/D bit,
629 anda #%00001011
630 endc
631 cmpa #%00001001 ;Check for data request
632 beq PDT1 ; (branch if request present)
633
634 * New -- sleep if controller not ready (D.DMAReq only)
635
636 lbsr Snooze
637 bra PDT0
638
639 * Ready. Put the data
640
641 PDT1 puls A
642 sta >HDDATA
643 rts
644
645 page
646 *
647 * Process detailed status request command.
648 * This routine performs the status request, then
649 * translates the controller's error code and returns
650 * it as the error status of the operation w/ C-bit set.
651 * "Null" and correctable errors do not cause C-bit set.
652 *
653 CMESTS equ *
654
655 * Recover error status from controller
656
657 bsr GetDat ;Read result of last disk command
658 pshs a ; (save)
659
660 ifne FMTFLG
661 bsr GetDat ; (dump head #)
662 bsr GetDat ;Get shifted cyl # MS byte
663 tfr A,B
664 bsr GetDat ;Get shifted cyl # LS byte
665 exg A,B
666 std ERRHCYL,U ;Save cylinder # of error for FORMAT
667 else
668 bsr DBLRDD ;Dump last 3 response bytes
669 bsr GetDat ; (dump last response byte)
670 endc
671
672 lbsr ewait ; Wait for command complete
673 lda >HDDATA ; and dump completion byte
674
675 puls a ; (recover error code)
676
677 * Look up error code in Reg-A -> Reg-B
678
679 anda #$3F ;Keep only error bits
680 beq NULERR
681
682 cmpa #WE$CER ;Correctable error
683 bne EL0
684
685 * Special processing for correctable errors.
686 * If formatting (RetryEn,U != 0), report these
687 * as READ ERRORS
688
689 tst RetryEn,U ;If retries disabled, error out.
690 beq NULERR ; (retries enabled -- ignore error)
691
692 EL0 equ *
693
694 ifne cchflg ;If read cache supported,
695 clr BFRFLG,U ;Dump cache on any error
696 endc
697 ifne errflg ;If good error messages enabled,
698
699 leax ERRTBL,PCR ;Point to lookup table
700
701 * Search error list. Error code is in Reg-A
702
703 EL1 tst ,X
704 bmi XXXERR
705 cmpa ,X++
706 bne EL1
707
708 * Found error code
709 comb ;Set carry
710 ldb -1,X ;Fetch error code
711 bra XCMXIT
712
713 endc
714
715 * Didn't find error code. Note that errors that translate
716 * to E$Read are not in the table -- we just let them default
717 * to here.
718
719 XXXERR comb
720 ldb #E$Read
721 bra XCMXIT ;Return status to caller
722
723 NULERR clrb ;Force carry clear
724 XCMXIT lbra CMEXIT ;Return status to caller
725
726 * Byte saver
727
728 DBLRDD lbsr GetDat ;Read 1 byte
729 lbra GetDat
730
731 page
732 ifne fmtflg ;If formatting allowed,
733 *
734 * Process special drive parameters command.
735 *
736 * This command sends the legal track count rather
737 * than the park track count.
738 *
739 CMEXIN ldd PD.CYL,Y ;get track count
740 bra CMIN01
741 endc
742
743 *
744 * Process command to send drive parameters to controller.
745 * Assumes Reg-Y points to real or bogus *PATH* descriptor.
746 *
747 * This routine fetches the drive parameters from the descriptor,
748 * and sends them to the controller.
749 *
750 CMEINI equ *
751
752 * Send # of cylinders. We send the park track, since it
753 * is the largest track # that will be used.
754
755 ifne (Drives-1) ;if 2 drives,
756 ifne trsflg ; if optimized for 32 SPT, 4 heads,
757 bsr GtPkLSN ;Get park LSN to B:X
758 pshs X,B
759 ldd ,S
760 addd ,S
761 leas 3,S ;Convert to track by dividing by 128
762 else
763 bsr GtPkLSN ;Get park LSN to B:X
764 lbsr LSNDIV
765 tfr X,D ;Calculate track and get to D
766 endc
767 else ;if 1 drive,
768 ifne trsflg ; if optimized for 32 SPT, 4 heads,
769 ldd PRKLSN,U
770 addd PRKLSN,U ;park track = park LSN/128
771 else
772 ldb (PRKLSN+0),U
773 ldx (PRKLSN+1),U ;get park LSN
774 lbsr LSNDIV
775 tfr X,D ;Calculate track and get to D
776 endc
777 endc
778
779 * Enter here w/ track count in Reg-D
780
781 CMIN01 addd #1 ; (advance track count by 1)
782 bsr PutDt2 ;Send last legal track to controller
783
784 * Send # of heads
785
786 lda PD.SID,Y
787 bsr PutDat
788
789 * Send (bogus) reduced write current cylinder
790
791 ldd PD.CYL,Y
792 lbsr PutDt2
793
794 * Send write pre-comp cylinder (DD had wpc/4)
795
796 ifne (Drives-1) ;if 2 drives,
797 pshs Y
798 ldb PD.DRV,Y ;Get drive #
799 lbsr GOBPtr ;Get option pointer for this drive
800 ldb (PCCYL-OBSTART),Y
801 puls Y
802 else
803 ldb PCCYL,U ;Get precomp cylinder / 4
804 endc
805 lda #4
806 mul ;Convert to real cyl # in D
807 lbsr PutDt2
808
809 * Send maximum error correction burst length (WD recommends 4)
810
811 lda #4
812 lbsr PutDat
813
814 * Wait for end of command, etc.
815
816 lbra WaiEnd
817
818 ifne (Drives-1)
819 page
820 *
821 * Utility to get park lsn to B:X for systems with 2 drives.
822 *
823 GtPkLSN pshs Y
824 ldb PD.DRV,Y ;Get drive #
825 lbsr GOBPtr ;Get option pointer for this drive
826 ldb (PRKLSN+0-OBSTART),Y
827 ldx (PRKLSN+1-OBSTART),Y
828 puls Y,PC
829 endc
830
831 ifne errflg ;If good errors enabled,
832 page
833 *
834 * Table of error code followed by OS9 error code
835 * This translation is somewhat arbitrary.
836 * Remember, E$Read errors are not in the table.
837 *
838
839 ERRTBL fcb WE$NSC,E$Seek,WE$WRF,E$Write,WE$NRD,E$NotRdy,WE$NT0,E$Seek
840 fcb WE$DSS,E$Seek,WE$SIK,E$Seek,WE$BTK,E$Read,WE$CMD,E$Unit
841 fcb WE$ISA,E$Sect
842 fcb -1
843
844 endc
845
846 *
847 * End of hdcmd.src
848 *
849