|
|
1.1 root 1: ////////
2: /
3: / I/O for Seagate ST01/ST02 SCSI Host Adapters.
4: /
5: / $Log: ssas.s,v $
6: / Revision 1.7 91/06/01 10:51:00 hal
7: / Add ffcopy().
8: /
9: / Revision 1.6 91/06/01 10:32:51 hal
10: / Do handshaking both ways. Now names are ss_getb()/ss_putb().
11: /
12: / Revision 1.5 91/05/20 17:22:03 root
13: / Not using ss_put() any more.
14: /
15: / Revision 1.4 91/05/20 16:21:35 root
16: / Call to ss_putc() now works.
17: /
18: / Revision 1.3 91/05/20 10:23:13 root
19: / Drop 3rd arg. Same code for Seagate & Future Domain.
20: /
21: / Revision 1.2 91/05/17 00:24:17 root
22: / Code ss_put - use REQ handshake.
23: /
24: / Revision 1.1 91/05/16 14:16:21 root
25: / Initial version - no code yet for ss_put().
26: /
27: /
28: / Since these functions are called from the midst of C code in
29: / the "ss" driver, they need to preserve the following registers:
30: / SI DI SP BP SS DS ES
31: / Additionally, surrounding C code is expected to leave the "D"
32: / CPU flag clear (string op's increment index registers).
33: /
34: ////////
35:
36: ////////
37: /
38: / Export functions.
39: /
40: ////////
41: .globl ss_getb_
42: .globl ss_putb_
43: .globl ffcopy_
44:
45: ////////
46: /
47: / Constants
48: /
49: / Relative to the RAM base address of the host adapter, offsets
50: / for Control/Status Register (CSR) and Data Port (DAT) differ
51: / between Seagate and Future Domain as follows:
52: / Seagate Future Domain
53: / SS_CSR 0x1A00 0x1C00
54: / SS_DAT 0x1C00 0x1E00
55: / The difference between these (CSR_OFF) is 0x200 in either case.
56: /
57: ////////
58:
59: BSIZE = 0x200 / Disk block size in bytes
60: CSR_OFF = 0x200
61:
62: REQ_LIM = 500
63: RS_REQUEST = 0x10
64:
65: ////////
66: /
67: / ss_getb(ss_dat_fp, buf_fp)
68: / faddr_t ss_dat_fp, buf_fp;
69: /
70: / Fetch input bytes from host adapter and store at buffer address.
71: /
72: / Do REQ handshaking and return the number of bytes remaining to transfer.
73: / (So return value of 0 means no error.)
74: /
75: / Here is the stack after initial "push bp":
76: /
77: / 10(bp) FP_SEL(buf_fp)
78: / 8(bp) FP_OFF(buf_fp)
79: / 6(bp) FP_SEL(ss_dat_fp)
80: / 4(bp) FP_OFF(ss_dat_fp)
81: / 2(bp) return IP
82: / 0(bp) old bp
83: /
84: ////////
85:
86: ss_getb_:
87: push bp
88: mov bp, sp
89: push es
90: push di
91: push ds
92: push si
93:
94: lds si, 4(bp) / ss_dat_fp to DS:SI
95: mov bx, si / .. and to DS:BX
96: sub bx, $CSR_OFF / ss_csr to DS:BX
97: les di, 8(bp) / buf_fp to ES:DI
98: mov cx, $BSIZE / rep count to CX
99:
100: G01: / start outer loop - reading bytes from SCSI
101: mov ax, $REQ_LIM / max # of times to look for REQ
102: G02: / start inner loop - polling for REQ
103: movb dl, (bx)
104: testb dl, $RS_REQUEST
105: jne G03 / got REQ
106: dec ax
107: jnz G02 / no REQ - look again
108: jmp G04 / no REQ - give up
109:
110: G03: / got REQ - ok to read a byte
111: movsb
112: loop G01
113: G04: / all done
114: mov ax, cx / normal exit returns 0
115:
116: pop si
117: pop ds
118: pop di
119: pop es
120: pop bp
121: ret
122:
123: ////////
124: /
125: / int ss_putb(ss_dat_fp, buf_fp)
126: / faddr_t ss_dat_fp, buf_fp;
127: /
128: / Write output bytes to host adapter from buffer address.
129: /
130: / Return the number of bytes remaining to be sent (should be 0).
131: /
132: / Here is the stack after initial "push bp":
133: /
134: / 10(bp) FP_SEL(buf_fp)
135: / 8(bp) FP_OFF(buf_fp)
136: / 6(bp) FP_SEL(ss_dat_fp)
137: / 4(bp) FP_OFF(ss_dat_fp)
138: / 2(bp) return IP
139: / 0(bp) old bp
140: /
141: ////////
142:
143: ss_putb_:
144: push bp
145: mov bp, sp
146: push es
147: push di
148: push ds
149: push si
150: lds si, 8(bp) / buf_fp to DS:SI
151: les di, 4(bp) / ss_dat_fp to ES:DI
152: mov bx, di / .. and to ES:BX
153: sub bx, $CSR_OFF / ss_csr to ES:BX
154: mov cx, $BSIZE / count to CX
155:
156: P01: / start outer loop - writing bytes to SCSI
157: mov ax, $REQ_LIM / max # of times to look for REQ
158: P02: / start inner loop - polling for REQ
159: movb dl, es:(bx)
160: testb dl, $RS_REQUEST
161: jne P03 / got REQ
162: dec ax
163: jnz P02 / no REQ - look again
164: jmp P04 / no REQ - give up
165:
166: P03: / got REQ - ok to write a byte
167: movsb
168: loop P01
169: P04: / all done - now restore registers
170: mov ax, cx
171: pop si
172: pop ds
173: pop di
174: pop es
175: pop bp
176: ret
177:
178: ////////
179: /
180: / void ffcopy(from_fp, to_fp, count)
181: / faddr_t from_fp, to_fp;
182: / int count;
183: /
184: / Copy count bytes from from_fp to to_fp.
185: /
186: / Here is the stack after initial "push bp":
187: /
188: / 12(bp) count
189: / 10(bp) FP_SEL(to_fp)
190: / 8(bp) FP_OFF(to_fp)
191: / 6(bp) FP_SEL(from_fp)
192: / 4(bp) FP_OFF(from_fp)
193: / 2(bp) return IP
194: / 0(bp) old bp
195: /
196: ////////
197:
198: ffcopy_:
199: push bp
200: mov bp, sp
201: push es
202: push di
203: push ds
204: push si
205:
206: lds si, 4(bp) / from_fp to DS:SI
207: les di, 8(bp) / to_fp to ES:DI
208: mov cx, 12(bp) / rep count to CX
209: rep
210: movsb
211:
212: pop si
213: pop ds
214: pop di
215: pop es
216: pop bp
217: ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.