/*
DOS interrupt-based keyboard driver.
-Copyright (C) 2013 John Tsiombikas <nuclear@member.fsf.org>
+Copyright (C) 2013-2023 John Tsiombikas <nuclear@member.fsf.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "keyb.h"
#include "scancode.h"
-#include "inttypes.h"
+#include "sizeint.h"
#include "dosutil.h"
-#define KB_INTR 0x9
-#define KB_PORT 0x60
+#define KEY_INTR 0x9
+#define KEY_PORT 0x60
#define PIC1_CMD_PORT 0x20
#define OCW2_EOI (1 << 5)
static void INTERRUPT kbintr();
-static int *buffer;
-static int buffer_size, buf_ridx, buf_widx;
+#define BUFSIZE 64
+static int buffer[BUFSIZE];
+static int buf_ridx, buf_widx;
static int last_key;
static unsigned int num_pressed;
-static unsigned char keystate[256];
+static unsigned char keystate[512];
-#define ADVANCE(x) ((x) = ((x) + 1) % buffer_size)
+#define ADVANCE(x) ((x) = ((x) + 1) & (BUFSIZE - 1))
-int kb_init(int bufsz)
+void kb_init(void)
{
if(DONE_INIT) {
- fprintf(stderr, "keyboard driver already initialized!\n");
- return 0;
+ errormsg("keyboard driver already initialized!\n");
+ return;
}
- buffer_size = bufsz;
- if(buffer_size && !(buffer = malloc(buffer_size * sizeof *buffer))) {
- fprintf(stderr, "failed to allocate input buffer, continuing without\n");
- buffer_size = 0;
- }
buf_ridx = buf_widx = 0;
last_key = -1;
/* set our interrupt handler */
_disable();
#ifdef __WATCOMC__
- prev_handler = _dos_getvect(KB_INTR);
- _dos_setvect(KB_INTR, kbintr);
+ prev_handler = _dos_getvect(KEY_INTR);
+ _dos_setvect(KEY_INTR, kbintr);
#endif
#ifdef __DJGPP__
- _go32_dpmi_get_protected_mode_interrupt_vector(KB_INTR, &prev_intr);
+ _go32_dpmi_get_protected_mode_interrupt_vector(KEY_INTR, &prev_intr);
intr.pm_offset = (intptr_t)kbintr;
intr.pm_selector = _go32_my_cs();
_go32_dpmi_allocate_iret_wrapper(&intr);
- _go32_dpmi_set_protected_mode_interrupt_vector(KB_INTR, &intr);
+ _go32_dpmi_set_protected_mode_interrupt_vector(KEY_INTR, &intr);
#endif
_enable();
-
- return 0;
}
void kb_shutdown(void)
/* restore the original interrupt handler */
_disable();
#ifdef __WATCOMC__
- _dos_setvect(KB_INTR, prev_handler);
+ _dos_setvect(KEY_INTR, prev_handler);
#endif
#ifdef __DJGPP__
- _go32_dpmi_set_protected_mode_interrupt_vector(KB_INTR, &prev_intr);
+ _go32_dpmi_set_protected_mode_interrupt_vector(KEY_INTR, &prev_intr);
_go32_dpmi_free_iret_wrapper(&intr);
#endif
_enable();
-
- free(buffer);
}
int kb_isdown(int key)
{
switch(key) {
- case KB_ANY:
+ case KEY_ANY:
return num_pressed;
- case KB_ALT:
- return keystate[KB_LALT] + keystate[KB_RALT];
+ case KEY_ALT:
+ return keystate[KEY_LALT] + keystate[KEY_RALT];
- case KB_CTRL:
- return keystate[KB_LCTRL] + keystate[KB_RCTRL];
+ case KEY_CTRL:
+ return keystate[KEY_LCTRL] + keystate[KEY_RCTRL];
+
+ case KEY_SHIFT:
+ return keystate[KEY_LSHIFT] + keystate[KEY_RSHIFT];
}
if(isalpha(key)) {
if(buffer) {
/* go back a place */
if(--buf_ridx < 0) {
- buf_ridx += buffer_size;
+ buf_ridx += BUFSIZE;
}
/* if the write end hasn't caught up with us, go back one place
int key, c, press;
static int ext;
- code = inp(KB_PORT);
+ code = inp(KEY_PORT);
if(code == 0xe0) {
ext = 1;
ext = 0;
} else {
key = scantbl[code];
- c = (keystate[KB_LSHIFT] | keystate[KB_RSHIFT]) ? scantbl_shift[code] : key;
+ c = (keystate[KEY_LSHIFT] | keystate[KEY_RSHIFT]) ? scantbl_shift[code] : key;
}
- if(press) {
+ if(press && !keystate[key]) {
/* append to buffer */
last_key = c;
- if(buffer_size > 0) {
- buffer[buf_widx] = c;
- ADVANCE(buf_widx);
- /* if the write end overtook the read end, advance the read end
- * too, to discard the oldest keypress from the buffer
- */
- if(buf_widx == buf_ridx) {
- ADVANCE(buf_ridx);
- }
+ buffer[buf_widx] = c;
+ ADVANCE(buf_widx);
+ /* if the write end overtook the read end, advance the read end
+ * too, to discard the oldest keypress from the buffer
+ */
+ if(buf_widx == buf_ridx) {
+ ADVANCE(buf_ridx);
}
}