# UNDF: UNDF-2026-000001049 --- a/src/ikbd.c +++ b/src/ikbd.c @@ -218,6 +218,28 @@ static const struct { void (*pCallFunction)(void); } KeyboardCommands[] = { + /* Dispatch table built at init from KeyboardCommands[] for O(1) lookup. */ + /* See IKBD_InitDispatch() and IKBD_RunKeyboardCommand(). */ /* Known messages, counts include command byte */ { 0x80,2, IKBD_Cmd_Reset }, { 0x07,2, IKBD_Cmd_MouseAction }, @@ -258,6 +280,33 @@ static const struct { { 0xFF,0, NULL } /* Term */ }; +/* Dispatch table: indexed by command byte, holds index into KeyboardCommands[] + * or -1 for unknown commands. Built once by IKBD_InitDispatch(). */ +static int IKBDCmdIndex[256]; + +/** + * Build the O(1) command-dispatch index from KeyboardCommands[]. + * Called once during IKBD initialisation. + */ +static void IKBD_InitDispatch(void) +{ + int i; + for (i = 0; i < 256; i++) + IKBDCmdIndex[i] = -1; + for (i = 0; KeyboardCommands[i].Command != 0xFF; i++) + IKBDCmdIndex[KeyboardCommands[i].Command] = i; +} + /*----------------------------------------------------------------------*/ /* Variables/defines/functions used to transfer data between the */ @@ -830,6 +879,7 @@ void IKBD_Reset(bool bCold) /* Reset */ memset(&Keyboard, 0, sizeof(Keyboard)); + IKBD_InitDispatch(); + /* IKBD gets reset whenever the computer does */ IKBD_ResetKeyboardProcessor(); @@ -1854,22 +1904,22 @@ static void IKBD_RunKeyboardCommand(uint8_t aciabyte) { - int i=0; /* Write into our keyboard input buffer if it's not full yet */ if ( Keyboard.nBytesInInputBuffer < SIZE_KEYBOARDINPUT_BUFFER ) Keyboard.InputBuffer[Keyboard.nBytesInInputBuffer++] = aciabyte; - /* Now check bytes to see if we have a valid/in-valid command string set */ - while (KeyboardCommands[i].Command!=0xff) - { - /* Found command? */ - if (KeyboardCommands[i].Command==Keyboard.InputBuffer[0]) - { - /* If the command is complete (with its possible parameters) we can execute it */ - /* Else, we wait for the next bytes until the command is complete */ - if (KeyboardCommands[i].NumParameters==Keyboard.nBytesInInputBuffer) - { - /* Any new valid command will unpause the output (if command 0x13 was used) */ - Keyboard.PauseOutput = false; - - CALL_VAR(KeyboardCommands[i].pCallFunction); - Keyboard.nBytesInInputBuffer = 0; /* Clear input buffer after processing a command */ - } - - return; - } - - i++; - } - - /* Command not known, reset buffer(IKBD assumes a NOP) */ - Keyboard.nBytesInInputBuffer = 0; + /* O(1) dispatch: look up command byte directly, no linear scan needed. */ + { + int idx = IKBDCmdIndex[(unsigned char)Keyboard.InputBuffer[0]]; + if (idx >= 0) + { + /* If the command is complete (with its possible parameters) we can execute it */ + /* Else, we wait for the next bytes until the command is complete */ + if (KeyboardCommands[idx].NumParameters==Keyboard.nBytesInInputBuffer) + { + /* Any new valid command will unpause the output (if command 0x13 was used) */ + Keyboard.PauseOutput = false; + + CALL_VAR(KeyboardCommands[idx].pCallFunction); + Keyboard.nBytesInInputBuffer = 0; /* Clear input buffer after processing a command */ + } + + return; + } + + /* Command not known, reset buffer (IKBD assumes a NOP) */ + Keyboard.nBytesInInputBuffer = 0; + } }