comparison 3rdparty/drivers/tccc/tccchd.asm @ 82:d76cc2119c4f

Bob Brose's driver for TC^3 Controller -- Thanks Bob!
author boisy
date Mon, 13 May 2002 03:59:20 +0000
parents
children
comparison
equal deleted inserted replaced
81:991471545e7b 82:d76cc2119c4f
1 * TCCCHD: Hard disk driver/scsi host adapter driver for OS9
2 * Copyright (C) 1990,1991,1992,1993,1994,1995,1996 Robert E. Brose II
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 opt w131
19 nam Hard Disk driver, flip-flop & latch version.
20 ttl title page
21
22 * experimental no DP version 9-11-90
23 **************************************************************
24 * T C C C (TC^3) *
25 * H A R D D I S K device driver for CoCo OS9 *
26 * written by Robert E. Brose II *
27 * uses Western digital WD 1002-shd or Xebec 5" controller*
28 * host adapter modeled after example in Xebec manual *
29 * Allows use of 2 different drives with separate offsets *
30 * for partitioning (ms 13 bits of 21 bit sector #) *
31 **************************************************************
32 *
33 *
34 * physical drive number stored in IT.DNS.
35 *
36 * revision history
37 *------------------------------------
38 * 2.0 Totally revamped
39 * Controller number gotten from the PD (PD.DNS lower 4 bits).
40 * Avoids use of DP, it's faster without it.
41 * Most subroutines moved to inline code to increase speed
42 * Added time slice release if controller is busy 12/01/90
43 * set blocks in init instead of doing it on every packet 12/01/90
44 * 2.1 Added adaptec conditional statements 02-23-92
45 * Uniform descriptors, params adaptec doesn't need are ignored 02-23-92
46 * 2.2 init/don't init drive, bit 6 of PD.DNS. 1=don't init 1-15-94
47 * resets drive in setup routine 1-16-94
48 * locks scsi packet, elims conflict on multiple drives on the same
49 * host adapter. 1-16-94
50 * altered format to work with seagate drives. 1-16-94
51 * 5/6.x changed revisn and versn below to match up with this history 1-19-94
52 * 5.x 256 byte sectors version.
53 * 6.x 1K HD sectors version. 1-19-94
54 * 5/6.2 added HOG flag for maximum speed, to hog the cpu
55 * 5/6/7/8.3 Added MEDSEC for 512 byte sectors
56 * 5/6/7/8.4 much 6309 optimisation
57 * 9.x Redid version/revision stuff again. Version is now 9, revision
58 * indicates sector size. 6809: 1=256 by/sec 2=512 by/sec 3=1024 by/sec
59 * Nitros 6309 4=256 by/sec 5=512 by/sec 6=1024 by/sec
60 *10.x Changes to allow >1 drive with large sectors. 11-5-94
61 * UGH removed for now, flush is too complicated with BIGSEC
62 * changed 6309 block moves to I/O to allow for a gap to service serial
63 * interrupts every 256 moves (affects sector sizes >256 bytes). 3-25-95
64 *11.x Optimizations from better understanding about when the driver can
65 * be interupted, thanks Alan DeKok. 1-7-96
66 * Handles inits of several scsi id'd devices. 1-7-96
67 * Fixed Calcsec, logread and logwrit to handle 512 bytes/sector 1-8-96
68 *12.x Added DISTO HD II support 3-9-96
69 * notes: sleep causes the only possible reentrant situation (~HOG)
70 * in this case cmd block and cache buffer must be preserved.
71 * To make multiple drives/driver work for 512 and 1024 (BUFSEC)
72 * cases will require info like drive, lun, offset, etc to be
73 * save for the previous sector so a cache flush can be done. YUK!
74 * Added sector 0 cache because rbf accesses it all the darn time! 6-8-96
75
76 H6309 equ 1 if 6309 cpu, 0=on!
77
78 ttl equates
79 DBHS equ 1 data requires req handshake version 0=ON! (i.e. adaptec)
80 BIGSEC equ 1 use 1024 byte physical sectors (0=ON!)
81 MEDSEC equ 0 use 512 byte physical sectors (0=ON!)
82 HOG equ 1 hog the cpu on waits (speeds up disk access 0=ON!)
83 DISTO equ 1 use HD II ports and status bits (0=ON!)
84 MDRIVES equ 1 can use more than 1 drive / driver in BUFSEC case (0=ON!)
85 MPAK equ 1 includes multipak switching code (needed for DISTO w/ MPAK 0=ON!)
86 CANFORM equ 0 drive formatting allowed (0=ON!)
87 CACHE equ 1 sector 0 cache (0=ON!).
88
89
90 * BUFSEC below means a buffer is used when reading/writing physical secs
91 * (0=on)
92
93 ifeq BIGSEC
94 BUFSEC equ $0
95 m.smask equ %11111100
96 m.nsmask equ %00000011
97 else
98
99 ifeq MEDSEC
100 BUFSEC equ $0
101 m.smask equ %11111110
102 m.nsmask equ %00000001
103 else
104
105 BUFSEC equ $1
106 endc
107 endc
108
109 ifeq H6309
110
111 ifeq BIGSEC
112 revisn equ 6
113 else
114 ifeq MEDSEC
115 revisn equ 5
116 else
117 revisn equ 4
118 endc
119 endc
120
121 else
122
123 ifeq BIGSEC
124 revisn equ 3
125 else
126 ifeq MEDSEC
127 revisn equ 2
128 else
129 revisn equ 1
130 endc
131 endc
132
133 endc
134
135 verson equ 12
136
137 numdrvs equ 4 number of drives supported by driver (logical)
138 * status byte mask
139
140 m.error equ %00000010 error flag
141
142 * status register bit masks
143
144 ifeq DISTO
145 m.req equ %10000000 data request line
146 m.busy equ %00000001 busy status line
147 * broken on disto??? m.msg equ %00000100 end of message status line
148 m.msg equ %00000000 end of message status line
149 m.cmd equ %01000000 command/data status line
150 m.in equ %00100000 input/output status line
151 * broken msg on disto ??? m.nnc equ %11100101 unconnected lines = ignore mask
152 m.nnc equ %11100001 unconnected lines = ignore mask
153
154 else
155
156 * normal TCCC defs
157 m.req equ %00000001 data request line
158 m.busy equ %00000010 busy status line
159 m.msg equ %00000100 end of message status line
160 m.cmd equ %00001000 command/data status line
161 m.in equ %00010000 input/output status line
162
163 endc
164
165 m.phys equ %00100000 physical drive mask (LUN on Controller)
166 m.init equ %01000000 initialize drive on change flag
167 m.cont equ %00001111 controller address mask
168 m.recal equ %00010000 do a recal (home) on 1st drive access
169 m.format equ %10000000 enable format command
170
171 ifeq MPAK
172 m.mpscs equ %11110000 Mpak slot select SCS clearing mask
173 mpsel equ $FF7F multipak select latch addr, used for disto.
174 EXTPRM equ 25 extra params in descriptor
175 else
176 EXTPRM equ 24 extra params in descriptor
177 endc
178
179 * input and output ports offsets for HOST ADAPTER bus
180
181 ifeq DISTO
182 datapo equ 3 read and write data
183 rstpo equ 1 software reset
184 selpo equ 2 controller select
185 statpo equ 1 read status
186 else
187
188 * Normal TCCC defines
189 datapo equ 0 read and write data
190 rstpo equ 1 software reset
191 selpo equ 2 controller select
192 selrst equ 3 reset of select (scuzzie adapters)
193 statpo equ 1 read status
194
195 endc
196
197 * controller opcodes
198
199 o.ready equ $00 test for drive ready
200 o.param equ $0c set parameters for the drives
201 o.read equ $08 read sector(s)
202 o.write equ $0a write sector(s)
203 o.formt equ $04 format drive
204 o.recal equ $01 recalibrate drive (head to track 0)
205
206 ifp1
207 use defsfile
208 endc
209
210 ttl data allocation
211
212 org DRVBEG
213 tables rmb DRVMEM*numdrvs reserve space for system tables
214
215 * command packet for controller
216
217 packet equ .
218
219 opcode rmb 1 command opcode
220 lun rmb 1 logical unit number : ms part of lsn
221 lsn rmb 2 logical sector number
222 blocks rmb 1 interleave or block count
223 control rmb 1 control byte set at packet send time
224 plocked rmb 1 above control block in use, locked
225 blocked rmb 1 buffer sector (caching) in use, locked
226
227 * extra parameters read in from the descriptor.
228
229 param rmb 8 physical drive 0 params
230 param1 rmb 8 physical drive 1 params
231
232 * logical drive offsets
233
234 offsd1 rmb 2
235 offsd2 rmb 2
236 offsd3 rmb 2
237 offsd4 rmb 2
238
239 ifeq MPAK
240 * Multipak latch temp storage and slot.
241 mpslot rmb 1 From descriptor, FF = no mpak
242 endc
243
244 * end of extra params read in from descriptor
245
246 ifeq MPAK
247 mpstor rmb 1 Current multipak value outside of this driver.
248 endc
249 didflag rmb 1 read lsn 0 flag
250 lastphy rmb 1 last drive accessed (physical)
251 sec0fl rmb numdrvs (recal (home) completed flag)
252 tempw1 rmb 2 word temp var
253 tempw2 rmb 2 word temp var
254
255 iniflg rmb numdrvs whether or not the device has been initalized
256
257 ifeq BUFSEC
258
259 ifeq BIGSEC
260 secbuf rmb 1024 buffer for physical sector
261 else
262 secbuf rmb 512 buffer for physical sector
263 endc
264
265 ifeq CACHE
266 sec0 rmb 256*numdrvs optional sector 0 cache
267 endc
268
269 lastdrv rmb 1 last LOGICAL drive accessed
270 lsech rmb 1 24 bit address, sector in buffer (logical w/o least sig 2 bits)
271 lsecm rmb 1 (part of above)
272 lsecl rmb 1 "
273 physech rmb 1 24 bit address, sector in buffer (physical sector in buffer)
274 physecm rmb 1 (part of above)
275 physecl rmb 1 "
276 cached rmb 1 cache is dirty flag
277 secidx rmb 1 index into physical sector
278 endc
279
280 endmem equ .
281
282 ttl module entry
283
284 mod endmod,name,drivr+objct,reent+verson,xferad,endmem
285 mode fcb $ff mode
286
287 ifeq DISTO
288 ifeq DBHS
289 name fcs "DIDBHS"
290 else
291 ifeq BIGSEC
292 name fcs "DI1024"
293 else
294 ifeq MEDSEC
295 name fcs "DIS512"
296 else
297 name fcs "DISTHD"
298 endc
299 endc
300 endc
301
302 else
303
304 ifeq DBHS
305 name fcs "DBHSHD"
306 else
307 ifeq BIGSEC
308 name fcs "TC1024"
309 else
310 ifeq MEDSEC
311 name fcs "TCC512"
312 else
313 name fcs "TCCCHD"
314 endc
315 endc
316 endc
317
318 endc
319
320 fcb revisn
321
322 * rbf dispatch vectors
323
324 xferad lbra INIT
325
326 ifeq BUFSEC
327 lbra LOGREAD
328 else
329 bra READ
330 nop
331 endc
332
333
334 ifeq BUFSEC
335 bra LOGWRIT
336 else
337 bra WRITE
338 endc
339
340 nop
341 lbra GETSTA
342 lbra SETSTA
343 lbra TERM
344
345 ifeq BUFSEC
346 ttl logical sector write
347
348 * logwrit
349 *
350 * input:
351 * b = msb of os9 lsn
352 * x = lsbs of os9 lsn
353 * y = path descriptor
354 * u = static storage
355 *
356 * output:
357 * 256 bytes moved from the os9 buffer to the physical buffer. Any
358 * necessary physical sector writing and reading is done also.
359 *
360 LOGWRIT
361
362 ifne HOG
363 pshs u
364 logwr01 tst blocked,u critical lock on this section
365 beq logwr02 because of the buffer
366 pshs b,x
367 ldx #1
368 os9 F$Sleep wait a while
369 puls b,x
370 bra logwr01 and check again
371 logwr02 com blocked,u set it
372 endc
373
374 pshs b save HSB
375 tfr x,d msb and lsb into d for manipulation
376 stb secidx,u save lsb for indexing into phys sec buf later
377 andb #m.smask zero indexing bits
378 cmpd lsecm,u lower part of logical sector
379 puls b get back HSB
380 bne diffwr if compare fails, new sector, need preread
381 cmpb lsech,u compare HSB's
382
383 ifne MDRIVES
384 beq cpysecw ok, in buffer
385 diffwr
386
387 else
388
389 bne diffwr failed new sec need preread
390 lda PD.DRV,y current drive
391 cmpa lastdrv,u = last drive?
392 beq cpysecw if same, log sector is in physical buffer
393 diffwr
394 sta lastdrv,u save logical drive for future compare
395 endc
396
397 tst cached,u need to flush physical sector?
398 beq cleanw no, skip ahead
399 pshs b,x,y,u save new sector
400 ldb physech,u get current HSB
401 ldx physecm,u get current msb & lsb
402 lbsr WRITE do the physical write
403 puls b,x,y,u restore new sector
404 bcs logwre exit on write error
405
406 cleanw lbsr calcsec
407 pshs y
408 lbsr READ read the physical sector
409 puls y
410 bcs logwre exit on read error
411
412 cpysecw
413 ldy PD.BUF,y os9 buffer
414 lda secidx,u index into physical buffer
415 anda #m.nsmask mask upper off
416 leax secbuf,u location of physical buffer
417 ldb #128
418 cpsw2 tsta done calculating index?
419 beq cpsw2b yup, exit loop
420 abx these 2 ins advance 256 bytes into physical buffer
421 abx
422 deca
423 bra cpsw2
424
425 cpsw2b clr cached,u
426 com cached,u set cache dirty flag
427
428 ifeq H6309
429
430 cpsw3 ldw #256 bytes to copy
431 tfm y+,x+
432
433 else
434
435 * 16 bit copy, 128 words from os9 buff to phys buff
436 cpsw3 ldu ,y++ get byte from os9 buffer
437 stu ,x++ to phys sector
438 decb
439 bne cpsw3
440
441 endc
442
443 clrb
444
445 logwre
446
447 ifne HOG
448 puls u restore static pointer
449 clr blocked,u clear lock on this section
450 endc
451
452 rts
453
454
455 ttl logical sector read
456
457 * logread
458 *
459 * input:
460 * b = msb of os9 lsn
461 * x = lsbs of os9 lsn
462 * y = path descriptor
463 * u = static storage
464 *
465 * output:
466 * 256 bytes moved from the physical buffer to the os9 buffer. Any
467 * necessary physical sector writing and reading is done first.
468 *
469 LOGREAD
470
471 ifne HOG
472 pshs u
473 logre01 tst blocked,u critical lock on this section
474 beq logre02 because of the buffer
475 pshs b,x
476 ldx #1
477 os9 F$Sleep wait a while
478 puls b,x
479 bra logre01 and check again
480 logre02 com blocked,u set lock
481 endc
482
483 pshs b save HSB
484 tfr x,d msb and lsb into d for manipulation
485 stb secidx,u save lsb for indexing into phys sec buf later
486 andb #m.smask zero indexing bits
487 cmpd lsecm,u lower part of phys sector
488 puls b get back HSB
489 bne diffrd if compare fails, new sector to read
490 cmpb lsech,u compare HSB's
491
492 ifne MDRIVES
493 beq cpysecr ok, in buffer
494 diffrd
495
496 else
497
498 bne diffrd failed new sec need preread
499 lda PD.DRV,y current drive
500 cmpa lastdrv,u = last drive?
501 beq cpysecr if same, log sector is in physical buffer
502 diffrd
503 sta lastdrv,u save logical drive for future compare
504 endc
505
506 tst cached,u need to flush physical sector?
507 beq cleanr no, skip ahead
508 pshs b,x,y,u save new sector
509 ldb physech,u get current HSB
510 ldx physecm,u get current msb & lsb
511 lbsr WRITE do the physical write
512 puls b,x,y,u restore new sector
513 bcs logrde exit on write error
514
515 cleanr bsr calcsec
516 pshs y
517 lbsr READ read the physical sector
518 puls y
519 bcs logrde exit on read error
520
521 cpysecr
522 ldy PD.BUF,y os9 buffer
523 lda secidx,u index into physical buffer
524 anda #m.nsmask mask upper off
525 leax secbuf,u location of physical buffer
526 ldb #128
527 cpsr2 tsta done calculating index?
528 beq cpsr3 yup, exit loop
529 abx these 2 ins advance 256 bytes into physical buffer
530 abx
531 deca
532 bra cpsr2
533
534 ifeq H6309
535
536 cpsr3 ldw #256
537 tfm x+,y+
538
539 else
540
541 * 16 bit copy, 128 words from phys buff to os9 buff
542 cpsr3 ldu ,x++ get byte from phys sec
543 stu ,y++ to os9 buffer
544 decb
545 bne cpsr3
546
547 endc
548
549 clrb
550 logrde
551
552 ifne HOG
553 puls u restore static pointer
554 clr blocked,u clear lock on this section
555 endc
556
557 rts
558
559 * fast calcsec (see comments in 6809 code below)
560
561 ifeq H6309
562 calcsec stb lsech,u
563 tfr x,w
564
565 tfr f,a
566 anda #m.smask
567 sta lsecl,u
568 ste lsecm,u
569
570 *aim #m.smask,lsecl,u
571
572 * 4x (256 x 4 =1k sector) or 2x (256 x 2 = 512 sector)
573
574 ifeq BIGSEC
575 lsrb
576 rorw
577 endc
578
579 lsrb
580 rorw
581 stb physech,u
582 tfr w,x
583 stx physecm,u
584 rts
585
586 else
587
588 calcsec stb lsech,u save logical sec hsb for next compare
589 stb physech,u and in physec for shifting
590 tfr x,d get msb & lsb into d for shifting
591 andb #m.smask strip lower bits lsb sec #
592 std lsecm,u save it for compare
593 std physecm,u as above for shifting
594 lsr physech,u shift 24 bits right 2 bits, converts to physical sec # (1st 8)
595 ror physecm,u (2nd 8)
596 ror physecl,u (3rd 8)
597
598 * 4x (256 x 4 =1k sector) or 2x (256 x 2 = 512 sector)
599 ifeq BIGSEC
600 lsr physech,u (1st 8, second time)
601 ror physecm,u (2nd 8, second time)
602 ror physecl,u (3rd 8, second time)
603 endc
604
605 ldx physecm,u for return value
606 ldb physech,u for return value
607 rts
608
609 endc (H6309)
610 endc (bufsec)
611
612 ttl write sector
613
614 * write
615 *
616 * input:
617 * b = msb of lsn
618 * x = lsb's of lsn
619 * y = path descriptor
620 * u = static storage
621 *
622 * output:
623 * b,x,y,u destroyed
624 * 256 bytes written (512/1024 bufsec version)
625 * otherwise, carry set and b = error code
626 *
627 *
628 WRITE
629 ifeq MPAK
630 pshs u need for restore at end of write routine
631 tst mpslot,u multipak in use? (1xxxxxxxb = no)
632 bmi slotw2 hi bit set, skip
633 lda >mpsel get current value
634 sta mpstor,u save it
635 anda #m.mpscs clear scs bits
636 ora mpslot,u add in scs select
637 sta >mpsel put it to mpak
638 slotw2
639 endc
640
641 lda #o.write controller write opcode
642 lbsr setup setup packet, initiate command
643
644 ifeq BUFSEC
645 leax secbuf,u get address of physical sector buffer
646 clr cached,u clear cache dirty flag
647 else
648 ldx PD.BUF,y get buffer address into x
649 endc
650
651 ldu V.PORT,u
652 leay statpo,U
653 leau datapo,u u points to data port
654 lda #m.req
655
656 ifeq HOG
657 W0 bita ,y get req bit
658 beq W0 wait till req
659
660 else
661
662 W00 clrb 256 tries
663 W0 bita ,y get req bit
664 bne W0B
665 decb
666 bne W0 keep trying
667 lbsr doslp
668 bra W00
669
670 endc
671
672 ifeq DBHS
673 W0B bra W1 first req got already, skip ahead
674 W0C ldb ,y status port
675 bitb #m.req have req?
676 beq W0C wait till we do
677 bitb #m.cmd finished putting data?
678 bne W2A if so, skip ahead
679 W1 lda ,x+ get a byte from memory
680 sta ,u put it to the drive
681 bra W0C go again
682
683 else
684
685 * for 6309, use block transfer fixed size. Not really according to scsi
686 * spec, but FAST!
687
688 ifeq H6309
689 W0B
690 ifeq BIGSEC
691 ldw #1024
692 tfm x+,u
693 else
694 ifeq MEDSEC
695 ldw #512
696 tfm x+,u
697 else
698 ldw #256
699 tfm x+,u
700 endc
701 endc
702
703 else
704
705 ifeq DISTO
706 W0B bra W2
707 W1 lda ,X+
708 sta ,U
709 W2 ldb ,Y
710 andb #m.nnc and out the floating bits
711 cmpb #m.req+m.busy still have data?
712 beq W1 yup go for more
713
714 else
715 W0B ldb #m.req+m.busy status mask for command/data mode
716 bra W2
717 W1 lda ,X+
718 sta ,U
719 W2 cmpb ,Y
720 beq W1
721 endc
722
723 * didn't work, don't know why. changed to make disto easier
724
725 *W0B ldb #m.cmd command mode?
726 * bra W2
727 *W1 LDA ,X+
728 * STA ,U
729 *W2 BITB ,Y
730 * BEQ W1 not command mode yet, go for more data
731
732 endc
733 endc
734
735 ifeq DISTO
736
737 W2A ldb ,y get status bits
738 andb #m.nnc strip floating bits
739 cmpb #m.req+m.busy+m.cmd+m.in
740 bne W2A
741 lda ,u status data byte
742 W2C ldb ,y get status bits
743 andb #m.nnc strip floating bits
744 cmpb #m.req+m.busy+m.msg+m.cmd+m.in
745 bne W2C
746
747 else
748
749 W2A ldb #m.req+m.busy+m.cmd+m.in
750 W2B cmpb ,y get status
751 bne W2B
752 lda ,u status data byte
753 ldb #m.req+m.busy+m.msg+m.cmd+m.in
754 W2C cmpb ,y
755 bne W2C get term byte
756
757 endc
758
759 ldb ,u discard
760 anda #m.error isolate error bit
761 beq w3 if no error
762 comb flag error
763 ldb #E$Write error code for OS9
764 bra w4
765
766 w3 clrb flag no errors
767
768 w4
769 ifeq MPAK
770 puls u saved at top of routine
771 pshs a,cc
772 lda mpstor,u
773 sta >mpsel restore old mpak slot value
774 puls a,cc
775 endc
776
777 rts
778
779
780 ttl read sector
781
782 * read
783 *
784 * input:
785 * b = hsb of lsn
786 * x = lsb's of lsn
787 * y = path descriptor
788 * u = static storage
789 * output:
790 * b,x,y destroyed, u preserved
791 * if no error, 256 bytes into sector buffer
792 * otherwise carry set and b = error
793 *
794 *
795 READ
796 ifeq MPAK
797 tst mpslot,u multipak in use? (1xxxxxxxb = no)
798 bmi slotr2 hi bit set, skip change
799 lda >mpsel get current value
800 sta mpstor,u save it
801 anda #m.mpscs clear scs bits
802 ora mpslot,u add in scs select
803 sta >mpsel put it to mpak
804 slotr2
805 endc
806
807 tstb hsb = 0
808 bne rdnot0 no, skip
809 leax ,x msb & lsb =0?
810 bne rdnot0
811
812 ifeq BUFSEC
813 lda secidx,u least 2 bits are in here
814 anda #m.nsmask
815 bne rdnot0
816 endc
817
818 * first access to drive (implied) so recal the drive to home heads.
819
820 pshs d,x
821 leax sec0fl,u get flag for this drive
822 lda PD.DRV,y get drive #
823 tst a,x drive LSN0 already read?
824 bne sec0dn yup, skip it
825 com a,x flag recal done now
826 clr didflag,u
827 com didflag,u set disk id sec flag on
828 lda PD.DNS,y
829 anda #m.recal should this drive be homed?
830 beq sec0dn
831
832 ldx #0 clear sector # back out (B is still clear)
833
834 lda #o.recal
835 lbsr setup
836
837 ifeq DISTO
838
839 recal0 ldb statpo,x (see comments at W2A)
840 andb #m.nnc
841 cmpb #m.req+m.busy+m.cmd+m.in
842 bne recal0
843 lda datapo,x
844 recal1 ldb statpo,x
845 andb #m.nnc
846 cmpb #m.req+m.busy+m.msg+m.cmd+m.in
847 bne recal1
848
849 else
850
851 ldb #m.req+m.busy+m.cmd+m.in
852 recal0 cmpb statpo,x
853 bne recal0
854 lda datapo,x
855 ldb #m.req+m.busy+m.msg+m.cmd+m.in
856 recal1 cmpb statpo,x
857 bne recal1
858
859 endc
860
861 lda datapo,x
862 sec0dn
863 puls d,x
864
865 rdnot0 lda #o.read opcode for read operation
866 lbsr setup setup packet, initiate command
867
868 ifeq BUFSEC
869 leax secbuf,u physical buffer location
870 clr cached,u
871 else
872 ldx PD.BUF,y setup buffer loc in x
873 endc
874
875 pshs Y,U
876 ldu V.PORT,u
877 leay statpo,U
878 leau datapo,u
879
880 lda #m.req wait for data request
881
882 ifeq HOG
883
884 R0 bita ,y
885 beq R0 wait for req
886
887 else
888 R00 clrb 256 tries for req
889 R0 bita ,y
890 bne R0B
891 decb
892 bne R0 keep trying
893 lbsr doslp
894 bra R00
895
896 endc
897
898 ifeq DBHS
899
900 R0B bra R1 first time have req, skip forward
901 R0C ldb ,y get status
902 bitb #m.req request bit
903 beq R0C no, go again
904 bitb #m.cmd finished with data?
905 bne R2A yes, skip ahead
906 R1 lda ,u get data from the controller
907 sta ,x+ to memory
908 bra R0C go again
909
910 else
911
912 R0B
913 * for 6309, use block transfer fixed size. Not really according to scsi
914 * spec, but FAST!
915
916 ifeq H6309
917 ifeq BIGSEC
918 ldw #256
919 orcc #%01010000
920 tfm u,x+
921 andcc #%10101111
922 ldw #256
923 orcc #%01010000
924 tfm u,x+
925 andcc #%10101111
926 ldw #256
927 orcc #%01010000
928 tfm u,x+
929 andcc #%10101111
930 ldw #256
931 orcc #%01010000
932 tfm u,x+
933 andcc #%10101111
934 else
935 ifeq MEDSEC
936 ldw #256
937 orcc #%01010000
938 tfm u,x+
939 andcc #%10101111
940 ldw #256
941 orcc #%01010000
942 tfm u,x+
943 andcc #%10101111
944 else
945 ldw #256
946 orcc #%01010000
947 tfm u,x+
948 andcc #%10101111
949 endc
950 endc
951
952 else
953
954 ifeq DISTO
955 bra R2
956 R1 lda ,U
957 sta ,X+
958 R2 ldb ,Y
959 andb #m.nnc and out floating bits
960 cmpb #m.in+m.busy+m.req still more data?
961 beq R1 yes, go for more
962 else
963 ldb #m.in+m.busy+m.req test bit for command/data mode
964 bra R2
965 R1 lda ,U
966 sta ,X+
967 R2 cmpb ,Y
968 beq R1
969 endc
970
971 endc
972 endc
973
974 ifeq DISTO
975
976 R2A ldb ,y get status bits
977 andb #m.nnc strip floating bits
978 cmpb #m.req+m.busy+m.cmd+m.in
979 bne R2A
980 lda ,u status data byte
981 R2C ldb ,y get status bits
982 andb #m.nnc strip floating bits
983 cmpb #m.req+m.busy+m.msg+m.cmd+m.in
984 bne R2C
985
986 else
987
988 R2A ldb #m.req+m.busy+m.cmd+m.in
989 R2B cmpb ,y get status
990 bne R2B
991 lda ,u status data byte
992 ldb #m.req+m.busy+m.msg+m.cmd+m.in
993 R2C cmpb ,y
994 bne R2C get term byte
995
996 endc
997
998 ldb ,u discard
999 anda #m.error isolate error bit
1000 puls Y,U
1001 beq r3 if no error detected
1002 comb flag error to OS9
1003 ldb #E$Read error code to be returned
1004 bra r6
1005 r3 lda didflag,u
1006 beq r5 if lsn not 0
1007 clr didflag,u
1008 lda PD.DRV,y get drive number
1009 ldb #DRVMEM size of each entry
1010 mul calculate the offset into the table
1011 leax tables,u get base address
1012 leax d,x get record address
1013
1014 ifeq BUFSEC
1015 leay secbuf,u physical sector buffer
1016 else
1017 ldy PD.BUF,y sector buffer address
1018 endc
1019
1020 ifeq H6309
1021
1022 ldw #DD.SIZ
1023 tfm y+,x+
1024
1025 else
1026
1027 ldb #DD.SIZ number of bytes to copy
1028 r4 lda ,y+ get a byte from the disk identification sector
1029 sta ,x+ put it into the drive table
1030 decb count bytes to copy
1031 bne r4
1032
1033 endc
1034
1035 r5 clrb
1036 r6
1037 ifeq MPAK
1038 pshs a,cc
1039 lda mpstor,u
1040 sta >mpsel restore old mpak slot value
1041 puls a,cc
1042 endc
1043
1044 rts
1045
1046 ttl device init
1047
1048 * init
1049 *
1050 * input:
1051 * y = device descriptor
1052 * u = static storage
1053 *
1054 * output:
1055 * carry set if error
1056 * b = error code
1057 *
1058 * y,u preserved. others destroyed
1059
1060 INIT pshs y
1061
1062 ldx V.PORT,u
1063
1064 ifne DISTO
1065 sta selrst,x reset select line
1066 endc
1067
1068 * removed 1-16-94, multiple drives are now imbeded scsi, each has controller
1069 * shouldn't do a scsi bus reset
1070
1071 * ifne ADAPTEC
1072 * sta rstpo,x reset controllers (if more than one device, should be removed)
1073 * ldb #m.busy
1074 *iniw bitb statpo,x wait till not busy
1075 * bne iniw
1076 * endc
1077
1078 leay $21,y get start of params & offsets in descriptor
1079 ldb #EXTPRM bytes to transfer
1080 leax param,u start of drive parameters in static storage
1081 offload lda ,y+ get drive parameters from descriptor
1082 sta ,x+ put into static
1083 decb
1084 bne offload if not done
1085 puls y
1086 clr didflag,u sector 0 read flag=cleared
1087 lda #$ff will set lastphy to undef
1088 sta lastphy,u store it
1089
1090 ifeq BUFSEC
1091 sta lastdrv,u set last logical read to unknown
1092 endc
1093
1094 ldb #numdrvs number of drives controller supports
1095 stb V.NDRV,u to the manager space
1096 leax tables,u
1097 lda #$ff
1098 fixtab sta DD.TOT,x setup starting info in the tables until the first sector
1099 clr V.TRAK,x of the device is read which will fill in the drive tables
1100 sta V.TRAK+1,x
1101 leax DRVMEM,x
1102 decb
1103 bne fixtab if not done with both tables
1104 lda #1
1105 sta blocks,u set up for normal read/write 1 sector
1106 clr blocked,u extended buffer locked flag
1107 clr plocked,u param block locked flag
1108
1109 ifeq BUFSEC
1110 clr cached,u cache dirty flag
1111 clr secidx,u index into physical sector
1112 ldb #$ff
1113 stb lsech,u set begin phy sec number to impossible value to force read
1114 stb lsecm,u
1115 ldb #m.smask
1116 stb lsecl,u
1117 endc
1118
1119 ldb #numdrvs
1120 leax sec0fl,u clean recal flags
1121 clnrecal
1122 clr ,x+
1123 decb
1124 bne clnrecal
1125
1126 clrb no errors
1127 rts
1128
1129 ttl sleep for rest of tick. Switch mpak slot if necessary (during HW Access)
1130
1131
1132 * entry conditions:
1133 * U = static storage
1134 * exit conditions
1135 * registers preserved
1136
1137 doslp
1138 pshs b,x
1139
1140 ifeq MPAK
1141 tst mpslot,u multipak in use? (1xxxxxxxb = no)
1142 bpl doslp2 hi bit clear, do change
1143 ldx #1
1144 os9 F$Sleep wait a while
1145 bra doslp exit
1146 doslp2 ldb mpstor,u get back old mpak sel value
1147 stb >mpsel put it to mpak
1148 endc
1149
1150 ldx #1
1151 os9 F$Sleep wait a while
1152
1153 ifeq MPAK
1154 ldb >mpsel get current value (could have changed)
1155 stb mpstor,u save it again
1156 andb #m.mpscs clear scs bits
1157 orb mpslot,u add in scs select
1158 stb >mpsel put it to mpak
1159 endc
1160
1161 doslpo
1162 puls b,x,pc
1163
1164
1165 ttl setup and initiate command
1166
1167 * entry conditions:
1168 * Y = path descriptor
1169 * A = opcode to controller
1170 * B = MSB of disk logical sector number
1171 * X = LSB's of disk logical sector number
1172 * U = static storage
1173 *
1174 * setup command packet
1175 * select controller
1176 * initiate command
1177 *
1178 * exit conditions:
1179 * A = destroyed
1180 * B = destroyed
1181 * X = controller base
1182 * U = unchanged (static)
1183 * Y = unchanged (PD)
1184 *
1185 setup
1186 set0
1187 ifne HOG
1188 tst plocked,u critical lock on this section
1189 beq set02
1190 * sleep was inline, now call
1191 bsr doslp sleep for a while
1192 bra set0 and check again
1193 set02 com plocked,u set the lock
1194 endc
1195
1196 sta opcode,u put controller opcode into command packet
1197 stb lun,u
1198 stx lsn,u
1199 lda PD.DNS,y get physical drive number (0 or 1 supported) and init flag
1200 tfr a,b
1201 anda #m.phys (bit 5 is physical drive number)
1202 andb #m.init
1203 beq set25 skip init if not set in desc
1204
1205 * changed 4-16-96, always check for init, based on descriptor
1206 *was ifne ADAPTEC adaptec handles drive parameter switches internally
1207
1208 cmpa lastphy,u current physical drive?
1209 beq set25 yes, continue
1210
1211 pshs a,y
1212 sta lastphy,u
1213 ldx V.PORT,u
1214
1215 * wait for controller to finish any previous command
1216 * needs x set to port base and y set to pd
1217
1218 ldb #m.busy busy status bit
1219 sel1 bitb statpo,x read status port
1220
1221 ifeq HOG
1222
1223 bne sel1 wait till not busy
1224
1225 else
1226
1227 beq sel1b skip if not busy
1228 bsr doslp
1229 bra sel1
1230
1231 endc
1232
1233 sel1b lda PD.DNS,y controller number (lower 4 bits of PD.DNS var)
1234 anda #m.cont isolate controller number
1235 sta datapo,x latch the controller select
1236 sta selpo,x generate a select strobe
1237 sel2 bitb statpo,x read status port
1238 beq sel2 wait for controller to recognize select
1239
1240 ifne DISTO
1241 sta selrst,x reset select (scuzzie version)
1242 endc
1243
1244 lda lastphy,u get drive back
1245 leay param,U Point to Drive 0 Params as Default
1246 tsta Is it Drive 0?
1247 beq setp2 yes, get drive 0 parameters
1248 leay param1-param,Y Point to Drive 1 Params
1249 setp2 lda #m.req
1250 setp3 bita statpo,x get status
1251 beq setp3 wait till ready
1252 lda #o.param set param command
1253 sta datapo,x send it out
1254 ldb #5 rest of packet
1255 clra
1256 pakout sta datapo,x dump em out!
1257 decb
1258 bne pakout if not done
1259 lda #m.req
1260 setp4 bita statpo,x
1261 beq setp4
1262 ldb #8 # of parameters to send out
1263 paramout lda ,y+ get a parameter
1264 sta datapo,x send it out
1265 decb
1266 bne paramout if not done, go again
1267
1268 ifeq DISTO
1269 setp5 ldb statpo,x get status bits
1270 andb #m.nnc strip floating bits
1271 cmpb #m.req+m.busy+m.cmd+m.in
1272 bne setp5
1273 lda datapo,x status data byte
1274 setp6 ldb statpo,x get status bits
1275 andb #m.nnc strip floating bits
1276 cmpb #m.req+m.busy+m.msg+m.cmd+m.in
1277 bne setp6
1278
1279 else
1280
1281 ldb #m.req+m.busy+m.cmd+m.in
1282 setp5 cmpb statpo,x get status
1283 bne setp5
1284 lda datapo,x status data byte
1285 ldb #m.req+m.busy+m.msg+m.cmd+m.in
1286 setp6 cmpb statpo,x
1287 bne setp6 get term byte
1288
1289 endc
1290
1291 ldb datapo,x discard
1292 puls a,Y
1293
1294 set25
1295 ora lun,u or in physical drive with sector number top 8 of 24 bits
1296 sta lun,u and put it back in place
1297 lda PD.STP,y get step and options
1298 sta control,u to the packet
1299 lda PD.DRV,y drive # from path descriptor
1300 lsla byte to word offset
1301 leax offsd1,u base of offsets
1302 ldd a,x get offset
1303 addd lun,u add in top 16 of 24 bit sector number
1304 std lun,u
1305 ldx V.PORT,u
1306
1307 * wait for controller to finish any previous command
1308 * needs x set to port base and y set to pd
1309
1310 set26 ldb #m.busy busy status bit
1311 sel3 bitb statpo,x read status port
1312
1313 ifeq HOG
1314
1315 bne sel3 wait till not busy
1316
1317 else
1318
1319 beq sel3b skip ahead if not busy
1320 lbsr doslp
1321 bra sel3
1322
1323 endc
1324
1325 sel3b lda PD.DNS,y controller number (lower 4 bits of PD.DNS var)
1326 anda #m.cont isolate controller number
1327 sta datapo,x latch the controller select
1328 sta selpo,x generate a select strobe
1329 sel4 bitb statpo,x read status port
1330 beq sel4 wait for controller to recognize select
1331
1332 ifne DISTO
1333 sta selrst,x reset select (scuzzie version)
1334 endc
1335
1336 ttl send command packet
1337 * sends the command packet to the disk controller
1338 * needs x set to V.PORT
1339
1340 taskout pshs y
1341 leay packet,u address of scsi packet
1342 ldb #6 number of bytes to transfer
1343 task00 lda #m.req
1344 task0 bita statpo,x
1345 beq task0
1346
1347 * ifeq H6309
1348 *
1349 * orcc #%01010000
1350 * ldw #6
1351 * tfm y+,x
1352 * andcc #%10101111
1353 *
1354 * else
1355
1356 task1 lda ,y+ get a byte from the packet
1357 sta datapo,x send it to the controller
1358 decb count the bytes
1359
1360 ifeq DBHS
1361 bne task00 need to check req again
1362 else
1363 bne task1
1364 endc
1365
1366 * endc
1367
1368 ifne HOG
1369 clr plocked,u clear critical section lock
1370 endc
1371
1372 puls y,pc
1373
1374 ifeq CANFORM
1375
1376 ttl format the drive
1377
1378 * format
1379 *
1380 * Called by setstat. Entire drive will be formatted.
1381 *
1382 FORMAT ldd R$U,X Get Track Number
1383 lbne nofrmerr If Not Zero We are Done
1384 ldd R$Y,X get sides
1385 tsta
1386 lbne nofrmerr
1387
1388 ifeq MPAK
1389 pshs b
1390 tst mpslot,u multipak in use? (1xxxxxxxb = no)
1391 bmi slotf2 hi bit set, skip change
1392 ldb >mpsel get current value
1393 stb mpstor,u save it
1394 andb #m.mpscs clear scs bits
1395 orb mpslot,u add in scs select
1396 stb >mpsel put it to mpak
1397 slotf2
1398 puls b
1399 endc
1400
1401 tfr D,X Set LSB's of Track # to Zero
1402
1403 lda PD.ILV,y get drive interleave
1404 *sta >$ff68 DEBUG
1405 sta blocks,u put into packet (in place of blocks, restored below)
1406
1407 * deal with the drive offset, needs to be zeroed for unit format
1408 pshs y
1409 * nitros adj
1410
1411 ifeq H6309
1412 lda PD.DRV+2,y
1413 else
1414 lda PD.DRV,y
1415 endc
1416
1417 lsla drive to index
1418 leax offsd1,u offset table
1419 stx tempw1,u save the offset location
1420 ldy a,x
1421 sty tempw2,u save the offset value
1422 ldy #0
1423 sty a,x set the offset temporarily to 0
1424 puls y
1425
1426 ifne HOG
1427 format0 tst plocked,u
1428 beq format1
1429 lbsr doslp
1430 bra format0
1431 com plocked,u
1432 format1
1433 endc
1434
1435 lda #o.formt Get Format Command
1436 clrb sector high byte
1437 ldx #0 sector low word
1438 lbsr setup
1439
1440 * restore the original offset
1441
1442 pshs x
1443 ldx tempw1,u offset loc
1444 ldd tempw2,u offset value
1445 std ,x put it back in the table
1446 puls x
1447
1448 lda #1
1449 sta blocks,u put 1 back to blocks
1450
1451 ifeq DISTO
1452 format2 ldb statpo,x get status bits
1453 andb #m.nnc strip floating bits
1454 cmpb #m.req+m.busy+m.cmd+m.in
1455 beq format2b
1456 lbsr doslp
1457 bra format2
1458 format2b lda datapo,x status data byte
1459 format3 ldb statpo,x get status bits
1460 andb #m.nnc strip floating bits
1461 cmpb #m.req+m.busy+m.msg+m.cmd+m.in
1462 bne format3
1463
1464 else
1465
1466 ldb #m.req+m.busy+m.cmd+m.in
1467 format2 cmpb statpo,x get status
1468 beq format2b
1469 lbsr doslp
1470 bra format2
1471 format2b lda datapo,x status data byte
1472 ldb #m.req+m.busy+m.msg+m.cmd+m.in
1473 format3 cmpb statpo,x
1474 bne format3 get term byte
1475
1476 endc
1477
1478 ldb datapo,x discard
1479 anda #m.error
1480 beq nofrmerr format sucessful
1481 comb indicate error
1482 ldb #E$Write
1483 bra formato
1484
1485 endc
1486
1487 nofrmerr clrb
1488 formato
1489 ifeq MPAK
1490 pshs a,cc
1491 lda mpstor,u
1492 sta >mpsel restore old mpak slot value
1493 puls a,cc
1494 endc
1495
1496 ifne HOG
1497 clr plocked,u
1498 endc
1499
1500 rts
1501
1502 SETSTA ldx PD.RGS,y find the stacked values
1503 cmpb #SS.Reset
1504 beq nofrmerr
1505
1506 ifeq CANFORM
1507
1508 cmpb #SS.WTrk is it the format command?
1509 bne noformat
1510
1511 * is it ok to format this drive?
1512 lda PD.DNS,y
1513 anda #m.format
1514 lbne format
1515 noformat
1516 endc
1517
1518 GETSTA comb
1519 ldb #E$UnkSvc unknown service request
1520 rts
1521
1522 TERM equ nofrmerr
1523
1524 emod
1525 endmod equ *
1526 end