#include "../h/devinterrupt_handler.h" extern pcb_t* currentProcess; // pointer to the current executing process extern int processCount; extern int device_semaphores[49]; // 49 device semaphores extern int softBlockCount; // number of soft blocked processes extern pcb_t* readyQueue; // tail pointer to the queue of ready pcbs extern cpu_t startTime; int interruptStartTime; void InterruptHandler(unsigned int cause) { STCK(interruptStartTime); //this is to record the time at which the interrupt happened // Extract bits 8 to 15 directly unsigned int ipField = (cause >> 8) & 0xFF; // Check if bit 0 is set; if so, call PANIC() if (ipField & (1 << 0)) { PANIC(); } else { // Check bits 1 through 7 for active interrupts for (int i = 1; i < 8; i++) { if (ipField & (1 << i)) { InterruptLineHandler(i); } } } } void InterruptLineHandler(int line) { if (line == 1) { // PLT timer currentProcess->p_time = currentProcess->p_time + (CURRENT_TOD - startTime); currentProcess->p_s = *((state_t*) BIOSDATAPAGE); insertProcQ(&readyQueue, currentProcess); Scheduler(); } else if (line == 2){ // Interval time exception LDIT(100000); // Unblock all pcbs blocked on the pseudo-clock semaphore while (headBlocked(&device_semaphores[48]) != NULL) { pcb_t* unblockedPcb = removeBlocked(&device_semaphores[48]); if (unblockedPcb != NULL) { unblockedPcb->p_semAdd = NULL; unblockedPcb->p_time = (unblockedPcb->p_time) + (CURRENT_TOD - startTime); insertProcQ(&readyQueue, unblockedPcb); softBlockCount--; } } device_semaphores[48] = 0; // reset the pseudo-clock semaphore to 0 if (currentProcess == NULL) Scheduler(); /* passing control to the current process (if there is one) */ else LDST((state_t *) 0x0FFFF000); } else { // Peripheral device interrupt memaddr* lineBitMapAddr = (memaddr*)(0x10000040 + ((line - 3)* 0x4)); // For each bit that is set to 1, call NonTimerHandler for (int i = 0; i < 8; i++) { if ((*lineBitMapAddr) & (1 << i)) { NonTimerHandler(line, i); } } } } void NonTimerHandler(int line, int device) { // Compute the address of the device register for the device that generated the interrupt devreg_t* deviceRegister = (devreg_t*) (0x10000054 + ((line - 3) * 0x80) + (device * 0x10)); // Declare a pointer variable called termReg of type termreg_t to point to the computed address termreg_t* pointer = (termreg_t*) deviceRegister; unsigned int relDevStatus; int num; // Check if the terminal is a transmitter if (pointer->recv_status == 1) { relDevStatus = pointer->transm_status; pointer->transm_command = 1; // Acknowledge transmitter interrupt num = 0; } else { relDevStatus = pointer->recv_status; pointer->recv_command = 1; // Acknowledge receiver interrupt num = 1; } // Compute the index position for the device in the device_semaphores[] array int deviceNum = 2 * device + num; int index = (line - 3) * 8 + deviceNum; device_semaphores[index]++; pcb_t* removedPcb = removeBlocked(&device_semaphores[index]); if (removedPcb != NULL) { // process is successfully unblocked removedPcb->p_time = removedPcb->p_time + (CURRENT_TOD - interruptStartTime); removedPcb->p_s.reg_v0 = relDevStatus; removedPcb->p_semAdd = NULL; insertProcQ(&readyQueue, removedPcb); softBlockCount--; } if (currentProcess == NULL) Scheduler(); /* passing control to the current process (if there is one) */ else LDST((state_t *) 0x0FFFF000); }