java-topology/defects/hatari-0001/patch/hatari-0001.patch

101 lines
3.3 KiB
Diff

# 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;
+ }
}