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