
/****************************************************************
**
**  Test to exercise the tapedvr.prg (SCSI TAPE DRIVER) program
**
**   Must execute tapedvrX.prg first to install the tape driver
**
*/

#include<stdio.h>
#include<osbind.h>
#include<tapeio.h>

#define BBLKS 254L
#define BBLKW 254
#define HBLKS 127L
#define HBLKW 127
#define BSIZE BBLKS*512L
#define HSIZE HBLKS*512L

/* 3.5 megs for disc/tape io test */
#define IOTS BBLKW * 30

main()
{
	int istape, i, blk, stat;
	long x;					/* Long index and GP */
	char *buffer;
	char *ptr;

	buffer = Malloc(BSIZE);
	if(!buffer)
	{
	    printf("Malloc error allocating %ld byte buffer\n", BSIZE);
	    exit(1);
	}

	printf("%ld byte buffer allocated at address 0x%lx\n", BSIZE, (long)buffer);

	istape = 0;

	printf("Test Unit Ready\n");
	stat = Tready();
	if(stat)
	{
	   printf("\tTape drive is Not ready\n");
	   goto bye;
	}

	bclear(buffer, 16L);
	printf("Inquiry\n");
	stat = Tinquir(buffer, 64L);
	if(stat) goto bye;
	if(buffer[0] != 1)
	{
	    printf("\tDevice is NOT a TAPE DRIVE!  Reported: %d\n", (int)(buffer[0]));
	    goto bye;
	}

	istape = 1;				/* Tape Device Flag */
	
	printf("Load Tape\n");
	stat = Tload(0L);			/* Load tape NO RETENSION */
	if(stat) goto bye;

	printf("Mode Select\n");
	bclear(buffer, 13L);
	buffer[2] = 0x10;			/* Buffered IO Mode */
	buffer[3] = 0x08;			/* Descriptor length */
	buffer[4] = 0x00;			/* Density Code = QIC24 */
	buffer[12] = 0x03;			/* Disable Soft Error Report */
	stat = Tmselect(buffer, 64L);		/* Perform Mode Select */
	if(stat) goto bye;

	printf("Mode Sense\n");
	stat = Mode_Sense();			/* Mode Sense */

	printf("Creating data buffer patterns\n");
	for(ptr = buffer, x = 0L; x < BSIZE; x++) *ptr++ = (char)(x);
	
	printf("Write Tape\n");
	stat = Twrite(buffer, BBLKS);		/* Write 64 512 byte blocks */
	if(stat) goto bye;
	
	printf("Write Filemark\n");
	stat = Tfmark(2L);			/* Write 2 filemarks */
	if(stat) goto bye;
	
	printf("Rewind Tape\n");
	stat = Trewind();			/* Rewind tape */
	if(stat) goto bye;
	
	printf("Clearing data buffer\n");
	bclear(buffer, BSIZE);
	
	printf("Read Tape\n");
	stat = Tread(buffer, BBLKS);		/* Read 64 512 byte blocks */
	if(stat) goto bye;
	
	printf("Rewind Tape\n");
	stat = Trewind();			/* Rewind Tape */
	if(stat) goto bye;
	
	printf("Checking data buffer\n");
	for(ptr = buffer, x = 0L; x < BSIZE; x++, ptr++)
	{
	    if(*ptr != (char)(x))
		printf("\nData error offset %lx, was %02x, sb %02x",
		    x, (unsigned int)(*ptr), (int)(x));
	}
	
	printf("Disk - Tape I/O test\n");

	for(blk = 0; blk < IOTS; blk += BBLKW)
	{
	    i = Rwabs(0, buffer, BBLKW, blk, 2);	/* Read Hard Disk */
	    if(i)
	    {
	    	printf("\n\tDisk IO error 0x%02x reading block %d\n", i, blk);
	    	goto bye;
	    }
	    stat = Twrite(buffer, BBLKS);	/* Write 1 Tape block */
	    if(stat)
	    {
	    	printf("\n\tTape IO error 0x%02x writing block %d\n", stat, blk);
		if(stat == 2)			/* Check Condition ? */
		{
		    printf("\tCheck Condition\n");
	    	    stat = Request_Sense();	/* Request Sense if Check */
	    	}
	    }
	    printf("Blocks transfered %d\n\033A", blk);
	}
	
	printf("\nWrite Filemark\n");
	stat = Tfmark(2L);			/* Write 2 file marks */
	if(stat) goto bye;
	
	printf("Rewind Tape\n");
	stat = Trewind();			/* Rewind Tape */
	if(stat) goto bye;
	
	printf("Mode Select (Turn off buffered mode)\n");
	bclear(buffer, 13L);
	buffer[2] = 0x00;			/* Unbuffered IO Mode */
	buffer[3] = 0x08;			/* Descriptor length */
	buffer[4] = 0x00;			/* Density Code = QIC24 */
	buffer[12] = 0x03;			/* Disable Soft Error Report */
	stat = Tmselect(buffer, 64L);	/* Perform Mode Select */
	if(stat) goto bye;
	
	/*  Read data from disc and tape and compare data */
	
	for(blk = 0; blk < IOTS; blk += HBLKW)
	{
	    i = Rwabs(0, buffer, HBLKW, blk, 2);	/* Read Hard Disk */
	    if(i)
	    {
	    	printf("\n\tDisk IO error 0x%02x reading block %d\n", i, blk);
	    	goto bye;
	    }
	    stat = Tread(&buffer[HSIZE], HBLKS);	/* Write Tape drive */
	    if(stat)
	    {
	    	printf("\n\tTape IO error 0x%02x reading block %d\n", stat, blk);
		if(stat == 2)			/* Check Condition ? */
		{
		    printf("\tCheck Condition\n");
	    	    stat = Request_Sense();	/* Request Sense if Check */
	    	}
	    }
	    
	    for(x = 0L; x < HSIZE; x++)
	    {
	       if(buffer[x] != buffer[x+HSIZE])
	       {
	       	   printf("\n\033pData Error!\033q\7\n");
	       	   x = HSIZE+1L;
	       }
	    }
	    printf("Blocks verified %d\n\033A", blk);
	} 
	printf("\nTest Completed.\n");
	printf("Mode Select (Turn on buffered mode)\n");
	bclear(buffer, 13L);
	buffer[2] = 0x10;			/* Buffered IO Mode */
	buffer[3] = 0x08;			/* Descriptor length */
	buffer[4] = 0x00;			/* Density Code = QIC24 */
	buffer[12] = 0x03;			/* Disable Soft Error Report */
	stat = Tmselect(buffer, 64L);		/* Perform Mode Select */
bye:
	if (stat == 0xACE)			/* Driver not installed */
	{
	   printf("Streaming Tape driver 'tapedvr.prg' not loaded\n");
	}
	else if (stat == 0x02)			/* Check Condition */
	{
	    printf("\tCheck Condition\n");
	    stat = Request_Sense();
	}
	else if(stat) 
	{
	    printf("\tExit with Error - Tape status = %02x\n");
	}

	if(stat != 0xACE && istape)
	{
	    printf("Unload Tape\n");
	    stat = Tunload(0L);			/* Unload tape NO RETENSION */
        }

	printf("Hit [RETURN] when ready ... ");
	i = getc(stdin);	
}

