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