  The DOSEMU Alterer Novices Guide DANG
  Alistair MacDonald, alistair@slitesys.demon.co.uk
  For DOSEMU v0.66 pl0.0

  This Document is the DOSEMU Alterer Novices Guide. It is known as the
  DANG.
  ______________________________________________________________________

  Table of Contents:

  1.      Introduction

  2.      The Main group of Modules

  2.1.    dos.c Information

  2.1.1.  Functions in dos.c

  2.1.1.1.        dosemu

  2.2.    emu.c Information

  2.2.1.  Functions in emu.c

  2.2.1.1.        jmp_emulate

  2.2.1.2.        SIG_int

  2.2.1.3.        emulate

  2.2.2.  Remarks in emu.c

  2.3.    include/emu.h Information

  2.3.1.  Functions in include/emu.h

  2.3.1.1.        NEWSETQSIG

  2.3.2.  Remarks in include/emu.h

  3.      The DPMI group of Modules

  3.1.    dosext/dpmi/dpmi.c Information

  3.1.1.  Functions in dosext/dpmi/dpmi.c

  3.1.1.1.        dpmi_control

  3.1.1.2.        run_pm_int

  3.1.1.3.        do_default_cpu_exception

  3.1.1.4.        do_cpu_exception

  3.1.1.5.        dpmi_fault

  3.1.2.  Remarks in dosext/dpmi/dpmi.c

  3.1.3.  Items for Fixing in dosext/dpmi/dpmi.c

  3.1.4.  New Ideas for dosext/dpmi/dpmi.c

  4.      The Video group of Modules

  4.1.    env/video/vc.c Information

  4.2.    env/video/video.c Information

  4.2.1.  Functions in env/video/video.c

  4.2.1.1.        video_init

  4.2.2.  Remarks in env/video/video.c

  4.3.    env/video/X.c Information

  4.3.1.  Functions in env/video/X.c

  4.3.1.1.        get_vga256_colors

  4.3.1.2.        X_close

  4.3.1.3.        X_setmode

  4.3.1.4.        X_change_mouse_cursor

  4.3.1.5.        X_redraw_screen

  4.3.1.6.        X_update_screen

  4.3.1.7.        set_mouse_position

  4.4.    env/video/console.c Information

  4.5.    env/video/dualmon.c Information

  4.5.1.  Functions in env/video/dualmon.c

  4.5.1.1.        MDA_init

  4.5.2.  Remarks in env/video/dualmon.c

  4.6.    env/video/et4000.c Information

  4.7.    env/video/hgc.c Information

  4.8.    base/bios/int10.c Information

  4.9.    env/video/s3.c Information

  4.10.   env/video/terminal.c Information

  4.11.   env/video/trident.c Information

  4.12.   env/video/vga.c Information

  5.      The Keyboard group of Modules

  5.1.    base/keyboard/Xkeyb.c Information

  5.2.    base/keyboard/keymaps.c Information

  5.2.1.  Remarks in base/keyboard/keymaps.c

  5.3.    base/keyboard/slang-termio.c Information

  6.      The Misc group of Modules

  6.1.    dosext/misc/emm.c Information

  6.2.    dosext/misc/xms.c Information

  6.3.    arch/linux/async/sigsegv.c Information

  6.3.1.  Functions in arch/linux/async/sigsegv.c

  6.3.1.1.        dosemu_fault

  6.3.1.2.        print_exception_info

  6.4.    include/int.h Information

  6.5.    include/ports.h Information

  6.6.    base/misc/dosio.c Information

  6.7.    base/misc/disks.c Information

  6.7.1.  Functions in base/misc/disks.c

  6.7.1.1.        disk_init

  6.8.    emi-i386/cpu.c Information

  6.9.    dev/misc/lpt.c Information

  7.      The Serial group of Modules

  7.1.    base/serial/ser_defs.h Information

  7.1.1.  Remarks in base/serial/ser_defs.h

  7.2.    base/serial/ser_init.c Information

  7.2.1.  Maintainers

  7.2.2.  Functions in base/serial/ser_init.c

  7.2.2.1.        serial_init

  7.2.3.  Items for Fixing in base/serial/ser_init.c

  7.3.    base/serial/ser_ports.c Information

  7.3.1.  Functions in base/serial/ser_ports.c

  7.3.1.1.        do_serial_in

  7.3.1.2.        do_serial_out

  7.3.2.  Items for Fixing in base/serial/ser_ports.c

  7.4.    base/serial/ser_irq.c Information

  7.4.1.  Functions in base/serial/ser_irq.c

  7.4.1.1.        serial_int_engine

  7.4.1.2.        pic_serial_run

  7.4.1.3.        serial_run

  7.4.2.  Remarks in base/serial/ser_irq.c

  7.4.3.  Items for Fixing in base/serial/ser_irq.c

  8.      The Mouse group of Modules

  8.1.    base/mouse/mouse.c Information

  8.1.1.  Functions in base/mouse/mouse.c

  8.1.1.1.        mouse_init

  9.      The Bios group of Modules

  9.1.    base/bios/bios.S Information

  10.     The PIC group of Modules

  10.1.   dev/pic/pic.c Information

  10.2.   devpic/pic.h Information

  11.     The Sound group of Modules

  11.1.   dosext/sound/sound.c Information

  11.1.1. Maintainers

  11.1.2. Functions in dosext/sound/sound.c

  11.1.2.1.       sb_io_read

  11.1.2.2.       adlib_io_read

  11.1.2.3.       mpu401_io_read

  11.1.2.4.       sb_io_write

  11.1.2.5.       sb_dsp_write

  11.1.3. Remarks in dosext/sound/sound.c

  11.1.4. Items for Fixing in dosext/sound/sound.c

  12.     And Finally ...
  ______________________________________________________________________

  11..  IInnttrroodduuccttiioonn

  This document is the preliminary draft of a manual to help people
  understand the inner workings of dosemu.  It is the goal of this
  document to create new dosemu hackers.  This concept was inspired by
  the linux kernel hackers guide.

  This Guide was concieved and originally written by "Corey Sweeney"
  <corey@interaccess.com>. It has been completely revised. It is now
  generated automatically directly from the source code. Special thanks
  to "James B. MacLean" <macleajb@ednet.ns.ca> for supplying the
  original information. (It was mostly ripped out of a mail message.)
  "Jochen Hein" has made many useful comments & suggestions.

  At the end if this document is a section detailing how this guide is
  put together. This may help you when trying to locate the relevant
  pieces of code. If you add new code, it would be useful if the
  relevant markers are added where appropriate.

  This file is a collective effort. If you don't like one of the
  explanations, or want to add anything, please send me something!

  22..  TThhee MMaaiinn ggrroouupp ooff MMoodduulleess

  These files are used to start DOSEMU as well as hold globally called
  functions and global vars.

  22..11..  ddooss..cc IInnffoorrmmaattiioonn

  22..11..11..  FFuunnccttiioonnss iinn ddooss..cc

  These are the functions defined in dos.c.

  22..11..11..11..  ddoosseemmuu

  Arguments are:

  +o  argc - Count of argumnents.

  +o  argc - Actual arguments.

     Function created by entry point into libdosemu. Called to jump into
     the emulate function of DOSEMU.

  22..22..  eemmuu..cc IInnffoorrmmaattiioonn

  22..22..11..  FFuunnccttiioonnss iinn eemmuu..cc

  These are the functions defined in emu.c.

  22..22..11..11..  jjmmpp__eemmuullaattee

  call the emulate function by way of the dll headers. Always make sure
  that this line is the first of emu.c and link emu.o as the first
  object file to the lib

  22..22..11..22..  SSIIGG__iinntt

  The IRQ numbers to monitor are taken from config.sillyint, each bit
  corresponding to one IRQ. The higher 16 bit are defining the use of
  SIGIO

  22..22..11..33..  eemmuullaattee

  Arguments are:

  +o  argc - Argument count.

  +o  argv - Arguments.

     Emulate gets called from dos.c. It initializes DOSEMU to prepare it
     for running in vm86 mode. This involves catching signals, preparing
     memory, calling all the initialization functions for the I/O
     subsystems (video/serial/etc...), getting the boot sector
     instructions and calling vm86().

  22..22..22..  RReemmaarrkkss iinn eemmuu..cc

  DOSEMU must not work within the 1 meg DOS limit, so start of code is
  loaded at a higher address, at some time this could conflict with
  other shared libs. If DOSEMU is compiled statically (without shared
  libs), and org instruction is used to provide the jump above 1 meg.

  22..33..  iinncclluuddee//eemmuu..hh IInnffoorrmmaattiioonn

  22..33..11..  FFuunnccttiioonnss iinn iinncclluuddee//eemmuu..hh

  These are the functions defined in include/emu.h.

  22..33..11..11..  NNEEWWSSEETTQQSSIIGG

  Arguments are:

  +o  sig - the signal to have a handler installed to.

  +o  fun - the signal handler function to install

     All signals that wish to be handled properly in context with the
     execution of vm86() mode, and signals that wish to use non-
     reentrant functions should add themselves to the SIGNALS_THAT_QUEUE
     define and use SETQSIG(). To that end they will also need to be set
     up in an order such as SIGIO.

  22..33..22..  RReemmaarrkkss iinn iinncclluuddee//eemmuu..hh

  The `vm86_struct` is used to pass all the necessary status/registers
  to DOSEMU when running in vm86 mode.

  -----

  We assume system call restarting... under linux 0.99pl8 and earlier,
  this was the default.  SA_RESTART was defined in 0.99pl8 to explicitly
  request restarting (and thus does nothing).  However, if this ever
  changes, I want to be safe

  -----

  DOSEMU keeps system wide configuration status in a structure called
  config.

  -----

  The var `fatalerr` can be given a true value at any time to have
  DOSEMU exit on the next return from vm86 mode.

  33..  TThhee DDPPMMII ggrroouupp ooff MMoodduulleess

  DPMI is Lutz's Baby. It's a really important part of the Emulator as
  far as we are concerned, since it will allow us to run so many more
  programs and, most importantly, bcc. This is the one thing that the
  WINE developers want that we haven't been able to give them.
  If you think you can help .... "Away you Go!" (Sorry to those non-UK
  folks ...  Thats a reference to a UK kids sports programme from my
  youth ... anyway ...  enough of this banter. You'll be wanting to know
  that this is all about DPMI ...)

  33..11..  ddoosseexxtt//ddppmmii//ddppmmii..cc IInnffoorrmmaattiioonn

  33..11..11..  FFuunnccttiioonnss iinn ddoosseexxtt//ddppmmii//ddppmmii..cc

  These are the functions defined in dosext/dpmi/dpmi.c.

  33..11..11..11..  ddppmmii__ccoonnttrrooll

  This function is similar to the vm86() syscall in the kernel and
  switches to dpmi code.

  33..11..11..22..  rruunn__ppmm__iinntt

  This routine is used for running protected mode hardware interrupts
  and software interrupts 0x1c, 0x23 and 0x24.  run_pm_int() switches to
  the locked protected mode stack and calls the handler. If no handler
  is installed the real mode interrupt routine is called.

  33..11..11..33..  ddoo__ddeeffaauulltt__ccppuu__eexxcceeppttiioonn

  This is the default CPU exception handler.  Exceptions 0, 1, 2, 3, 4,
  5 and 7 are reflected to real mode. All other exceptions are
  terminating the client (and may be dosemu too :-)).

  33..11..11..44..  ddoo__ccppuu__eexxcceeppttiioonn

  This routine switches to the locked protected mode stack, disables
  interrupts and calls the DPMI client exception handler.  If no handler
  is installed the default handler is called.

  33..11..11..55..  ddppmmii__ffaauulltt

  This is the brain of DPMI. All CPU exceptions are first reflected
  (from the signal handlers) to this code.  Exception from nonprivileged
  instructions INT XX, STI, CLI, HLT and from WINDOWS 3.1 are handled
  here.  All here unhandled exceptions are reflected to
  do_cpu_exception()

  33..11..22..  RReemmaarrkkss iinn ddoosseexxtt//ddppmmii//ddppmmii..cc

  We are caching ldt here for speed reasons and for Windows 3.1.  I
  would love to have an readonly ldt-alias (located in the first 16MByte
  for use with 16-Bit descriptors (WIN-LDT)). This is on my wish list
  for the kernel hackers (Linus mainly) :-))))))).

  -----

  DPMI is designed such that the stack change needs a task switch.  We
  are doing it via an SIGSEGV - instead of one task switch we have now
  four :-(.  Arrgh this is the point where I should start to include
  DPMI stuff in the kernel, but then we could include the rest of dosemu
  too.  Would Linus love this? I don't :-((((.  Anyway I would love to
  see first a working DPMI port, maybe we will later (with version 0.9
  or similar :-)) start with it to get a really fast dos
  emulator...............

  NOTE: Using DIRECT_DPMI_CONTEXT_SWITCH we avoid these 4  taskswitches
  actually doing 0. We don't need a 'physical' taskswitch (not having
  different TSS for us and DPMI), we only need a complete register
  (context) replacement. For back-switching, however, we need the
  sigcontext technique, so we build a proper sigcontext structure even
  for 'hand made taskswitch'. (Hans Lermen, June 1996)

  -----

  Hopefully the below LAR can serve as a replacement for the KERNEL_LDT,
  which we are abandoning now. Especially the 'accessed-bit' will get
  updated in the ldt-cache with the code below.  Most DPMI-clients
  fortunately _are_ using LAR also to get this info, however, some do
  not. Some of those which do _not_, atleast use the DPMI-GetDescriptor
  function, so this may solve the problem.  (Hans Lermen, July 1996)

  -----

  Handling of the virtual interrupt flag is still not correct and there
  are many open questions since DPMI specifications are unclear in this
  point.  An example: If IF=1 in protected mode and real mode code is
  called which is disabling interrupts via cli and returning to
  protected mode, is IF then still one or zero?  I guess I have to think
  a lot about this and to write a small dpmi client running under a
  commercial dpmi server :-).

  -----

  Here we handle all prefixes prior switching to the appropriate
  routines The exception CS:EIP will point to the first prefix that
  effects the the faulting instruction, hence, 0x65 0x66 is same as 0x66
  0x65.  So we collect all prefixes and remember them.  - Hans Lermen

  33..11..33..  IItteemmss ffoorr FFiixxiinngg iinn ddoosseexxtt//ddppmmii//ddppmmii..cc

  Should we really care for the Memory info?

  -----

  We shouldn't return to dosemu code if IF=0, but it helps - WHY?

  -----

  we should not change registers for hardware interrupts

  33..11..44..  NNeeww IIddeeaass ffoorr ddoosseexxtt//ddppmmii//ddppmmii..cc

  Simulate Local Descriptor Table for MS-Windows 3.1 must be read only,
  so if krnl386.exe/krnl286.exe try to write to this table, we will bomb
  into sigsegv() and and emulate direct ldt access

  44..  TThhee VViiddeeoo ggrroouupp ooff MMoodduulleess

  All of the Video handling code is in the "video" subdirectory.

  There is one file for each video card or chipset and the master file.
  To Add a new card, it needs a set of save & restore routines putting
  in a file here.

  44..11..  eennvv//vviiddeeoo//vvcc..cc IInnffoorrmmaattiioonn

  44..22..  eennvv//vviiddeeoo//vviiddeeoo..cc IInnffoorrmmaattiioonn

  44..22..11..  FFuunnccttiioonnss iinn eennvv//vviiddeeoo//vviiddeeoo..cc

  These are the functions defined in env/video/video.c.

  44..22..11..11..  vviiddeeoo__iinniitt

  Set pointer to correct structure of functions to initialize, close,
  etc... video routines.

  44..22..22..  RReemmaarrkkss iinn eennvv//vviiddeeoo//vviiddeeoo..cc

  Here the sleeping lion will be awoken and eat much of CPU time !!!

  The result of setting VM86_SCREEN_BITMAP (at state of Linux 1.1.56):
  Each vm86 call will set 32 pages of video mem RD-only (there may be
  1000000 per second) Write access to RD-only page results in page-fault
  (mm/memory.c), which will set a bit in current->screen_bitmap and
  calls do_wp_page() which does __get_free_page(GFP_KERNEL) but frees it
  immediatly, because copy-on-write is not neccessary and sets RD/WR for
  the page.  (this could happen 32000000 per second, if the CPU were
  fast enough) It would be better to get the DIRTY-bit directly from the
  page table, isn't it?  A special syscall in emumodule could do this.

  -----

  reserve_video_memory()

  This procedure is trying to eke out all the UMB blocks possible to
  maximize your memory under DOSEMU.  If you know about dual monitor
  setups, you can contribute by putting in the correct graphics page
  address values.

  44..33..  eennvv//vviiddeeoo//XX..cc IInnffoorrmmaattiioonn

  44..33..11..  FFuunnccttiioonnss iinn eennvv//vviiddeeoo//XX..cc

  These are the functions defined in env/video/X.c.

  44..33..11..11..  ggeett__vvggaa225566__ccoolloorrss

  Allocates a colormap for 256 color modes and initializes it.

  44..33..11..22..  XX__cclloossee

  Destroys the window, unloads font, pixmap and colormap.

  44..33..11..33..  XX__sseettmmooddee

  Resizes the window, also the graphical sizes/video modes.  remember
  the dos videomodi

  44..33..11..44..  XX__cchhaannggee__mmoouussee__ccuurrssoorr

  This function seems to be called each screen_update :( It is called in
  base/mouse/mouse.c:mouse_cursor(int) a lot for show and hide.

  44..33..11..55..  XX__rreeddrraaww__ssccrreeeenn

  Redraws the entire screen, also in graphics mode Used for expose
  events etc.  returns: nothing

  Arguments are:

  +o  none

  44..33..11..66..  XX__uuppddaattee__ssccrreeeenn

  Updates, also in graphics mode Graphics in X has to be smarter and
  improved returns: 0 - nothing updated 2 - partly updated 1 - whole
  update

  Arguments are:

  +o  none

  44..33..11..77..  sseett__mmoouussee__ppoossiittiioonn

  places the mouse on the right position Not tested in X with graphics
  returns: nothing

  Arguments are:

  +o  x,y - coordinates

  44..44..  eennvv//vviiddeeoo//ccoonnssoollee..cc IInnffoorrmmaattiioonn

  44..55..  eennvv//vviiddeeoo//dduuaallmmoonn..cc IInnffoorrmmaattiioonn

  44..55..11..  FFuunnccttiioonnss iinn eennvv//vviiddeeoo//dduuaallmmoonn..cc

  These are the functions defined in env/video/dualmon.c.

  44..55..11..11..  MMDDAA__iinniitt

  Initializes the monochrome card. First detects which monochrome card
  is used, because the Hercules RamFont and the Hercules InColor need
  one more register to be initialized. If there is no monochrome card at
  all, we just think there is one and poke an peek in the void.  After
  the detection the card is initialized.  returns: nothing

  Arguments are:

  +o  none

  44..55..22..  RReemmaarrkkss iinn eennvv//vviiddeeoo//dduuaallmmoonn..cc

  After MDA_init() the VGA is configured, something in video.c or
  console.c "reprograms" the monochrome card again in such a way that I
  always have to run hgc.com before I can use any program that uses the
  monochrome card. I've spent a day trying to find it, but I can't
  figure out. Something is writing to one of the following ports: 0x3b4,
  0x3b5, 0x3b8, 0x3b9, 0x3ba, 0x3bb, 0x3bf.  The problem occurs at (at
  least) the following 2 systems:

  - AMD 386DX40, Trident 9000/512Kb ISA, Hercules Graphics Card Plus -
  Intel 486DX2/66, Cirrus Logic 5426/1Mb VLB, Hercules clone

  The problem doesn't occur when I start dosemu from a telnet connection
  or from a VT100 terminal. (Erik Mouw, jakmouw@et.tudelft.nl)

  44..66..  eennvv//vviiddeeoo//eett44000000..cc IInnffoorrmmaattiioonn

  44..77..  eennvv//vviiddeeoo//hhggcc..cc IInnffoorrmmaattiioonn

  44..88..  bbaassee//bbiiooss//iinntt1100..cc IInnffoorrmmaattiioonn

  44..99..  eennvv//vviiddeeoo//ss33..cc IInnffoorrmmaattiioonn

  44..1100..  eennvv//vviiddeeoo//tteerrmmiinnaall..cc IInnffoorrmmaattiioonn

  44..1111..  eennvv//vviiddeeoo//ttrriiddeenntt..cc IInnffoorrmmaattiioonn

  44..1122..  eennvv//vviiddeeoo//vvggaa..cc IInnffoorrmmaattiioonn

  55..  TThhee KKeeyybbooaarrdd ggrroouupp ooff MMoodduulleess

  All of the Keyboard handling code is in the "keyboard" subdirectory.

  Latest addition is SLANG.

  55..11..  bbaassee//kkeeyybbooaarrdd//XXkkeeyybb..cc IInnffoorrmmaattiioonn

  55..22..  bbaassee//kkeeyybbooaarrdd//kkeeyymmaappss..cc IInnffoorrmmaattiioonn

  55..22..11..  RReemmaarrkkss iinn bbaassee//kkeeyybbooaarrdd//kkeeyymmaappss..cc

  The DEAD codes must refer to keys that don't exist on any language
  keyboard. I hope nobody has a smily face key :-) dead_key_table is a
  list of the dead keys supported. They must be placed on the correct
  key in the keymaps above. See key_map_es_latin1.

  -----

  dos850_dead_map consists of the triple, {deadkey, letter, result}.  It
  should be correct for all the code page 850 users (Western Europe).
  If you uses a different code page, please create a map!  Jon Tombs
  jon@gtex02.us.es

  55..33..  bbaassee//kkeeyybbooaarrdd//ssllaanngg--tteerrmmiioo..cc IInnffoorrmmaattiioonn

  66..  TThhee MMiisscc ggrroouupp ooff MMoodduulleess

  These are the remaining important files, that do not really fit into
  another group. These should not be dismissed as unimportant - rather,
  they are often amongst the most important.

  66..11..  ddoosseexxtt//mmiisscc//eemmmm..cc IInnffoorrmmaattiioonn

  66..22..  ddoosseexxtt//mmiisscc//xxmmss..cc IInnffoorrmmaattiioonn

  66..33..  aarrcchh//lliinnuuxx//aassyynncc//ssiiggsseeggvv..cc IInnffoorrmmaattiioonn

  66..33..11..  FFuunnccttiioonnss iinn aarrcchh//lliinnuuxx//aassyynncc//ssiiggsseeggvv..cc

  These are the functions defined in arch/linux/async/sigsegv.c.

  66..33..11..11..  ddoosseemmuu__ffaauulltt

  All CPU exceptions (except 13=general_protection from V86 mode, which
  is directly scanned by the kernel) are handled here.

  66..33..11..22..  pprriinntt__eexxcceeppttiioonn__iinnffoo

  Prints information about an exception: exception number, error code,
  address, reason, etc.

  66..44..  iinncclluuddee//iinntt..hh IInnffoorrmmaattiioonn

  66..55..  iinncclluuddee//ppoorrttss..hh IInnffoorrmmaattiioonn

  66..66..  bbaassee//mmiisscc//ddoossiioo..cc IInnffoorrmmaattiioonn

  66..77..  bbaassee//mmiisscc//ddiisskkss..cc IInnffoorrmmaattiioonn

  66..77..11..  FFuunnccttiioonnss iinn bbaassee//mmiisscc//ddiisskkss..cc

  These are the functions defined in base/misc/disks.c.

  66..77..11..11..  ddiisskk__iinniitt

  Test by opening all floppies/hardrives configured.

  66..88..  eemmii--ii338866//ccppuu..cc IInnffoorrmmaattiioonn

  66..99..  ddeevv//mmiisscc//llpptt..cc IInnffoorrmmaattiioonn

  77..  TThhee SSeerriiaall ggrroouupp ooff MMoodduulleess

  This is the code that works our serial emulation. This needs to be
  very fast if we are to convince DOS that we have a very fast serial
  port.

  77..11..  bbaassee//sseerriiaall//sseerr__ddeeffss..hh IInnffoorrmmaattiioonn

  77..11..11..  RReemmaarrkkss iinn bbaassee//sseerriiaall//sseerr__ddeeffss..hh

  Extensions to serial debugging.

  SER_DEBUG_MAIN   (0 or 1) - extra debug output on the most critical
  information.

  SER_DEBUG_HEAVY   (0 or 1) - super-heavy extra debug output, including
  all ports reads and writes, and every character received and
  transmitted!

  SER_DEBUG_INTERRUPT   (0 or 1) - additional debug output related to
  serial interrupt code, including flagging serial interrupts, or PIC-
  driven code.

  SER_DEBUG_FOSSIL_RW   (0 or 1) - heavy FOSSIL debug output, including
  all reads and writes.

  SER_DEBUG_FOSSIL_STATUS   (0 or 1) - super-heavy FOSSIL debug output,
  including all status checks.

  You must recompile dosemu everytime one of these constants are
  modified.  Just type 'make' in the dosemu dir and it will recompile
  the changes only.

  -----

  IMPORTANT INFO about com[] variable array structure used in serial.c

  Most of the serial variables are stored in the com[] array.  The com[]
  array is a structure in itself.   Take a look at the about this.  Only
  the most commonly referenced global variables are listed here:
  config.num_ser         Number of serial ports active.
  com[x].base_port       The base port address of emulated serial port.
  com[x].real_comport    The COM port number.  com[x].interrupt
  The PIC interrupt level (based on IRQ number) com[x].mouse
  Flag  mouse (to enable extended features) com[x].fd              File
  descriptor for port device com[x].dev[]           Filename of port
  port device com[x].dev_locked      Flag whether device has been locked

  The arbritary example variable 'x' in com[x] can have a minimum value
  of 0 and a maximum value of (config.numser - 1).  There can be no gaps
  for the value 'x', even though gaps between actual COM ports are
  permitted.  It is strongly noted that the 'x' does not equal the COM
  port number.  This example code illustrates the fact, and how the
  com[] array works:

  for (i = 0; i < config.numser; i++) s_printf("COM port number %d has a
  base address of %x", com[i].real_comport, com[i].base_port);

  77..22..  bbaassee//sseerriiaall//sseerr__iinniitt..cc IInnffoorrmmaattiioonn

  77..22..11..  MMaaiinnttaaiinneerrss

  Mark Rejhon  <markg@magmacom.com>
  Mark Rejhon  <ag115@freenet.carleton.ca>

  77..22..22..  FFuunnccttiioonnss iinn bbaassee//sseerriiaall//sseerr__iinniitt..cc

  These are the functions defined in base/serial/ser_init.c.

  77..22..22..11..  sseerriiaall__iinniitt

  This is the master serial initialization function that is called upon
  startup of DOSEMU to initialize ALL the emulated UARTs for all
  configured serial ports.  The UART is initialized via the
  initialize_uart function, which opens the serial ports and defines
  variables for the specific UART.  If the port is a mouse, the port is
  only initialized when i

  77..22..33..  IItteemmss ffoorr FFiixxiinngg iinn bbaassee//sseerriiaall//sseerr__iinniitt..cc

  This needs more work before it is implemented into /etc/dosemu.conf as
  an 'rtscts' option.

  77..33..  bbaassee//sseerriiaall//sseerr__ppoorrttss..cc IInnffoorrmmaattiioonn

  77..33..11..  FFuunnccttiioonnss iinn bbaassee//sseerriiaall//sseerr__ppoorrttss..cc

  These are the functions defined in base/serial/ser_ports.c.

  77..33..11..11..  ddoo__sseerriiaall__iinn

  The following function returns a value from an I/O port.  The port is
  an I/O address such as 0x3F8 (the base port address of COM1).  There
  are 8 I/O addresses for each serial port which ranges from the base
  port (ie 0x3F8) to the base port plus seven (ie 0x3FF).  [num =
  abritary port number for serial line, address = I/O port address]

  77..33..11..22..  ddoo__sseerriiaall__oouutt

  The following function writes a value to an I/O port.  The port is an
  I/O address such as 0x3F8 (the base port address of COM1).  [num =
  abritary port number for serial line, address = I/O port address, val
  = value to write to I/O port address]

  77..33..22..  IItteemmss ffoorr FFiixxiinngg iinn bbaassee//sseerriiaall//sseerr__ppoorrttss..cc

  Should clearing UART cause THRE int if it's enabled?

  -----

  Fix the calculation assumption

  -----

  Is this safe to put this here?

  -----

  Is this safe to put this here?

  77..44..  bbaassee//sseerriiaall//sseerr__iirrqq..cc IInnffoorrmmaattiioonn

  77..44..11..  FFuunnccttiioonnss iinn bbaassee//sseerriiaall//sseerr__iirrqq..cc

  These are the functions defined in base/serial/ser_irq.c.

  77..44..11..11..  sseerriiaall__iinntt__eennggiinnee

  This function is the serial interrupts scheduler.  Its purpose is to
  update interrupt status and/or invoke a requested serial interrupt.
  If interrupts are not enabled, the Interrupt Identification Register
  is still updated and the function returns.  See pic_serial_run() below
  it is executed right at the instant the interrupt is actually invoked.
  Since it is not possible to run the interrupt on the spot, it triggers
  the interrupt via the pic_request() function (which is in pic.c) and
  sets a flag that an interrupt is going to be occur soon.  Please read
  pic_serial_run() for more information about interrupts.  [num = port,
  int_requested = the requested serial interrupt]

  77..44..11..22..  ppiicc__sseerriiaall__rruunn

  This function is called by the priority iunterrupt controller when a
  serial interrupt occurs.  It executes the highest priority serial
  interrupt for that port. (Priority order is: RLSI, RDI, THRI, MSI)
  Because it is theoretically possible for things to change between the
  interrupt trigger and the actual interrupt, some checks must be
  repeated.

  77..44..11..33..  sseerriiaall__rruunn

  This is the main housekeeping function, which should be called about
  20 to 100 times per second.  The more frequent, the better, up to a
  certain point.   However, it should be self-compensating if it
  executes 10 times or even 1000 times per second.   Serial performance
  increases with frequency of execution of serial_run.  Serial mouse
  performance becomes more smooth if the time between calls to
  serial_run are smaller.

  77..44..22..  RReemmaarrkkss iinn bbaassee//sseerriiaall//sseerr__iirrqq..cc

  Linux code hackers: How do I detect a break signal without having to
  rely on Linux signals?  Can I peek a 'break state bit'?  Also, how do
  I 'turn on' and 'turn off' the break state, via an ioctl() or
  tcsetattr(), rather than using POSIX tcsendbrk()?

  77..44..33..  IItteemmss ffoorr FFiixxiinngg iinn bbaassee//sseerriiaall//sseerr__iirrqq..cc

  how do we cancel a PIC interrupt, when we have come this far?

  -----

  Perhaps this can be modified to limit max chain length?

  88..  TThhee MMoouussee ggrroouupp ooff MMoodduulleess

  All of the Mouse handling code is in the "mouse" subdirectory.

  There are only 2 main files, mouse.c and mouseint.c.

  88..11..  bbaassee//mmoouussee//mmoouussee..cc IInnffoorrmmaattiioonn

  88..11..11..  FFuunnccttiioonnss iinn bbaassee//mmoouussee//mmoouussee..cc

  These are the functions defined in base/mouse/mouse.c.

  88..11..11..11..  mmoouussee__iinniitt

  Initialize internal mouse.

  99..  TThhee BBiiooss ggrroouupp ooff MMoodduulleess

  All of the Bios code is in the "bios" subdirectory.

  DOSEMU requires certain code to be coded in assembler and also code to
  be located in the F000 segment. This is where all such code should be
  put.

  99..11..  bbaassee//bbiiooss//bbiiooss..SS IInnffoorrmmaattiioonn

  1100..  TThhee PPIICC ggrroouupp ooff MMoodduulleess

  All of the PIC handling code is in the "PIC" subdirectory.

  1100..11..  ddeevv//ppiicc//ppiicc..cc IInnffoorrmmaattiioonn

  1100..22..  ddeevvppiicc//ppiicc..hh IInnffoorrmmaattiioonn

  1111..  TThhee SSoouunndd ggrroouupp ooff MMoodduulleess

  The sound code provides emulation of the SB. The actual emulation
  provided depends upon the support available from the kernel sound
  driver. Because this is very OS dependant the driver code itself is
  kept in architecture specifc files under
  src/arch/osname/dosext/sound/. Communication is via a set of interface
  functions and the device independant structures.

  1111..11..  ddoosseexxtt//ssoouunndd//ssoouunndd..cc IInnffoorrmmaattiioonn

  1111..11..11..  MMaaiinnttaaiinneerrss

  Alistair MacDonald  <alistair@slitesys.demon.co.uk>
  David Brauman  <crisk@netvision.net.il>
  Rutger Nijlunsing  <rutger@null.net>

  1111..11..22..  FFuunnccttiioonnss iinn ddoosseexxtt//ssoouunndd//ssoouunndd..cc

  These are the functions defined in dosext/sound/sound.c.

  1111..11..22..11..  ssbb__iioo__rreeaadd

  Arguments are:

  +o  port - The I/O port being read from.

     This handles all of the reads for the SB emulation. The value read
     is returned. The value of 0xFF indicates an invalid read. (assumes
     the ports float high when not pulled low by the hardware.)

  1111..11..22..22..  aaddlliibb__iioo__rreeaadd

  Arguments are:

  +o  port - The I/O port being read from.

     This handles all of the reads for the adlib (FM) emulation. The
     value read is returned. The value of 0xFF indicates an invalid
     read. (assumes the ports float high when not pulled low by the
     hardware.)  The FM emulation is not written yet. The current plan
     is to use the midi emulation where available as this is the most
     common use for the FM sound.

  1111..11..22..33..  mmppuu440011__iioo__rreeaadd

  Arguments are:

  +o  port - The I/O port being read from.

     The MPU-401 functionality is primarily provided by 'midid' - a
     standalone program. This makes most of the MPU-401 code simply a
     pass-through driver.

  1111..11..22..44..  ssbb__iioo__wwrriittee

  Arguments are:

  +o  port - The I/O port being written to.

  +o  value - The value being output.

     This handles the writes for the SB emulation. Very little of the
     processing is performed in this function as it basically consists
     of a very large switch() statement. The processing here is limited
     to trivial (1 line) items and distinguishing between the different
     actions and responses that the different revisions of the SB series
     give.

  1111..11..22..55..  ssbb__ddsspp__wwrriittee

  Arguments are:

  +o  value - The value being written to the DSP.

     The SB DSP is a complete I/O system in itself controlled via a
     number of data bytes. The number of bytes depends upon the
     function. The function to be executed is determined by the first
     byte.  If there is no existing command then the command is stored.
     This then used in the switch to identify the action to be taken.
     When the command has supplied all of its arguments, or failed, then
     the command storage is cleared. Each DSP function is responsible
     for clearing this itself.  Again, this function relies on other
     functions to do the real work, and apart from storing details of
     the command and parameters is basically a large switch statement.

  1111..11..33..  RReemmaarrkkss iinn ddoosseexxtt//ssoouunndd//ssoouunndd..cc

  Write silence could probably be implemented by setting up a "DMA"
  transfer from /dev/null - AM

  1111..11..44..  IItteemmss ffoorr FFiixxiinngg iinn ddoosseexxtt//ssoouunndd//ssoouunndd..cc

  The file header needs tidying up a _LOT_ !

  -----

  Adlib status reads are unimplemented

  -----

  Advanced adlib reads are unimplemented

  -----

  CMS Writes are unimplemented.

  -----

  DSP Status is unimplemented

  -----

  Write Silence is not implemented.

  -----

  Adlib register writes are unimplemented

  -----

  Adlib data writes are unimplemented

  -----

  Advanced Adlib register writes are unimplemented

  -----

  Advanced Adlib data writes are unimplemented

  -----

  SB Midi is Unimplemented

  -----

  Sine Generation is unimplemented

  -----

  AUX Status is Unimplemented

  -----

  Stero Input is no implemented

  -----

  ADC is Unimplemented

  -----

  Stopping Auto-Init DMA is not implemented

  1122..  AAnndd FFiinnaallllyy ......

  The Following items are used to delimit the text used to create this
  file.  Whilst it is not necessary to know this, they are included
  because they may be useful for searching, as they are (at least at the
  moment) reasonably unique.

  DANG_BEGIN_MODULE / DANG_END_MODULE This will bracket a description of
  the file (normally at the start).

  DANG_BEGIN_FUNCTION / DANG_END_FUNCTION This brackets a description of
  functions (good this, isn't it!)  Not every function needs to be
  described in this way - just the major ones.

  DANG_BEGIN_REMARK / DANG_END_REMARK This brackets descriptions of
  obscure items, like data structures and architecture.

  DANG_FIXTHIS This is a one line item, indicating a an area requiring a
  fix, or redesign.

  DANG_BEGIN_NEWIDEA / DANG_END_NEWIDEA New Ideas Start Here! As Ideas
  are proposed, that get added with their description, so that future
  generations can laugh at or code the ideas ..... These bracket the
  idea description.

  DANG_BEGIN_CHANGELOG / DANG_END_CHANGELOG Changelogs - very useful for
  bug fixing, and avvailable for use with DPR (or that's the theory)

