#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include <conio.h>
#include <dos.h>
+
+#ifdef __WATCOMC__
#include <i86.h>
+#endif
+#ifdef __DJGPP__
+#include <dpmi.h>
+#include <go32.h>
+#include <pc.h>
+#endif
+
#include "keyb.h"
#include "scancode.h"
+#include "inttypes.h"
+#include "dosutil.h"
#define KB_INTR 0x9
#define KB_PORT 0x60
#define PIC1_CMD_PORT 0x20
#define OCW2_EOI (1 << 5)
+#ifdef __WATCOMC__
+#define INTERRUPT __interrupt __far
+
#define DONE_INIT (prev_handler)
+static void (INTERRUPT *prev_handler)();
+#endif
+
+#ifdef __DJGPP__
+#define INTERRUPT
-static void __interrupt __far kbintr();
+#define DONE_INIT prev_intr.pm_offset
+static _go32_dpmi_seginfo intr, prev_intr;
+#endif
-static void (__interrupt __far *prev_handler)();
+static void INTERRUPT kbintr();
static int *buffer;
static int buffer_size, buf_ridx, buf_widx;
/* set our interrupt handler */
_disable();
+#ifdef __WATCOMC__
prev_handler = _dos_getvect(KB_INTR);
_dos_setvect(KB_INTR, kbintr);
+#endif
+#ifdef __DJGPP__
+ _go32_dpmi_get_protected_mode_interrupt_vector(KB_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);
+#endif
_enable();
return 0;
/* restore the original interrupt handler */
_disable();
+#ifdef __WATCOMC__
_dos_setvect(KB_INTR, prev_handler);
+#endif
+#ifdef __DJGPP__
+ _go32_dpmi_set_protected_mode_interrupt_vector(KB_INTR, &prev_intr);
+ _go32_dpmi_free_iret_wrapper(&intr);
+#endif
_enable();
free(buffer);
case KB_CTRL:
return keystate[KB_LCTRL] + keystate[KB_RCTRL];
}
+
+ if(isalpha(key)) {
+ key = tolower(key);
+ }
return keystate[key];
}
+#ifdef __WATCOMC__
+void halt(void);
+#pragma aux halt = \
+ "sti" \
+ "hlt";
+#endif
+
+#ifdef __DJGPP__
+#define halt() asm volatile("sti\n\thlt\n\t")
+#endif
+
void kb_wait(void)
{
int key;
while((key = kb_getkey()) == -1) {
+#ifdef USE_HLT
/* put the processor to sleep while waiting for keypresses, but first
* make sure interrupts are enabled, or we'll sleep forever
*/
- __asm {
- sti
- hlt
- }
+ halt();
+#endif
}
kb_putback(key);
}
}
}
-static void __interrupt __far kbintr()
+static void INTERRUPT kbintr()
{
unsigned char code;
- int key, press;
+ int key, c, press;
+ static int ext;
code = inp(KB_PORT);
- if(code >= 128) {
+ if(code == 0xe0) {
+ ext = 1;
+ goto eoi;
+ }
+
+ if(code & 0x80) {
press = 0;
- code -= 128;
+ code &= 0x7f;
if(num_pressed > 0) {
num_pressed--;
num_pressed++;
}
- key = scantbl[code];
+ if(ext) {
+ key = scantbl_ext[code];
+ c = key;
+ ext = 0;
+ } else {
+ key = scantbl[code];
+ c = (keystate[KB_LSHIFT] | keystate[KB_RSHIFT]) ? scantbl_shift[code] : key;
+ }
if(press) {
/* append to buffer */
- last_key = key;
+ last_key = c;
if(buffer_size > 0) {
- buffer[buf_widx] = key;
+ 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
/* and update keystate table */
keystate[key] = press;
+eoi:
outp(PIC1_CMD_PORT, OCW2_EOI); /* send end-of-interrupt */
}