示例#1
0
void test1g(void)
{

    GET_PROCESS_ID("", &Z502_REG2, &Z502_REG9);
    printf("Release %s:Test 1g: Pid %ld\n", CURRENT_REL, Z502_REG2);

    // Make a legal target
    CREATE_PROCESS("test1g_a", test1x, LEGAL_PRIORITY_1G, &Z502_REG1,
                   &Z502_REG9);
    SuccessExpected(Z502_REG9, "CREATE_PROCESS");

    // Target Illegal PID
    CHANGE_PRIORITY((INT32) 9999, LEGAL_PRIORITY_1G, &Z502_REG9);
    ErrorExpected(Z502_REG9, "CHANGE_PRIORITY");

    // Use illegal priority
    CHANGE_PRIORITY(Z502_REG1, ILLEGAL_PRIORITY_1G, &Z502_REG9);
    ErrorExpected(Z502_REG9, "CHANGE_PRIORITY");

    // Use legal priority on legal process
    CHANGE_PRIORITY(Z502_REG1, LEGAL_PRIORITY_1G, &Z502_REG9);
    SuccessExpected(Z502_REG9, "CHANGE_PRIORITY");
    // Terminate all existing processes
    TERMINATE_PROCESS(-2, &Z502_REG9);

} // End of test1g
示例#2
0
void test1d(void)
{
    static long sleep_time = 1000;

    printf("This is Release %s:  Test 1d\n", CURRENT_REL);
    CREATE_PROCESS("test1d_1", test1x, PRIORITY1, &Z502_REG1, &Z502_REG9);
    SuccessExpected(Z502_REG9, "CREATE_PROCESS");

    CREATE_PROCESS("test1d_2", test1x, PRIORITY2, &Z502_REG2, &Z502_REG9);

    CREATE_PROCESS("test1d_3", test1x, PRIORITY3, &Z502_REG3, &Z502_REG9);

    CREATE_PROCESS("test1d_4", test1x, PRIORITY4, &Z502_REG4, &Z502_REG9);

    CREATE_PROCESS("test1d_5", test1x, PRIORITY5, &Z502_REG5, &Z502_REG9);

    // Now we sleep, see if one of the five processes has terminated, and
    // continue the cycle until one of them is gone.  This allows the test1x
    // processes to exhibit scheduling.
    // We know that the process terminated when we do a GET_PROCESS_ID and
    // receive an error on the system call.

    Z502_REG9 = ERR_SUCCESS;
    while (Z502_REG9 == ERR_SUCCESS)
    {
        SLEEP(sleep_time);
        GET_PROCESS_ID("test1d_4", &Z502_REG6, &Z502_REG9);
    }

    TERMINATE_PROCESS(-2, &Z502_REG9);

} // End test1d
示例#3
0
void test2g(void)
{
    static long sleep_time = 1000;

    printf("This is Release %s:  Test 2g\n", CURRENT_REL);
    CREATE_PROCESS("test2g_a", test2f, PRIORITY2G, &Z502_REG1, &Z502_REG9);
    CREATE_PROCESS("test2g_b", test2f, PRIORITY2G, &Z502_REG2, &Z502_REG9);
    CREATE_PROCESS("test2g_c", test2f, PRIORITY2G, &Z502_REG3, &Z502_REG9);
    CREATE_PROCESS("test2g_d", test2f, PRIORITY2G, &Z502_REG4, &Z502_REG9);
    CREATE_PROCESS("test2g_e", test2f, PRIORITY2G, &Z502_REG5, &Z502_REG9);
    SuccessExpected(Z502_REG9, "CREATE_PROCESS");

    // In these next three cases, we will loop until the target
    // process ( test2g_e ) has terminated.  We know it
    // terminated because for a while we get success on the call
    // GET_PROCESS_ID, and then we get failure when the process
    // no longer exists.

    Z502_REG9 = ERR_SUCCESS;
    while (Z502_REG9 == ERR_SUCCESS)
    {
        SLEEP(sleep_time);
        GET_PROCESS_ID("test2g_e", &Z502_REG6, &Z502_REG9);
    }
    TERMINATE_PROCESS(-2, &Z502_REG9); // Terminate all

} // End test2g
示例#4
0
void test1b(void)
{
    static char process_name[16];

    // Try to create a process with an illegal priority.
    printf("This is Release %s:  Test 1b\n", CURRENT_REL);
    CREATE_PROCESS("test1b_a", test1x, ILLEGAL_PRIORITY, &Z502_REG1,
                   &Z502_REG9);
    ErrorExpected(Z502_REG9, "CREATE_PROCESS");

    // Create two processes with same name - 1st succeeds, 2nd fails
    // Then terminate the process that has been created
    CREATE_PROCESS("two_the_same", test1x, LEGAL_PRIORITY, &Z502_REG2,
                   &Z502_REG9);
    SuccessExpected(Z502_REG9, "CREATE_PROCESS");
    CREATE_PROCESS("two_the_same", test1x, LEGAL_PRIORITY, &Z502_REG1,
                   &Z502_REG9);
    ErrorExpected(Z502_REG9, "CREATE_PROCESS");
    TERMINATE_PROCESS(Z502_REG2, &Z502_REG9);
    SuccessExpected(Z502_REG9, "TERMINATE_PROCESS");

    // Loop until an error is found on the create_process.
    // Since the call itself is legal, we must get an error
    // because we exceed some limit.
    Z502_REG9 = ERR_SUCCESS;
    while (Z502_REG9 == ERR_SUCCESS)
    {
        Z502_REG3++; /* Generate next unique program name*/
        sprintf(process_name, "Test1b_%ld", Z502_REG3);
        printf("Creating process \"%s\"\n", process_name);
        CREATE_PROCESS(process_name, test1x, LEGAL_PRIORITY, &Z502_REG1,
                       &Z502_REG9);
    }

    //  When we get here, we've created all the processes we can.
    //  So the OS should have given us an error
    ErrorExpected(Z502_REG9, "CREATE_PROCESS");
    printf("%ld processes were created in all.\n", Z502_REG3);

    //      Now test the call GET_PROCESS_ID for ourselves
    GET_PROCESS_ID("", &Z502_REG2, &Z502_REG9); // Legal
    SuccessExpected(Z502_REG9, "GET_PROCESS_ID");
    printf("The PID of this process is %ld\n", Z502_REG2);

    // Try GET_PROCESS_ID on another existing process
    strcpy(process_name, "Test1b_1");
    GET_PROCESS_ID(process_name, &Z502_REG1, &Z502_REG9); /* Legal */
    SuccessExpected(Z502_REG9, "GET_PROCESS_ID");
    printf("The PID of target process is %ld\n", Z502_REG1);

    // Try GET_PROCESS_ID on a non-existing process
    GET_PROCESS_ID("bogus_name", &Z502_REG1, &Z502_REG9); // Illegal
    ErrorExpected(Z502_REG9, "GET_PROCESS_ID");

    GET_TIME_OF_DAY(&Z502_REG4);
    printf("Test1b, PID %ld, Ends at Time %ld\n", Z502_REG2, Z502_REG4);
    TERMINATE_PROCESS(-2, &Z502_REG9)

} // End of test1b
示例#5
0
void test1e(void)
{

    GET_PROCESS_ID("", &Z502_REG2, &Z502_REG9);
    printf("Release %s:Test 1e: Pid %ld\n", CURRENT_REL, Z502_REG2);

    // Make a legal target process
    CREATE_PROCESS("test1e_a", test1x, LEGAL_PRIORITY_1E, &Z502_REG1,
                   &Z502_REG9);
    SuccessExpected(Z502_REG9, "CREATE_PROCESS");

    // Try to Suspend an Illegal PID
    SUSPEND_PROCESS((INT32) 9999, &Z502_REG9);
    ErrorExpected(Z502_REG9, "SUSPEND_PROCESS");

    // Try to Resume an Illegal PID
    RESUME_PROCESS((INT32) 9999, &Z502_REG9);
    ErrorExpected(Z502_REG9, "RESUME_PROCESS");

    // Suspend alegal PID
    SUSPEND_PROCESS(Z502_REG1, &Z502_REG9);
    SuccessExpected(Z502_REG9, "SUSPEND_PROCESS");

    // Suspend already suspended PID
    SUSPEND_PROCESS(Z502_REG1, &Z502_REG9);
    ErrorExpected(Z502_REG9, "SUSPEND_PROCESS");

    // Do a legal resume of the process we have suspended
    RESUME_PROCESS(Z502_REG1, &Z502_REG9);
    SuccessExpected(Z502_REG9, "RESUME_PROCESS");

    // Resume an already resumed process
    RESUME_PROCESS(Z502_REG1, &Z502_REG9);
    ErrorExpected(Z502_REG9, "RESUME_PROCESS");

    // Try to resume ourselves
    RESUME_PROCESS(Z502_REG2, &Z502_REG9);
    ErrorExpected(Z502_REG9, "RESUME_PROCESS");

    // It may or may not be legal to suspend ourselves;
    // architectural decision.   It can be a useful technique
    // as a way to pass off control to another process.
    SUSPEND_PROCESS(-1, &Z502_REG9);

    /* If we returned "SUCCESS" here, then there is an inconsistency;
     * success implies that the process was suspended.  But if we
     * get here, then we obviously weren't suspended.  Therefore
     * this must be an error.                                    */
    ErrorExpected(Z502_REG9, "SUSPEND_PROCESS");

    GET_TIME_OF_DAY(&Z502_REG4);
    printf("Test1e, PID %ld, Ends at Time %ld\n", Z502_REG2, Z502_REG4);

    TERMINATE_PROCESS(-2, &Z502_REG9);
} // End of test1e
示例#6
0
文件: mytest.c 项目: jazzboysc/CS502
//****************************************************************************
// Preemptive-based Dispatching Test
// Please type “cs502 test1l?and see my preemptive algorithm implemented in 
// the scheduler module. Notice that processes 3 and 4 with high priorities 
// get much more chances running than process 5, 6 and 7 who have low 
// priorities.
//****************************************************************************
void mytest(void)
{
    CREATE_PROCESS("mytest_a", mytestx, PRIORITY_1, &Z502_REG3, &Z502_REG9);
    CREATE_PROCESS("mytest_b", mytestx, PRIORITY_2, &Z502_REG4, &Z502_REG9);
    CREATE_PROCESS("mytest_c", mytestx, PRIORITY_3, &Z502_REG5, &Z502_REG9);
    CREATE_PROCESS("mytest_d", mytestx, PRIORITY_4, &Z502_REG6, &Z502_REG9);
    CREATE_PROCESS("mytest_e", mytestx, PRIORITY_5, &Z502_REG7, &Z502_REG9);

    SLEEP(2000);

    TERMINATE_PROCESS(-2, &Z502_REG9);
}
示例#7
0
void test0(void)
{
    printf("This is Release %s:  Test 0\n", CURRENT_REL);
    GET_TIME_OF_DAY(&Z502_REG1);

    printf("Time of day is %ld\n", Z502_REG1);
    TERMINATE_PROCESS(-1, &Z502_REG9);

    // We should never get to this line since the TERMINATE_PROCESS call
    // should cause the program to end.
    printf("ERROR: Test should be terminated but isn't.\n");
} // End of test0
示例#8
0
void test1f(void)
{

    static long sleep_time = 300;
    int iterations;

    // Get OUR PID
    Z502_REG1 = 0; // Initialize
    GET_PROCESS_ID("", &Z502_REG2, &Z502_REG9);

    // Make legal targets
    printf("Release %s:Test 1f: Pid %ld\n", CURRENT_REL, Z502_REG2);
    CREATE_PROCESS("test1f_a", test1x, PRIORITY_1F1, &Z502_REG3, &Z502_REG9);

    CREATE_PROCESS("test1f_b", test1x, PRIORITY_1F2, &Z502_REG4, &Z502_REG9);

    CREATE_PROCESS("test1f_c", test1x, PRIORITY_1F3, &Z502_REG5, &Z502_REG9);

    CREATE_PROCESS("test1f_d", test1x, PRIORITY_1F4, &Z502_REG6, &Z502_REG9);

    CREATE_PROCESS("test1f_e", test1x, PRIORITY_1F5, &Z502_REG7, &Z502_REG9);

    // Let the 5 processes go for a while
    SLEEP(sleep_time);

    // Do a set of suspends/resumes four times
    for (iterations = 0; iterations < 4; iterations++)
    {
        // Suspend 3 of the pids and see what happens - we should see
        // scheduling behavior where the processes are yanked out of the
        // ready and the waiting states, and placed into the suspended state.

        SUSPEND_PROCESS(Z502_REG3, &Z502_REG9);
        SUSPEND_PROCESS(Z502_REG5, &Z502_REG9);
        SUSPEND_PROCESS(Z502_REG7, &Z502_REG9);

        // Sleep so we can watch the scheduling action
        SLEEP(sleep_time);

        RESUME_PROCESS(Z502_REG3, &Z502_REG9);
        RESUME_PROCESS(Z502_REG5, &Z502_REG9);
        RESUME_PROCESS(Z502_REG7, &Z502_REG9);
    }

    //   Wait for children to finish, then quit
    SLEEP((INT32) 10000);
    TERMINATE_PROCESS(-2, &Z502_REG9);

} // End of test1f
示例#9
0
void test1h(void)
{
    long ourself;

    GET_PROCESS_ID("", &Z502_REG2, &Z502_REG9);

    // Make our priority high
    printf("Release %s:Test 1h: Pid %ld\n", CURRENT_REL, Z502_REG2);
    ourself = -1;
    CHANGE_PRIORITY(ourself, MOST_FAVORABLE_PRIORITY, &Z502_REG9);

    // Make legal targets
    CREATE_PROCESS("test1h_a", test1x, NORMAL_PRIORITY, &Z502_REG3,
                   &Z502_REG9);
    CREATE_PROCESS("test1h_b", test1x, NORMAL_PRIORITY, &Z502_REG4,
                   &Z502_REG9);
    CREATE_PROCESS("test1h_c", test1x, NORMAL_PRIORITY, &Z502_REG5,
                   &Z502_REG9);

    //      Sleep awhile to watch the scheduling
    SLEEP(200);

    //  Now change the priority - it should be possible to see
    //  that the priorities have been changed for processes that
    //  are ready and for processes that are sleeping.

    CHANGE_PRIORITY(Z502_REG3, FAVORABLE_PRIORITY, &Z502_REG9);

    CHANGE_PRIORITY(Z502_REG5, LEAST_FAVORABLE_PRIORITY, &Z502_REG9);

    //      Sleep awhile to watch the scheduling
    SLEEP(200);

    //  Now change the priority - it should be possible to see
    //  that the priorities have been changed for processes that
    //  are ready and for processes that are sleeping.

    CHANGE_PRIORITY(Z502_REG3, LEAST_FAVORABLE_PRIORITY, &Z502_REG9);

    CHANGE_PRIORITY(Z502_REG4, FAVORABLE_PRIORITY, &Z502_REG9);

    //     Sleep awhile to watch the scheduling
    SLEEP(600);

    // Terminate everyone
    TERMINATE_PROCESS(-2, &Z502_REG9);

} // End of test1h  
示例#10
0
文件: mytest.c 项目: jazzboysc/CS502
//****************************************************************************
void mytestx(void)
{
    int    i;

    GET_PROCESS_ID("", &Z502_REG2, &Z502_REG9);
    printf("Release %s: mytestx: Pid %ld\n", CURRENT_REL, Z502_REG2);

    for( i = 0; i < 50; i++ )
    {
        printf("PID: %d is printing.\n", Z502_REG2);
        SLEEP(2);
    }

    TERMINATE_PROCESS(-1, &Z502_REG9);
    printf("ERROR: mytestx should be terminated but isn't.\n");

}
示例#11
0
void test2e(void)
{
    int Iterations;

    GET_PROCESS_ID("", &Z502_REG4, &Z502_REG9);
    printf("\n\nRelease %s:Test 2e: Pid %ld\n", CURRENT_REL, Z502_REG4);

    for (Iterations = 0; Iterations < VIRTUAL_MEM_PGS; Iterations +=
            STEP_SIZE)
    {
        Z502_REG3 = PGSIZE * Iterations; // Generate address
        Z502_REG1 = Z502_REG3 + Z502_REG4; // Generate data 
        MEM_WRITE(Z502_REG3, &Z502_REG1); // Write the data

        MEM_READ(Z502_REG3, &Z502_REG2); // Read back data

        if (Iterations % DISPLAY_GRANULARITY2e == 0)
            printf("PID= %ld  address= %ld   written= %ld   read= %ld\n",
                   Z502_REG4, Z502_REG3, Z502_REG1, Z502_REG2);
        if (Z502_REG2 != Z502_REG1) // Written = read?
            printf("AN ERROR HAS OCCURRED.\n");

        // It makes life more fun!! to write the data again
        MEM_WRITE(Z502_REG3, &Z502_REG1); // Write the data

    } // End of for loop

    // Now read back the data we've written and paged
    printf("Reading back data: test 2e, PID %ld.\n", Z502_REG4);
    for (Iterations = 0; Iterations < VIRTUAL_MEM_PGS; Iterations +=
            STEP_SIZE)
    {

        Z502_REG3 = PGSIZE * Iterations; // Generate address
        Z502_REG1 = Z502_REG3 + Z502_REG4; // Data expected
        MEM_READ(Z502_REG3, &Z502_REG2); // Read back data

        if (Iterations % DISPLAY_GRANULARITY2e == 0)
            printf("PID= %ld  address= %ld   written= %ld   read= %ld\n",
                   Z502_REG4, Z502_REG3, Z502_REG1, Z502_REG2);
        if (Z502_REG2 != Z502_REG1) // Written = read?
            printf("AN ERROR HAS OCCURRED.\n");

    } // End of for loop
    TERMINATE_PROCESS(-2, &Z502_REG5); // Added 12/1/2013
} // End of test2e    
示例#12
0
void test1a(void)
{
    static long SleepTime = 100;
    static INT32 time1, time2;

    printf("This is Release %s:  Test 1a\n", CURRENT_REL);
    GET_TIME_OF_DAY(&time1);

    SLEEP(SleepTime);

    GET_TIME_OF_DAY(&time2);

    printf("Sleep Time = %ld, elapsed time= %d\n", SleepTime, time2 - time1);
    TERMINATE_PROCESS(-1, &Z502_REG9);

    printf("ERROR: Test should be terminated but isn't.\n");

} /* End of test1a    */
示例#13
0
void test2d(void)
{
    static INT32 trash;

    GET_PROCESS_ID("", &Z502_REG4, &Z502_REG5);
    printf("\n\nRelease %s:Test 2d: Pid %ld\n", CURRENT_REL, Z502_REG4);
    CHANGE_PRIORITY(-1, MOST_FAVORABLE_PRIORITY, &Z502_REG9);

    CREATE_PROCESS("first", test2c, 5, &trash, &Z502_REG5);
    CREATE_PROCESS("second", test2c, 5, &trash, &Z502_REG5);
    CREATE_PROCESS("third", test2c, 7, &trash, &Z502_REG5);
    CREATE_PROCESS("fourth", test2c, 7, &trash, &Z502_REG5);
    CREATE_PROCESS("fifth", test2c, 7, &trash, &Z502_REG5);

    SLEEP(50000);

    TERMINATE_PROCESS(-2, &Z502_REG5);

} // End of test2d 
示例#14
0
/**************************************************************************
 Test2a exercises a simple memory write and read

 Use:  Z502_REG1                data_written
 Z502_REG2                data_read
 Z502_REG3                address
 Z502_REG4                process_id
 Z502_REG9                error

 In global.h, there's a variable  DO_MEMORY_DEBUG.   Switching it to
 TRUE will allow you to see what the memory system thinks is happening.
 WARNING - it's verbose -- and I don't want to see such output - it's
 strictly for your debugging pleasure.
 **************************************************************************/
