/* * Update the location of the hardware cursor. */ static void Update_Cursor(void) { /* * The cursor location is a character offset from the beginning * of page memory (I think). */ uint_t characterPos = (s_cons.row * NUMCOLS) + s_cons.col; uchar_t origAddr; /* * Save original contents of CRT address register. * It is considered good programming practice to restore * it to its original value after modifying it. */ origAddr = In_Byte(CRT_ADDR_REG); IO_Delay(); /* Set the high cursor location byte */ Out_Byte(CRT_ADDR_REG, CRT_CURSOR_LOC_HIGH_REG); IO_Delay(); Out_Byte(CRT_DATA_REG, (characterPos >> 8) & 0xff); IO_Delay(); /* Set the low cursor location byte */ Out_Byte(CRT_ADDR_REG, CRT_CURSOR_LOC_LOW_REG); IO_Delay(); Out_Byte(CRT_DATA_REG, characterPos & 0xff); IO_Delay(); /* Restore contents of the CRT address register */ Out_Byte(CRT_ADDR_REG, origAddr); }
void NE2000_Handle_Ring_Buffer_Overflow(struct Net_Device *device) { int txp, resend; ulong_t baseAddr = device->baseAddr; /* 1. Read and store the value of the TXP bit */ txp = In_Byte(baseAddr + NE2K_CR) & NE2K_CR_TXP; /* 2. Issue the STOP command to the NIC */ Out_Byte(baseAddr + NE2K_CR, 0x21); /* 3. Wait for at least 1.6 ms */ IO_Delay(); /* 4. Clear the NIC’s Remote Byte Count */ Out_Byte(baseAddr + NE2K0W_RBCR0, 0x00); Out_Byte(baseAddr + NE2K0W_RBCR1, 0x00); /* 5. Handle resend */ if (!txp) { resend = 0; } else { int isr = In_Byte(baseAddr + NE2K0R_ISR); if ((isr & NE2K_ISR_PTX) || (isr & NE2K_ISR_TXE)) { resend = 0; } else { resend = 1; } } /* 6. Place the NIC into loopback mode */ Out_Byte(baseAddr + NE2K0W_TCR, 0x02); /* 7. Issue START command to the NIC */ Out_Byte(baseAddr + NE2K_CR, 0x22); /* 8. Remove one or more packets from the receive buffer ring */ NE2000_Do_Receive(device); /* 9. Reset the overwrite warning (OVW) bit in the ISR */ Out_Byte(baseAddr + NE2K0R_ISR, NE2K_ISR_OVW); /* 10. Take the NIC out of loopback */ Out_Byte(baseAddr + NE2K0W_TCR, 0x00); /* 11. Restart the interrupted transmit if resend = 1 */ if (resend) { Out_Byte(baseAddr + NE2K_CR, 0x26); } }
/* * Handler for keyboard interrupts. */ static void Keyboard_Interrupt_Handler(struct Interrupt_State* state) { uchar_t status, scanCode; unsigned flag = 0; bool release = false, shift; Keycode keycode; Begin_IRQ(state); status = In_Byte(KB_CMD); IO_Delay(); if ((status & KB_OUTPUT_FULL) != 0) { /* There is a byte available */ scanCode = In_Byte(KB_DATA); IO_Delay(); /* * Print("code=%x%s\n", scanCode, (scanCode&0x80) ? " [release]" : ""); */ if (scanCode & KB_KEY_RELEASE) { release = true; scanCode &= ~(KB_KEY_RELEASE); } if (scanCode >= SCAN_TABLE_SIZE) { Print("Unknown scan code: %x\n", scanCode); goto done; } /* Process the key */ shift = ((s_shiftState & SHIFT_MASK) != 0); keycode = shift ? s_scanTableWithShift[scanCode] : s_scanTableNoShift[scanCode]; /* Update shift, control and alt state */ switch (keycode) { case KEY_LSHIFT: flag = LEFT_SHIFT; break; case KEY_RSHIFT: flag = RIGHT_SHIFT; break; case KEY_LCTRL: flag = LEFT_CTRL; break; case KEY_RCTRL: flag = RIGHT_CTRL; break; case KEY_LALT: flag = LEFT_ALT; break; case KEY_RALT: flag = RIGHT_ALT; break; default: goto noflagchange; } if (release) s_shiftState &= ~(flag); else s_shiftState |= flag; /* * Shift, control and alt keys don't have to be * queued, flags will be set! */ goto done; noflagchange: /* Format the new keycode */ if (shift) keycode |= KEY_SHIFT_FLAG; if ((s_shiftState & CTRL_MASK) != 0) keycode |= KEY_CTRL_FLAG; if ((s_shiftState & ALT_MASK) != 0) keycode |= KEY_ALT_FLAG; if (release) keycode |= KEY_RELEASE_FLAG; /* Put the keycode in the buffer */ Enqueue_Keycode(keycode); /* Wake up event consumers */ Wake_Up(&s_waitQueue); /* * Pick a new thread upon return from interrupt * (hopefully the one waiting for the keyboard event) */ g_needReschedule = true; } done: End_IRQ(state); }