Annotation of cci/d/pits/tape.c, revision 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.