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