home *** CD-ROM | disk | FTP | other *** search
- /*
- * DiskSpeed v4.0
- * by
- * Michael Sinz
- *
- * Copyright (c) 1989 by MKSoft Development
- *
- * MKSoft Development
- * 163 Appledore Drive
- * Downingtown, PA 19335
- *
- * Yes, this is yet another disk speed testing program, but with a few
- * differences. It was designed to give the most accurate results of the
- * true disk performance in the system. For this reason many of
- * DiskSpeed's results may look either lower or higher than current disk
- * performance tests.
- *
- ******************************************************************************
- * *
- * Reading legal mush can turn your brain into guacamole! *
- * *
- * So here is some of that legal mush: *
- * *
- * Permission is hereby granted to distribute this program's source *
- * executable, and documentation for non-commercial purposes, so long as the *
- * copyright notices are not removed from the sources, executable or *
- * documentation. This program may not be distributed for a profit without *
- * the express written consent of the author Michael Sinz. *
- * *
- * This program is not in the public domain. *
- * *
- * Fred Fish is expressly granted permission to distribute this program's *
- * source and executable as part of the "Fred Fish freely redistributable *
- * Amiga software library." *
- * *
- * Permission is expressly granted for this program and it's source to be *
- * distributed as part of the Amicus Amiga software disks, and the *
- * First Amiga User Group's Hot Mix disks. *
- * *
- ******************************************************************************
- *
- * Main code and testing sections...
- */
-
- #include <exec/types.h>
- #include <exec/execbase.h>
- #include <exec/memory.h>
- #include <exec/lists.h>
- #include <exec/nodes.h>
- #include <exec/devices.h>
- #include <exec/io.h>
- #include <exec/ports.h>
- #include <devices/timer.h>
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <intuition/intuition.h>
- #include <intuition/screens.h>
- #include <workbench/workbench.h>
- #include <workbench/startup.h>
-
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/timer_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/icon_protos.h>
-
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/dos_pragmas.h>
- #include <pragmas/timer_pragmas.h>
- #include <pragmas/intuition_pragmas.h>
- #include <pragmas/icon_pragmas.h>
-
- #include <string.h>
- #include <stdio.h>
-
- #include "renderinfo.h"
- #include "mks_list.h"
- #include "makeboxes.h"
-
- /*
- * First, the timer stuff...
- */
- struct MyTimer
- {
- struct timerequest *tr;
- struct timeval time;
- struct MsgPort *port;
- BOOL Open;
- };
-
- /*
- * The "TextLine" structure used to display text in the information
- * "window" in DiskSpeed.
- */
- struct TextLine
- {
- struct Node tl_Node;
- ULONG tl_Size; /* Size of the allocation */
- char tl_Text[1]; /* For the NULL... */
- };
-
- /*
- * My global structure...
- */
- struct DiskSpeed
- {
- struct Window *Window; /* The DiskSpeed window... */
- struct RenderInfo *ri; /* MKSoft Render Info */
-
- BPTR Output; /* The output file handle! */
- struct Process *Me; /* Pointer to my process... */
- struct MyTimer *timer; /* Pointer to a timer structure */
-
- struct FileInfoBlock *fib; /* Pointer to a FileInfoBlock */
-
- /* */
- struct MinList TextList; /* The list the results test is linked to... */
- struct DisplayList *List; /* The "List" gadget */
- /* */
- ULONG Min_Time; /* Minimum time in seconds for a test */
- ULONG Base_CPU; /* Base CPU available... */
- ULONG CPU_Total; /* Sum of CPU availability */
- ULONG CPU_Count; /* Count of CPU availability */
-
- /* Testing parameters */
- UBYTE HighDMA; /* Set to TRUE for high video DMA... */
- UBYTE Test_DIR; /* Set to test directory stuff */
- UBYTE Test_SEEK; /* Set to test SEEK/READ */
- UBYTE pad;
-
- ULONG Align_Types; /* Set bits of alignment types... */
- ULONG Mem_TYPES; /* Set memory type flags to test... */
- ULONG Test_Size[4]; /* The four test sizes... */
-
- /* Now for the gadgets */
- struct Gadget DeviceGadget;
- struct Gadget CommentsGadget;
- struct Gadget StartTestGadget;
- struct Gadget SaveResultsGadget;
- struct Gadget StopTestGadget;
-
- struct StringInfo DeviceInfo;
- struct StringInfo CommentsInfo;
-
- struct Border StringBorder[4];
- struct Border ActionBorder[4];
- struct Border DetailBorder[2];
-
- struct IntuiText DeviceText;
- struct IntuiText CommentsText;
- struct IntuiText StartTest;
- struct IntuiText SaveResults;
- struct IntuiText StopTest;
-
- SHORT StringVectors[5*2*4];
- SHORT ActionVectors[5*2*2];
-
- /* */
- char Device[256]; /* Device name under test... */
- char Comments[256]; /* Comments string gadget... */
- char Undo[256]; /* Our one UNDO buffer... */
-
- /* */
- char CPU_Type[6]; /* 680?0 in this string (plus NULL) */
- char Exec_Ver[14]; /* Version of Exec */
-
- /* */
- char tmp1[256]; /* Some temp buffer space... */
- };
-
- #define DEVICE_GADGET 1
- #define COMMENT_GADGET 2
- #define TEST_GADGET 3
- #define SAVE_GADGET 4
- #define STOP_GADGET 5
-
- extern struct Library *SysBase;
- extern struct Library *DOSBase;
- extern struct Library *IntuitionBase;
- extern struct Library *GfxBase;
- extern struct Library *IconBase;
- struct Library *LayersBase;
-
- /* Some prototypes not given... BTW - This is mainly needed for 1.3 compatibility... ARG!!! */
- void *CreateExtIO( struct MsgPort *msg, long size );
- struct MsgPort *CreatePort( UBYTE *name, long pri );
- void DeleteExtIO( struct IORequest *io );
- void DeletePort( struct MsgPort *io );
- void DeleteTask( struct Task *task );
- void NewList( struct List *list );
-
- char FILE_CREATE[]= "File Create: ";
- char FILE_OPEN[]= "File Open: ";
- char FILE_SCAN[]= "Directory Scan:";
- char FILE_DELETE[]= "File Delete: ";
- char SEEK_READ[]= "Seek/Read: ";
-
- char BYTES_CREATE[]= "Create file: ";
- char BYTES_WRITE[]= "Write to file: ";
- char BYTES_READ[]= "Read from file:";
-
- char SEEK_UNITS[]= "seeks/sec";
- char FILE_UNITS[]= "files/sec";
- char BYTE_UNITS[]= "bytes/sec";
-
- char FILE_STRING[]= "%04lx DiskSpeed Test File ";
-
- char TEST_DIR[]= " DiskSpeed Test Directory ";
-
- char COPYRIGHT[]= "MKSoft DiskSpeed 4.0 - Copyright ⌐ 1989-91 MKSoft Development";
-
- char START_TEST[]= "Start Test";
- char SAVE_RESULTS[]= "Save Results";
- char STOP_TEST[]= "Stop Test";
-
- static char fontnam[11]="topaz.font";
- struct TextAttr TOPAZ80={fontnam,8,0,FPF_ROMFONT};
-
- #define NUM_FILES 200
-
- /*
- * This is the minimum time for test that can be extended/shorted automatically
- * This number should not be set too low otherwise the test results will be
- * inaccurate due to timer granularity. (in seconds)
- */
- #define MIN_TEST_TIME 8
-
- /*
- * This section of code is used to test CPU availability. Due to the nature of
- * the code, the actual test code for the task is in assembly...
- */
- extern ULONG __far CPU_Use_Base;
- extern ULONG __far CPU_State_Flag;
- extern ULONG __far CPU_Count_Low;
- extern ULONG __far CPU_Count_High;
-
- struct Task *Init_CPU_Available(void);
- void Free_CPU_Available(void);
- void CPU_Calibrate(void);
-
-
- /* The Wait pointer I use... */
- USHORT __chip WaitPointer[36] =
- {
- 0x0000, 0x0000, 0x0400, 0x07C0, 0x0000, 0x07C0, 0x0100, 0x0380, 0x0000,
- 0x07E0, 0x07C0, 0x1FF8, 0x1FF0, 0x3FEC, 0x3FF8, 0x7FDE, 0x3FF8, 0x7FBE,
- 0x7FFC, 0xFF7F, 0x7EFC, 0xFFFF, 0x7FFC, 0xFFFF, 0x3FF8, 0x7FFE, 0x3FF8,
- 0x7FFE, 0x1FF0, 0x3FFC, 0x07C0, 0x1FF8, 0x0000, 0x07E0, 0x0000, 0x0000
- };
-
- /*
- * These two defines set up and clear the WaitPointer...
- */
- #define SetWait(x) SetPointer(x,WaitPointer,16L,16L,-6L,0L)
- #define ClearWait(x) ClearPointer(x)
-
- /*
- * This routine returns the amount of time in the timer...
- * The number returned is in Seconds...
- */
- ULONG Read_Timer(struct MyTimer *mt)
- {
- struct Library *TimerBase=(struct Library *)(mt->tr->tr_node.io_Device);
-
- /* Get the current time... */
- mt->tr->tr_node.io_Command=TR_GETSYSTIME;
- mt->tr->tr_node.io_Flags=IOF_QUICK;
- DoIO((struct IORequest *)(mt->tr));
-
- /* Subtract last timer result and store as the timer result */
- SubTime(&(mt->tr->tr_time),&(mt->time));
- return(mt->tr->tr_time.tv_secs);
- }
-
- /*
- * Start the timer...
- */
- void Start_Timer(struct MyTimer *mt)
- {
- /* Get the current time... */
- mt->tr->tr_node.io_Command=TR_GETSYSTIME;
- mt->tr->tr_node.io_Flags=IOF_QUICK;
- DoIO((struct IORequest *)(mt->tr));
-
- /* Store current time as the timer result */
- mt->time=mt->tr->tr_time;
-
- /*
- * This here is a nasty trick... Since the timer device
- * has a low resolution, we wait until we get to the exact
- * cross-over from one TICK to the next. We know that the
- * tick value is larger than 10 so if the difference
- * between two calls to the timer is > 10 then it must
- * have been a TICK that just went through. This is
- * not "friendly" code but since we are testing the system
- * and it is not "application" code, it is not a problem.
- */
- while ((mt->tr->tr_time.tv_micro-mt->time.tv_micro) < 10)
- {
- /* Store current time as the timer result */
- mt->time=mt->tr->tr_time;
-
- /* Get the current time... */
- mt->tr->tr_node.io_Command=TR_GETSYSTIME;
- mt->tr->tr_node.io_Flags=IOF_QUICK;
- DoIO((struct IORequest *)(mt->tr));
- }
-
- /* Store current time as the timer result */
- mt->time=mt->tr->tr_time;
- }
-
- /*
- * Stop the timer...
- */
- void Stop_Timer(struct MyTimer *mt)
- {
- struct Library *TimerBase=(struct Library *)(mt->tr->tr_node.io_Device);
-
- /* Get the current time... */
- mt->tr->tr_node.io_Command=TR_GETSYSTIME;
- mt->tr->tr_node.io_Flags=IOF_QUICK;
- DoIO((struct IORequest *)(mt->tr));
-
- /* Subtract last timer result and store as the timer result */
- SubTime(&(mt->tr->tr_time),&(mt->time));
- mt->time=mt->tr->tr_time;
- }
-
- /*
- * Free a MyTimer structure as best as possible. Do all of the error checks
- * here since this will also be called for partial timer initializations.
- */
- void Free_Timer(struct MyTimer *mt)
- {
- if (mt)
- {
- if (mt->port)
- {
- if (mt->tr)
- {
- if (mt->Open)
- {
- CloseDevice((struct IORequest *)(mt->tr));
- }
- DeleteExtIO((struct IORequest *)(mt->tr));
- }
- DeletePort(mt->port);
- }
- FreeMem(mt,sizeof(struct MyTimer));
- }
- }
-
- /*
- * Initialize a MyTimer structure. It will return NULL if it did not work.
- */
- struct MyTimer *Init_Timer(void)
- {
- struct MyTimer *mt;
-
- if (mt=AllocMem(sizeof(struct MyTimer),MEMF_PUBLIC|MEMF_CLEAR))
- {
- mt->Open=FALSE;
- if (mt->port=CreatePort(NULL,0L))
- {
- if (mt->tr=CreateExtIO(mt->port,sizeof(struct timerequest)))
- {
- if (!OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)(mt->tr),0L))
- {
- mt->Open=TRUE;
- }
- }
- }
- if (!(mt->Open))
- {
- Free_Timer(mt);
- mt=NULL;
- }
- }
- return(mt);
- }
-
- /*
- * Now, for the routines that will pull in the lines and display them as
- * needed in the display...
- */
- void AddDisplayLine(struct DiskSpeed *global,char *line)
- {
- ULONG size=strlen(line);
- struct TextLine *tline;
-
- if (global->Window)
- {
- if (tline=AllocMem(size+=sizeof(struct TextLine),MEMF_PUBLIC|MEMF_CLEAR))
- {
- tline->tl_Size=size;
- tline->tl_Node.ln_Name=tline->tl_Text;
- strcpy(tline->tl_Text,line);
-
- AddTail((struct List *)&(global->TextList),&(tline->tl_Node));
-
- /* Now display it... */
- FreshList(global->Window,global->List,&(global->TextList));
- }
- }
- else if (global->Output)
- {
- Write(global->Output,line,size);
- Write(global->Output,"\n",1);
- }
- }
-
- void FreeDisplayList(struct DiskSpeed *global)
- {
- struct TextLine *tline;
-
- while (tline=(struct TextLine *)RemHead((struct List *)&(global->TextList)))
- {
- FreeMem(tline,tline->tl_Size);
- }
-
- /* Update the display */
- if (global->Window) FreshList(global->Window,global->List,NULL);
- }
-
- /*...*/
-
- BOOL Check_Quit(struct DiskSpeed *global)
- {
- BOOL worked=TRUE;
- struct IntuiMessage *msg;
-
- if (global->Window)
- {
- while (msg=(struct IntuiMessage *)GetMsg(global->Window->UserPort))
- {
- if (msg->Class==CLOSEWINDOW) worked=FALSE;
- else if (msg->Class==GADGETUP) if (msg->IAddress=&(global->StopTestGadget)) worked=FALSE;
- Check_ListGadget(global->Window,msg);
- ReplyMsg((struct Message *)msg);
- }
- }
-
- if (SetSignal(0,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) worked=FALSE;
-
- if (!worked) AddDisplayLine(global,"*** Interrupted by user ***");
-
- return(worked);
- }
-
- /*...*/
-
- /*
- * It knows that the Y value is fixed point by n-digits...
- */
- ULONG MaxDivide(ULONG x,ULONG y,ULONG digits)
- {
- ULONG result;
- ULONG num=0; /* Number of 10 units adjusted for so far */
-
- while ((x<399999999) && (num<digits))
- {
- x*=10;
- num++;
- }
-
- while (num<digits)
- {
- num++;
- if (num==digits) y+=5; /* Round it if last digit... */
- y=y/10;
- }
-
- if (y) result=x/y;
- else result=-1; /* MAX INT if y=0 */
-
- return(result);
- }
-
- /*
- * Build a string and add it to the display of results.
- * This routine knows how to take the timer results and the CPU
- * results and format them into a string with the given header
- * and the given unit of measure.
- */
- VOID Display_Result(struct DiskSpeed *global,char *Header,ULONG number,char *Units)
- {
- char *p=global->tmp1;
- char format[48];
- ULONG clicks; /* To figure out the number of clicks/second */
- ULONG time;
- ULONG tmp_time;
-
- /* First, make sure (as best as possible) that the CPU values are right */
- CPU_State_Flag=TRUE;
- Delay(1); /* Let it run into the TRUE CPU_State_Flag */
-
- /* 1,000,000 micro = 1 second... */
- time=(global->timer->time.tv_secs * 1000000) + global->timer->time.tv_micro;
- /* time is now in micro seconds... */
-
- number=MaxDivide(number,time,6);
-
- strcpy(format,"%s %9ld %s");
- if (!number)
- {
- strcpy(format,"%s < %ld %s");
- number=1;
- }
-
- if (global->Base_CPU)
- {
- tmp_time=time; /* For below... */
-
- while (CPU_Count_High)
- {
- /* Adjust the time and the CPU count as needed */
- tmp_time=tmp_time >> 1;
- CPU_Count_Low=CPU_Count_Low >> 1;
- if (CPU_Count_High & 1) CPU_Count_Low += 0x80000000;
- CPU_Count_High=CPU_Count_High >> 1;
- }
-
- clicks=MaxDivide(CPU_Count_Low,tmp_time,6);
- clicks=(MaxDivide(clicks,global->Base_CPU,3)+5)/10;
- global->CPU_Total+=clicks;
- global->CPU_Count++;
-
- strcat(format," | CPU Available: %ld%%");
- }
-
- sprintf(p,format,Header,number,Units,clicks);
-
- AddDisplayLine(global,p);
- }
-
- VOID Display_Error(struct DiskSpeed *global,char *test)
- {
- sprintf(global->tmp1,"Error: %s test failed.");
- AddDisplayLine(global,global->tmp1);
- }
-
- /*
- * In order to keep the file create test fair, it must always do
- * the same number of files. The way filing systems work, many times
- * the get slower as the number of files in a directory grow
- */
- BOOL CreateFileTest(struct DiskSpeed *global)
- {
- BPTR file;
- ULONG count;
- BOOL worked=TRUE;
- char *p=global->tmp1; /* For speed reasons */
-
- Start_Timer(global->timer);
- Init_CPU_Available(); /* Start counting free CPU cycles... */
-
- for (count=0;(count<NUM_FILES) && (worked &= Check_Quit(global));count++)
- {
- sprintf(p,FILE_STRING,count);
- if (file=Open(p,MODE_NEWFILE)) Close(file);
- else
- {
- Display_Error(global,"File Create");
- worked=FALSE;
- }
- }
-
- Stop_Timer(global->timer);
-
- if (worked) Display_Result(global,FILE_CREATE,NUM_FILES,FILE_UNITS);
-
- Free_CPU_Available();
-
- return(worked);
- }
-
- BOOL OpenFileTest(struct DiskSpeed *global)
- {
- BPTR file;
- ULONG count=0;
- BOOL worked=TRUE;
- char *p=global->tmp1;
-
- Start_Timer(global->timer);
- Init_CPU_Available(); /* Start counting free CPU cycles... */
- while ((worked &= Check_Quit(global)) && (Read_Timer(global->timer) < global->Min_Time))
- {
- sprintf(p,FILE_STRING,(ULONG)(count % NUM_FILES));
- count++;
- if (file=Open(p,MODE_OLDFILE)) Close(file);
- else
- {
- Display_Error(global,"File Open");
- worked=FALSE;
- }
- }
- Stop_Timer(global->timer);
-
- if (worked) Display_Result(global,FILE_OPEN,count,FILE_UNITS);
-
- Free_CPU_Available();
- return(worked);
- }
-
- BOOL ScanDirectoryTest(struct DiskSpeed *global)
- {
- BPTR lock=NULL;
- ULONG count=0;
- BOOL worked=TRUE;
-
- Start_Timer(global->timer);
- Init_CPU_Available(); /* Start counting free CPU cycles... */
- while ((worked &= Check_Quit(global)) && (Read_Timer(global->timer) < global->Min_Time))
- {
- if (lock)
- {
- if (!ExNext(lock,global->fib)) lock=NULL;
- else count++;
- }
- else
- {
- CurrentDir(lock=CurrentDir(NULL));
- if (Examine(lock,global->fib)) count++;
- else
- {
- Display_Error(global,"Directory Scan");
- worked=FALSE;
- }
- }
- }
- Stop_Timer(global->timer);
-
- if (worked) Display_Result(global,FILE_SCAN,count,FILE_UNITS);
-
- Free_CPU_Available();
- return(worked);
- }
-
- /*
- * In order to keep the file delete test fair, it must always do
- * the same number of files. The way filing systems work, many times
- * the get slower as the number of files in a directory grow
- */
- BOOL DeleteFileTest(struct DiskSpeed *global)
- {
- ULONG count;
- BOOL worked=TRUE;
- char *p=global->tmp1;
-
- Start_Timer(global->timer);
- Init_CPU_Available(); /* Start counting free CPU cycles... */
-
- for (count=0;(count<NUM_FILES) && (worked &= Check_Quit(global));count++)
- {
- sprintf(p,FILE_STRING,count);
- if (!DeleteFile(p))
- {
- Display_Error(global,"File Delete");
- worked=FALSE;
- }
- }
-
- Stop_Timer(global->timer);
-
- if (worked) Display_Result(global,FILE_DELETE,NUM_FILES,FILE_UNITS);
-
- Free_CPU_Available();
-
- return(worked);
- }
-
- BOOL SeekReadTest(struct DiskSpeed *global)
- {
- BPTR file;
- ULONG size;
- ULONG count;
- LONG pos=0;
- LONG buffer[16];
- BOOL worked=FALSE;
- void *buf;
-
- /* First we build a file by writing the ROM to disk... */
- if (file=Open(FILE_STRING,MODE_NEWFILE))
- {
- size=0x40000; /* Start by asking for 256K */
- while (size && (!(buf=AllocMem(size,MEMF_PUBLIC)))) size=size>>1;
-
- if (buf)
- {
- worked=TRUE;
- /* Write a 256K file... */
- count=0x40000/size;
- while ((count>0) && (worked&=Check_Quit(global)))
- {
- count--;
- if (size!=Write(file,buf,size))
- {
- worked=FALSE;
- Display_Error(global,"Seek/Read");
- }
- }
- FreeMem(buf,size);
- }
- else Display_Error(global,"Seek/Read");
-
- Start_Timer(global->timer);
- Init_CPU_Available(); /* Start counting free CPU cycles... */
- while ((worked &= Check_Quit(global)) && (Read_Timer(global->timer) < global->Min_Time))
- {
- Seek(file,pos,OFFSET_BEGINING);
- Read(file,buffer,64);
- count++;
-
- Seek(file,-(pos+64),OFFSET_END);
- Read(file,buffer,64);
- count++;
-
- Seek(file,-(pos+(size/3)),OFFSET_CURRENT);
- Read(file,buffer,64);
- count++;
-
- /* Come up with another position... */
- pos=(pos+(size/11)) % (size/3);
- }
- Stop_Timer(global->timer);
-
- if (worked) Display_Result(global,SEEK_READ,count,SEEK_UNITS);
-
- Free_CPU_Available();
-
- Close(file);
- DeleteFile(FILE_STRING);
- }
- else Display_Error(global,"Seek/Read");
-
- return(worked);
- }
-
- BOOL SpeedTest(struct DiskSpeed *global,ULONG size,ULONG offset,ULONG mem_type)
- {
- BOOL worked=TRUE;
- char *buffer;
- char *mem; /* What we really allocated */
- char *type;
- char *type2;
- ULONG loop;
- ULONG count;
- LONG times;
- BPTR file=NULL;
-
- AddDisplayLine(global,"");
-
- type="FAST";
- if (mem_type & MEMF_CHIP) type="CHIP";
-
- type2="LONG";
- if (offset & 2) type2="WORD";
- if (offset & 1) type2="BYTE";
-
- if (mem=AllocMem(size+offset,mem_type|MEMF_PUBLIC))
- {
- /* Set up memory... */
- buffer=&(mem[offset]);
-
- for (loop=0;loop<size;loop++) buffer[loop]=(UBYTE)loop;
-
- sprintf(global->tmp1,"Testing with a %ld byte buffer. (%s-aligned, MEMF_%s)",size,type2,type);
- AddDisplayLine(global,global->tmp1);
-
- count=0;
- times=0;
-
- Start_Timer(global->timer);
- Init_CPU_Available(); /* Start counting free CPU cycles... */
- while ((worked &= Check_Quit(global)) && (Read_Timer(global->timer) < global->Min_Time))
- {
- if (times<1)
- {
- if (file) Close(file);
- DeleteFile(FILE_STRING);
- if (!(file=Open(FILE_STRING,MODE_NEWFILE)))
- {
- Display_Error(global,"Create File");
- worked=FALSE;
- }
- times=0x40000/size; /* Try to make file at least 256K size */
- }
- if (file)
- {
- if (size!=Write(file,buffer,size))
- {
- Display_Error(global,"Create File");
- worked=FALSE;
- }
- else count+=size;
- times--;
- }
- }
- Stop_Timer(global->timer);
-
- if (worked) Display_Result(global,BYTES_CREATE,count,BYTE_UNITS);
-
- /* Fill out the file... */
- if (file) while ((worked &= Check_Quit(global)) && (times>0))
- {
- Write(file,buffer,size);
- times--;
- }
-
- if (file) Close(file);
- file=NULL;
-
- if (worked) if (!(file=Open(FILE_STRING,MODE_OLDFILE)))
- {
- Display_Error(global,"Write File");
- worked=FALSE;
- }
-
- count=0;
- times=0;
-
- Start_Timer(global->timer);
- Init_CPU_Available(); /* Start counting free CPU cycles... */
- while ((worked &= Check_Quit(global)) && (Read_Timer(global->timer) < global->Min_Time))
- {
- if (times<1)
- {
- Seek(file,0,OFFSET_BEGINNING);
- times=0x40000/size; /* Try to make file at least 256K size */
- }
- if (size!=Write(file,buffer,size))
- {
- Display_Error(global,"Write File");
- worked=FALSE;
- }
- else count+=size;
- times--;
- }
- Stop_Timer(global->timer);
-
- if (worked) Display_Result(global,BYTES_WRITE,count,BYTE_UNITS);
-
- if (file) Close(file);
- file=NULL;
-
- if (worked) if (!(file=Open(FILE_STRING,MODE_OLDFILE)))
- {
- Display_Error(global,"Read File");
- worked=FALSE;
- }
-
- count=0;
- times=0;
-
- Start_Timer(global->timer);
- Init_CPU_Available(); /* Start counting free CPU cycles... */
- while ((worked &= Check_Quit(global)) && (Read_Timer(global->timer) < global->Min_Time))
- {
- if (times<1)
- {
- Seek(file,0,OFFSET_BEGINNING);
- times=0x40000/size; /* Try to make file at least 256K size */
- }
- if (size!=Read(file,buffer,size))
- {
- Display_Error(global,"Read File");
- worked=FALSE;
- }
- else count+=size;
- times--;
- }
- Stop_Timer(global->timer);
-
- if (worked)
- {
- for (loop=0;loop<size;loop++) worked &= (buffer[loop]==(UBYTE)loop);
- if (!worked) AddDisplayLine(global,"*** Data Error *** Buffer did not read correctly.");
- }
-
- if (worked) Display_Result(global,BYTES_READ,count,BYTE_UNITS);
-
- if (file) Close(file);
-
- Free_CPU_Available();
- FreeMem(mem,size+offset);
- DeleteFile(FILE_STRING);
- }
- else
- {
- sprintf(global->tmp1,"Skipping %ld byte MEMF_%s test due to lack of memory.",size,type);
- AddDisplayLine(global,global->tmp1);
- }
-
- return(worked);
- }
-
- /*
- * Clean up (remove) all of the files in the current directory...
- */
- void CleanUpFiles(struct DiskSpeed *global)
- {
- BPTR lock;
-
- CurrentDir(lock=CurrentDir(NULL)); /* Get current directory lock */
-
- while (lock)
- {
- if (Examine(lock,global->fib))
- {
- if (ExNext(lock,global->fib)) DeleteFile(global->fib->fib_FileName);
- else lock=NULL;
- }
- else lock=NULL;
- }
- }
-
- void DoTests(struct DiskSpeed *global)
- {
- char *p=global->tmp1;
- BOOL working;
- ULONG memtype;
- ULONG offset;
- LONG buffers;
- char *fstring;
- short size;
-
- /*
- * Ok, so now we are ready to run... Display the
- * test conditions...
- */
- strcpy(p,"CPU: ");
- strcat(p,global->CPU_Type);
- strcat(p," OS Version: ");
- strcat(p,global->Exec_Ver);
- if (global->HighDMA) strcat(p," High");
- else strcat(p," Normal");
- strcat(p," Video DMA");
- AddDisplayLine(global,p);
-
- /*
- * Now, if we are in 2.0 OS, we can also find out the number of buffers
- * (maybe) on that device. This is important.
- */
- fstring="Device: %s Buffers: <information unavailable>";
- if (DOSBase->lib_Version > 36L)
- {
- /*
- * Ok, so we can now try to get a reading of the buffers
- * for the place we are about to test...
- *
- * Note: Since we are in the "CURRENTDIR" of the test disk,
- * we are using "" as the "device" to which to call AddBuffers()
- */
- if ((buffers=AddBuffers("",0)) > 0) fstring="Device: %s Buffers: %ld";
- }
-
- sprintf(p,fstring,global->Device,buffers);
- AddDisplayLine(global,p);
-
- if (global->Comments[0])
- {
- strcpy(p,"Comments: ");
- strcat(p,global->Comments);
- AddDisplayLine(global,p);
- }
-
- AddDisplayLine(global,"");
-
- if (CPU_Use_Base) Delay(60); /* Make sure filesystem has flushed... */
-
- Init_CPU_Available();
- if (CPU_Use_Base) Delay(75); /* Get a quick reading (~1.5 seconds) */
- Free_CPU_Available();
-
- if (CPU_Use_Base)
- {
- /*
- * Now, generate a countdown value that is aprox 3 times 1.5 second...
- */
- CPU_Use_Base=(CPU_Count_Low * 3) + 1;
- CPU_Count_Low=CPU_Use_Base;
- Forbid();
- Start_Timer(global->timer);
- CPU_Calibrate();
- Stop_Timer(global->timer);
- Permit();
-
- /*
- * If it looks like we did not get a good reading,
- * set up CPU_Use_Base to 0 in order to turn off
- * CPU readings...
- */
- if (global->timer->time.tv_secs<4)
- {
- AddDisplayLine(global,"CPU Calibration shows that CPU availability tests");
- AddDisplayLine(global,"would be inaccurate in the current system state.");
- CPU_Use_Base=0;
- }
- else CPU_Use_Base=MaxDivide(CPU_Use_Base,(global->timer->time.tv_secs * 1000000) + global->timer->time.tv_micro,6);
- }
-
- global->Base_CPU=CPU_Use_Base;
-
- if (CPU_Use_Base) sprintf(p,"CPU Speed Rating: %ld",(((CPU_Use_Base/500)+1) >> 1 ));
- else strcpy(p,"No CPU Speed Rating -- CPU % not available.");
- AddDisplayLine(global,p);
- AddDisplayLine(global,"");
-
- global->CPU_Total=0L;
- global->CPU_Count=0L;
-
- working=Check_Quit(global);
-
- if (working) if (global->Test_DIR)
- {
- AddDisplayLine(global,"Testing directory manipulation speed.");
- if (working) working=CreateFileTest(global);
- if (working) working=OpenFileTest(global);
- if (working) working=ScanDirectoryTest(global);
- if (working) working=DeleteFileTest(global);
- }
-
- if (working) if (global->Test_SEEK)
- {
- AddDisplayLine(global,"");
- if (working) working=SeekReadTest(global);
- }
-
- /* Now for some of the more complex tests */
- /* result=SpeedTest(global,Buffer,offset,mem_type); */
-
- memtype=MEMF_FAST;
- while (memtype)
- {
- if (memtype & global->Mem_TYPES) for (offset=4;offset>0;offset=offset >> 1) if (offset & global->Align_Types)
- {
- for (size=0;size<4;size++) if (global->Test_Size[size])
- {
- if (working) working=SpeedTest(global,global->Test_Size[size],offset&3,memtype);
- }
- }
-
- if (memtype & MEMF_CHIP) memtype=0;
- else memtype=MEMF_CHIP;
- }
-
- CleanUpFiles(global);
-
- if ((working) && (global->CPU_Count))
- {
- AddDisplayLine(global,"");
- global->CPU_Total=(((global->CPU_Total << 1) / global->CPU_Count)+1) >> 1;
- global->CPU_Count=(((global->Base_CPU * global->CPU_Total) / 50000)+1) >> 1;
- sprintf(p,"Average CPU Available: %ld%% | CPU Availability index: %ld",global->CPU_Total,global->CPU_Count);
- AddDisplayLine(global,p);
- }
- }
-
- void StartTest(struct DiskSpeed *global)
- {
- BPTR lock;
- BPTR newlock;
- APTR oldwindow;
-
- oldwindow=global->Me->pr_WindowPtr;
- global->Me->pr_WindowPtr=(APTR)(-1L);
-
- FreeDisplayList(global);
-
- AddDisplayLine(global,COPYRIGHT);
- AddDisplayLine(global,"-------------------------------------------------------------");
-
- if (lock=Lock(global->Device,ACCESS_READ))
- {
- lock=CurrentDir(lock);
- if (newlock=CreateDir(TEST_DIR))
- {
- UnLock(newlock);
- if (newlock=Lock(TEST_DIR,ACCESS_READ))
- {
- newlock=CurrentDir(newlock);
-
- /*
- * Now do all of the tests...
- */
- DoTests(global);
-
- newlock=CurrentDir(newlock);
- UnLock(newlock);
- }
- else AddDisplayLine(global,"Error: Could not access test directory.");
- DeleteFile(TEST_DIR);
- }
- else AddDisplayLine(global,"Error: Could not create test directory.");
- lock=CurrentDir(lock);
- UnLock(lock);
- }
- else AddDisplayLine(global,"Error: Could not get a lock on test device.");
-
- global->Me->pr_WindowPtr=oldwindow;
- }
-
- VOID SetVersionStrings(struct DiskSpeed *global)
- {
- UWORD flags=((struct ExecBase *)(SysBase))->AttnFlags;
- char *p;
-
- strcpy(global->CPU_Type,"68000");
- p=&(global->CPU_Type[3]);
- if (flags & AFF_68010) *p='1';
- if (flags & AFF_68020) *p='2';
- if (flags & AFF_68030) *p='3';
- if (flags & AFF_68040) *p='4';
-
- sprintf(global->Exec_Ver,"%ld.%ld",(ULONG)(SysBase->lib_Version),(ULONG)(((struct ExecBase *)SysBase)->SoftVer));
- }
-
- /*
- * A simple string check that also works with '=' at the end of the string
- */
- char *Check_String(char *arg,char *match)
- {
- char *p;
- char *next=NULL;
-
- p=arg;
- while (*p)
- {
- if (*p=='=')
- {
- *p='\0';
- next=p;
- }
- else p++;
- }
-
- if (stricmp(arg,match))
- {
- if (next) *next='=';
- next=NULL;
- }
- else
- {
- if (next) next++;
- else next=p;
- }
-
- return(next);
- }
-
- /*
- * This routine closes down the GUI
- */
- void Close_GUI(struct DiskSpeed *global)
- {
- if (global->Window)
- {
- CloseWindow(global->Window);
- global->Window=NULL;
- }
- if (global->List)
- {
- FreeListGadget(global->List);
- global->List=NULL;
- }
- if (global->ri)
- {
- CleanUp_RenderInfo(global->ri);
- global->ri=NULL;
- }
- }
-
- /*
- * This routine is used to open the GUI...
- */
- BOOL Open_GUI(struct DiskSpeed *global)
- {
- BOOL worked=FALSE;
- UWORD internalwidth;
- UWORD internalheight;
- struct Gadget *gad=NULL;
- struct NewWindow nw;
-
- if (!global->Window)
- {
- /* Now, open/set up the GUI... */
- nw.LeftEdge=0;
- nw.TopEdge=11;
- nw.Width=540;
- nw.Height=180;
- nw.DetailPen=-1;
- nw.BlockPen=-1;
- nw.IDCMPFlags=GADGETDOWN|GADGETUP|CLOSEWINDOW|ACTIVEWINDOW;
- nw.Flags=SMART_REFRESH|ACTIVATE|NOCAREREFRESH|RMBTRAP|WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG;
- nw.FirstGadget=NULL;
- nw.CheckMark=NULL;
- nw.Title=COPYRIGHT;
- nw.Type=WBENCHSCREEN;
-
- if (global->Window=OpenWindow(&nw)) if ((global->Window->Height-global->Window->BorderTop-global->Window->BorderBottom) > 120)
- {
- if (global->ri=Get_RenderInfo(global->Window->WScreen))
- {
- internalwidth=global->Window->Width-global->Window->BorderLeft-global->Window->BorderRight;
- internalheight=global->Window->Height-global->Window->BorderTop-global->Window->BorderBottom;
-
- global->List=InitListGadget(&TOPAZ80,&gad,1,
- global->ri->Highlight,
- global->ri->Shadow,
- global->Window->BorderLeft+4,
- global->Window->BorderTop+33,
- internalwidth-8,
- internalheight-49);
-
- /*
- * Set up borders for the string gadgets
- */
- global->StringBorder[0].LeftEdge=-5;
- global->StringBorder[0].TopEdge=-3;
- global->StringBorder[0].FrontPen=global->ri->Highlight;
- global->StringBorder[0].DrawMode=JAM1;
- global->StringBorder[0].Count=5;
- global->StringBorder[0].XY=&(global->StringVectors[0*5*2]);
- global->StringBorder[0].NextBorder=&(global->StringBorder[1]);
-
- global->StringBorder[1]=global->StringBorder[0];
- global->StringBorder[1].FrontPen=global->ri->Shadow;
- global->StringBorder[1].XY=&(global->StringVectors[1*5*2]);
- global->StringBorder[1].NextBorder=&(global->StringBorder[2]);
-
- global->StringBorder[2].LeftEdge=-3;
- global->StringBorder[2].TopEdge=-2;
- global->StringBorder[2].FrontPen=global->ri->Shadow;
- global->StringBorder[2].DrawMode=JAM1;
- global->StringBorder[2].Count=5;
- global->StringBorder[2].XY=&(global->StringVectors[2*5*2]);
- global->StringBorder[2].NextBorder=&(global->StringBorder[3]);
-
- global->StringBorder[3]=global->StringBorder[2];
- global->StringBorder[3].FrontPen=global->ri->Highlight;
- global->StringBorder[3].XY=&(global->StringVectors[3*5*2]);
- global->StringBorder[3].NextBorder=NULL;
-
- FillTopLeft_Border(&(global->StringBorder[0]),internalwidth-81,14);
- FillBottomRight_Border(&(global->StringBorder[1]),internalwidth-81,14);
- FillTopLeft_Border(&(global->StringBorder[2]),internalwidth-85,12);
- FillBottomRight_Border(&(global->StringBorder[3]),internalwidth-85,12);
-
- /*
- * Now add the few other gadgets to the window...
- */
- global->DeviceGadget.NextGadget=gad; gad=&(global->DeviceGadget);
- gad->LeftEdge=82+global->Window->BorderLeft;
- gad->TopEdge=5+global->Window->BorderTop;
- gad->Width=internalwidth-91;
- gad->Height=8;
- gad->Flags=GADGHCOMP;
- gad->Activation=RELVERIFY;
- gad->GadgetType=STRGADGET;
- gad->GadgetRender=(APTR)&(global->StringBorder[0]);
- gad->GadgetText=&(global->DeviceText);
- gad->SpecialInfo=(APTR)&(global->DeviceInfo);
- gad->GadgetID=DEVICE_GADGET;
-
- global->CommentsGadget=global->DeviceGadget;
- global->CommentsGadget.NextGadget=gad; gad=&(global->CommentsGadget);
- gad->TopEdge+=15;
- gad->GadgetText=&(global->CommentsText);
- gad->SpecialInfo=(APTR)&(global->CommentsInfo);
- gad->GadgetID=COMMENT_GADGET;
-
- global->DeviceInfo.Buffer=global->Device;
- global->DeviceInfo.UndoBuffer=global->Undo;
- global->DeviceInfo.MaxChars=250;
- global->CommentsInfo=global->DeviceInfo;
- global->CommentsInfo.Buffer=global->Comments;
-
- global->DeviceText.FrontPen=1;
- global->DeviceText.BackPen=0;
- global->DeviceText.DrawMode=JAM2;
- global->DeviceText.LeftEdge=-64; /* 8 x 8 */
- global->DeviceText.TopEdge=0;
- global->DeviceText.ITextFont=&TOPAZ80;
- global->DeviceText.IText="Device:";
-
- global->CommentsText=global->DeviceText;
- global->CommentsText.LeftEdge=-80; /* 10 x 8 */
- global->CommentsText.IText="Comments:";
-
- /*
- * Set up borders for the action gadgets (One set for all gadgets...)
- */
- global->ActionBorder[0].FrontPen=global->ri->Highlight;
- global->ActionBorder[0].DrawMode=JAM1;
- global->ActionBorder[0].Count=5;
- global->ActionBorder[0].XY=&(global->ActionVectors[0*5*2]);
- global->ActionBorder[0].NextBorder=&(global->ActionBorder[1]);
-
- global->ActionBorder[1].FrontPen=global->ri->Shadow;
- global->ActionBorder[1].DrawMode=JAM1;
- global->ActionBorder[1].Count=5;
- global->ActionBorder[1].XY=&(global->ActionVectors[1*5*2]);
- global->ActionBorder[1].NextBorder=NULL;
-
- global->ActionBorder[2]=global->ActionBorder[0];
- global->ActionBorder[2].FrontPen=global->ri->Shadow;
- global->ActionBorder[2].NextBorder=&(global->ActionBorder[3]);
-
- global->ActionBorder[3]=global->ActionBorder[1];
- global->ActionBorder[3].FrontPen=global->ri->Highlight;
-
- FillTopLeft_Border(&(global->ActionBorder[0]),108,12);
- FillBottomRight_Border(&(global->ActionBorder[1]),108,12);
-
- /*
- * Now for the two action gadgets at the bottom...
- */
- global->StartTestGadget.NextGadget=gad; gad=&(global->StartTestGadget);
- gad->LeftEdge=global->Window->BorderLeft+4;
- gad->TopEdge=global->Window->Height-global->Window->BorderBottom-14;
- gad->Width=108;
- gad->Height=12;
- gad->Flags=((global->ri->Shadow==global->ri->Highlight) ? GADGHCOMP : GADGHIMAGE);
- gad->Activation=RELVERIFY;
- gad->GadgetType=BOOLGADGET;
- gad->GadgetRender=(APTR)&(global->ActionBorder[0]);
- gad->SelectRender=(APTR)&(global->ActionBorder[2]);
- gad->GadgetText=&(global->StartTest);
- gad->GadgetID=TEST_GADGET;
-
- global->StartTest.FrontPen=1;
- global->StartTest.DrawMode=JAM1;
- global->StartTest.ITextFont=&TOPAZ80;
- global->StartTest.IText=START_TEST;
- global->StartTest.TopEdge=2;
- global->StartTest.LeftEdge=14;
-
- global->SaveResultsGadget=global->StartTestGadget;
- global->SaveResultsGadget.NextGadget=gad; gad=&(global->SaveResultsGadget);
- gad->LeftEdge=global->Window->Width-global->Window->BorderRight-112;
- gad->GadgetText=&(global->SaveResults);
- gad->GadgetID=SAVE_GADGET;
-
- global->SaveResults=global->StartTest;
- global->SaveResults.IText=SAVE_RESULTS;
- global->SaveResults.LeftEdge=6;
-
- global->StopTestGadget=global->StartTestGadget;
- global->StopTestGadget.NextGadget=gad; gad=&(global->StopTestGadget);
- gad->LeftEdge=(global->Window->Width-108)/2;
- gad->GadgetText=&(global->StopTest);
- gad->GadgetID=STOP_GADGET;
-
- global->StopTest=global->StartTest;
- global->StopTest.IText=STOP_TEST;
- global->StopTest.LeftEdge=18;
-
- if (global->List)
- {
- AddGList(global->Window,gad,-1,-1,NULL);
- RefreshGList(gad,global->Window,NULL,-1);
- worked=TRUE;
- }
- }
- }
-
- if (!worked) Close_GUI(global);
- }
-
- return(global->Window!=NULL);
- }
-
- /*
- * This routine will append to the end of a file the results currently in memory...
- */
- void Save_Results(struct DiskSpeed *global)
- {
- BPTR fh;
- struct Node *node;
-
- if (fh=Open("DiskSpeed.Results",MODE_OLDFILE))
- {
- Seek(fh,0,OFFSET_END);
- Write(fh,"\n\n\n",2);
- }
- else fh=Open("DiskSpeed.Results",MODE_NEWFILE);
-
- if (fh)
- {
- node=(struct Node *)(global->TextList.mlh_Head);
- while (node->ln_Succ)
- {
- Write(fh,node->ln_Name,strlen(node->ln_Name));
- Write(fh,"\n",1);
- node=node->ln_Succ;
- }
-
- Close(fh);
- }
- }
-
- /*
- * This routine is used to control the GUI
- */
- void Do_GUI(struct DiskSpeed *global)
- {
- BOOL done=FALSE;
- struct IntuiMessage *msg;
-
- while (!done)
- {
- WaitPort(global->Window->UserPort);
- while (msg=(struct IntuiMessage *)GetMsg(global->Window->UserPort))
- {
- if (!Check_ListGadget(global->Window,msg))
- {
- if (msg->Class==CLOSEWINDOW) done=TRUE;
- else if (msg->Class==GADGETUP)
- {
- switch(((struct Gadget *)(msg->IAddress))->GadgetID)
- {
- case DEVICE_GADGET: ActivateGadget(&(global->CommentsGadget),global->Window,NULL);
- break;
- case COMMENT_GADGET: ActivateGadget(&(global->DeviceGadget),global->Window,NULL);
- break;
- case TEST_GADGET: SetWait(global->Window);
- StartTest(global);
- ClearWait(global->Window);
- break;
- case SAVE_GADGET: SetWait(global->Window);
- Save_Results(global);
- ClearWait(global->Window);
- break;
- }
- }
- else if (msg->Class=ACTIVEWINDOW)
- {
- ActivateGadget(&(global->DeviceGadget),global->Window,NULL);
- }
- }
- ReplyMsg((struct Message *)msg);
- }
- }
- /* Shut down GUI */
- Close_GUI(global);
- }
-
- /*
- * DRIVE/K - select drive (Default is current directory)
- * COMMENT/K - set comment string
- * ALL/S - select all tests
- * DIR/S - setect DIR tests
- * SEEK/S - select SEEK tests
- * CHIP/S - select CHIP memory buffer tests
- * FAST/S - select FAST memory buffer tests
- * LONG/S - select LONG aligned tests
- * WORD/S - select WORD aligned tests
- * BYTE/S - select BYTE aligned tests
- * NOCPU/S - turn off CPU availability tests
- * BUF1/K/N - select buffer size 1
- * BUF2/K/N - select buffer size 2
- * BUF3/K/N - select buffer size 3
- * BUF4/K/N - select buffer size 4
- * MINTIME/K/N - select the minimum test time (default=8) in seconds
- * WINDOW/S - use the GUI even though started from the CLI
- */
-
- /*
- * do the command line parsing here...
- */
- BOOL ParseArg(struct DiskSpeed *global,int argc,char *argv[],int start)
- {
- int loop;
- char *arg;
- char *next;
- BOOL working=TRUE;
- BOOL window=FALSE;
-
- for (loop=start;loop<argc;loop++)
- {
- arg=argv[loop];
- if (*arg=='?')
- {
- loop=argc;
- working=FALSE;
- }
- else if (next=Check_String(arg,"DRIVE"))
- {
- if (!(*next))
- {
- loop++;
- if (loop<argc) next=argv[loop];
- }
- if (strlen(next)>255) *next='\0';
- if (*next) strcpy(global->Device,next);
- else working=FALSE;
- }
- else if (next=Check_String(arg,"COMMENT"))
- {
- if (!(*next))
- {
- loop++;
- if (loop<argc) next=argv[loop];
- }
- if (strlen(next)>255) *next='\0';
- if (*next) strcpy(global->Comments,next);
- else working=FALSE;
- }
- else if (Check_String(arg,"ALL"))
- {
- /* All tests */
- global->Test_DIR=TRUE;
- global->Test_SEEK=TRUE;
- global->Align_Types=4|2|1;
- global->Mem_TYPES=MEMF_CHIP | MEMF_FAST;
- }
- else if (next=Check_String(arg,"BUF1"))
- {
- if (!(*next))
- {
- loop++;
- if (loop<argc) next=argv[loop];
- }
- if (*next) stcd_l(next,&(global->Test_Size[0]));
- else working=FALSE;
- }
- else if (next=Check_String(arg,"BUF2"))
- {
- if (!(*next))
- {
- loop++;
- if (loop<argc) next=argv[loop];
- }
- if (*next) stcd_l(next,&(global->Test_Size[1]));
- else working=FALSE;
- }
- else if (next=Check_String(arg,"BUF3"))
- {
- if (!(*next))
- {
- loop++;
- if (loop<argc) next=argv[loop];
- }
- if (*next) stcd_l(next,&(global->Test_Size[2]));
- else working=FALSE;
- }
- else if (next=Check_String(arg,"BUF4"))
- {
- if (!(*next))
- {
- loop++;
- if (loop<argc) next=argv[loop];
- }
- if (*next) stcd_l(next,&(global->Test_Size[3]));
- else working=FALSE;
- }
- else if (next=Check_String(arg,"MINTIME"))
- {
- if (!(*next))
- {
- loop++;
- if (loop<argc) next=argv[loop];
- }
- if (*next) stcd_l(next,&(global->Min_Time));
- else working=FALSE;
- }
- else if (Check_String(arg,"DIR")) global->Test_DIR=TRUE;
- else if (Check_String(arg,"SEEK")) global->Test_SEEK=TRUE;
- else if (Check_String(arg,"CHIP")) global->Mem_TYPES|=MEMF_CHIP;
- else if (Check_String(arg,"FAST")) global->Mem_TYPES|=MEMF_FAST;
- else if (Check_String(arg,"LONG")) global->Align_Types|=4;
- else if (Check_String(arg,"WORD")) global->Align_Types|=2;
- else if (Check_String(arg,"BYTE")) global->Align_Types|=1;
- else if (Check_String(arg,"NOCPU")) CPU_Use_Base=FALSE;
- else if (Check_String(arg,"WINDOW")) window=TRUE;
- else
- { /* Did not match, so error */
- working=FALSE;
- }
- }
-
- if (global->Min_Time < 1) global->Min_Time=1;
-
- if (working) if (window) working=Open_GUI(global);
-
- return(working);
- }
-
- /*
- * This routine is called when we want to run from a GUI
- * Normally, it is only called when started from Workbench
- * or when the CLI WINDOW option is given...
- */
- void DoWorkbench(struct DiskSpeed *global,int argc,char *argv[])
- {
- struct WBStartup *wbmsg;
- struct WBArg *wbarg;
- BPTR lock;
- struct DiskObject *icon;
-
- wbmsg=(struct WBStartup *)argv;
-
- if ((wbarg=wbmsg->sm_ArgList) && (wbmsg->sm_NumArgs))
- {
- /* We only care about the first one... */
- lock=CurrentDir(wbarg->wa_Lock);
-
- argc=0;
- if (icon=GetDiskObject(wbarg->wa_Name))
- {
- argv=icon->do_ToolTypes;
- while (argv[argc]) argc++;
- /*
- * Don't care about argument errors in tooltypes
- * since other things may have been in there...
- */
- ParseArg(global,argc,argv,0);
- FreeDiskObject(icon);
- }
- if (!argc)
- {
- /* All tests */
- global->Test_DIR=TRUE;
- global->Test_SEEK=TRUE;
- global->Align_Types=4|2|1;
- global->Mem_TYPES=MEMF_CHIP | MEMF_FAST;
- }
-
- if (Open_GUI(global)) Do_GUI(global);
-
- CurrentDir(lock);
- }
- }
-
- /*
- * This is the CLI starting point. We do the command line parsing here...
- */
- void DoCLI(struct DiskSpeed *global,int argc,char *argv[])
- {
- if (ParseArg(global,argc,argv,1))
- {
- if (global->Window) Do_GUI(global);
- else StartTest(global);
- }
- else AddDisplayLine(global,"DRIVE/K,ALL/S,DIR/S,SEEK/S,CHIP/S,FAST/S,LONG/S,WORD/S,BYTE/S,NOCPU/S,BUF1/K/N,BUF2/K/N,BUF3/K/N,BUF4/K/N,MINTIME/K/N,WINDOW/S");
- }
-
- void main(int argc, char *argv[])
- {
- struct DiskSpeed *global;
-
- CPU_Use_Base=TRUE; /* We want to test with CPU */
-
- if (IntuitionBase=OpenLibrary("intuition.library",33L))
- {
- if (GfxBase=OpenLibrary("graphics.library",33L))
- {
- if (LayersBase=OpenLibrary("layers.library",33L))
- {
- if (IconBase=OpenLibrary("icon.library",33L))
- {
- if (global=AllocMem(sizeof(struct DiskSpeed),MEMF_PUBLIC|MEMF_CLEAR))
- {
- NewList((struct List *)&(global->TextList));
- SetVersionStrings(global);
- global->Me=(struct Process *)FindTask(NULL);
-
- /* Standard MinTime */
- global->Min_Time=MIN_TEST_TIME;
-
- /* Standard sizes */
- global->Test_Size[0]=0x200;
- global->Test_Size[1]=0x1000;
- global->Test_Size[2]=0x8000;
- global->Test_Size[3]=0x40000;
-
- if (global->fib=AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC))
- {
- if (global->timer=Init_Timer())
- {
- /*
- * Now either set up Window or Output
- * depending on where we were started...
- *
- * If we can not get Output, we set up the window...
- */
- if ((argc) && (global->Output=Output()))
- {
- DoCLI(global,argc,argv);
- }
- else DoWorkbench(global,argc,argv);
-
- Free_Timer(global->timer);
- }
- FreeMem(global->fib,sizeof(struct FileInfoBlock));
- }
-
- FreeDisplayList(global);
- FreeMem(global,sizeof(struct DiskSpeed));
- }
- CloseLibrary(IconBase);
- }
- CloseLibrary(LayersBase);
- }
- CloseLibrary(GfxBase);
- }
- CloseLibrary(IntuitionBase);
- }
- }
-