int Request_Sense()
{
    int stat, i;
    char sense[512];
    
    bclear(&sense[0], 32L);
    stat = Trsense(&sense[0], 64L);
    printf("\tSense Data: ");
    for(i = 0; i < 11; i++) printf(" %02x", (int)(sense[i]) & 0xFF);
    printf("\n");
    return(stat);
}

int Mode_Sense()
{
	int stat;
	long x;
	char buffer[512];

	bclear(&buffer[0], 13L);
	stat = Tmsense(&buffer[0], 255L);	/* Display Mode Sense */
	if(stat) return(stat);
	printf("    Media Type           : %02x\n", (int)(buffer[1]) & 0xFF);
	printf("    Write Protect        : %s\n", (buffer[2] & 0x80) ? "On" : "Off");
	printf("    Buffered Mode        : %s\n", (buffer[2] & 0x10) ? "On" : "Off");
	printf("    Speed                : %d\n", (int)(buffer[2] & 3));
	printf("    Density Code         : %02x\n", (int)(buffer[4]));
	x = ((long)(buffer[5]) & 0xff) << 16;
	x |= ((long)(buffer[6]) & 0xff) << 8;
	x |= ((long)(buffer[7]) & 0xff);
	printf("    Number of Blocks     : %ld\n", x);
	x = ((buffer[9] & 0xff) << 16);
	x |= ((buffer[10] & 0xff) << 8);
	x |= ((buffer[11]) & 0xff);
	printf("    Block Size           : %ld\n", x);
	printf("    Disable Erase Ahead  : %s\n", (buffer[12] & 4) ? "On" : "Off");
	printf("    Auto Inhibit         : %s\n", (buffer[12] & 2) ? "On" : "Off");
	printf("    Soft Error Count     : %s\n", (buffer[12] & 1) ? "Supressed" : "Enabled");
	return(stat);
}

bclear(p, cnt)
char *p;
long cnt;
{
    long x;

    for(x = 0L; x < cnt; x++)
	*p++ = 0;
}

