/************************************************************************ 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
/************************************************************************ 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