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, &regs, &regs);
        return regs.h.al;
    } else { /* new by Eric 11/2002 */

        regs.h.ah = 0x12; /* extended shift: AL as above... */
        int86(KEYBRD, &regs, &regs);
        /* 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

Reply via email to