コード例 #1
0
ファイル: base.c プロジェクト: tyang1991/Operating-System
/************************************************************************
 INTERRUPT_HANDLER
 When the Z502 gets a hardware interrupt, it transfers control to
 this routine in the OS.
 ************************************************************************/
void InterruptHandler(void) {
	INT32 DeviceID;
//	INT32 Status;

	MEMORY_MAPPED_IO mmio;       // Enables communication with hardware

	static BOOL remove_this_in_your_code = TRUE; /** TEMP **/
	static INT32 how_many_interrupt_entries = 0; /** TEMP **/

	// Get cause of interrupt
	mmio.Mode = Z502GetInterruptInfo;
	mmio.Field1 = mmio.Field2 = mmio.Field3 = 0;
	MEM_READ(Z502InterruptDevice, &mmio);
	DeviceID = mmio.Field1;
	//Status = mmio.Field2;

/////////////////////////Code go here////////////////////////////////////

	//take all timeout PCB from timer queue and put into ready queue
	struct Process_Control_Block *tmpPCB;

	do{
		tmpPCB = deTimerQueue();
		enReadyQueue(tmpPCB);
	} while (ResetTimer() == 0);

/////////////////////////Code end here///////////////////////////////////
	
	// Clear out this device - we're done with it
	mmio.Mode = Z502ClearInterruptStatus;
	mmio.Field1 = DeviceID;
	mmio.Field2 = mmio.Field3 = 0;
	MEM_WRITE(Z502InterruptDevice, &mmio);
}           // End of InterruptHandler
コード例 #2
0
ファイル: Control.c プロジェクト: tyang1991/Operating-System
//This function resumes a PCB
void ResumeProcess(struct Process_Control_Block *PCB) {
	//check input PCB, do action only if PCB is not NULL
	if (PCB != NULL) {
		//resume a process only if it has been suspended
		if (PCB->ProcessState == PCB_STATE_SUSPEND) {
			//set state
			PCB->ProcessState = PCB_STATE_LIVE;
			pcbTable->Suspended_Number -= 1;
			//if the PCB is not on ready queue nor timer queue, put the
			//PCB on ready queue
			if (PCB->ProcessLocation != PCB_LOCATION_READY_QUEUE
				&& PCB->ProcessLocation != PCB_LOCATION_TIMER_QUEUE) {
				enReadyQueue(PCB);
			}
		}
	}
}
コード例 #3
0
ファイル: base.c プロジェクト: tyang1991/Operating-System
void osInit(int argc, char *argv[]) {
	void *PageTable = (void *) calloc(2, VIRTUAL_MEM_PAGES);
	INT32 i;
	MEMORY_MAPPED_IO mmio;

	//init Queues
	initPCBTable();
	initTimerQueue();
	initReadyQueue();
	initMessageTable();

  // Demonstrates how calling arguments are passed thru to here       

    printf( "Program called with %d arguments:", argc );
    for ( i = 0; i < argc; i++ )
        printf( " %s", argv[i] );
    printf( "\n" );
    printf( "Calling with argument 'sample' executes the sample program.\n" );
    // Here we check if a second argument is present on the command line.
    // If so, run in multiprocessor mode
    if ( argc > 2 ){
    	printf("Simulation is running as a MultProcessor\n\n");
		mmio.Mode = Z502SetProcessorNumber;
		mmio.Field1 = MAX_NUMBER_OF_PROCESSORS;
		mmio.Field2 = (long) 0;
		mmio.Field3 = (long) 0;
		mmio.Field4 = (long) 0;

		MEM_WRITE(Z502Processor, &mmio);   // Set the number of processors
    }
    else {
    	printf("Simulation is running as a UniProcessor\n");
    	printf("Add an 'M' to the command line to invoke multiprocessor operation.\n\n");
    }

	//          Setup so handlers will come to code in base.c   

	TO_VECTOR[TO_VECTOR_INT_HANDLER_ADDR ] = (void *) InterruptHandler;
	TO_VECTOR[TO_VECTOR_FAULT_HANDLER_ADDR ] = (void *) FaultHandler;
	TO_VECTOR[TO_VECTOR_TRAP_HANDLER_ADDR ] = (void *) svc;

	//  Determine if the switch was set, and if so go to demo routine. 

	PageTable = (void *) calloc(2, VIRTUAL_MEM_PAGES);
  	if ((argc > 1) && (strcmp(argv[1], "sample") == 0)) {
		mmio.Mode = Z502InitializeContext;
		mmio.Field1 = 0;
		mmio.Field2 = (long) SampleCode;
		mmio.Field3 = (long) PageTable;

		MEM_WRITE(Z502Context, &mmio);   // Start of Make Context Sequence
		mmio.Mode = Z502StartContext;
		// Field1 contains the value of the context returned in the last call
		mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND;
		MEM_WRITE(Z502Context, &mmio);     // Start up the context

 	} // End of handler for sample code - This routine should never return here

	/****************************Parse Input******************************/
	long *TestToRun;
	switch (argc){
		case 2:
			TestToRun = TestParser(argv[1]);
			ProcessorMode = Uniprocessor;
			break;
		case 3:
			TestToRun = TestParser(argv[1]);
			ProcessorMode = Multiprocessor;
			break;
		default:
			TestToRun = test1c;
			ProcessorMode = Uniprocessor;
			break;
	}
	/********************************************************************/

	long ErrorReturned;
	long newPID;
	struct Process_Control_Block *newPCB = OSCreateProcess((long*)"test1", TestToRun, (long*)3, (long*)&newPID, (long*)&ErrorReturned);
	if (newPCB != NULL) {
		enPCBTable(newPCB);
		enReadyQueue(newPCB);
	}
	Dispatcher();
}                                               // End of osInit
コード例 #4
0
ファイル: base.c プロジェクト: tyang1991/Operating-System
void svc(SYSTEM_CALL_DATA *SystemCallData) {
	short call_type;
	static short do_print = 10;
	short i;

	//for hardware interface
	MEMORY_MAPPED_IO mmio;
	//for GET_TIME_OF_DAY
	INT32 Temp_Clock;
	//for SLEEP
	long Sleep_Time;
	struct Process_Control_Block *sleepPCB;
	//for RESTART_PROCESS
	long PID_restart;
	struct Process_Control_Block *restartPCB;
	struct Process_Control_Block *recreatedPCB;
	//for CREATE_PROCESS
	struct Process_Control_Block *newPCB;
	//for TERMINATE_PROCESS
	long termPID;
	struct Process_Control_Block *termPCB;
	//for GET_PROCESS_ID
	int ReturnedPID;
	char* ProcessName;
	struct Process_Control_Block *PCBbyProcessName;
	//for SUSPEND_PROCESS
	int suspendPID;
	struct Process_Control_Block *suspendPCB;
	//for RESUME_PROCESS
	int resumePID;
	struct Process_Control_Block *resumePCB;
	//for CHANGE_PRIORITY
	int changePrioPID;
	struct Process_Control_Block *changePrioPCB;
	int newPriority;
	//for SEND_MESSAGE
	long TargetPID;
	char *MessageBuffer;
	long SendLength;
	struct Message *MessageCreated;
	long *ErrorReturned_SendMessage;
	//for RECEIVE_MESSAGE
	long SourcePID;
	char *ReceiveBuffer;
	long ReceiveLength;
	long *ActualSendLength;
	long *ActualSourcePID;
	long *ErrorReturned_ReceiveMessage;
	struct Process_Control_Block *Mess_PCB;

	call_type = (short) SystemCallData->SystemCallNumber;
	if (do_print > 0) {
		printf("SVC handler: %s\n", call_names[call_type]);
		for (i = 0; i < SystemCallData->NumberOfArguments - 1; i++) {
			//Value = (long)*SystemCallData->Argument[i];
			printf("Arg %d: Contents = (Decimal) %8ld,  (Hex) %8lX\n", i,
					(unsigned long) SystemCallData->Argument[i],
					(unsigned long) SystemCallData->Argument[i]);
		}
		do_print--;
	}
	switch (call_type) {
		//get and return current system time
		case SYSNUM_GET_TIME_OF_DAY:
			mmio.Mode = Z502ReturnValue;
			mmio.Field1 = mmio.Field2 = mmio.Field3 = 0;
			MEM_READ(Z502Clock, &mmio);
			Temp_Clock = mmio.Field1;
			*SystemCallData->Argument[0] = Temp_Clock;
			break;
		//create a new PCB and put it into pcb table and ready queue
		case SYSNUM_CREATE_PROCESS:
			//create a new PCB
			newPCB = OSCreateProcess(SystemCallData->Argument[0], SystemCallData->Argument[1],
							SystemCallData->Argument[2], SystemCallData->Argument[3], 
							SystemCallData->Argument[4]);
			//if create successfully, put it into PCB table and ready queue
			if (newPCB != NULL) {
				SchedularPrinter("Create", newPCB->ProcessID);//print states
				enPCBTable(newPCB);
				enReadyQueue(newPCB);
			}
			break;
		//return PID regarding process name
		case SYSNUM_GET_PROCESS_ID:
			ProcessName = (char*)SystemCallData->Argument[0];
			//if no input process name, return the current running PID
			if (strcmp(ProcessName, "") == 0) {
				PCBbyProcessName = CurrentPCB();
				*SystemCallData->Argument[1] = PCBbyProcessName->ProcessID;
				*SystemCallData->Argument[2] = ERR_SUCCESS;
			}
			//find the PCB in PCB table and return PID if found
			else {
				PCBbyProcessName = findPCBbyProcessName(ProcessName);
				//if found, return PID
				if (PCBbyProcessName != NULL) {
					ReturnedPID = PCBbyProcessName->ProcessID;
					*SystemCallData->Argument[1] = ReturnedPID;
					*SystemCallData->Argument[2] = ERR_SUCCESS;
				}
				//if not found, return error
				else {
					*SystemCallData->Argument[2] = ERR_BAD_PARAM;
				}
			}
			break;
		//if a PCB wanna sleep, put itself into timer queue and start
		//a new PCB
		case SYSNUM_SLEEP:
			//print states
			SchedularPrinter("Sleep", CurrentPID());
			//Calculate WakeUpTime for PCB
			Sleep_Time = (long)SystemCallData->Argument[0];
			sleepPCB = CurrentPCB();
			sleepPCB->WakeUpTime = CurrentTime() + Sleep_Time;
			//Put current running PCB into timer queue and reset time 
			lockTimer();
			enTimerQueue(sleepPCB);
			if (sleepPCB == timerQueue->First_Element->PCB){
				SetTimer(Sleep_Time);
			}
			unlockTimer();
			//in uniprocessor, start a new PCB
			//in multiprocessor, only suspend itself
			if (ProcessorMode == Uniprocessor) {
				//first PCB in Ready Queue starts
				Dispatcher();
			}
			else {
				OSSuspendCurrentProcess();
			}
			break;
		//restart a PCB by terminate itself and created a new PCB with everything the same except PID
		case SYSNUM_RESTART_PROCESS:
			//initial return error
			*SystemCallData->Argument[2] = ERR_BAD_PARAM;
			PID_restart = (long)SystemCallData->Argument[0];
			//if not restart itself
			if (PID_restart != CurrentPID()){
				//find restarted PCB
				restartPCB = findPCBbyProcessID(PID_restart);
				//if PCB found, terminate itself and create a new one
				if (restartPCB != NULL){
					TerminateProcess(restartPCB);
					recreatedPCB = OSCreateProcess(restartPCB->ProcessName, restartPCB->TestToRun,
						restartPCB->Priority, SystemCallData->Argument[1], SystemCallData->Argument[2]);
					//if create successfully, put it into PCB table and ready queue
					if (recreatedPCB != NULL) {
						*SystemCallData->Argument[2] = ERR_SUCCESS;
						SchedularPrinter("Create", recreatedPCB->ProcessID);//print states
						enPCBTable(recreatedPCB);
						enReadyQueue(recreatedPCB);
						SchedularPrinter("Restart", restartPCB->ProcessID);
					}
				}
				else{
					*SystemCallData->Argument[2] = ERR_BAD_PARAM;
				}
			}
			else{
				*SystemCallData->Argument[2] = ERR_BAD_PARAM;
			}
			break;
		//terminate a process
		case SYSNUM_TERMINATE_PROCESS:
			termPID = (long)SystemCallData->Argument[0];
			//if PID = -1, terminate current running PCB
			if (termPID == -1) {
				if (PCBLiveNumber() > 1) {
					*SystemCallData->Argument[1] = ERR_SUCCESS;
					//print states
					SchedularPrinter("Terminate", termPID);
					//terminate current PCB
					TerminateProcess(CurrentPCB());
				}
				else {
					*SystemCallData->Argument[1] = ERR_SUCCESS;
					HaltProcess();
				}
			}
			//if PID = -2, terminate OS
			if (termPID == -2) {
				*SystemCallData->Argument[1] = ERR_SUCCESS;
				HaltProcess();
			}
			//if PID positive, terminate specified PID
			else {
				termPCB = findPCBbyProcessID((long)SystemCallData->Argument[0]);
				//if PCB found, terminate it
				if (termPCB != NULL) {
					*SystemCallData->Argument[1] = ERR_SUCCESS;
					//if more than one PCB alive, simply terminate it
					if (PCBLiveNumber() > 1) {
						//print states
						SchedularPrinter("Terminate", termPID);
						//terminate specified PCB
						TerminateProcess(termPCB);
					}
					//if last alive PCB, terminate OS
					else {
						HaltProcess();
					}
				}
				else {
					*SystemCallData->Argument[1] = ERR_BAD_PARAM;
				}
			}
			break;
		//suspend a PCB, which can be resumed
		case SYSNUM_SUSPEND_PROCESS:
			suspendPID = (int)SystemCallData->Argument[0];
			//if PID = -1, suspend current running PCB
			if (suspendPID == -1) {
				//if more than one PCB alive, suspend it
				if (PCBLiveNumber() > 1) {
					*SystemCallData->Argument[1] = ERR_SUCCESS;
					//print states
					SchedularPrinter("Suspend", suspendPID);
					//Suspend Current Process
					SuspendProcess(CurrentPCB());
				}
				//if last one PCB alive, return error
				else {
					*SystemCallData->Argument[1] = ERR_BAD_PARAM;
				}
			}
			//if PID positive, suspend specified PCB
			else {
				suspendPCB = findPCBbyProcessID((int)suspendPID);
				//if PCB found
				if (suspendPCB != NULL) {
					//if more than one PCB alive, suspend it
					if (suspendPCB->ProcessState == PCB_STATE_LIVE && PCBLiveNumber() > 1) {
						*SystemCallData->Argument[1] = ERR_SUCCESS;
						//print states
						SchedularPrinter("Suspend", suspendPID);
						//Suspend specified process
						SuspendProcess(suspendPCB);
					}
					//if last one PCB alive, return error
					else {
						*SystemCallData->Argument[1] = ERR_BAD_PARAM;
					}
				}
				else {
					*SystemCallData->Argument[1] = ERR_BAD_PARAM;
				}
			}
			break;
		//resumes a previously suspended PCB
		case SYSNUM_RESUME_PROCESS:
			resumePID = (int)SystemCallData->Argument[0];
			resumePCB = findPCBbyProcessID(resumePID);
			//if PCB found
			if (resumePCB != NULL) {
				//if PCB is previously suspended
				if (resumePCB->ProcessState == PCB_STATE_SUSPEND) {
					*SystemCallData->Argument[1] = ERR_SUCCESS;
					//print states
					SchedularPrinter("Resume", resumePID);
					//Resume specified process
					ResumeProcess(resumePCB);
				}
				else {
					*SystemCallData->Argument[1] = ERR_BAD_PARAM;
				}
			}
			else {
				*SystemCallData->Argument[1] = ERR_BAD_PARAM;
			}
			break;
		//change the priority of a PCB
		case SYSNUM_CHANGE_PRIORITY:
			changePrioPID = (int)SystemCallData->Argument[0];
			changePrioPCB = findPCBbyProcessID((int)changePrioPID);
			newPriority = (int)SystemCallData->Argument[1];
			//if legal priority
			if (newPriority<=40 && newPriority>=0) {
				if (changePrioPCB != NULL) {
					*SystemCallData->Argument[2] = ERR_SUCCESS;
					//print states
					printf("Before changing Priority\n");
					SchedularPrinter("ChangePrio", changePrioPID);
					//if PCB in ready queue, change order in ready queue
					if (changePrioPCB->ProcessLocation == PCB_LOCATION_READY_QUEUE
										&& newPriority != changePrioPCB->Priority) {
						changePrioPCB = deCertainPCBFromReadyQueue(changePrioPID);
						changePrioPCB->Priority = newPriority;
						enReadyQueue(changePrioPCB);
					}
					else {
						changePrioPCB->Priority = newPriority;
					}
					//print states
					printf("After changing Priority\n");
					SchedularPrinter("ChangePrio", changePrioPID);
				}
				else {
					*SystemCallData->Argument[2] = ERR_BAD_PARAM;
				}
			}
			else {
				*SystemCallData->Argument[2] = ERR_BAD_PARAM;
			}
			break;
		//PCB stores a message in message table
		case SYSNUM_SEND_MESSAGE:
			TargetPID = (long)SystemCallData->Argument[0];
			MessageBuffer = (char*)SystemCallData->Argument[1];
			SendLength = (long)SystemCallData->Argument[2];
			ErrorReturned_SendMessage = SystemCallData->Argument[3];
			//create a message
			MessageCreated = CreateMessage(TargetPID, MessageBuffer, 
				                        SendLength, ErrorReturned_SendMessage);
			//if successfully create a message, put it into message table
			if (MessageCreated != NULL) {
				SchedularPrinter("SendMsg", TargetPID);
				enMessageTable(MessageCreated);
			}
			break;
		//retrive a message in message table
		case SYSNUM_RECEIVE_MESSAGE:
			SourcePID = (long)SystemCallData->Argument[0];
			ReceiveBuffer = (char*)SystemCallData->Argument[1];
			ReceiveLength = (long)SystemCallData->Argument[2];
			ActualSendLength = SystemCallData->Argument[3];
			ActualSourcePID = SystemCallData->Argument[4];
			ErrorReturned_ReceiveMessage = SystemCallData->Argument[5];
			Mess_PCB = CurrentPCB();
			Mess_PCB->ProcessState = PCB_STATE_MSG_SUSPEND;
			pcbTable->Msg_Suspended_Number += 1;
			//PCB kept suspended by sleep until find a message
			while (findMessage(SourcePID, ReceiveBuffer, ReceiveLength,
				ActualSendLength, ActualSourcePID, ErrorReturned_ReceiveMessage) == 0) {
				Mess_PCB->WakeUpTime = CurrentTime() + 10;
				//Put current running PCB into timer queue and reset time 
				enTimerQueue(Mess_PCB);
				if (Mess_PCB == timerQueue->First_Element->PCB) {
					SetTimer(10);
				}
				//first PCB in Ready Queue starts
				Dispatcher();
			}

			Mess_PCB->ProcessState = PCB_STATE_LIVE;
			pcbTable->Msg_Suspended_Number -= 1;
			SchedularPrinter("ReceiveMsg", CurrentPID());
			break;
		default:
			printf("ERROR!  call_type not recognized!\n");
			printf("Call_type is - %i\n", call_type);
	}
}                                               // End of svc
コード例 #5
0
ファイル: base.c プロジェクト: khuang2/Operating-System
/************************************************************************
 INTERRUPT_HANDLER
 When the Z502 gets a hardware interrupt, it transfers control to
 this routine in the OS.Catch valid interrupts as much as possible (Using 
 While Loop).
 If it's a disk interrupt,remove the PCB from its disk queue (8 disk queues 
 in total) and add it to ready queue.
 If it's a timer interrupt,remove the PCB from timer queue and add it to 
 ready queue.
 ************************************************************************/
