Hi!
As this is in context of EDIT, here are some EDIT 0.7d snippets :-)
In message.c function collect_events() we have:
- refresh the clock display, but only once per second,
and in a COUNTRY setting sensitive way :-)
- compatibility-friendly BIOS keyboard handling:
if ((sk = getshift()) != ShiftKeys) {
ShiftKeys = sk;
PostEvent(SHIFT_CHANGED, sk, 0);
if (sk & ALTKEY)
AltDown = TRUE;
}
- NO keyboard IRQ hooks in default compile-time settings!
if (keyhit()) {
int c = getkey(); /* ASCII, or (FKEY | scancode) */
AltDown = FALSE;
PostEvent(KEYBOARD, c, sk);
}
- mouse button and movement event handling
In message.c function dispatch_message() we have the call
to int 2a function 84 if the event queue is empty, in other
words: (EventQueueCtr == 0) && (MsgQueueCtr == 0) &&
(handshaking == 0) to save energy while EDIT is idle.
The message.c function SendMessage() also uses the keyboard:
case WAITKEYBOARD:
waitforkeyboard();
break;
and many mouse, cursor, window etc. related things.
In system.h we have:
#define waitforkeyboard() while (Xbioskey(1)) (void)Xbioskey(0)
#define bioskey _bios_keybrd
Finally, console.c contains:
/* ---- BIOS keyboard routines with 84 and 102 key keyboard support ---- */
int Xbioskey(int cmd)
{
static int keybase = -1;
union REGS kregs;
if (keybase < 0) {
volatile char far *kbtype = MK_FP(0x40,0x96); /* BIOS data flag */
keybase = ( ((*kbtype) & 0x10) != 0 ) ? 0x10 : 0;
/* 0 for 84 key XT mode, 0x10 for 102 key AT mode. */
/* (0x20 for 122 key mode, which is not used here) */
}
kregs.h.ah = (char) (keybase + cmd);
kregs.h.al = 0;
int86(0x16, &kregs, &kregs);
if ( (cmd == 1) && (kregs.x.flags & 0x40 /* zero flag */) )
return 0;
return kregs.x.ax;
}
So whether int 16 function 0/1 or 10/11 are used depends
on the 40:96 bit 4 flag freshly read for each BIOS call.
/* ---- Test for keystroke ---- */
BOOL keyhit(void)
{
#if MSC | WATCOM
return (kbhit() ? TRUE : FALSE);
#else
return (Xbioskey(1) != 0) ? TRUE : FALSE;
#endif
}
As you see, only Turbo C relies on Xbioskey, the other
dialects hope that kbhit of the C library is good enough!
Showing only the default variant here of getkey() here:
/* ---- Read a keystroke ---- */
int getkey(void)
{
unsigned int c;
unsigned int theShift;
unsigned int theScan;
c = Xbioskey(0); /* fetch key */
theShift = getshift();
theScan = c >> 8; /* scan code */
c = c & 0xff; /* ASCII code or 0 of 0xe0 */
if ( theShift & (LEFTSHIFT|RIGHTSHIFT) ) {
/* BIOS normally calls shift-ins "ins" and shift-del "del" */
if (theScan == 0x52) /* INS */
return CTRL_V; /* SHIFT_INS; */ /* shift-ins is paste,
ctrl-v */
if (theScan == 0x53) /* DEL */
return CTRL_X; /* SHIFT_DEL; */ /* shift-del is cut, ctrl-x */
} /* special SHIFT cases */
if ( (theShift & ALTKEY) && (theScan == 0x0e) ) /* Alt-BS */
return CTRL_Z; /* ALT_BS; */ /* alt-backspace is undo, ctrl-z */
if (theShift & CTRLKEY) {
if (theScan == 0x92) { /* ^ins / ^-numpad-Ins */
return CTRL_C; /* CTRL_INS; */ /* ctrl-ins is copy, ctrl-c */
}
} /* special CTRL cases */
if ( (c != 0) && (c != 0xe0) ) /* nonzero / nonnumpad ASCII
part? */
return c; /* then return only the ASCII
part */
/* Watch out: special case for Russian non-numpad "0xe0 ASCII" */
if ( (c == 0xe0) && (theScan == 0) )
return 0xe0;
return (FKEY | theScan); /* else return scancode and a flag */
}
As with Xbioskey, whether int 16 function 2 or 12 is used
depends on the 40:96 bit 4 flag for every single BIOS call,
with some special treatment for right Alt, in Germany AltGr:
/* ---------- read the keyboard shift status --------- */
int getshift(void)
{
static int enhkeyb = -1; /* 1 for an enhanced keyboard */
static char far *kbtype = MK_FP(0x40,0x96);
/* new check method (10/2003) */
if (enhkeyb == -1) { /* if we do not yet know... */
enhkeyb = (((*kbtype) & 0x10) != 0) ? 1 : 0; /* read BIOS data
flag! */
} /* now enhkeyb is either 0 or 1 - Eric */
if (!enhkeyb) { /* old/new by Eric */
regs.h.ah = 2;
int86(KEYBRD, ®s, ®s);
return regs.h.al;
} else { /* new by Eric 11/2002 */
regs.h.ah = 0x12; /* extended shift: AL as above... */
int86(KEYBRD, ®s, ®s);
/* ignore SysRQ (Alt-PrtScr) and shift lock presses */
regs.x.ax &= 0x0fff;
/* treat RALT as NO ALT (but as AltGr): */
if (regs.x.ax & RALTKEY)
regs.x.ax &= ~ALTKEY;
return regs.x.ax;
}
}
Regards, Eric
PS: Note that beep() uses direct port 42/43/61 I/O, as
there is no BIOS way to do custom beeps. However, one
could use the BIOS TTY call to output a default beep.
Maybe it would be nice if beeps were user-selectable?
Also, short waiting does not idle the CPU yet:
static int far *clk = MK_FP(0x40,0x6c);
/* ------- macro to wait one clock tick -------- */
#define wait() { int now = *clk; while (now == *clk); }
_______________________________________________
Freedos-devel mailing list
Freedos-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freedos-devel