// i8042 controller driver. This file owns PS/2 controller commands, IRQ handling, and packet decoding. #include "ps2.h" void Ps2Pause(void) { _mm_pause(); } void Ps2WaitInput(void) { int timeout = 100000; while ((__inbyte(PS2_STAT) & PS2_STAT_IN_FULL) && --timeout) { Ps2Pause(); } } bool Ps2WaitOutput(void) { int timeout = 5000000; while (!(__inbyte(PS2_STAT) & PS2_STAT_OUT_FULL) && --timeout) { Ps2Pause(); } return timeout != 0; } void Ps2FlushOutput(void) { int timeout = 100000; while ((__inbyte(PS2_STAT) & PS2_STAT_OUT_FULL) && --timeout) { (void)__inbyte(PS2_DATA); } } uint8_t Ps2ReadData(void) { if (!Ps2WaitOutput()) return 0xFFu; return __inbyte(PS2_DATA); } void Ps2WriteCommand(uint8_t command) { Ps2WaitInput(); __outbyte(PS2_CMD, command); } void Ps2WriteData(uint8_t data) { Ps2WaitInput(); __outbyte(PS2_DATA, data); } uint8_t Ps2ReadCommandByte(void) { Ps2WriteCommand(0x20u); return Ps2ReadData(); } void Ps2WriteCommandByte(uint8_t commandByte) { Ps2WriteCommand(0x60u); Ps2WriteData(commandByte); } bool Ps2SendKeyboard(uint8_t byte) { Ps2WriteData(byte); return Ps2ReadData() == 0xFAu; } bool Ps2SendMouse(uint8_t byte) { Ps2WriteCommand(0xD4u); Ps2WriteData(byte); return Ps2ReadData() == 0xFAu; }