Annotation of cci/d/pits/tape.c, revision 1.1.1.1

1.1       root        1: 
                      2: /*
                      3:  *********************
                      4:  *
                      5:  * Cypher tape driver
                      6:  *
                      7:  *********************/
                      8: 
                      9: #include "pte.h"
                     10: #include "cy.h"
                     11: #include "cyconf.h"
                     12: 
                     13: struct scp *SCP;       /* Pointer System configuration block */
                     14: struct scb scblk;      /* System conf. block */
                     15: struct ccb ccblk;      /* Channel control block */
                     16: struct tpb tpb;                /* Tape parameter block */
                     17: struct tpb tpb1;       /* Tape parameter block (spare) */
                     18: long cmd_done;         /* 1 : cmd completed without error */
                     19:                        /* 2 : cmd error */
                     20: long CYattn;           /* Virtual address of Cypher I/O attention address */
                     21: long ntape;
                     22: extern long unused, Multi, Berr;
                     23: extern short erase, unit;
                     24: 
                     25: chk_tape()
                     26: {      register long r12;
                     27:        long oldvec;
                     28: 
                     29:        m_cy();                 /* Map Tape master space */
                     30: 
                     31:        /* Set handler for tape master interrupt */
                     32:        asm("movab cyhdlr,r12");
                     33:        set_handler(CYVEC,&oldvec,r12);
                     34: 
                     35:        cy_reset();             /* Reset Tape master */
                     36:        return(ntape); 
                     37: }
                     38: tape()
                     39: {
                     40:        if (ntape == 0) {
                     41:                writes("\n\nNo Tape controller installed\n");
                     42:                return(0); }
                     43:        return(cy_setup());   /* Set up structures and initialize Tape master */
                     44: }
                     45: long tm_cnt;
                     46: /*     
                     47:        Routine to sent a command to Tape master
                     48:        return -1 if error
                     49:        return return count of TPB if sucessful
                     50: */
                     51: sent_tm()
                     52: {      register long cntr, rtn_cnt;
                     53: 
                     54:        tm_cnt = 0;
                     55:        ccblk.gate = (char)GATE_CLOSED;         /* Close gate */
                     56:        cy_attn();                              /* Execute command */
                     57:        cntr = RETRY;
                     58:        cmd_done = 0;
                     59:        if (Multi) return;
                     60:        while (!cmd_done) {             /* Wait for completion interrupt */
                     61:                DELAY(0x100000);
                     62:                if (--cntr == 0) {
                     63:                        writes("\n...sent_tm no interrupt respond");
                     64:                        return(-1);     /* Time out */
                     65:                        }
                     66:                }
                     67:        if (cmd_done == 2) return(-1);  /* Command has error */ 
                     68:        return(tm_cnt);
                     69: }
                     70: 
                     71: /*     Tape master completion interrupt handler
                     72: */
                     73: tm_hdlr()
                     74: {
                     75:        if (chk_cstat())
                     76:                cmd_done = 2;   /* completion error */
                     77:           else cmd_done = 1;   /* completion without error */
                     78:        tm_cnt = gt_bcnt();     /* Get return count from TPB */
                     79:        clr_tint();             /* Clear tape master interrupt */
                     80: }
                     81: /*     
                     82:        Routine to ACK on tape master completion interrupt
                     83:        Sent out a NOOP command without interrupt on completion
                     84: */
                     85: clr_tint()
                     86: {
                     87:        while (g_open()==0)     /* Gate close */
                     88:                { tm_init();
                     89:                error("\n...Received interrupt but gate closed.");
                     90:                }
                     91:        ccblk.gate = GATE_CLOSED;       
                     92:        ccblk.ccw = 0x9;                /* Clear tape master interrupt */
                     93:        set_g3(&tpb,NOOP,0,0,0);        /* No Interrupt on completion please */
                     94:        cy_attn();
                     95:        DELAY(0x1500);                  /* wait for completion */
                     96:        while (g_open()==0)     /* Gate close */
                     97:                { tm_init();
                     98:                error("\n...Cannot clear interrupt");
                     99:                return(0);
                    100:                }
                    101:        ccblk.ccw = 0x11;
                    102:        return(1);
                    103: }
                    104: /*     
                    105:        Check status of command previously issued
                    106:        If all are OK return 0
                    107:                else return Status byte.
                    108: */
                    109: chk_cstat()
                    110: {
                    111:        register long *r12, cstat;
                    112:        r12 = (long *)&tpb.status[1];
                    113:        uncache(r12);
                    114:        /* Cmd status without retry bit */
                    115:        cstat = (long)tpb.status[1];
                    116:        if (((cstat & 0x87) == 0x87) && (erase))
                    117:                { writes("\nCy hard error 87 expected, tape is blank\n");
                    118:                  return(cstat); } 
                    119:        if ((cstat & 0xc0) != 0xc0)
                    120:                { writes("\n...Cy hard error ");
                    121:                  writeh(cstat & 0xff); writec('\n');
                    122:                  return(cstat); } 
                    123:        return(0);
                    124: }
                    125: /*     
                    126:        Check status of drive after received command
                    127:        completion interrupt. If all are OK return 0
                    128:        else return Status byte.
                    129: */
                    130: chk_dstat()
                    131: {      register long *r12, tstat;
                    132: 
                    133:        r12 = (long *)&tpb.status[0];
                    134:        uncache(r12);
                    135:        tstat = tpb.status[0];
                    136:        if ( (tstat & 0x48) != 0x48)
                    137:                { writes("\n...drive error ");
                    138:                  writeh(tstat & 0xff);
                    139:                  return(tstat); }
                    140:        return(0);
                    141: }
                    142: /*
                    143:        Routine to get return_count field of TPB after
                    144:        receive command completion interrupt
                    145: */
                    146: gt_bcnt()
                    147: {      register long *r12, tmp1, tmp2;
                    148: 
                    149:        r12 = (long *)&tpb.count;
                    150:        uncache(r12);
                    151:        tmp1 = (long)((tpb.count & (short)0xff)<<8);
                    152:        tmp2 = (long)((tpb.count & (short)0xff00)>>8);
                    153:        return(tmp1|tmp2);
                    154: }
                    155: /*     
                    156:        Routine to issue a GO command to tape master
                    157:        also known as Channel attention interrupt
                    158: */
                    159: cy_attn()
                    160: {      register long r12;
                    161: 
                    162:        r12 = CYattn;           /* R12 = Cypher attention address */
                    163:        asm("movob $0xff,(r12)");
                    164: }
                    165: /*     
                    166:        Routine to reset Tape master controller 
                    167: */
                    168: cy_reset()
                    169: {      register long r12;
                    170: 
                    171:        r12 = CYattn + 1;               /* R12 = Cypher attention address */
                    172:        asm("movob $0xff,(r12)");
                    173:        DELAY(100);
                    174:        ntape = 0;
                    175:        writes("\n\nProbing for Tape Master controller...");
                    176:        if(!Berr) { 
                    177:                writes("\nTape Master controller at address ");
                    178:                writeh(TBASE);
                    179:                ntape++; }
                    180:        writes("\n"); writed(ntape); writes(" Tape controller(s) found");
                    181: }
                    182: /*     
                    183:        Map channel attention address of Tape master 
                    184: */
                    185: m_cy()
                    186: {      register long r12;
                    187:        long phys_pg, pte, old_pte, which1;
                    188: 
                    189:        /* physical page of Tape master in IO space */
                    190:        phys_pg = ((TBASE+IOBASE) >> PGSHIFT) & 0x3fffff;
                    191:        pte = phys_pg | PG_KW | PG_V | PG_NC;
                    192:        fix_pte(SBR,unused,&old_pte,pte);
                    193:        CYattn = (unused << PGSHIFT);   /* Virtual address of CY attn address */
                    194:        asm("mfpr $SLR,r12");
                    195:        r12++;
                    196:        asm("mtpr r12,$SLR");
                    197:        unused++;               /* Next unused PTE in system map */
                    198: }
                    199: /*     
                    200:        Set up all structures for Tape master
                    201:        and initialize Tape master
                    202: */
                    203: cy_setup()
                    204: {
                    205:        register long cntr;
                    206: 
                    207:        SCP = (struct scp *)SCP_ADR;    /* absolute - for setup */
                    208: 
                    209:        /* Initialize the system configuration pointer  */
                    210:        SCP->sysbus = 1;                        /* system width = 16 bits. */
                    211:        set_pointer(&scblk.sysblk,(char *)SCP->pt_scb);
                    212: 
                    213:        /* Initialize the system configuration block. */
                    214:        scblk.sysblk = 0x3;             /* fixed value */
                    215:        scblk.nu2 = 0;                  /* not used */
                    216:        set_pointer(&ccblk.ccw,(char *)scblk.pt_ccb);
                    217: 
                    218:        /* Initialize the channel control block. */
                    219:        ccblk.ccw = 0x11;               /* normal interrupts */
                    220:        set_pointer(&tpb,(char *)ccblk.pt_tpb);
                    221: 
                    222:        ccblk.gate = GATE_CLOSED;       
                    223:        cy_attn();              /* 1st attention : initialization Cypher */
                    224:        cntr = RETRY;
                    225:        while (ccblk.gate == GATE_CLOSED) {
                    226:                DELAY(0x400);                   /* wait for completion */
                    227:                if (--cntr == 0) {
                    228:                        writes("\n...Init : Cypher time out");
                    229:                        return(0); }    /* Time out */
                    230:                }
                    231:        return(1);
                    232: }
                    233:  /*
                    234:        Set a TAPEMASTER 20_bit pointer (first parameter), into
                    235:        the 4 bytes array pointed by the second parameter.
                    236:  */
                    237: set_pointer(pointer,dest)
                    238: long pointer;
                    239: char *dest;
                    240: {
                    241:        *dest++ = pointer & 0xff;               /* low byte - offset */
                    242:        *dest++ = (pointer >> 8) & 0xff;        /* high byte - offset */
                    243:        *dest++ = 0; 
                    244:        *dest   = (pointer & 0xf0000) >> 12;    /* base */
                    245: }
                    246: g_open()
                    247: {      register long *r12, cntr;
                    248: 
                    249:        r12 = (long *)&ccblk.gate;
                    250:        cntr = RETRY;
                    251:        while (ccblk.gate!=0) {
                    252:                uncache(r12);
                    253:                DELAY(0x500);                   /* wait for completion */
                    254:                if (--cntr == 0) {
                    255:                        writes("\n...g_open time out");
                    256:                        return(0);
                    257:                        }
                    258:                }
                    259:        return(1);
                    260: }
                    261: error(msg)
                    262: char *msg;
                    263: {
                    264:        writes(msg);
                    265: }
                    266: /*     
                    267:        Set Tape Parameter Block
                    268:        Input :
                    269:              cmd    = Opcode
                    270:              bufsiz = Block size 
                    271:              bufadr = System buffer address
                    272:              int    = interrupt on completion or not
                    273: */
                    274: set_g3(tpblk,cmd,bufsiz,bufadr,intr)
                    275: struct tpb *tpblk;
                    276: long cmd, bufsiz, intr;
                    277: char *bufadr;
                    278: {      char *cptr;
                    279: 
                    280:        tpblk->cmd = cmd;                       /* Command */
                    281:        tpblk->control[1] = 0x80 | CW_100ips;   /* 16_bit system bus */
                    282:        tpblk->control[0] = ((unit << 2)|(intr << 5)); /* Drive,interrupt */
                    283:        tpblk->count = 0;                       /* Return count = 0 */
                    284:        cptr = (char *)&tpblk->size;            /* Set buffer size */
                    285:        *cptr++ = (char)(bufsiz & 0xff);
                    286:        *cptr = (char)((bufsiz & 0xff00)>>8);   
                    287:        if(cmd == ERASE_F) 
                    288:                tpblk->rec_over = 0x0004;       /* Set record count, erase */
                    289:        else
                    290:                tpblk->rec_over = 0;            /* Set record count */
                    291:        /* Set system buffer address */
                    292:        set_pointer((long)(bufadr),(char *)tpblk->pt_data);
                    293:        tpblk->status[0] = tpblk->status[1] = 0;/* Clear ctlr & drive status */
                    294: }
                    295: /*     
                    296:        *************************************
                    297:        Routine to Read/Write Cypher tape 
                    298:        return 0 if cannot complete operation
                    299:        *************************************
                    300: */
                    301: long tape_op(cmd,buf_adr,buf_siz)
                    302: long cmd, buf_siz;
                    303: char *buf_adr;
                    304: {      char *cptr;
                    305:        register long cnt, stat, tmp1, tmp2;
                    306: 
                    307:        set_g3(&tpb,cmd,buf_siz,buf_adr,1);     /* Set up command block */
                    308:        while (g_open()==0) {           /* Gate closed !! */
                    309:                tm_init();              /* Init controller */
                    310:                writes("\n...tape_op : Can not open gate !!");
                    311:                return(0);
                    312:                } 
                    313:        return(sent_tm());
                    314: }
                    315: 
                    316: /*     
                    317:        Rewind tapemaster
                    318: */
                    319: tm_rew()
                    320: {      char tstat;
                    321:        writes("\nTape rewinding");
                    322:        if (tape_op(REWD_TA,0,0) == -1)  return(0);
                    323:        tstat = tpb.status[0];
                    324:        if ( (tstat & 0x20) != 0x20) return(0);
                    325:        return(1);
                    326: }
                    327: /*     
                    328:        Erase 1024 records 
                    329: */
                    330: tm_erase()
                    331: {
                    332:        writes("\nErasing 1024 records");
                    333:        if (tape_op(ERASE_F,0,0) == -1) return(0);
                    334:        return(1);
                    335: }      
                    336: /*     
                    337:        Routine to initialize tape master 
                    338: */
                    339: tm_init()
                    340: {      register long cntr;
                    341: 
                    342:        cy_reset();
                    343:        if (!g_open()) return(0);
                    344:        ccblk.gate = GATE_CLOSED;       
                    345:        cy_attn();              /* 1st attention : initialization Cypher */
                    346:        cntr = RETRY;
                    347:        while (ccblk.gate == GATE_CLOSED) {
                    348:                DELAY(2000);                    /* wait for completion */
                    349:                if (--cntr == 0) {
                    350:                        writes("\n...Init : Cypher time out");
                    351:                        return(0); }    /* Time out */
                    352:                }
                    353:        return(1);
                    354: }
                    355: cyhandler()
                    356: {      long dummy;
                    357: 
                    358:        asm(".align 2");
                    359: asm("cyhdlr:");
                    360:        asm("svpctx");
                    361:        tm_hdlr();
                    362:        asm("ldpctx");
                    363:        asm("rei");
                    364:        dummy = 0;
                    365: }
                    366: 

unix.superglobalmegacorp.com

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