USHORT IOReadW(USHORT Port) { if (IoPortProc[Port].hVdd == INVALID_HANDLE_VALUE && IoPortProc[Port].IoHandlers.InW) { return IoPortProc[Port].IoHandlers.InW(Port); } else if (IoPortProc[Port].hVdd != NULL && IoPortProc[Port].hVdd != INVALID_HANDLE_VALUE && IoPortProc[Port].VddIoHandlers.inw_handler) { USHORT Data; ASSERT(Port <= MAXWORD); IoPortProc[Port].VddIoHandlers.inw_handler(Port, &Data); return Data; } else { UCHAR Low, High; // FIXME: Is it ok on Little endian and Big endian ?? Low = IOReadB(Port); High = IOReadB(Port + sizeof(UCHAR)); return MAKEWORD(Low, High); } }
VOID IOReadStrB(USHORT Port, PUCHAR Buffer, ULONG Count) { if (IoPortProc[Port].hVdd == INVALID_HANDLE_VALUE && IoPortProc[Port].IoHandlers.InsB) { IoPortProc[Port].IoHandlers.InsB(Port, Buffer, Count); } else if (IoPortProc[Port].hVdd != NULL && IoPortProc[Port].hVdd != INVALID_HANDLE_VALUE && IoPortProc[Port].VddIoHandlers.insb_handler) { ASSERT(Port <= MAXWORD); ASSERT(Count <= MAXWORD); IoPortProc[Port].VddIoHandlers.insb_handler(Port, Buffer, (WORD)Count); } else { while (Count--) *Buffer++ = IOReadB(Port); } }
// Keyboard IRQ 1 static VOID WINAPI BiosKeyboardIrq(LPWORD Stack) { BOOLEAN SkipScanCode; BYTE ScanCode, VirtualKey; WORD Character; /* * Get the scan code from the PS/2 port, then call the * INT 15h, AH=4Fh Keyboard Intercept function to try to * translate the scan code. CF must be set before the call. * In return, if CF is set we continue processing the scan code * stored in AL, and if not, we skip it. */ BYTE CF; WORD AX; CF = getCF(); AX = getAX(); setCF(1); setAL(IOReadB(PS2_DATA_PORT)); setAH(0x4F); Int32Call(&BiosContext, BIOS_MISC_INTERRUPT); /* Retrieve the modified scan code in AL */ SkipScanCode = (getCF() == 0); ScanCode = getAL(); setAX(AX); setCF(CF); /* Check whether CF is clear. If so, skip the scan code. */ if (SkipScanCode) goto Quit; /* Get the corresponding virtual key code */ VirtualKey = MapVirtualKey(ScanCode & 0x7F, MAPVK_VSC_TO_VK); /* Check if this is a key press or release */ if (!(ScanCode & (1 << 7))) { /* Key press */ if (VirtualKey == VK_NUMLOCK || VirtualKey == VK_CAPITAL || VirtualKey == VK_SCROLL || VirtualKey == VK_INSERT) { /* For toggle keys, toggle the lowest bit in the keyboard map */ BiosKeyboardMap[VirtualKey] ^= ~(1 << 0); } /* Set the highest bit */ BiosKeyboardMap[VirtualKey] |= (1 << 7); /* Find out which character this is */ Character = 0; if (ToAscii(VirtualKey, ScanCode, BiosKeyboardMap, &Character, 0) == 0) { /* Not ASCII */ Character = 0; } /* Push it onto the BIOS keyboard queue */ BiosKbdBufferPush(MAKEWORD(Character, ScanCode)); } else { /* Key release, unset the highest bit */ BiosKeyboardMap[VirtualKey] &= ~(1 << 7); } /* Clear the keyboard flags */ Bda->KeybdShiftFlags = 0; /* Set the appropriate flags based on the state */ if (BiosKeyboardMap[VK_RSHIFT] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_RSHIFT; if (BiosKeyboardMap[VK_LSHIFT] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_LSHIFT; if (BiosKeyboardMap[VK_CONTROL] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_CTRL; if (BiosKeyboardMap[VK_MENU] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_ALT; if (BiosKeyboardMap[VK_SCROLL] & (1 << 0)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_SCROLL_ON; if (BiosKeyboardMap[VK_NUMLOCK] & (1 << 0)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_NUMLOCK_ON; if (BiosKeyboardMap[VK_CAPITAL] & (1 << 0)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_CAPSLOCK_ON; if (BiosKeyboardMap[VK_INSERT] & (1 << 0)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_INSERT_ON; if (BiosKeyboardMap[VK_RMENU] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_RALT; if (BiosKeyboardMap[VK_LMENU] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_LALT; if (BiosKeyboardMap[VK_SNAPSHOT] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_SYSRQ; if (BiosKeyboardMap[VK_PAUSE] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_PAUSE; if (BiosKeyboardMap[VK_SCROLL] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_SCROLL; if (BiosKeyboardMap[VK_NUMLOCK] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_NUMLOCK; if (BiosKeyboardMap[VK_CAPITAL] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_CAPSLOCK; if (BiosKeyboardMap[VK_INSERT] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_INSERT; DPRINT("BiosKeyboardIrq - Character = 0x%X, ScanCode = 0x%X, KeybdShiftFlags = 0x%X\n", Character, ScanCode, Bda->KeybdShiftFlags); Quit: PicIRQComplete(Stack); }
VOID FASTCALL EmulatorReadIo(PFAST486_STATE State, USHORT Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize) { UNREFERENCED_PARAMETER(State); if (DataSize == 0 || DataCount == 0) return; if (DataSize == sizeof(UCHAR)) { if (DataCount == 1) *(PUCHAR)Buffer = IOReadB(Port); else IOReadStrB(Port, Buffer, DataCount); } else if (DataSize == sizeof(USHORT)) { if (DataCount == 1) *(PUSHORT)Buffer = IOReadW(Port); else IOReadStrW(Port, Buffer, DataCount); } else if (DataSize == sizeof(ULONG)) { if (DataCount == 1) *(PULONG)Buffer = IOReadD(Port); else IOReadStrD(Port, Buffer, DataCount); } else { PUCHAR Address = (PUCHAR)Buffer; while (DataCount--) { ULONG CurrentPort = Port; ULONG Count; UCHAR NewDataSize = DataSize; /* Read dword */ Count = NewDataSize >> 2; // NewDataSize / sizeof(ULONG); NewDataSize = NewDataSize & 3; // NewDataSize % sizeof(ULONG); while (Count--) { *(PULONG)Address = IOReadD(CurrentPort); CurrentPort += sizeof(ULONG); Address += sizeof(ULONG); } /* Read word */ Count = NewDataSize >> 1; // NewDataSize / sizeof(USHORT); NewDataSize = NewDataSize & 1; // NewDataSize % sizeof(USHORT); while (Count--) { *(PUSHORT)Address = IOReadW(CurrentPort); CurrentPort += sizeof(USHORT); Address += sizeof(USHORT); } /* Read byte */ Count = NewDataSize; // NewDataSize / sizeof(UCHAR); // NewDataSize = NewDataSize % sizeof(UCHAR); while (Count--) { *(PUCHAR)Address = IOReadB(CurrentPort); CurrentPort += sizeof(UCHAR); Address += sizeof(UCHAR); } } } }