  The DOSEMU Alterer Novices Guide DANG
  Alistair MacDonald, am20@unix.york.ac.uk
  For DOSEMU v0.53 pl28

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

  1.  Introduction

  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@amiganet.chi.il.us>. It has been completely revised. It is now
  generated automatically directly from the source code. Special thanks
  to "James B. MacLean" <jmaclean@fox.nstn.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!





  2.  The Main group of Modules

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



  2.1.	dos.c Information

  Initial program executed to run DOSEMU. Gets access to libdosemu and
  sets international character parms. Finally calls entry point of
  DOSEMU emulate() function which is loaded above the usual DOS memory
  area from 0 - 1meg. Emulate() is in emu.c.



  2.1.1.  Functions in dos.c

  These are the functions defined in dos.c.


  2.1.1.1.  dosemu


  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.



  2.1.2.  Remarks in dos.c

  Apparently, no-one has anything interesting to say about dos.c.


  2.1.3.  Items for Fixing in dos.c

  Apparently, nothing needs fixing in dos.c.


  2.1.4.  New Ideas for dos.c

  Apparently, there are no new ideas for dos.c.


  2.2.	emu.c Information

  Here is where DOSEMU gets booted. From emu.c external calls are made
  to the specific I/O systems (video/keyboard/serial/etc...) to
  initialize them. Memory is cleared/set up and the boot sector is read
  from the boot drive. Many SIGNALS are set so that DOSEMU can exploit
  things like timers, I/O signals, illegal instructions, etc...	When
  every system gives the green light, vm86() is called to switch into
  vm86 mode and start executing i86 code.

  The vm86() function will return to DOSEMU when certain `exceptions`
  occur as when some interrupt instructions occur (0xcd).

  The top level function emulate() is called from dos.c by way of a dll
  entry point.



  2.2.1.  Functions in emu.c

  These are the functions defined in emu.c.


  2.2.1.1.  jmp_emulate

  This function allows the startup program `dos` to know how to 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



  2.2.1.2.  DBGTIME


  o  x - character to print with time.

     Inline function to debug time differences between different points
     of execution within DOSEMU. Thanks Ronnie :-).  Only used by
     developers and not expected to execute in any general releases.



  2.2.1.3.  signal_init

  Initialize the signals to have NONE being blocked.  Currently this is
  NOT of much use to DOSEMU.




  2.2.1.4.  cli

  Stop additional signals from interrupting DOSEMU.



  2.2.1.5.  sti

  Allow all signals to interrupt DOSEMU.



  2.2.1.6.  handle_signals

  Due to signals happening at any time, the actual work to be done
  because a signal occurs is done here in a serial fashion.  The
  concept, should this eventualy work, is that a signal should only flag
  that it has occurred and let DOSEMU deal with it in an orderly fashion
  as it executes the rest of it's code.



  2.2.1.7.  run_vm86

  Here is where DOSEMU runs VM86 mode with the vm86() call which also
  has the registers that it will be called with. It will stop vm86 mode
  for many reasons, like trying to execute an interrupt, doing port I/O
  to ports not opened for I/O, etc ...



  2.2.1.8.  memory_init

  Set up all memory areas as would be present on a typical i86 during
  the boot phase.



  2.2.1.9.  SIGNAL_save


  o  context	- signal context to save.

  o  signal_call - signal handling routine to be called.

     Save into an array structure queue the signal context of the
     current signal as well as the function to call for dealing with
     this signal.  This is a queue because any signal may occur multiple
     times before DOSEMU deals with it down the road.



  2.2.1.10.  SIGIO_call

  Whenever I/O occurs on devices allowing SIGIO to occur, DOSEMU will be
  flagged to run this call which inturn checks which fd(s) was set and
  execute the proper routine to get the I/O from that device.



  2.2.1.11.  parse_debugflags


  o  s - string of options.

     This part is fairly flexible...you specify the debugging flags you
     wish with -D string.  The string consists of the following
     characters: +   turns the following options on (initial state) -
     turns the following options off a	turns all the options on/off,
     depending on whether +/- is set 0-9 sets debug levels (0 is off, 9
     is most verbose) #	where # is a letter from the valid option list
     (see docs), turns that option off/on depending on the +/- state.
     Any option letter can occur in any place.	Even meaningless
     combinations, such as "01-a-1+0vk" will be parsed without error, so
     be careful.  Some options are set by default, some are clear. This
     is subject to my whim.  You can ensure which are set by explicitly
     specifying.



  2.2.1.12.  config_defaults

  Set all values in the `config` structure to their default value.
  These will be modified by the config parser.



  2.2.1.13.  SIG_int

  Allow DOSEMU to be made aware when a hard interrupt occurs Requires
  the sig/sillyint.o driver loaded (using NEW modules package), or a
  kernel patch (implementing sig/int.c driver).	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



  2.2.1.14.  check_special_mapping

  This is called after all configuration stuff is done to make sure that
  no mapped areas are overlapping.  It checks EMS, VBIOS, HARDWARE_RAM
  and exits with "false", if any of it overlapp.



  2.2.1.15.  emulate


  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().



  2.2.1.16.  hardware_init

  Initialize any leftover hardware.



  2.2.1.17.  version_init

  Find version of OS running and set necessary global parms.



  2.2.1.18.  add_to_io_select


  o  fd - File handle to add to select statment.

  o  want_sigio - Specifiy whether you want SIGIO (1) if it's available,
     or

  o  not (0).

     Add file handle to one of 2 select FDS_SET's depending on whether
     the kernel can handle SIGIO.



  2.2.2.  Remarks in emu.c

  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.

  -----

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

  -----

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

  -----

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

  -----

  At this time we have to use SIGALRM in addition to SIGIO I don't (yet)
  know why the SIGIO signal gets lost sometimes (once per minute or
  longer).  But if it happens, we can retrigger this way over SIGALRM.
  Normally SIGIO happens before SIGALARM, so nothing hurts.  (Hans)

  -----

  If DOSEMU starts up with stderr == stdout, then stderr gets redirected
  to '/dev/null'.

  -----

  For simpler support of X, DOSEMU can be started by a symbolic link
  called `xdos` which DOSEMU will use to switch into X-mode.


  2.2.3.  Items for Fixing in emu.c

  Apparently, nothing needs fixing in emu.c.


  2.2.4.  New Ideas for emu.c

  Apparently, there are no new ideas for emu.c.



  2.3.	emu.h Information

  There appears to be no MODULE information for this file.


  2.3.1.  Functions in emu.h

  These are the functions defined in emu.h.


  2.3.1.1.  NEWSETQSIG


  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.



  2.3.2.  Remarks in emu.h

  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


  2.3.3.  Items for Fixing in emu.h

  Apparently, nothing needs fixing in emu.h.


  2.3.4.  New Ideas for emu.h

  Apparently, there are no new ideas for emu.h.


  3.  The Clients group of Modules

  One of the long term aims of the DOSEMU development team is to provide
  a client-server based system. This will allow people to add different
  display systems in more simply. Those in current development are
  detailed in this section.



  3.1.	clients/ncurses.c Information

  This is James' client based around NCURSES. It (un-)succesfully
  demonstrates the procedure for making initial connections to the
  server.



  3.1.1.  Functions in clients/ncurses.c

  These are the functions defined in clients/ncurses.c.



  3.1.1.1.  main


  o  argc - Number of Command Line arguments.

  o  argv - Command Line arguments - as an array of char*'s

     This function does all of the work associated with this client. It
     grabs the shared memory used to hold the current Video data and
     makes some comments about its current screen.



  3.1.2.  Remarks in clients/ncurses.c

  Some of the functions are undocumented. These are the trivial ones.


  -----

  You must be mad if you want to get involved in all of this Shared
  memory stuff .... 8-)



  3.1.3.  Items for Fixing in clients/ncurses.c

  Apparently, nothing needs fixing in clients/ncurses.c.


  3.1.4.  New Ideas for clients/ncurses.c

  Apparently, there are no new ideas for clients/ncurses.c.


  4.  The DPMI group of Modules

  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 ...)



  4.1.	dpmi/dpmi.c Information

  dpmi.c

  DOS Protected Mode Interface allows DOS programs to run in the
  protected mode of 2345..86 processors



  4.1.1.  Functions in dpmi/dpmi.c

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





  4.1.1.1.  dpmi_control

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



  4.1.1.2.  do_default_cpu_exception

  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 :-)).



  4.1.1.3.  do_cpu_exception

  This calls the DPMI client exception handler. If none is installed
  do_default_cpu_exception() is called.



  4.1.1.4.  dpmi_fault

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



  4.1.2.  Remarks in dpmi/dpmi.c

  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...............



  4.1.3.  Items for Fixing in dpmi/dpmi.c

  don't free protected mode stack if DPMI client terminates from
  exception handler

  -----

  not yet implemented

  -----

  not yet implemented

  4.1.4.  New Ideas for dpmi/dpmi.c

  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


  5.  The Video group of Modules

  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.



  5.1.	video/vc.c Information

  Here's all the calls to the code to try and properly save & restore
  the video state between VC's and the attempts to control updates to
  the VC whilst the user is using another. We map between the real
  screen address and that used by DOSEMU here too.

  Attempts to use a cards own bios require the addition of the parameter
  "graphics" to the video statement in "/etc/dosemu.conf". This will
  make the emulator try to execute the card's initialization routine
  which is normally located at address c000:0003. This can now be
  changed as an option.



  5.1.1.  Functions in video/vc.c

  We appear to have no information on the functions in video/vc.c.


  5.1.2.  Remarks in video/vc.c

  Apparently, no-one has anything interesting to say about video/vc.c.


  5.1.3.  Items for Fixing in video/vc.c

  Apparently, nothing needs fixing in video/vc.c.


  5.1.4.  New Ideas for video/vc.c

  Apparently, there are no new ideas for video/vc.c.


  5.2.	video/video.c Information

  There appears to be no MODULE information for this file.


  5.2.1.  Functions in video/video.c

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


  5.2.1.1.  video_init

  Set pointer to correct structure of functions to initialize, close,
  etc... video routines.
  5.2.2.  Remarks in video/video.c

  Apparently, no-one has anything interesting to say about
  video/video.c.


  5.2.3.  Items for Fixing in video/video.c

  Apparently, nothing needs fixing in video/video.c.


  5.2.4.  New Ideas for video/video.c

  Apparently, there are no new ideas for video/video.c.


  5.3.	termio.c Information

  This handles the keyboard.

  Two keyboard modes are handled 'raw' and 'xlate'. 'Raw' works with
  codes as sent out by the kernel and 'xlate' uses plain ASCII as used
  over serial lines. The mapping for different languages & the two ALT-
  keys is done here, but the definitions are elsewhere. Only the default
  (US) keymap is stored here.



  5.3.1.  Functions in termio.c

  These are the functions defined in termio.c.


  5.3.1.1.  keyboard_init

  Initialize the keyboard to DOSEMU deafaults plus those requested in
  the configs if allowable.



  5.3.1.2.  convascii


  o  cc - count of characters on queue

     For dealing with translating esc character sequences received in
     XLATE mode. Every effort is made to give the characters a time
     slice of approx. 3/4 of a second to arrive at DOSEMU.  Also handles
     alt-keys and other character translations.



  5.3.2.  Remarks in termio.c

  Code is called at start up to set up the terminal line for non-raw
  mode.



  5.3.3.  Items for Fixing in termio.c

  Apparently, nothing needs fixing in termio.c.




  5.3.4.  New Ideas for termio.c

  Apparently, there are no new ideas for termio.c.


  6.  The Misc group of Modules

  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.



  6.1.	bios_emm.c Information

  This provides the EMM Memory Management for DOSEMU. It was originally
  part of the Mach Dos Emulator.

  Recent work in this area has involved a patch to the Kernel. If this
  is used and the DEFINE MMAP_EMS line used, a faster form of EMS memory
  support is included, using the /proc filesystem.

  In contrast to some of the comments (Yes, _I_ know the adage about
  that...)  we appear to be supporting EMS 4.0, not 3.2



  6.1.1.  Functions in bios_emm.c

  We appear to have no information on the functions in bios_emm.c.


  6.1.2.  Remarks in bios_emm.c

  Apparently, no-one has anything interesting to say about bios_emm.c.


  6.1.3.  Items for Fixing in bios_emm.c

  Apparently, nothing needs fixing in bios_emm.c.


  6.1.4.  New Ideas for bios_emm.c

  Apparently, there are no new ideas for bios_emm.c.


  6.2.	xms.c Information

  Currently the XMS 3.0 spec is covered in this file. XMS is fairly
  simple as it only deals with allocating extended memory and then
  moving it around in specific calls. This spec also includes the
  allocation of UMB's, so they are also included as part of this file.
  The amount of xms memory returned to DOS programs via the XMS
  requests, or int15 fnc88 is set in "/etc/dosemu.conf" via the XMS
  paramter.



  6.2.1.  Functions in xms.c

  We appear to have no information on the functions in xms.c.




  6.2.2.  Remarks in xms.c

  Apparently, no-one has anything interesting to say about xms.c.


  6.2.3.  Items for Fixing in xms.c

  Apparently, nothing needs fixing in xms.c.


  6.2.4.  New Ideas for xms.c

  Apparently, there are no new ideas for xms.c.


  6.3.	keymaps.c Information

  These are definitions, giving which key is related to which scancode
  in raw keyboard mode. Basically, the code of 'x' on a US keyboard may
  be that of a 'Y' on a German keyboard. This way, all types of keyboard
  can be represented under DOSEMU. Also, the right ALT-key is often a
  function key in it's own right.



  6.3.1.  Functions in keymaps.c

  We appear to have no information on the functions in keymaps.c.


  6.3.2.  Remarks in keymaps.c

  Apparently, no-one has anything interesting to say about keymaps.c.


  6.3.3.  Items for Fixing in keymaps.c

  Apparently, nothing needs fixing in keymaps.c.


  6.3.4.  New Ideas for keymaps.c

  Apparently, there are no new ideas for keymaps.c.


  6.4.	sigsegv.c Information

  There appears to be no MODULE information for this file.


  6.4.1.  Functions in sigsegv.c

  These are the functions defined in sigsegv.c.


  6.4.1.1.  vm86_GP_fault

  All from the kernel unhandled general protection faults from V86 mode
  are handled here. This are mainly port IO and the HLT instruction.



  6.4.1.2.  dosemu_fault

  All CPU exceptions (except 13=general_protection from V86 mode, which
  is directly scaned by the kernel) are handled here.
  6.4.2.  Remarks in sigsegv.c

  In a properly functioning emulator :-), sigsegv's will never come
  while in a non-reentrant system call (ioctl, select, etc).  Therefore,
  there's really no reason to worry about them, so I say that I'm NOT in
  a signal handler (I might make this a little clearer later, to show
  that the purpose of in_sighandler is to stop non-reentrant system
  calls from being reentered.  I reiterate: sigsegv's should only happen
  when I'm running the vm86 system call, so I really shouldn't be in a
  non-reentrant system call (except maybe vm86) - Robert Sanders


  6.4.3.  Items for Fixing in sigsegv.c

  Apparently, nothing needs fixing in sigsegv.c.


  6.4.4.  New Ideas for sigsegv.c

  Apparently, there are no new ideas for sigsegv.c.


  6.5.	int.h Information

  Centralized area for interrupt service routine calls and support
  functions.



  6.5.1.  Functions in int.h

  These are the functions defined in int.h.


  6.5.1.1.  DO_INT

  DO_INT is used to deal with interrupts returned to DOSEMU by the
  kernel.



  6.5.1.2.  DEFAULT_INTERRUPT

  DEFAULT_INTERRUPT is the default interrupt service routine called when
  DOSEMU initializes.



  6.5.1.3.  SETUP_INTERRUPTS

  SETUP_INTERRUPTS is used to initialize those interrupt calls that we
  are specifically handling in protected mode.



  6.5.2.  Remarks in int.h

  Apparently, no-one has anything interesting to say about int.h.


  6.5.3.  Items for Fixing in int.h

  Apparently, nothing needs fixing in int.h.



  6.5.4.  New Ideas for int.h

  Apparently, there are no new ideas for int.h.


  6.6.	ports.h Information

  There appears to be no MODULE information for this file.


  6.6.1.  Functions in ports.h

  These are the functions defined in ports.h.


  6.6.1.1.  inb

  INB is used to do controlled emulation of input from ports.



  6.6.2.  Remarks in ports.h

  Apparently, no-one has anything interesting to say about ports.h.


  6.6.3.  Items for Fixing in ports.h

  Apparently, nothing needs fixing in ports.h.


  6.6.4.  New Ideas for ports.h

  Apparently, there are no new ideas for ports.h.


  6.7.	dosio.c Information

  There appears to be no MODULE information for this file.


  6.7.1.  Functions in dosio.c

  These are the functions defined in dosio.c.


  6.7.1.1.  memory_setup

  Setup HMA area via IPC. Call EMS and XMS initialization routines.



  6.7.2.  Remarks in dosio.c

  Apparently, no-one has anything interesting to say about dosio.c.


  6.7.3.  Items for Fixing in dosio.c

  Apparently, nothing needs fixing in dosio.c.


  6.7.4.  New Ideas for dosio.c

  Apparently, there are no new ideas for dosio.c.

  6.8.	mouse/mouse.c Information

  There appears to be no MODULE information for this file.


  6.8.1.  Functions in mouse/mouse.c

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


  6.8.1.1.  mouse_init

  Initialize internal mouse.



  6.8.2.  Remarks in mouse/mouse.c

  Apparently, no-one has anything interesting to say about
  mouse/mouse.c.


  6.8.3.  Items for Fixing in mouse/mouse.c

  Apparently, nothing needs fixing in mouse/mouse.c.


  6.8.4.  New Ideas for mouse/mouse.c

  Apparently, there are no new ideas for mouse/mouse.c.


  6.9.	serial.c Information

  There appears to be no MODULE information for this file.


  6.9.1.  Functions in serial.c

  These are the functions defined in serial.c.


  6.9.1.1.  serial_init

  The following is the master serial initialization function called
  externally (from this serial.c module) during DOSEMU startup. It
  initializes all the configured serial ports.



  6.9.2.  Remarks in serial.c

  Apparently, no-one has anything interesting to say about serial.c.


  6.9.3.  Items for Fixing in serial.c

  Apparently, nothing needs fixing in serial.c.


  6.9.4.  New Ideas for serial.c

  Apparently, there are no new ideas for serial.c.



  6.10.	disks.c Information

  There appears to be no MODULE information for this file.


  6.10.1.  Functions in disks.c

  These are the functions defined in disks.c.


  6.10.1.1.  disk_init

  Test by opening all floppies/hardrives configured.



  6.10.2.  Remarks in disks.c

  Apparently, no-one has anything interesting to say about disks.c.


  6.10.3.  Items for Fixing in disks.c

  Apparently, nothing needs fixing in disks.c.


  6.10.4.  New Ideas for disks.c

  Apparently, there are no new ideas for disks.c.


  6.11.	cpu.c Information

  CPU/V86 support for dosemu



  6.11.1.  Functions in cpu.c

  These are the functions defined in cpu.c.


  6.11.1.1.  cpu_init

  Setup initial interrupts which can be revectored so that the kernel
  does not need to return to DOSEMU if such an interrupt occurs.



  6.11.2.  Remarks in cpu.c

  Apparently, no-one has anything interesting to say about cpu.c.


  6.11.3.  Items for Fixing in cpu.c

  Apparently, nothing needs fixing in cpu.c.


  6.11.4.  New Ideas for cpu.c

  Apparently, there are no new ideas for cpu.c.




  6.12.	lpt.c Information

  There appears to be no MODULE information for this file.


  6.12.1.  Functions in lpt.c

  These are the functions defined in lpt.c.


  6.12.1.1.  printer_init

  Initialize printer control structures



  6.12.2.  Remarks in lpt.c

  Apparently, no-one has anything interesting to say about lpt.c.


  6.12.3.  Items for Fixing in lpt.c

  Apparently, nothing needs fixing in lpt.c.


  6.12.4.  New Ideas for lpt.c

  Apparently, there are no new ideas for lpt.c.


  6.13.	sig/int.c Information

  Silly Interrupt Generator device driver for Linux 1.1.47 or higher.
  Needs the new modules utilities.

  The driver uses MAJOR 19, the minors can be from 3 .. 15 and represent
  the IRQ-level, which is intercepted for use with DOSEMU.  This driver
  must be compiled on the system it is running on, see the doc in the
  modules packages.  To load it (must be the superuser) type insmod
  sillyint.o or insmod sillyint.o SIG_MAJOR=mm if you want to use MAJOR
  mm intstead of the default 19.

  To make the devices go into your /dev directory and create a
  subdirectory called int. Change into this directory and add a node for
  the IRQ you wish to use. Bare in mind that in the future if you use
  another interrupt, you'll have to come to /dev/int and add it too.  To
  MaKe this NODe, type: mknod <x> c 19 <x> where <x> is the IRQ number
  you wish to use. I will add at this time that SIG will not open an
  interrupt up that is already in use. This will mean that some
  applications that access their interrupts from boot up like ethernet
  cards, must not be configured into the kernel or must be given port
  bases, that are not probed by the kernel. You may use the kernel
  command line feature, either from LILO or LOADLIN to change those
  ports at boot time of Linux.


  6.13.1.  Functions in sig/int.c

  We appear to have no information on the functions in sig/int.c.


  6.13.2.  Remarks in sig/int.c

  Apparently, no-one has anything interesting to say about sig/int.c.

  6.13.3.  Items for Fixing in sig/int.c

  Apparently, nothing needs fixing in sig/int.c.


  6.13.4.  New Ideas for sig/int.c

  Apparently, there are no new ideas for sig/int.c.


  7.  The PIC group of Modules

  All of the PIC handling code is in the "timer" subdirectory. Odd isn't
  it.




  7.1.	timer/pic.c Information

  pic.c is a fairly complete emulation of both 8259 Priority Interrupt
  Controllers.	It also includes provision for 16 lower level
  interrupts.  This implementation supports the following i/o commands:

  ICW1	bits 0 and 1	number of ICWs to expect ICW2    bits 3 - 7
  base address of IRQs ICW3    no bits		accepted but ignored
  ICW4	no bits	  accepted but ignored

  OCW1	all bits	 sets interrupt mask OCW2    bits 7,5-0
  EOI commands only OCW3    bits 0,1,5,6     select read register,
  select special mask mode

  Reads of both pic ports are supported completely.

  An important concept to understand in pic is the interrupt level.
  This is a value which represents the priority of the current
  interrupt.  It is used to identify interrupts, and IRQs can be mapped
  to these levels(see pic.h ). The currently active interrupt level is
  maintained in pic_ilevel, which is globally available,   A pic_ilevel
  of 32 means no interrupts are active; 0, the highest priority,
  represents the NMI.  IRQs 0 through 15 are mapped, in priority order,
  to values of 1-15 (there is no IRQ2 in an AT). Values of 16 - 31
  represent additional interrupt levels available for internal dosemu
  usage.

  More detail is available in the file README.pic



  7.1.1.  Functions in timer/pic.c

  These are the functions defined in timer/pic.c.


  7.1.1.1.  write_pic0

  write_pic_0() and write_pic1() implement dos writes to the pic ports.
  They are called by the code that emulates inb and outb instructions.
  Each function implements both ports for the pic:  pic0 is on ports
  0x20 and 0x21; pic1 is on ports 0xa0 and 0xa1.  These functions take
  two arguements: a port number (0 or 1) and a value to be written.





  7.1.1.2.  read_pic0

  read_pic0 and read_pic1 return the values for the interrupt mask
  register (port 1), or either the in service register or interrupt
  request register, as determined by the last OCW3 command (port 0).
  These functions take a single parameter, which is a port number (0 or
  1).  They are called by code that emulates the inb instruction.



  7.1.1.3.  pic_mask

  The pic maintains an additional interrupt mask which is not visible to
  the DOS process.  This is normally cleared (enabling an interrupt)
  when an interrupt is initialized, but dosemu code may choose to use
  this mask internally.	One possible use is to implement the interrupt
  gate controlled by the OUT2 bit of the 16550A UART's Modem Control
  Register.  This mask is cleared by pic_unmaski() and set by
  pic_maski()



  7.1.1.4.  pic_seti

  pic_seti is used to initialize an interrupt for dosemu.  It requires
  three parameters.  The first parameter is the interrupt level, which
  man select the NMI, any of the IRQs, or any of the 16 extra levels (16
  - 31).  The second parameter is the dosemu function to be called when
  the interrupt is activated.  This function should call do_irq() if the
  DOS interruptis really to be activated.  If there is no special dosemu
  code to call, the second parameter can specify do_irq(), but see that
  description for some special considerations.



  7.1.1.5.  run_irqs

  run_irqs, which is initiated via the macro pic_run, is the "brains" of
  the pic.  It is called from the vm86() loop, checks for the highest
  priority interrupt requested, and executes it.  This function is
  written in assembly language in order to take advantage of atomic
  (indivisible) instructions, so that it should be safe for a two
  process model, even in a multiple CPU machine.  A c language version
  was started, but it became impossible, even with in-line assembly
  macros, because such macros can only return a single result.	If I
  find a way to do it in c, I will, but don't hold your breath.



  7.1.1.6.  do_irq

  do_irq() calls the correct do_int().	It then executes a vm86 loop
  until an outb( end-of-interrupt) is found.  For priority levels 0 and
  >15 (not real IRQs), vm86 executes once, then returns, since no outb20
  will come.  Returns: 0 = complete, 1 = interrupt not run because it
  directly calls our "bios"   See run_timer_tick() in timer.c for an
  example This routine is RE-ENTRANT - it calls run_irqs, which which
  may call an interrupt routine, which may call do_irq().  Be Careful!
  !!!!!!!!!!!!!!!!!!  No single interrupt is ever re-entered.



  7.1.1.7.  pic_request

  pic_request triggers an interrupt.  There is presently no way to "un-
  trigger" an interrupt.  The interrupt will be initiated the next time
  pic_run is called, unless masked or superceded by a higher priority
  interrupt.  pic_request takes one arguement, an interrupt level, which
  specifies the interrupt to be triggered.  If that interrupt is already
  active, the request will be queued until all active interrupts have
  been completed.  The queue is only one request deep for each
  interrupt, so it is the responsibility of the interrupt code to
  retrigger itself if more interrupts are needed.



  7.1.1.8.  pic_iret

  pic_iret is used to sense that all active interrupts are really
  complete, so that interrupts queued by pic_request can be triggered.
  Interrupts end when they issue an outb 0x20 to the pic, however it is
  not yet safe at that time to retrigger interrupts, since the stack has
  not been restored to its initial state by an iret.  pic_iret is called
  whenever interrupts have been enabled by a popf, sti, or iret.  It
  determines if an iret was the cause by comparing stack contents with
  cs and ip.  If so, it decrements a count of interrupts on the stack
  (set by do_irq()).  If the count is then zero, pic_iret moves all
  queued interrupts to the interrupt request register.	It is possible
  for pic_iret to be fooled by dos code; for this reason active
  interrupts are checked, any queued interrupts that are also active
  will remain queued.



  7.1.2.  Remarks in timer/pic.c

  Apparently, no-one has anything interesting to say about timer/pic.c.


  7.1.3.  Items for Fixing in timer/pic.c

  Apparently, nothing needs fixing in timer/pic.c.


  7.1.4.  New Ideas for timer/pic.c

  Apparently, there are no new ideas for timer/pic.c.


  7.2.	timer/pic.h Information

  There appears to be no MODULE information for this file.


  7.2.1.  Functions in timer/pic.h

  We appear to have no information on the functions in timer/pic.h.


  7.2.2.  Remarks in timer/pic.h

  Apparently, no-one has anything interesting to say about timer/pic.h.


  7.2.3.  Items for Fixing in timer/pic.h

  Apparently, nothing needs fixing in timer/pic.h.





  7.2.4.  New Ideas for timer/pic.h

  Apparently, there are no new ideas for timer/pic.h.


  8.  And Finally ...

  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)


































