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
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
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
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
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
//**************************************************************************** // 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); }
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
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
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
//**************************************************************************** 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"); }
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
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 */
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
/************************************************************************** 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
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 */
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
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