Annotation of researchv8dc/sys/dev/ctu.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * driver for comet (nebula?) console cassette
        !             3:  */
        !             4: 
        !             5: #include "../h/param.h"
        !             6: #include "../h/dir.h"
        !             7: #include "../h/user.h"
        !             8: #include "../h/file.h"
        !             9: #include "../h/mtpr.h"
        !            10: #include "../h/tty.h"
        !            11: #include "../h/buf.h"
        !            12: 
        !            13: /*
        !            14:  * bits in console registers
        !            15:  */
        !            16: 
        !            17: #define        DONE    0200
        !            18: #define        IE      0100
        !            19: #define        BRK     01              /* transmit a break */
        !            20: 
        !            21: /*
        !            22:  * packet types
        !            23:  */
        !            24: 
        !            25: #define        DATA    01      /* data packet */
        !            26: #define        CTL     02      /* command */
        !            27: #define        INIT    04      /* init handshake */
        !            28: #define        CONT    020     /* continue */
        !            29: #define        STOP    023     /* stop (flow control) */
        !            30: 
        !            31: /*
        !            32:  * opcodes in control packets
        !            33:  */
        !            34: 
        !            35: #define        RESET   01      /* reset controller */
        !            36: #define        READ    02      /* read a block */
        !            37: #define        WRITE   03      /* write a block */
        !            38: #define        END     0100    /* response from tu58 */
        !            39: 
        !            40: /*
        !            41:  * switches
        !            42:  */
        !            43: 
        !            44: #define        MRSP    010
        !            45: 
        !            46: /*
        !            47:  * status codes in END packet
        !            48:  */
        !            49: 
        !            50: #define        SOK     0
        !            51: #define        SSOFT   1       /* ok but had to retry */
        !            52: #define        SEOT    (-2)    /* ran off end of tape */
        !            53: #define        SBBLK   (-55)   /* block number too big */
        !            54: 
        !            55: /*
        !            56:  * misc sizes
        !            57:  */
        !            58: 
        !            59: #define        TBSIZE  512     /* size of a block on the tape */
        !            60: #define        PMAX    sizeof(struct dpkt)     /* biggest packet size */
        !            61: #define        DMAX    128     /* max bytes of data per packet */
        !            62: #define        CCNT    10      /* count for CTL packets */
        !            63: 
        !            64: /*
        !            65:  * prototype control packet
        !            66:  */
        !            67: 
        !            68: struct cpkt {
        !            69:        char cp_flag;   /* CTL */
        !            70:        unsigned char cp_cnt;   /* count == 012 */
        !            71:        char cp_op;     /* op code */
        !            72:        char cp_mod;    /* modifiers */
        !            73:        char cp_unit;   /* unit number */
        !            74:        char cp_sw;     /* switches (eg MRSP) */
        !            75:        u_short cp_seq; /* sequence number (always 0) */
        !            76:        u_short cp_bcnt;        /* byte count */
        !            77:        u_short cp_bno; /* desired block number */
        !            78: };
        !            79: 
        !            80: #define        ce_sts  cp_mod  /* for END packet, success code */
        !            81: #define        ce_xsts cp_bno  /* extended status */
        !            82: 
        !            83: /*
        !            84:  * data packet
        !            85:  */
        !            86: 
        !            87: struct dpkt {
        !            88:        char cp_flag;   /* DATA */
        !            89:        unsigned char cp_cnt;   /* count of data bytes following */
        !            90:        char cd_data[DMAX];
        !            91: };
        !            92: 
        !            93: typedef union packet {
        !            94:        struct cpkt C;
        !            95:        struct dpkt D;
        !            96:        char B[PMAX];
        !            97:        u_short W[PMAX / sizeof(u_short)];
        !            98: } PACKET;
        !            99: 
        !           100: /*
        !           101:  * quick and dirty pseudo-clist
        !           102:  */
        !           103: 
        !           104: #define        CBDAT   512
        !           105: #define        QHI     400
        !           106: #define        QLO     200
        !           107: 
        !           108: struct cbuf {
        !           109:        int cb_cc;
        !           110:        unsigned char *cb_rptr;
        !           111:        unsigned char *cb_wptr;
        !           112:        unsigned char cb_data[CBDAT];
        !           113: };
        !           114: 
        !           115: struct cbuf ctuin, ctuout;
        !           116: int ctuflag;
        !           117: 
        !           118: #define        TBUSY   01      /* output busy */
        !           119: #define        OPEN    02      /* device already open */
        !           120: #define        WAIT    04      /* someone waiting for input */
        !           121: #define        OSLEEP  010     /* someone waiting for output to drain */
        !           122: 
        !           123: #define        DEBUG   0100000 /* debugging flag */
        !           124: 
        !           125: #define        IPRI    28
        !           126: #define        OPRI    29
        !           127: 
        !           128: #define        hibyte(x)       (((u_char *)&x)[1])
        !           129: #define        lobyte(x)       (((u_char *)&x)[0])
        !           130: #define        hiword(x)       (((u_short *)&x)[1])
        !           131: #define        loword(x)       (((u_short *)&x)[0])
        !           132: 
        !           133: ctuopen(dev, mode)
        !           134: {
        !           135:        if (ctuflag & OPEN) {
        !           136:                u.u_error = EBUSY;
        !           137:                return;
        !           138:        }
        !           139:        ctuflag |= OPEN;
        !           140:        ctuinit();
        !           141: }
        !           142: 
        !           143: ctuclose(dev, mode)
        !           144: {
        !           145: 
        !           146:        mtpr(CSTS, 0);
        !           147:        mtpr(CSRS, 0);
        !           148:        ctuflag &=~ OPEN;
        !           149: }
        !           150: 
        !           151: cturead(dev, mode)
        !           152: {
        !           153:        PACKET pkt;
        !           154:        register PACKET *pk = &pkt;
        !           155: 
        !           156:        if (u.u_count & 01)
        !           157:                u.u_count--;    /* tu58 prefers even byte count */
        !           158:        pk->C.cp_flag = CTL;
        !           159:        pk->C.cp_cnt = CCNT;
        !           160:        pk->C.cp_op = READ;
        !           161:        pk->C.cp_mod = 0;
        !           162:        pk->C.cp_unit = 0;
        !           163:        pk->C.cp_sw = MRSP;
        !           164:        pk->C.cp_seq = 0;
        !           165:        pk->C.cp_bcnt = u.u_count;
        !           166:        pk->C.cp_bno = u.u_offset / TBSIZE;
        !           167:        ctuput(pk);
        !           168:        for (;;) {
        !           169:                if (ctuget(pk) == 0) {
        !           170:                        u.u_error = EIO;
        !           171:                        break;
        !           172:                }
        !           173:                if (u.u_count == 0)
        !           174:                        break;
        !           175:                if (pk->C.cp_flag != DATA)
        !           176:                        break;
        !           177:                iomove(pk->D.cd_data, pk->C.cp_cnt, B_READ);
        !           178:                if (u.u_error)
        !           179:                        break;
        !           180:        }
        !           181:        if (pk->C.cp_flag != CTL || pk->C.cp_op != END)
        !           182:                u.u_error = EIO;
        !           183:        if (u.u_error) {
        !           184:                ctuinit();
        !           185:                return;
        !           186:        }
        !           187:        if (pk->C.ce_sts != SOK
        !           188:        &&  pk->C.ce_sts != SSOFT
        !           189:        &&  pk->C.ce_sts != SEOT        /* operation overlapped end of tape */
        !           190:        &&  pk->C.ce_sts != SBBLK) {    /* operation past end of block */
        !           191:                u.u_error = EIO;
        !           192:                printf("err on TU58: %o %o\n", pk->C.ce_sts & 0377, pk->C.ce_xsts);
        !           193:                return;
        !           194:        }
        !           195: }
        !           196: 
        !           197: ctuwrite(dev, mode)
        !           198: {
        !           199:        PACKET pkt;
        !           200:        register PACKET *pk = &pkt;
        !           201: 
        !           202:        if (u.u_count & 01)
        !           203:                u.u_count--;
        !           204:        pk->C.cp_flag = CTL;
        !           205:        pk->C.cp_cnt = CCNT;
        !           206:        pk->C.cp_op = WRITE;
        !           207:        pk->C.cp_mod = 0;
        !           208:        pk->C.cp_unit = 0;
        !           209:        pk->C.cp_sw = MRSP;
        !           210:        pk->C.cp_seq = 0;
        !           211:        pk->C.cp_bcnt = u.u_count;
        !           212:        pk->C.cp_bno = u.u_offset / TBSIZE;
        !           213:        ctuput(pk);
        !           214:        for (;;) {
        !           215:                if (ctuget(pk) == 0) {
        !           216:                        u.u_error = EIO;
        !           217:                        break;
        !           218:                }
        !           219:                if (pk->C.cp_flag != CONT)
        !           220:                        break;
        !           221:                if (u.u_count == 0)
        !           222:                        break;
        !           223:                pk->C.cp_cnt = min(u.u_count, DMAX);
        !           224:                iomove(pk->D.cd_data, pk->C.cp_cnt, B_WRITE);
        !           225:                if (u.u_error)
        !           226:                        break;
        !           227:                pk->C.cp_flag = DATA;
        !           228:                ctuput(pk);
        !           229:        }
        !           230:        if (pk->C.cp_flag != CTL || pk->C.cp_op != END)
        !           231:                u.u_error = EIO;
        !           232:        if (u.u_error) {
        !           233:                ctuinit();
        !           234:                return;
        !           235:        }
        !           236:        if (pk->C.ce_sts != SOK
        !           237:        &&  pk->C.ce_sts != SSOFT
        !           238:        &&  pk->C.ce_sts != SEOT) {
        !           239:                u.u_error = EIO;
        !           240:                printf("err on TU58: %o %o\n", pk->C.ce_sts & 0377, pk->C.ce_xsts);
        !           241:                return;
        !           242:        }
        !           243: }
        !           244: 
        !           245: /*
        !           246:  * send a packet to the tu58
        !           247:  */
        !           248: 
        !           249: ctuput(pk)
        !           250: register PACKET *pk;
        !           251: {
        !           252:        register u_short *wp;
        !           253:        register char *cp;
        !           254:        register int n;
        !           255:        long sum;
        !           256: 
        !           257:        if (ctusbc(pk->C.cp_flag)) {
        !           258:                ctputc(pk->C.cp_flag, &ctuout);
        !           259:                ctustart();
        !           260:                return;
        !           261:        }
        !           262:        while (ctuout.cb_cc >= QHI) {
        !           263:                ctuflag |= OSLEEP;
        !           264:                sleep((caddr_t)&ctuout, OPRI);
        !           265:        }
        !           266:        wp = pk->W;
        !           267:        sum = 0;
        !           268:        n = (pk->C.cp_cnt / sizeof(u_short)) + 1;
        !           269:        while (--n >= 0) {
        !           270:                sum += *wp++;
        !           271:                if (hiword(sum)) {      /* wrap carry around */
        !           272:                        sum++;
        !           273:                        hiword(sum) = 0;
        !           274:                }
        !           275:        }
        !           276:        cp = pk->B;
        !           277:        n = pk->C.cp_cnt + 2;
        !           278:        while (--n >= 0)
        !           279:                ctputc(*cp++, &ctuout);
        !           280:        ctputc(lobyte(sum), &ctuout);
        !           281:        ctputc(hibyte(sum), &ctuout);
        !           282:        ctustart();
        !           283: }
        !           284: 
        !           285: /*
        !           286:  * retrieve a packet from the tu58
        !           287:  * returns zero if packet is illegal (eg bad checksum)
        !           288:  * if no packet, wait for one
        !           289:  */
        !           290: 
        !           291: ctuget(pk)
        !           292: register PACKET *pk;
        !           293: {
        !           294:        register u_short *wp;
        !           295:        register char *cp;
        !           296:        register int n;
        !           297:        long sum;
        !           298:        u_short xsum;
        !           299: 
        !           300:        pk->C.cp_flag = ctuchr();
        !           301:        if (ctusbc(pk->C.cp_flag))
        !           302:                return (1);
        !           303:        pk->C.cp_cnt = ctuchr();
        !           304:        cp = &pk->B[2];
        !           305:        n = pk->C.cp_cnt;
        !           306:        if (n > PMAX)
        !           307:                return (0);
        !           308:        while (--n >= 0)
        !           309:                *cp++ = ctuchr();
        !           310:        lobyte(xsum) = ctuchr();
        !           311:        hibyte(xsum) = ctuchr();
        !           312:        wp = pk->W;
        !           313:        n = (pk->C.cp_cnt / sizeof(u_short)) + 1;
        !           314:        sum = 0;
        !           315:        while (--n >= 0) {
        !           316:                sum += *wp++;
        !           317:                if (hiword(sum)) {      /* wrap carry around.  ugh. */
        !           318:                        sum++;
        !           319:                        hiword(sum) = 0;
        !           320:                }
        !           321:        }
        !           322:        if (ctuflag & DEBUG)
        !           323:                printf("ctu %x\n", pk->C.cp_flag);
        !           324:        if (sum != xsum) {
        !           325:                printf("ctu: sum %x is %x\n", xsum, sum);
        !           326:                return (0);
        !           327:        }
        !           328:        return (1);
        !           329: }
        !           330: 
        !           331: /*
        !           332:  * is this type a single byte packet?
        !           333:  */
        !           334: 
        !           335: ctusbc(type)
        !           336: register int type;
        !           337: {
        !           338: 
        !           339:        switch (type) {
        !           340:        case DATA:
        !           341:        case CTL:
        !           342:                return (0);
        !           343: 
        !           344:        default:
        !           345:                return (1);
        !           346:        }
        !           347: }
        !           348: 
        !           349: /*
        !           350:  * hard reset
        !           351:  * called on open or error
        !           352:  */
        !           353: 
        !           354: ctuinit()
        !           355: {
        !           356: 
        !           357:        mtpr(CSRS, 0);
        !           358:        mtpr(CSTS, BRK);
        !           359:        DELAY(250000);
        !           360:        mtpr(CSTS, 0);
        !           361:        ctflushq(&ctuin);
        !           362:        ctflushq(&ctuout);
        !           363:        mtpr(CSRS, IE);
        !           364:        ctputc(INIT, &ctuout);
        !           365:        ctputc(INIT, &ctuout);
        !           366:        ctustart();
        !           367:        while (ctuchr() != CONT)
        !           368:                ;
        !           369: }
        !           370: 
        !           371: /*
        !           372:  * wait for one character from tu58
        !           373:  */
        !           374: 
        !           375: ctuchr()
        !           376: {
        !           377:        register int s;
        !           378: 
        !           379:        s = spl7();
        !           380:        while (ctuin.cb_cc == 0) {
        !           381:                ctuflag |= WAIT;
        !           382:                sleep((caddr_t)&ctuin, IPRI);
        !           383:        }
        !           384:        splx(s);
        !           385:        return (ctgetc(&ctuin));
        !           386: }
        !           387: 
        !           388: /*
        !           389:  * start output from queue
        !           390:  */
        !           391: 
        !           392: ctustart()
        !           393: {
        !           394:        register int c;
        !           395:        register int s;
        !           396: 
        !           397:        s = spl7();
        !           398:        if (ctuflag & TBUSY)
        !           399:                return;
        !           400:        if ((c = ctgetc(&ctuout)) >= 0) {
        !           401:                ctuflag |= TBUSY;
        !           402:                mtpr(CSTD, c);
        !           403:                mtpr(CSTS, IE);
        !           404:        }
        !           405:        if (ctuflag & OSLEEP && ctuout.cb_cc < QLO) {
        !           406:                wakeup((caddr_t)&ctuout);
        !           407:                ctuflag &=~ OSLEEP;
        !           408:        }
        !           409:        splx(s);
        !           410: }
        !           411: 
        !           412: ctuxint(dev)
        !           413: {
        !           414: 
        !           415:        ctuflag &=~ TBUSY;
        !           416:        ctustart();
        !           417: }
        !           418: 
        !           419: cturint(dev)
        !           420: {
        !           421:        static char cont = CONT;
        !           422: 
        !           423:        while (mfpr(CSRS) & DONE) {
        !           424:                ctputc(mfpr(CSRD), &ctuin);
        !           425:                ctuput((PACKET *)&cont);
        !           426:                if (ctuin.cb_cc > QHI) {
        !           427:                        printf("ctu input overrun\n");
        !           428:                        ctflushq(&ctuin);
        !           429:                }
        !           430:        }
        !           431:        if (ctuflag & WAIT) {
        !           432:                ctuflag &=~ WAIT;
        !           433:                wakeup((caddr_t)&ctuin);
        !           434:        }
        !           435: }
        !           436: 
        !           437: /*
        !           438:  * fake clist routines
        !           439:  */
        !           440: 
        !           441: ctflushq(q)
        !           442: register struct cbuf *q;
        !           443: {
        !           444:        register int s;
        !           445: 
        !           446:        s = spl7();
        !           447:        q->cb_cc = 0;
        !           448:        q->cb_rptr = q->cb_wptr = q->cb_data;
        !           449:        splx(s);
        !           450: }
        !           451: 
        !           452: int
        !           453: ctgetc(q)
        !           454: register struct cbuf *q;
        !           455: {
        !           456:        register int s;
        !           457:        register int c;
        !           458: 
        !           459:        s = spl7();
        !           460:        if (q->cb_cc <= 0)
        !           461:                c = -1;
        !           462:        else {
        !           463:                q->cb_cc--;
        !           464:                c = *q->cb_rptr++;
        !           465:                if (q->cb_rptr >= &q->cb_data[CBDAT])
        !           466:                        q->cb_rptr = q->cb_data;
        !           467:        }
        !           468:        splx(s);
        !           469:        return (c);
        !           470: }
        !           471: 
        !           472: ctputc(c, q)
        !           473: char c;
        !           474: register struct cbuf *q;
        !           475: {
        !           476:        register int s;
        !           477: 
        !           478:        s = spl7();
        !           479:        q->cb_cc++;
        !           480:        *q->cb_wptr++ = c;
        !           481:        if (q->cb_wptr >= &q->cb_data[CBDAT])
        !           482:                q->cb_wptr = q->cb_data;
        !           483:        splx(s);
        !           484: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.