* * 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. * * * ****************************************************************************** * INCLUDE "exec/types.i" INCLUDE "exec/tasks.i" INCLUDE "exec/lists.i" INCLUDE "exec/libraries.i" * ****************************************************************************** * * This section of code is used to test CPU availability. It was important * that it be in assembly as it would otherwise be unpredictable. * SECTION "CPU_TEST",CODE * xdef _CPU_Use_Base xdef _CPU_State_Flag xdef _CPU_Count_Low xdef _CPU_Count_High xdef @Init_CPU_Available xdef @Free_CPU_Available xdef @CPU_Calibrate * xref _LVOAddTask xref _LVORemTask xref _AbsExecBase * ****************************************************************************** * * This init routine does all sorts of work to install the task... * @Init_CPU_Available: lea _CPU_State_Flag(pc),a0 ; Point at state flag... moveq.l #0,d0 ; Get a NULL... move.l d0,(a0)+ ; Clear state flag... move.l d0,(a0)+ ; Clear low count... move.l d0,(a0)+ ; Clear high count... move.l (a0),d0 ; Check if we are already running... bne.s Task_Set ; If so, we don't start again... * lea _CPU_Use_Base(pc),a1 ; Point at use flag... tst.l (a1) ; Check if we are to run... beq.s Task_Set ; If not, we just return... * * The task is not running... First, clear the task structure... * lea Task_Struct(pc),a1 ; Point at task structure... moveq.l #TC_SIZE-1,d1 ; We want to clear the task Clear_TC: move.b d0,(a1)+ ; Clear a byte... dbra d1,Clear_TC ; Clear all of the task... * * Ok, now set up the task structure and get going... * movem.l a2/a3/a6,-(sp) ; Save these... lea CPU_Available(pc),a2 ; Initial PC... move.l d0,a3 ; NULL final PC... lea Task_Struct(pc),a1 ; Point at task structure... lea TC_MEMENTRY(a1),a0 ; Point at the TC_MEMENTRY NEWLIST a0 ; list header; initialize it. lea Stack_Lower(pc),a0 ; Point at low stack... move.l a0,TC_SPLOWER(a1) ; Set the task structure... lea Stack_Upper(pc),a0 ; Task upper stack... move.l a0,TC_SPUPPER(a1) ; Set the task structure... move.l a0,TC_SPREG(a1) ; Starting point... move.b #NT_TASK,LN_TYPE(a1) ; It is a task... move.b #-127,LN_PRI(a1) ; Set to minimal priority... move.l _AbsExecBase,a6 ; Get ExecBase... jsr _LVOAddTask(a6) ; Add the task... * ******************************************************************************* * * Check to see if we are running in V37 ROM or better. If so, * we want to use the result of the AddTask() call... Otherwise * we just want the task structure address... * cmp.w #36,LIB_VERSION(a6) ; Check if exec is > V36 bcc.s TooNew ; If greater than V36, skip... lea Task_Struct(pc),a1 ; Get task structure... move.l a1,d0 ; Put it into d0... TooNew: * ******************************************************************************* * movem.l (sp)+,a2/a3/a6 ; Restore... Set_Task: lea CPU_Task(pc),a0 ; Point at storage... move.l d0,(a0) ; Save the pointer... * * D0 is now either a task pointer or NULL since it did not get added... * Task_Set: rts * ****************************************************************************** * * This routine will kill the task... * @Free_CPU_Available: move.l CPU_Task(pc),d0 ; Check if we have a task... beq.s Task_Set ; If not, just return... move.l d0,a1 ; Point at task... move.l a6,-(sp) ; Save a6... move.l _AbsExecBase,a6 ; Get ExecBase... jsr _LVORemTask(a6) ; Remove the task... move.l (sp)+,a6 ; Restore a6... moveq.l #0,d0 ; Clear d0... bra.s Set_Task ; Set the task pointer... * ****************************************************************************** * * This routine will set up and then count the number of times through the loop * below. Since CPUs may become very fast, the counters are 64-bits. This * should last for a long time! (Currently, it would most likely never need * more than the first 32-bit word...) * CPU_Available: lea _CPU_State_Flag(pc),a0 ; Set up some pointers lea _CPU_Count_Low(pc),a1 lea _CPU_Count_High(pc),a2 * * Here, we check if the state flag is zero. Once it is, we drop * down into the next routine... * CheckState: tst.l (a0) ; Check if we got the green-light. bne.s CheckState ; If not, try again... * * Now, we count the low order counter. If it does not wrap, we loop back... * addq.l #1,(a1) ; Add 1 to low order counter... bne.s CheckState ; If we did not wrap, we go back... * * Since the low order counter just wrapped, we now count the high order... * Note that we assume that there would never be an overflow in the high order * counter word. * addq.l #1,(a2) ; Add 1 to high order counter... bra.s CheckState ; Loop back... * ****************************************************************************** * * This routine is used to calibrate the CPU available number... * @CPU_Calibrate: lea _CPU_Count_Low(pc),a0 ; Get up pointer... * * Now, we want to make the same instructions so that timing will * be the same... * Calibrate: tst.l (a0) ; Check if we are done... beq.s CalibrateDone ; If so, exit... * * Now, count backwards until we get to 0... * subq.l #1,(a0) ; Subtract 1 from low order counter... bne.s Calibrate ; Loop back for some more... * * We get here when done with the calibration loop... * CalibrateDone: rts * ****************************************************************************** * _CPU_Use_Base: dc.l 0 ; Set to TRUE in order to use CPU... _CPU_State_Flag: dc.l 0 ; Used to control this routine... _CPU_Count_Low: dc.l 0 ; The low-order word for CPU count _CPU_Count_High: dc.l 0 ; The high-order word for CPU count CPU_Task: dc.l 0 ; The task pointer... * ****************************************************************************** * Stack_Lower: ds.l 80 ; 80 long-words of stack for task Stack_Upper: dc.l 0 Task_Struct: ds.b TC_SIZE ; The task structure... Task_Name: dc.b 'MKSoft DiskSpeed CPU Test',0 * ****************************************************************************** * END