91
|
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
|