void InterruptHandler(void) {
	INT32 DeviceID;
	PCB *tempPCB;

	INT32 currTime;  //current time

	INT32 newDelay;


	MEMORY_MAPPED_IO mmio;       // Enables communication with hardware

	INT32 LockResult=0;
	INT32 UnlockResult=0;
	
	static BOOL remove_this_in_your_code = TRUE; /** TEMP **/
	static INT32 how_many_interrupt_entries = 0; /** TEMP **/

	mmio.Mode = Z502GetInterruptInfo;
	mmio.Field1 = mmio.Field2 = mmio.Field3 = 0;
	MEM_READ(Z502InterruptDevice, &mmio);
	//DeviceID = mmio.Field1;


	while  ( mmio.Field4 == ERR_SUCCESS ) {               //a valid interrupt
			DeviceID = mmio.Field1;

			//Disk Interrupt

			switch(DeviceID){
				case DISK_INTERRUPT_DISK1:
					READ_MODIFY(0x7FE00002, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					READ_MODIFY(0x7FE00004, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					tempPCB=deDiskQueue(&diskQHead1);
					enReadyQueue(&readyQHead,tempPCB);
					READ_MODIFY(0x7FE00004, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					READ_MODIFY(0x7FE00002, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					break;

				case DISK_INTERRUPT_DISK2:
					READ_MODIFY(0x7FE00002, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					READ_MODIFY(0x7FE00004, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					tempPCB=deDiskQueue(&diskQHead2);
					enReadyQueue(&readyQHead,tempPCB);
					READ_MODIFY(0x7FE00004, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					READ_MODIFY(0x7FE00002, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					break;

				case DISK_INTERRUPT_DISK3:
					READ_MODIFY(0x7FE00002, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					READ_MODIFY(0x7FE00004, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					tempPCB=deDiskQueue(&diskQHead3);
					enReadyQueue(&readyQHead,tempPCB);
					READ_MODIFY(0x7FE00004, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					READ_MODIFY(0x7FE00002, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					break;

				case DISK_INTERRUPT_DISK4:
					READ_MODIFY(0x7FE00002, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					READ_MODIFY(0x7FE00004, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					tempPCB=deDiskQueue(&diskQHead4);
					enReadyQueue(&readyQHead,tempPCB);
					READ_MODIFY(0x7FE00004, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					READ_MODIFY(0x7FE00002, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					break;

				case DISK_INTERRUPT_DISK5:
					READ_MODIFY(0x7FE00002, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					READ_MODIFY(0x7FE00004, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					tempPCB=deDiskQueue(&diskQHead5);
					enReadyQueue(&readyQHead,tempPCB);
					READ_MODIFY(0x7FE00004, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					READ_MODIFY(0x7FE00002, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					break;

				case DISK_INTERRUPT_DISK6:
					READ_MODIFY(0x7FE00002, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					READ_MODIFY(0x7FE00004, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					tempPCB=deDiskQueue(&diskQHead6);
					enReadyQueue(&readyQHead,tempPCB);
					READ_MODIFY(0x7FE00004, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					READ_MODIFY(0x7FE00002, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					break;

				case DISK_INTERRUPT_DISK7:
					READ_MODIFY(0x7FE00002, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					READ_MODIFY(0x7FE00004, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					tempPCB=deDiskQueue(&diskQHead7);
					enReadyQueue(&readyQHead,tempPCB);
					READ_MODIFY(0x7FE00004, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					READ_MODIFY(0x7FE00002, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					break;

				case DISK_INTERRUPT_DISK8:
					READ_MODIFY(0x7FE00002, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					READ_MODIFY(0x7FE00004, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					tempPCB=deDiskQueue(&diskQHead8);
					enReadyQueue(&readyQHead,tempPCB);
					READ_MODIFY(0x7FE00004, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					READ_MODIFY(0x7FE00002, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					break;

				case TIMER_INTERRUPT:
					//get current time 
					mmio.Mode = Z502ReturnValue;
					mmio.Field1 = mmio.Field2 = mmio.Field3 = 0;
					MEM_READ(Z502Clock, &mmio);//hardware call
					currTime = mmio.Field1;

					READ_MODIFY(0x7FE00001, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					READ_MODIFY(0x7FE00002, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					READ_MODIFY(0x7FE00003, DO_LOCK, SUSPEND_UNTIL_LOCKED,
					&LockResult);
					while(timerQHead!=NULL&&timerQHead->pcb->time<=currTime){


						tempPCB=deTimerQueue(&timerQHead);
		

						if(tempPCB->suspend==1){
							enSuspendQueue(&suspendQHead, tempPCB);
						}else{

							enReadyQueue(&readyQHead,tempPCB);
		
						}

						mmio.Mode = Z502ReturnValue;
						mmio.Field1 = mmio.Field2 = mmio.Field3 = 0;
						MEM_READ(Z502Clock, &mmio);//hardware call
						currTime = mmio.Field1;
					}


						mmio.Mode = Z502ReturnValue;
						mmio.Field1 = mmio.Field2 = mmio.Field3 = 0;
						MEM_READ(Z502Clock, &mmio);//hardware call
						currTime = mmio.Field1;




					//reset the timer with the new delay time.
					if(timerQHead!=NULL){
						newDelay=timerQHead->pcb->time-currTime;
						mmio.Mode = Z502Start;
						mmio.Field1 =(long) newDelay;
						mmio.Field2 = mmio.Field3 = 0;
						MEM_WRITE(Z502Timer, &mmio);


					}

					READ_MODIFY(0x7FE00003, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					READ_MODIFY(0x7FE00002, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
					&UnlockResult);
					READ_MODIFY(0x7FE00001, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
						&UnlockResult);
					break;

			}

			

			 
			mmio.Mode = Z502ClearInterruptStatus;            // Now clear that interrupt
			mmio.Field1 = DeviceID;
			mmio.Field2 = mmio.Field3  = mmio.Field4 = 0;
			MEM_WRITE( Z502InterruptDevice, &mmio );
			mmio.Mode = Z502GetInterruptInfo;               // See if there's another Interrupt
			mmio.Field1 = mmio.Field2 = mmio.Field3  = mmio.Field4 = 0;
			MEM_READ( Z502InterruptDevice, &mmio );
	}   // End of while
	
}           // End of InterruptHandler