
/****************************************************************
**
**  Tape IO fuctions for tar
**
**   Must execute TAPEDVR.PRG first to install the tape driver
**
*/

#include<stdio.h>
#include<osbind.h>
#include<tapeio.h>

extern int blocks;
int qblk;

extern char *tbuf;

int topen(rite)
int rite;
{
    int stat, x;
    char jbuf[512];

    qblk = 0;
    tbuf = Malloc((long)(blocks) * 512L);
    if(!tbuf)
    {
        printf("Insufficient memory for %d block buffer\n");
        return(1);
    }

    for(x = 10; x > 0 && stat; x--)
    {
        stat = Tready();
        if(stat == 2) Reques_Sense();
        if(stat) sleep(1);
    }
    if(stat)
    {
        printf("\nTape drive is Not ready\n");
        return(stat);
    }

    bzero(jbuf, 16);
    stat = Tinquir(jbuf, 64L);
    if(stat)
    {
        printf("\nTape error during Inquiry\n");
        if(stat == 2) Reques_Sense();
        return(stat);
    }
    if(jbuf[0] != 1)
    {
        printf("\tDevice is NOT a TAPE DRIVE!  Reported: %d\n", (int)(jbuf[0]));
        return(1);
    }

    for(x = 512; x > 0; x--);
    stat = Tload(0L);           /* Load tape NO RETENSION */
    if(stat)
    {
       printf("\nTape error during Load\n");
       if(stat == 2) Reques_Sense();
       return(stat);
    }
    for(x = 512; x > 0; x--);
    bzero(&jbuf[0], 512L);
    jbuf[2] = 0x10; 		    /* Buffered IO Mode */
    jbuf[3] = 0x08;                 /* Descriptor length */
    jbuf[4] = 0x05;                 /* Density Code = QIC24 */
    jbuf[12] = 0x03;                /* Disable Soft Error Report & autoinit */
    stat = Tmselect(&jbuf[0], 64L); /* Perform Mode Select */
    if(stat)
    {
       printf("\nTape error during Mode Select\n");
       if(stat == 2) Reques_Sense();
       return(stat);
    }

    for(x = 512; x > 0; x--);

    if(rite)		/* If open for write then check write protect */
    {
	bzero(&jbuf[0], 512L);
	stat = Tmsense(&jbuf[0], 255L);
	if(stat || (jbuf[2] & 0x80))
	{
	    printf("\t*** Tape is WRITE PROTECTED ***\007\n");
	    printf("STAT: %02x    ", stat);
	    for(x = 0; x < 16; x++)
		printf("%02x ", jbuf[x]);
	    printf("\n");
	    return(1);
	}
    }
    return(0);
}

int tclose()
{
    int stat;

    sleep(1);
    stat = Trewind();
    if(stat)
    {
       printf("\nTape error during Rewind\n");
       if(stat == 2) Reques_Sense();
    }
    sleep(1);
    stat = Tunload(0L);
    if(stat)
    {
       printf("\nTape error during Unload\n");
       if(stat == 2) Reques_Sense();
    }
    return(stat);
}

int twritef(blks)
int blks;
{
    int stat;
    qblk = 0;
    stat = Twrite(tbuf, (long)(blks));    /* Write data to tape */
    if(stat)
    {
       if(stat == 2) Reques_Sense();
    }
    return(stat);
}


int twrite(bufr, bites)
char *bufr;
int bites;
{
    int stat;

    lcopy(bufr, &tbuf[(long)(qblk) * 512L], (bites >> 2));
    qblk += 1;
    if(qblk == blocks)
    {
        qblk = 0;
        stat = Twrite(tbuf, (long)(blocks));    /* Write data to tape */
        if(stat)
        {
           if(stat == 2) Reques_Sense();
        }
        return(stat);
    }
    return(0);
}
    
int tread(bufr, bites)
char *bufr;
int bites;
{
    int blks, stat;

    blks = (bites >> 9);
    stat = Tread(bufr, (long)(blks));   /* Read data from tape */
    if(stat)
    {
       printf("\nTape error during Read:%d\n", stat);
       if(stat == 2) Reques_Sense();
    }
    return(stat);
}

int tspace(bites)
long bites;
{
    long blks;
    int x, stat;

    blks = (bites / 512L);
    if(bites % 512L) blks += 1L;
    stat = Tspace(blks);	   /* space out file size blocks */
    if(stat)
    {
       printf("\nTape error during Spacing:%d\n", stat);
       if(stat == 2) Reques_Sense();
    }
    for(x = 512; x > 0; x--);
    return(stat);
}

int tfmark()
{
    int stat;

    bzero( &tbuf[(long)(qblk) * 512L], 512 );
    qblk += 1;
    stat = Twrite(tbuf, (long)(qblk));  /* Write data to tape */
    if(stat)
    {
       if(stat == 2) Reques_Sense();
    }
    qblk = 0;

    sleep(1);
    stat = Tfmark(2L);          /* Write 2 filemarks */
    if(stat)
    {
       printf("\nTape error during filemark write\n");
       if(stat == 2) Reques_Sense();
    }
    return(stat);
}

int Reques_Sense()
{
    int stat, i;
    char sense[512];
    
    bzero(sense, 32);
    stat = Trsense(&sense[0], 64L);
#ifdef DEBUG
    printf("\nSense Data: ");
    for(i = 0; i < 11; i++) printf(" %02x", (int)(sense[i]) & 0xFF);
    printf("\n");
#endif
    return(stat);
}

