Previous Next Table of Contents

7. New Keyboard Code

This file describes the new keyboard code which was written in late '95 for scottb's dosemu-0.61, and adapted to the mainstream 0.63 in mid-'96.

It was last updated by R.Zimmermann <zimmerm@mathematik.uni-marburg.de> on 18 Sep 96 and updated by Hans <lermen@fgan.de> on 17 Jan 97. ( correction notes marked *HH -- Hans )

7.1 Whats New

What's new in the new keyboard code? A lot.

To the user:

To the dosemu hacker:

There is a compile-time option NEW_KBD_CODE (on by default) to activate the new keyboard code. The old stuff is still in there, but I haven't recently checked whether it still works, or even compiles. Once the new code is reasonably well tested I'll remove it. ( *HH: the old code is made workeable and remains ON per default, it will stay maintained for a while, so we can easily check where the bugs come from )

Just like the old keyboard code, we still have the rawkeyboard=on/off and keybint=on/off modes.

7.2 Status

Almost everything seems to work well now.

The keyboard server should now quite accurately emulate all key combinations described the 'MAKE CODES' & 'SCAN CODES' tables of HelpPC 2.1, which I used as a reference.

See below for a list of known bugs.

What I need now is YOUR beta-testing... please go ahead and try if all your application's wierd key combinations work, and let me know if they don't.

7.3 Keyboard server interface

This is all you should need to know if you just want to send keystrokes to DOS.

Use the functions

You may also read (but not write!) the variable 'shiftstate' if necessary.

ehm... see the DANG comments in base/newkbd-server.c for more information...

NOTE: the server's queue is limited to a relatively small number of keyboard events (currently 15). IMO, it is not a good idea to let the queue be arbitrarily long, as this would render the behaviour more incontrollable if the user typed a lot of mad things while a dos program wasn't polling the keyboard.

For pasting, there is special support in base/keyboard/keyb_clients.c which runs on top of the server.

7.4 Keyboard server structure

[NOTE: you won't need to read this unless you actually want to modify the keyboard server code. In that case, however, you MUST read it!]

[Note: I'll have to update this. The queue backend works somewhat different now.]

The central data structure of the keyboard server is the dosemu keyboard queue (to be distinguished from the bios keyboard buffer, which is run by int09 and int16).

The keyboard server code can be largely divided into the `queue frontend' (serv_xlat.c, serv_maps.c), which does keycode translation, and the `queue backend' (serv_backend.c, serv_8042.c), which does the interfacing to DOS. The two sides communicate only through the queue.

Each queue entry holds a data structure corresponding to (mostly) one keypress or release event. [The exception are the braindead 0xe02a / 0xe0aa shift key emulation codes the keyboard processor 'decorates' some kinds of keyboard events with, which for convenience are treated as seperate events.]

Each queue entry holds a up to 4 bytes of raw keycodes for the port 60h emulation, along with a 2-byte translated int16h keycode and the shift state after this event was processed. Note that the bios_key field can be empty (=0), e.g. for shift keys, while the raw field should always contain something.

queue handling functions

Accordingly, the keyboard code is largely divided into two parts,

The Front End


 putrawkey() -------->----+
      \   \               |
       \   v              |
        \  translate()    |
         \     |          |
          \    v          \    (t_rawkeycode[4])      /---QUEUE----\
     /->---\---|-----------*------------------------> [ raw        ]
    /       \  \  (t_keysym+char)                     [            ]
 putkey() ->-\--*--------------> make_bios_code() --> [ bios_key   ]
    \         \                                       [            ]
     \         v                           /--------> [ shiftstate ]
      \---> do_shift_keys()               /           \------------/
                |                        /
                v        (t_shiftstate) /
            [shiftstate]---------------/


--------->  data flow (&calls, sometimes)
.........>  calls

Functions in serv_xlat.c

Any keyboard client or other part of dosemu wishing to send keyboard events to DOS will do so by calling one of the functions putrawkey, putkey, and putkey_shift.

putrawkey

is called with a single raw scancode byte. Scancodes from subsequent calls are assembled into complete keyboard events, translated and placed into the queue.

putkey & others

...to be documented.

The Back End

Queue Back End in keybint=on mode


                   EMULATOR SIDE        |    x86 SIDE
                                        |
                      ....[through PIC].|....................
                      :                 |           :        v
QUEUE      .....> out_b_8042() --> [ port 60h ] ----:---> other_int9_handler
|         :                             |        \  `.......    (:) (|)
|         :                             |         \         v   (v) (|)
+->int_chk_q()-> bios_buffer----> [ get_bios_key ]-----> default_int9_handler
      ^  \                           :  |                   |       (|)
      :   \----> shiftstate_buffer   :  |                   v       (v)
      :               |         .....:  |               bios keyb buffer
      :               v        v        |
      :          copy_shift_state() ----+-------------> bios shiftstate
      :                                 |
      :                                 |
      :                                 |
    backend_run()                       |

Abbreviations:
int_chk_q() = int_check_queue()
out_b_8042() = output_byte_8042()

Queue Back End in keybint=off mode

                  EMULATOR SIDE         |    x86 SIDE
                                        |
             kbd_process()              |
                  :     :               |
                  :     v               |
 QUEUE -----------:--> put_keybuf() ----+-------------> bios keyb buffer
     \            v                     |
      \--------> copy_shift_state() ----+-------------> bios shiftstate
                                        |
                                        |   
                                        |

Functions in newkbd-server.c

Transfer of the keyboard events from the dosemu queue to DOS is done in two completely different ways, depending on the keybint setting in dosemu.conf:

keybint=off

kbd_process() simply reads the queue until it finds a bios keycode (as we're not interested in raw scancodes without int9 emulation), which it stores in the bios keyboard buffer, while also copying the shift state to the appropriate bios variables.

keybint=on

As soon as a key is stored into the empty queue, kbd_process() triggers IRQ1 through the PIC emulation, which some time later will call do_irq1().

do_irq1() will prepare for the interrupt execution by reading from the queue and storing the values in the variables raw_buffer, shiftstate_buffer, and bios_buffer, and then call run_irq() to run the actual DOS interrupt handler.

again, there are two cases:

This is not a complete documentation. If you actually want to hack the keyboard server, you can't avoid reading the code, I'm afraid ;-)

7.5 Known bugs & incompatibilites

7.6 Changes from 0.61.10

7.7 TODO


Previous Next Table of Contents