/*** dtest.c * * DTEST.TTP -- Disk/DMA test program * gcc {-DVERBOSE} -o dtest.ttp dtest.c -liio * * 910315 JWTittsler originally a wrapper for TT DMA test program * 910325 jwt make the GetBPB() call only if given the -B switch * show only first 10 errors/cycle, unless given -E switch * 910326 jwt make clearing the buffers optional, setable fill value * -L sets limit from base record; if set then -I specifies * increment from one cycle to next, if I==0 then random * blocks * 910404 jwt ring bell on errors unless given the -q (quiet) switch * 910627 jwt -T nn enter standby mode before writes, pause nn ticks * -U nn enter standby mode before reads, pause nn ticks * keywait at end of Usage() help screen */ #define VERSION " Version of Jun 27 17:50:00 JST 1991" #define OPTIONS "bBc:C:d:D:eEfFi:I:l:L:o:O:p:P:qQr:R:s:S:t:T:u:U:Zz" #define RECORDSIZE (512L) #define SLOP (8L) /* space between buffers (in bytes) */ #define SHOWABLEERRORS (10L) /* default number of errors to show per pass */ /* hardware and OS address definitions */ #define HZ200 ((volatile long *)0x000004BAL) #define IDECOMMAND ((volatile short *)0xFFF0001CL) #define IDESTATUS ((volatile short *)0xFFF0001CL) #define IDEBUSY (0x80) /* IDE commands */ #define IDESTANDBY (0xE0) #define IDEIDLE (0xE1) /* BIOS Definitions */ /* Bconxx() handles */ #define CONSOLE 2 /* Rwabs() flags */ #define READ (0) #define WRITE (1) #define PHYSICAL (8) #define PHYSREAD (READ+PHYSICAL) #define PHYSWRITE (WRITE+PHYSICAL) #include #include #include #include #include #include extern int opterr,optind; extern char *optarg; long lErrors=0L; int bAllErrors=0; int bQuiet=0; int nWritePause=-1; int nReadPause=-1; void Usage(void){ puts("DTEST -B -E -F -Z -C nnnn -D nn -I nnnn \ -L nnnn -O n -P nnn -R nnnn -T nn -U nn"); puts(" where:"); puts(" -B do getbpb() call"); puts(" -E show all errors {first 10/cycle}"); puts(" -F put buffer in Fast RAM"); puts(" -Q be quiet on errors"); puts(" -Z don't preset read buffers"); puts(" -C nnnn record count {40}"); puts(" -D nn TOS physical device number {0}"); puts(" -I nnnn increment {0, random if limit specified}"); puts(" -L nnnn limit to be added to base record number {0}"); puts(" -O n offset from long alignment {0}"); puts(" -P nnn read buffer preset value {0}"); puts(" -R nnnn base starting record number {100}"); puts(" -T nnn enter standby, pause nn sec before writes"); puts(" -U nnn enter standby, pause nn sec before reads"); printf("\nStrike a key to continue..."); fflush(stdout); (void)Cconin(); /* swallow up character */ } void StandbyPause(int nTickDelay){ long lOldSSP; long lTimeOut; lOldSSP = Super(0L); /* enter supervisor mode */ /* make sure the drive is not busy, and clear any pending IRQ */ while(*IDESTATUS & IDEBUSY) ; /* issue command to immediately enter STANDBY mode */ *IDECOMMAND = IDESTANDBY; /* wait for BUSY to go away, and clear IRQ */ while(*IDESTATUS & IDEBUSY) ; if(nTickDelay > 0) { lTimeOut = *HZ200 + nTickDelay; while(*HZ200 < lTimeOut) ; } (void)Super(lOldSSP); /* return to user mode */ } int GetNumArg(char *string){ return(atoi(string)); /* someday this will handle hex and decimal */ } /* yeah, sure */ char *Myalloc(long size, short type){ int nTOSVersion, nTemp; nTemp = Sversion(); nTOSVersion = (nTemp>>8) | ((nTemp&0xFF)<<8); /* byte swap */ if (nTOSVersion >= 0x0019) return (char *)Mxalloc(size, type); else if (type) return NULL; /* old TOS only has one kind of RAM */ else return (char *)Malloc(size); } void SetBuffer(unsigned char *pB, long lBufferSize, int nPass) { register int i; register unsigned char bVal; bVal = (unsigned char) nPass; for(i=0; i= 0){ putchar('T'); fflush(stdout); StandbyPause(nWritePause); } /* write a known pattern to the disk */ SetBuffer(pBuf1, lBufferSize, nPass); putchar('W'); fflush(stdout); if(nResult=Rwabs(PHYSWRITE, pBuf1, nCount, nRecord, nDevice)){ printf("%02X", nResult); ++lErrors; bHadError = 1; } /* now preset the destination buffers */ if(bDoBufferFill){ memset(pBuf2, cSeed, lBufferSize); memset(pBuf3, cSeed, lBufferSize); } /* read it in once */ if(nReadPause >= 0) { putchar('U'); fflush(stdout); StandbyPause(nReadPause); } putchar('R'); fflush(stdout); if(nResult=Rwabs(PHYSREAD, pBuf2, nCount, nRecord, nDevice)){ printf("%02X", nResult); ++lErrors; bHadError = 1; } /* read it in a second time */ if(nReadPause >= 0) { putchar('U'); fflush(stdout); StandbyPause(nReadPause); } putchar('S'); fflush(stdout); if(nResult=Rwabs(PHYSREAD, pBuf3, nCount, nRecord, nDevice)){ printf("%02X", nResult); ++lErrors; bHadError = 1; } /* now compare the two reads to the original */ putchar('C'); fflush(stdout); bHadError += CompareBuffers(pBuf1, pBuf2, pBuf3, lBufferSize); if(bHadError) { putchar('\n'); if(bQuiet==0) putchar('\007'); } else putchar('.'); fflush(stdout); /* set up a new starting record for the next cycle */ if(nLimit){ /* is the starting record allowed to change? */ if(nIncrement){ /* a linear increment */ if((nRecord += nIncrement) > (nBaseRecord+nLimit)) nRecord = nBaseRecord; } else /* a random distance up to limit away */ nRecord = nBaseRecord + (int)(Random()%(long)nLimit); } } (void)Cconin(); /* swallow up character */ }