
  c't/Harald Albrecht: created the v86 monitor part and EMS functions
  1990

  tom ehlert: implemented UMB support,
  2001-2004   reboot hooks (keyboard ctrl-alt-del, BIOS FFFF:0000)
              int 15h ext memory copy,
              VDS lock function,
              introduced english comments.

  michael devore: implemented support for VCPI, VDS (partially), dynamic
  2004-2006           XMS memory allocation, EMS v4.0 (partially)
  - Modified for >64M and VCPI support
  - Updated for EMS 4.0, some extended API returns unsupported, this will
    change as requested or needed by other software requirements
  - Documented EMS 4.0 only supports up to 32M (0x800 pages), but some EMS
    drivers allow more than 32M.      The EMS 4.0 spec could be extended to 1G-32K
    (map value of 0xFFFF means unmap) without breaking the spec API,
    but unfortunately breaking unsophisticated programs which get confused.
    I have arbitrarily decided to allow up to 32M of EMS allocations,
    leaving the high bit of page allocation alone since specific drivers
    may make use of high bit values other than 0xFFFF for their own purposes,
    or may only check high bit for unmap -- as FreeDOS EMM386 does.
      - Minor English corrections where useful for comprehension

    Michael Devore's changes are not copyrighted and are released
    to the public domain.
    This does not affect copyright on the rest of the code.

    the following modifications are done for JEMM:
    
    generally:
     + comments were deleted if they were definitely wrong or outdated.
     + All modifications are public domain.
     + The source is now best viewed with Tab Size 4!

    1. bugfix: changes done in proc pm_entry: switch to host stack
       and back.
    2. bugfix: in proc VCPI_GetInterface: do not return a fixed value
       in DI for the page table 0 offset, instead calculate this value
       from the V86-monitor code descriptor. Return with an error
       if page table 0 is "full". (obsolete).
    3. moved V86 monitor stack into shared extended memory.
       temp stack removed. saves 1 kB of conv. memory.
    4. moved GDT into shared extended memory, thrown away LDT and
       temp. TSS.
    5. IO-Bitmap and IDT created on the fly. Reduces size of binary by
       about 10 kB.
    6. rearranged segments to simplify binary structure.
       RSEG            resident code and data (=GROUP RESGRP)
       V86SEG          protected-mode code (+data) moved to extended memory
       INITSEG         code for monitor initialization
       _TEXT,_DATA real-mode code+data shared with the C part
    7. illegal opcode error handler rewritten which further reduces
       conv. memory requirements.
    8. most of the VDS code moved to extended memory, runs in protected
       mode now. The real-mode part (about 40h bytes) will not stay
       resident if option NOVDS is given (this has been made obsolete
       by later development, the real-mode part is now just a few bytes).
    9. display more infos for exceptions occuring in ring 0.
       page faults and GPFs will display the proper protected mode CS:EIP.
       external exceptions (caused by intruders) may be detected and
       will prompt the user to reboot.
   10. code rearranged. now paging is enabled much earlier and
       the monitor code will always be located at linear address 110000h
       regardless where the physical address is. large parts of the
       data moved to linear address 0FFExxxxx, to release PTEs in
       page table 0. This also makes 2. obsolete.
   11. the full physical memory is no longer mapped in the monitor's
       address space. The Int 15h emulation has been adjusted and will
       now always use scratch PTEs for the copy operation. This reduces
       extended memory usage a lot. On 80486+ cpus the INVLPG opcode
       will be used to flush TLB entries.
   12. option NOALTBOOT deleted. It is obsolete now since IRQ 1 is never
       hooked. Instead a HLT breakpoint has been added at FFFF:0000.
   13. option MEMCHECK deleted. It is obsolete now, the Int 15h emulation
       will *always* build the PTEs on the fly. NOCHECK still checks if
       the memory range is inside physical ram. Else a page fault is
       generated.
   14. command line switch S=XXXX-YYYY added to allow Jemm to include
       upper memory being activated by UMBPCI as UMBs. This allows UMBPCI
       to be called before Himem and then removed entirely from DOS memory.
   15. if a DOS app hooks IVT vector 67h, the interrupt is now routed to
       v86-mode (and catched at last by a breakpoint, which will transfer
       control to the V86 monitor). Previously hooking IVT vector 67h in
       real-mode was useless, because this interrupt was handled in
       protected-mode and the hook proc was never called. This is mainly
       to increase compatibility with MS Emm386.
 ------ v5.00pre
   16. implemented the EMMXXXX0 device, and allow some minimal
       communication with it. Makes several apps happy, among them MS-DOS.
   17. DMA buffering code redesigned. Int 13h and 40h are no longer
       hooked, instead it is checked in int 15h, ax=9100h and ax=9101h
       if the DMA buffer content should be transfered back (this was
       reverted later, Int 13h and 40h are hooked again).
   17a.All variables handling DMA moved to V86SEG segment. Furthermore all
       real-mode ints are hooked *after* the monitor has been installed.
   18. DMA bug fixed: the buffer is 64k max, but phys. addr. wasn't checked
       if it crosses a 64 kB boundary. Now the check is done and also size
       is checked if it exceeds maximum size. (no error msg is displayed,
       though). The DMA buffer size may be below 64 kB now (fixed with 26.).
       Bugs still open: A truly safe buffer would beginn on a 128 kB border
       and be 128 kB in size. It also must be located entirely in the first
       16 MB (should be no problem usually).
   19. DMA: Single Mask and Master Mask ports also trapped now. It is
       checked if the channel is active, and nothing is done unless it is.
   20. DMA bugfix: the DMA buffer is not always used when it has to be
       used. The CONTINUOUS? proc was not strict enough.
   21. bugfix accessing XMS handle array: unused handles got the FREE flag
       set (bit 0). Now unused handles got the "INPOOL" flag set (bit 2).
       This makes Jemm work better with MS Himem (at least).
   22. bugfix: mapped page at F0000 (to catch RESET) wasn't write protected.
       The fix requires to catch page faults caused by write accesses and
       "emulate" them.
   23. display FS and GS in invalid opcode handler and wait for ESC key
       before trying to abort the current program with int 21h, ah=4Ch.
   24. A20 disable/enable emulation activated
   25. VME extension supported. Software interrupt redirection bitmap
       added to the TSS. Detection of CPUID opcode support. If VME
       extensions are present (Pentium+), the VME bit in CR4 is set.
   26. DMA buffer is now 64 kB in size again and begins on a physical
       64 kB border. This is achieved by rearranging PTEs.
   27. the EMMXXXX0 device interface may be used to query the current EMM
       status.
 ------ v5.00
   28. bugfix: the VDS disable/enable DMA translation cannot be dummies.
       They must decrease/increase a counter and if zero the automatic
       translation for the channel must be disabled.
   29. debug display of "unsupported" VDS functions removed. These functions
       will only succeed if a valid buffer ID has been supplied, which
       currently is never the case. Now just the proper error code is
       returned.
 ------ v5.01
   30. support for variable DMA buffer size added.
   31. VDS functions 07/08 (req/rel buffer) and 09/0A (copy in/out of
       DMA buffer) implemented. VDS functions 03/04 (lock/unlock region)
       now really implemented (they will use functions 07/08 if needed).
   32. option ALTBOOT implemented. Uses Int 15h, ah=4Fh as keyboard hook.
   33. bugfix: install an XMS handler even if no UMBs are supplied, since
       the XMS handler is also used for A20 handling.
   34. bugfix: NoVCPI no longer requires NoEMS to work. Why was this ever
       implemented?
   35. bugfix: INT 67h, AH=4Eh, Subfunc 2 didn't set state.
   36. INT 67h, AH=4Fh implemented
   37. bugfix: INT 67h, AH=43h left EMM in an inconsistent state if it
       ran out of free pages during the allocation.
 ------ v5.10
   38. bugfix: ALTBOOT not set and a write into FF00 segment caused a
       page fault which was not handled correctly, causing crash.
   39. EMS/VCPI memory management improved, no space wasted.
   40. 32 MB limit for EMS may be overcome with MIN= option.
   41. if pool sharing cannot be activated and MIN= parameter is not
       set in command line, a reasonable assumption is made about amount
       of EMS/VCPI memory to allocate.
   42. debug messages during protected-mode initialization implemented.
   43. Jemm's ASM part can be assembled with MASM 6.1
   44. protected-mode segments V86SEG and INITSEG made 32-bit.
   45. save/restore CR2 on page faults at page FF (ALTBOOT).
       (reverted in v5.21 since it was useless).
   46. bugfix: if pool sharing is on, A20 disabled and Himem has placed
       its handle table into the HMA ...
   47. A20 emulation now (also) done on the "port" level. The XMS hook
       still is useful if XMS host has decided not to disable A20 ever
       (because it has found A20 on on startup).
   48. all inline assembler code moved to Jemm's ASM part to make the
       C source compileable with other compilers (Open Watcom, MS VC).
       Compiler specific helper functions for DWORD div/mod/mul/shl/shr
       added.
   49. bugfix: some EMS functions (int 67h, ah=57h) destroyed hiword(eax).
   50. int 67h, ax=5900 "implemented".
   51. bugfix: in MAP_PAGE, the logical page to map may be invalid
       (because the page was mapped into the page frame, but its handle
       has long been released). Then do not try to get pool information
       for this page, this may map "random" pages into the page frame.
       Instead, unmap the page, which will result in linear=phys.
 ------ v5.20
   52. check CX parameter is not > 8000h in int 15h, ah=87h emulation.
   53. LOAD command line parameter support added.
 ------ v5.21
   54. bugfix: EMS realloc may have changed logical page order of a handle.
 ------ v5.22
   55. close files before going resident as TSR.
   56. implemented VDS 8105 (scatter lock) with bit 6 of DL set
       (returning PTEs).
   57. EMX option added.
 ------ v5.23
   58. bugfix: int 67h, ax=5001h, didn't work, but may have reported
       success.
   59. PGE option added.
 ------ v5.24
   60. bugfix: if Ctrl-Alt-Del is detected the real-mode int 15h chain
       is called first before rebooting (allows SmartDrv and others to
       cleanup).
 ------ v5.25
   61. bugfix: VDS Request/Release Buffer called VDS Copy In/Out of buffer,
       but the latter has an additional parameter (offset in buffer in
       BX:CX), which has to be set to 0 first.
   62. bugfix: VDS Request Buffer was unable to alloc the last kb of the
       DMA buffer.
   63. bugfix: VDS Release Buffer was unable to release a buffer if size
       was < 400h and > 0.
 ------ v5.26
   64. bugfix: int 67h, ah=5Ah with BX=0 didn't return a valid handle in DX
   65. bugfix: int 67h, ah=51h destroyed content of AL register
   66. bugfix: int 67h, ah=51h may have called function TryFreeToXMS with
       DF set, which might have caused data corruption.
 ------ v5.27
   67. bugfix: int 4Bh, ax=8105h (scatter lock): if bits 0-11 of offset in
       EDDS were <> 000h, the first page was returned as a separate region.
   68. bugfix: int 4Bh, ax=8105h (scatter lock): if this function failed
       with AL=9, it should have set field NumUsed in EDDS with a value
       required to describe the full region. This wasn't always the case.
   69. bugfix: Int 67h, ah=53h and 54h accessed (nonexistant) name table
       entries. Since it is possible to alloc a handle even with NOEMS,
       the name table must always exist.
   70. bugfix: int 67h, ah=57h (move to/from expanded memory) didn't work
       without a page frame.
 ------ v5.28
   71. int 67h, ah=58h now works with NOEMS.
   72. error code of int 67h, ah=41h, 47h, 48h if no page frame is defined
       changed to 80h from 91h, because 91h seems to be defined for EMS
       v4.0 only.
   73. NOINVLPG option added.
 ------ v5.29
   74. int 67h, ah=55h/56h implemented.
   75. bugfix: int 67h, ah=57h didn't always flush the correct TLB entries.
   76. bugfix: int 67h, ax=4F01h didn't work.
 ------ v5.30
   77. bugfix int 67h, ah=57h: test for overlapping EMS regions didn't
       work.
   78. bugfix int 67h, ah=57h: conventional memory regions weren't tested
       if they exceed the 1 MB boundary, in which case error A2h should be
       returned.
   79. bugfix: int 67h, ah=57h didn't return status 92h if an overlapp
       occured (92h is a hint that part of the source has been overwritten).
   80. bugfix: if an exception occured in the v86-monitor, the register
       contents were displayed wrongly in v5.30.
   81. exceptions occured in protected-mode are now displayed the same way
       as the v86-exceptions, that is, through int 29h in v86-mode. The
       previous solution (writing directly into the video screen buffer
       from protected-mode) didn't work if screen was in graphics mode.
   82. handler for v86-int06 (invalid opcode exception) moved to protected
       mode, reduces monitor's conventional memory usage to 192 bytes.
 ------ v5.31
   83. removed an optimisation in MAP_PAGE, which caused problems with
       PKZIP/PKUNZIP.
 ------ v5.32
   84. changes in REBOOT (some old machines still didn't reboot with
       Ctrl-Alt-Del).
   85. monitor stack, GDT and IDT added to V86SEG. Thus the extra
       monitor stack segment is no longer needed, and SS can be used
       to access monitor data. Small catch: file size increases by about
       2,5 kB because stack, GDT and IDT are now a static part of the
       binary.
   86. V86SEG + INITSEG grouped into one 32bit segment (_TEXT32),
       and RSEG + _TEXT grouped into one 16bit code segment (_TEXT16).
       This finally reduces number of physical segments to 3:
       _TEXT16: 16 bit code (real-mode)
       _TEXT32: 32 bit code+data (protected-mode)
        DGROUP: 16 bit data (real-mode)
   87. bugfix: EMS might have been disabled due to a query with a
       wrong segment register assume.
 ------ v5.33
   88. bugfix: ALTBOOT was erroneously always enabled since int 15h
       is always hooked in protected-mode.
 ------ v5.34
   89. bugfix: msg "unable to continue - please reboot" wasn't displayed
       in versions 5.31-5.34
   90. bugfix: clearing "Dirty" and "Accessed" bits in PTEs of page
       table 0 on initialization didn't work in versions 5.24-5.34
   91. bugfix: int15h, ah=87h emulation cleared TF, not CF
   92. bugfix: exc06 display did always print the v86 exc type display
       (that is, with segment registers), although they weren't rendered.
   93. ASM source splitted into Jemm32.asm (32bit) and Jemm16.asm.
       The 32bit part is now true FLAT and assembled+linked in a
       separate module in Win32 COFF format.
   94. NOHI option implemented.
   95. Exec_Int implemented to execute v86 interrupts directly from inside
       the monitor, which makes some hacks unnecessary and further reduces
       conventional memory usage.
 ------ v5.4
   96. "int 67h, ah=87h" hack removed. The int 15h extended memory block
       move emulation code is now called the same way as the other code,
       by a v86 breakpoint.
   97. the Jemm386 binary can be unloaded.
 ------ v5.45
   98. bugfix: 16-bit DMA channel I/O was wrong (wrong I/O port for
       base address calculated in Dma_Checkchannel.
   99. bugfix: 2 lines 'disappeared' in v5.45, making Jemm to always
       display "can't continue" message.
  100. FASTBOOT option implemented.
 ------ v5.46
  101. int 10h, ah=0Eh now used for character output. Previously int 29h
       was used, but int 10h will work even if no DOS is running.
  102. bugfix: if FASTBOOT is active, calling int 15h, ax=C201h to reset a
       PS/2 mouse wasn't done.
  103. FASTBOOT now works also if INT 19h is called. And it no longer
       automatically enables ALTBOOT option.
  104. optionally an XMM can be included (switch ?INTEGRATED).
  105. implemented interrupt window for memory block moves (int 15h, ah=87h
       and XMS function 0Bh). Currently for JemmEx only.
 ------ v5.50
  106. interrupt window also implemented for EMS memory move (ah=57h)
       Currently for JemmEx only.
  107. bugfix: xms memory realloc function 0Fh caused the stack not to be
       dword-aligned. If an interrupt occured during the memory block move,
       a GPF might happen.
 ------ v5.51
  108. bugfix in jemm16.asm: when moving the resident part high there was
       too much copied, resulting in garbage being displayed if I=B000-B7FF
       was set.
 ------ v5.52
  109. bugfix: it's ensured now that an invalid value of the cpu flags
       (IOPL != 3) onto the stack will not cause a GPF if an IRET in
       v86-mode has to be emulated by Jemm (Simulate_Iret).
  110. new function code 08 implemented for EMMXXXX0 device IOCTL reads
       which returns position (and size) of the VMM service table.
  111. dword and string I/O now simulated correctly for trapped port access.
  112. GDT and IDT moved to nonshared memory.
  113. the ring 0 stack has been increased to 4 kB and moved to nonshared
       space.
  114. table-oriented IO-port trapping implementation activated.
 ------ v5.6
  115. "service table info" extended with full GDTR, IDTR and TR info, thus
       allowing JLoad to avoid SGDT/SIDT opcodes (which are a problem for
       virtualizers).
  116. bugfix: Int 67h, ah=51h (EMS reallocate) might have failed to
       increase the handle's pages although there were enough free pages
       available.
  117. bugfix: trying to release the NULL handle will now reallocate it with
       size 0.
  118. bugfix: 4 VCPI pages in second pool block might have got lost if
       first block contained an odd number of 16k pages.
  119. VCPI 4k page alloc optimized, does no longer need to calculate
       the current amount of allocated pages.
  120. Jemm32.asm splitted into several parts.
  121. bugfix: memory used to map in UMBs is no longer contained in EMS
       system handle 0.
  122. mapping UMBs is no longer done in Jemm16c.c. There is also no
       longer an "initialization phase" terminated by an int 67h, ax=449Fh.
  123. bugfix: if Jemm was loaded from the command line and the resident
       part was moved high, the driver chain got corrupted.
  124. bugfix: unmapping EMS pages did not work with int 67h, ah=50h.
  125. B=xxxx parameter added. Pages 4000-9FFF are now "mappable". 
  126. bugfix: EMS function "alter page map and call" did unconditionally
       restore the status of the page frame, ignoring the "old" parameter
       in the map_and_call_struct. 
 ------ v5.61
  127. bugfix: EMS function 5900h still returned 8 as size for a map context
       save (v5.61 only).
  128. bugfix: EMS function 5301h (set handle name) did not check if the
       name already exists.
  129. bugfix: when Jemm was loaded from the command line, it didn't hook
       in the driver chain if it didn't moved itself high (v5.61 only).
  130. bugfix: there was a chance that Jemm386 didn't install an UMB 
       handler, resulting in the UMB not being used by DOS (v5.61 only).
  131. bugfix: I=TEST might have reduced amount of UMBs by 4 kB.
  132. int 67h, ah=5Bh implemented (alternate map register sets).
  133. the EMS system handle is now populated with the mappable pages below
       A000h, as described in EMS 4.0 docs (and also done by MS Emm386).
 ------ v5.62
  134. bugfix: NOEMS didn't deactivate EMS in v5.62
 ***************************************************************************