void test2a(void)
{

    GET_PROCESS_ID("", &Z502_REG4, &Z502_REG9);

    printf("Release %s:Test 2a: Pid %ld\n", CURRENT_REL, Z502_REG4);
    Z502_REG3 = 412;
    Z502_REG1 = Z502_REG3 + Z502_REG4;
    MEM_WRITE(Z502_REG3, &Z502_REG1);

    MEM_READ(Z502_REG3, &Z502_REG2);

    printf("PID= %ld  address= %ld   written= %ld   read= %ld\n", Z502_REG4,
           Z502_REG3, Z502_REG1, Z502_REG2);
    if (Z502_REG2 != Z502_REG1)
        printf("AN ERROR HAS OCCURRED.\n");
    TERMINATE_PROCESS(-1, &Z502_REG9);

} // End of test2a   
示例#15
0
void test1x(void)
{
    long RandomSleep = 17;
    int Iterations;

    GET_PROCESS_ID("", &Z502_REG2, &Z502_REG9);
    printf("Release %s:Test 1x: Pid %ld\n", CURRENT_REL, Z502_REG2);

    for (Iterations = 0; Iterations < NUMBER_OF_TEST1X_ITERATIONS;
            Iterations++)
    {
        GET_TIME_OF_DAY(&Z502_REG3);
        RandomSleep = (RandomSleep * Z502_REG3) % 143;
        SLEEP(RandomSleep);
        GET_TIME_OF_DAY(&Z502_REG4);
        printf("Test1X: Pid = %d, Sleep Time = %ld, Latency Time = %d\n",
               (int) Z502_REG2, RandomSleep, (int) (Z502_REG4 - Z502_REG3));
    }
    printf("Test1x, PID %ld, Ends at Time %ld\n", Z502_REG2, Z502_REG4);

    TERMINATE_PROCESS(-1, &Z502_REG9);
    printf("ERROR: Test1x should be terminated but isn't.\n");

} /* End of test1x    */
示例#16
0
void test2f(void)
{
    MEMORY_TOUCHED_RECORD *mtr;
    short Iterations, Index, Loops;

    mtr = (MEMORY_TOUCHED_RECORD *) calloc(1, sizeof (MEMORY_TOUCHED_RECORD));

    GET_PROCESS_ID("", &Z502_REG4, &Z502_REG9);
    printf("\n\nRelease %s:Test 2f: Pid %ld\n", CURRENT_REL, Z502_REG4);

    for (Iterations = 0; Iterations < NUMBER_OF_ITERATIONS; Iterations++)
    {
        for (Index = 0; Index < LOOP_COUNT; Index++) // Bugfix Rel 4.03  12/1/2013
            mtr->page_touched[Index] = 0;
        for (Loops = 0; Loops < LOOP_COUNT; Loops++)
        {
            // Get a random page number
            get_skewed_random_number(&Z502_REG7, LOGICAL_PAGES_TO_TOUCH);
            Z502_REG3 = PGSIZE * Z502_REG7; // Convert page to addr.
            Z502_REG1 = Z502_REG3 + Z502_REG4; // Generate data for page
            MEM_WRITE(Z502_REG3, &Z502_REG1);
            // Write it again, just as a test
            MEM_WRITE(Z502_REG3, &Z502_REG1);

            // Read it back and make sure it's the same
            MEM_READ(Z502_REG3, &Z502_REG2);
            if (Loops % DISPLAY_GRANULARITY2 == 0)
                printf("PID= %ld  address= %ld   written= %ld   read= %ld\n",
                       Z502_REG4, Z502_REG3, Z502_REG1, Z502_REG2);
            if (Z502_REG2 != Z502_REG1)
                printf("AN ERROR HAS OCCURRED: READ NOT EQUAL WRITE.\n");

            // Record in our data-base that we've accessed this page
            mtr->page_touched[(short) Loops] = Z502_REG7;

        } // End of for Loops

        for (Loops = 0; Loops < LOOP_COUNT; Loops++)
        {

            // We can only read back from pages we've previously
            // written to, so find out which pages those are.
            Z502_REG6 = mtr->page_touched[(short) Loops];
            Z502_REG3 = PGSIZE * Z502_REG6; // Convert page to addr.
            Z502_REG1 = Z502_REG3 + Z502_REG4; // Expected read
            MEM_READ(Z502_REG3, &Z502_REG2);

            if (Loops % DISPLAY_GRANULARITY2 == 0)
                printf("PID= %ld  address= %ld   written= %ld   read= %ld\n",
                       Z502_REG4, Z502_REG3, Z502_REG1, Z502_REG2);
            if (Z502_REG2 != Z502_REG1)
                printf("ERROR HAS OCCURRED: READ NOT SAME AS WRITE.\n");
        } // End of for Loops

        // We've completed reading back everything
        printf("TEST 2f, PID %ld, HAS COMPLETED %d ITERATIONS\n", Z502_REG4,
               Iterations);
    } // End of for Iterations

    TERMINATE_PROCESS(-1, &Z502_REG9);

} // End of test2f
示例#17
0
void test2c(void)
{
    DISK_DATA *data_written;
    DISK_DATA *data_read;
    long disk_id;
    INT32 sanity = 1234;
    long sector;
    int Iterations;

    data_written = (DISK_DATA *) calloc(1, sizeof (DISK_DATA));
    data_read = (DISK_DATA *) calloc(1, sizeof (DISK_DATA));
    if (data_read == 0)
        printf("Something screwed up allocating space in test2c\n");

    GET_PROCESS_ID("", &Z502_REG4, &Z502_REG9);

    sector = Z502_REG4;
    printf("\n\nRelease %s:Test 2c: Pid %ld\n", CURRENT_REL, Z502_REG4);

    for (Iterations = 0; Iterations < TEST2C_LOOPS; Iterations++)
    {
        // Pick some location on the disk to write to
        disk_id = (Z502_REG4 / 2) % MAX_NUMBER_OF_DISKS + 1;
        sector = (sector * 177) % NUM_LOGICAL_SECTORS;
        data_written->int_data[0] = disk_id;
        data_written->int_data[1] = sanity;
        data_written->int_data[2] = sector;
        data_written->int_data[3] = (int) Z502_REG4;
        DISK_WRITE(disk_id, sector, (char*) (data_written->char_data));

        // Now read back the same data.  Note that we assume the
        // disk_id and sector have not been modified by the previous
        // call.
        DISK_READ(disk_id, sector, (char*) (data_read->char_data));

        if ((data_read->int_data[0] != data_written->int_data[0])
                || (data_read->int_data[1] != data_written->int_data[1])
                || (data_read->int_data[2] != data_written->int_data[2])
                || (data_read->int_data[3] != data_written->int_data[3]))
        {
            printf("AN ERROR HAS OCCURRED.\n");
        }
        else if (Z502_REG6 % DISPLAY_GRANULARITY2c == 0)
        {
            printf("SUCCESS READING  PID= %ld  disk_id =%ld, sector = %ld\n",
                   Z502_REG4, disk_id, sector);
        }
    } // End of for loop

    // Now read back the data we've written and paged

    printf("Reading back data: test 2c, PID %ld.\n", Z502_REG4);
    sector = Z502_REG4;

    for (Iterations = 0; Iterations < TEST2C_LOOPS; Iterations++)
    {
        disk_id = (Z502_REG4 / 2) % MAX_NUMBER_OF_DISKS + 1;
        sector = (sector * 177) % NUM_LOGICAL_SECTORS;
        data_written->int_data[0] = disk_id;
        data_written->int_data[1] = sanity;
        data_written->int_data[2] = sector;
        data_written->int_data[3] = Z502_REG4;

        DISK_READ(disk_id, sector, (char*) (data_read->char_data));

        if ((data_read->int_data[0] != data_written->int_data[0])
                || (data_read->int_data[1] != data_written->int_data[1])
                || (data_read->int_data[2] != data_written->int_data[2])
                || (data_read->int_data[3] != data_written->int_data[3]))
        {
            printf("AN ERROR HAS OCCURRED.\n");
        }
        else if (Z502_REG6 % DISPLAY_GRANULARITY2c == 0)
        {
            printf("SUCCESS READING  PID= %ld  disk_id =%ld, sector = %ld\n",
                   Z502_REG4, disk_id, sector);
        }

    } // End of for loop

    GET_TIME_OF_DAY(&Z502_REG8);
    printf("Test2c, PID %ld, Ends at Time %ld\n", Z502_REG4, Z502_REG8);
    TERMINATE_PROCESS(-1, &Z502_REG9);

} // End of test2c