Showing preview only (1,301K chars total). Download the full file or copy to clipboard to get everything.
Repository: Baron-von-Riedesel/Jemm
Branch: master
Commit: 87055a625835
Files: 197
Total size: 1.2 MB
Directory structure:
gitextract_t40dgl9z/
├── Artistic.txt
├── History.txt
├── Html/
│ └── Readme.html
├── Include/
│ ├── FILEACC.INC
│ ├── FINDRES.INC
│ ├── JLM.H
│ ├── JLM.INC
│ ├── JLMFASM.INC
│ ├── JSYSTEM.INC
│ ├── PRINTF.INC
│ ├── VDS.INC
│ └── X86.INC
├── JLM/
│ ├── AHCICD/
│ │ ├── AHCICD.ASM
│ │ ├── AHCICD.txt
│ │ ├── MAKE.BAT
│ │ └── MAKEM.BAT
│ ├── GENERIC/
│ │ ├── GENERIC.ASM
│ │ ├── MAKEFILE
│ │ ├── README.TXT
│ │ └── TESTGEN.ASM
│ ├── HELLO/
│ │ ├── HELLO.ASM
│ │ ├── MAKE.BAT
│ │ └── README.TXT
│ ├── HELLO2/
│ │ ├── HELLO2.C
│ │ ├── HELLO2W.C
│ │ ├── JLMW.ASM
│ │ ├── JLMW.h
│ │ ├── MAKEJLMW.BAT
│ │ ├── MAKEOW.BAT
│ │ ├── MAKEVC.BAT
│ │ ├── README.TXT
│ │ └── makeow.sh
│ ├── IOTRAP/
│ │ ├── IOTRAP.ASM
│ │ ├── MAKEFILE
│ │ ├── README.TXT
│ │ └── TESTIOT.ASM
│ ├── JCLOCK/
│ │ ├── JCLOCK.ASM
│ │ ├── JCLOCK2.ASM
│ │ ├── JCLOCK3.ASM
│ │ ├── MAKE.BAT
│ │ ├── MAKE3.BAT
│ │ └── README.TXT
│ ├── JLSTUB/
│ │ ├── Build/
│ │ │ └── JLSTUB.lst
│ │ ├── JLSTUB.ASM
│ │ ├── JLStub.txt
│ │ └── Make.BAT
│ ├── KEYBGR/
│ │ ├── KEYBGR.ASM
│ │ ├── MAKE.BAT
│ │ ├── MAKEFILE
│ │ └── README.TXT
│ ├── QPIEMU/
│ │ ├── MAKE.BAT
│ │ ├── MAKEFILE
│ │ ├── QPIEMU.ASM
│ │ ├── QPIEMU.txt
│ │ └── Test/
│ │ ├── MAKEFILE
│ │ ├── PRINTF16.INC
│ │ ├── SETARGV.INC
│ │ ├── TESTDMA.ASM
│ │ └── TESTQPI.ASM
│ ├── README.TXT
│ ├── REBOOT/
│ │ ├── FASTBOOT.ASM
│ │ ├── FASTBOOT.txt
│ │ ├── FASTBRM.ASM
│ │ ├── FBOOT.ASM
│ │ ├── LDI13EXT.ASM
│ │ ├── MAKE.BAT
│ │ ├── REBOOT.ASM
│ │ └── REBOOT.txt
│ ├── XCDROM32/
│ │ ├── History.txt
│ │ ├── MAKE.BAT
│ │ ├── MAKEM.BAT
│ │ ├── XCDROM32.ASM
│ │ └── XCDROM32.txt
│ └── XDMA32/
│ ├── History.txt
│ ├── IDENTIFY.INC
│ ├── MAKE.BAT
│ ├── MAKEM.BAT
│ ├── XDMA32.ASM
│ └── XDMA32.txt
├── JemmExL.mak
├── Linux.mak
├── Makefile
├── Readme.txt
├── Test/
│ ├── BMINTRM.ASM
│ ├── EMS4E.ASM
│ ├── EMS4F.ASM
│ ├── EMS56.ASM
│ ├── EMS57.ASM
│ ├── EMS57A.ASM
│ ├── EMS5B.ASM
│ ├── EXC00.ASM
│ ├── EXC06.ASM
│ ├── FRAMERES.ASM
│ ├── HLTTEST.ASM
│ ├── HLTTEST2.ASM
│ ├── I15MOVE.ASM
│ ├── INT67.ASM
│ ├── INT88.ASM
│ ├── MACROS.INC
│ ├── MAKE.BAT
│ ├── PRINTF.INC
│ ├── README.TXT
│ ├── TEST0C.DEB
│ ├── TEST0C1.DEB
│ ├── TEST0D.DEB
│ ├── TEST10.DEB
│ ├── TEST11.DEB
│ ├── TESTDMA.ASM
│ ├── TESTDMA2.ASM
│ ├── TESTDMA3.ASM
│ ├── TESTVCPI.ASM
│ ├── TESTVDS.ASM
│ ├── TESTVDS2.ASM
│ ├── TESTVDS3.ASM
│ ├── TIMERMS.INC
│ ├── VCPI.INC
│ ├── XMSTEST.ASM
│ ├── XMSTEST2.ASM
│ ├── XMSTEST3.ASM
│ ├── XMSTEST4.ASM
│ └── XMSTEST5.ASM
├── Tools/
│ ├── CLEAR.BAT
│ ├── CPUID/
│ │ ├── CPUID.ASM
│ │ ├── MAKE.BAT
│ │ └── PRINTF.INC
│ ├── Cpustat/
│ │ ├── CPUSTAT.ASM
│ │ ├── MAKE.BAT
│ │ └── PRINTF.INC
│ ├── EMSSTAT/
│ │ ├── EMSSTAT.ASM
│ │ ├── MAKE.BAT
│ │ └── PRINTF.INC
│ ├── JEMFBHLP/
│ │ ├── JEMFBHLP.ASM
│ │ └── MAKE.BAT
│ ├── JLOAD/
│ │ ├── DEBUG.INC
│ │ ├── DPRINTF.INC
│ │ ├── DPRNTF16.INC
│ │ ├── History.txt
│ │ ├── JLOAD.ASM
│ │ ├── JLOAD.INC
│ │ ├── JLOAD.TXT
│ │ ├── JLOAD.txt
│ │ ├── JLOAD32.ASM
│ │ ├── JLOAD32.INC
│ │ ├── Linux.mak
│ │ ├── MAKEFILE
│ │ ├── VDMAD.ASM
│ │ ├── VIOOUT.INC
│ │ ├── VMM.ASM
│ │ ├── WINNT.INC
│ │ └── license.txt
│ ├── MAKE.BAT
│ ├── MEMSTAT/
│ │ ├── MAKE.BAT
│ │ ├── MEMSTAT.ASM
│ │ └── PRINTF.INC
│ ├── MoveXBDA/
│ │ ├── MAKE.BAT
│ │ └── MOVEXBDA.ASM
│ ├── UMBM/
│ │ ├── MAKE.BAT
│ │ └── UMBM.ASM
│ ├── VCPI/
│ │ ├── MAKE.BAT
│ │ ├── PRINTF.INC
│ │ ├── VCPI.ASM
│ │ ├── VCPI.INC
│ │ └── VIOOUT.INC
│ └── XMSSTAT/
│ ├── MAKE.BAT
│ ├── PRINTF.INC
│ └── XMSSTAT.ASM
├── XMS35.txt
└── src/
├── AUXIO.INC
├── DEBUG.ASM
├── DEBUG16.INC
├── DEBUG32.INC
├── DEBUGSYS.INC
├── DEV.ASM
├── DMA.INC
├── DPRINTF.INC
├── DPRNTF16.INC
├── EMS.ASM
├── EMS.INC
├── EMS32.INC
├── EMU.ASM
├── EXTERN32.INC
├── I15.ASM
├── INIT.ASM
├── INIT16.ASM
├── JEMM.INC
├── JEMM16.ASM
├── JEMM16.INC
├── JEMM32.ASM
├── JEMM32.INC
├── POOL.ASM
├── UMB.ASM
├── VCPI.ASM
├── VCPI.INC
├── VDMA.ASM
├── VDS.ASM
├── XMS.ASM
└── XMS.INC
================================================
FILE CONTENTS
================================================
================================================
FILE: Artistic.txt
================================================
The Artistic License Preamble
The intent of this document is to state the conditions under which a Package may
be copied, such that the Copyright Holder maintains some semblance of artistic
control over the development of the package, while giving the users of the
package the right to use and distribute the Package in a more-or-less customary
fashion, plus the right to make reasonable modifications.
Definitions:
"Package" refers to the collection of files distributed by the Copyright Holder,
and derivatives of that collection of files created through textual
modification. "Standard Version" refers to such a Package if it has not been
modified, or has been modified in accordance with the wishes of the Copyright
Holder. "Copyright Holder" is whoever is named in the copyright or copyrights
for the package. "You" is you, if you're thinking about copying or distributing
this Package. "Reasonable copying fee" is whatever you can justify on the basis
of media cost, duplication charges, time of people involved, and so on. (You
will not be required to justify it to the Copyright Holder, but only to the
computing community at large as a market that must bear the fee.) "Freely
Available" means that no fee is charged for the item itself, though there may be
fees involved in handling the item. It also means that recipients of the item
may redistribute it under the same conditions they received it. 1. You may make
and give away verbatim copies of the source form of the Standard Version of this
Package without restriction, provided that you duplicate all of the original
copyright notices and associated disclaimers.
2. You may apply bug fixes, portability fixes and other modifications derived
from the Public Domain or from the Copyright Holder. A Package modified in such
a way shall still be considered the Standard Version.
3. You may otherwise modify your copy of this Package in any way, provided that
you insert a prominent notice in each changed file stating how and when you
changed that file, and provided that you do at least ONE of the following:
a) place your modifications in the Public Domain or otherwise make them Freely
Available, such as by posting said modifications to Usenet or an equivalent
medium, or placing the modifications on a major archive site such as ftp.uu.net,
or by allowing the Copyright Holder to include your modifications in the
Standard Version of the Package.
b) use the modified Package only within your corporation or organization.
c) rename any non-standard executables so the names do not conflict with
standard executables, which must also be provided, and provide a separate manual
page for each non-standard executable that clearly documents how it differs from
the Standard Version.
d) make other distribution arrangements with the Copyright Holder.
4. You may distribute the programs of this Package in object code or executable
form, provided that you do at least ONE of the following:
a) distribute a Standard Version of the executables and library files, together
with instructions (in the manual page or equivalent) on where to get the
Standard Version.
b) accompany the distribution with the machine-readable source of the Package
with your modifications.
c) accompany any non-standard executables with their corresponding Standard
Version executables, giving the non-standard executables non-standard names, and
clearly documenting the differences in manual pages (or equivalent), together
with instructions on where to get the Standard Version.
d) make other distribution arrangements with the Copyright Holder.
5. You may charge a reasonable copying fee for any distribution of this Package.
You may charge any fee you choose for support of this Package. You may not
charge a fee for this Package itself. However, you may distribute this Package
in aggregate with other (possibly commercial) programs as part of a larger
(possibly commercial) software distribution provided that you do not advertise
this Package as a product of your own.
6. The scripts and library files supplied as input to or produced as output from
the programs of this Package do not automatically fall under the copyright of
this Package, but belong to whomever generated them, and may be sold
commercially, and may be aggregated with this Package.
7. C or perl subroutines supplied by you and linked into this Package shall not
be considered part of this Package.
8. The name of the Copyright Holder may not be used to endorse or promote
products derived from this software without specific prior written permission.
9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
The End
================================================
FILE: History.txt
================================================
History
__.__.____: v5.87
- fixed regression in v5.86: exceptions in PL0 were displayed incorrectly.
- fixed: NMIs that occured while no full stack frame was setup caused
a crash.
- segment registers DS/ES/FS/GS and [CS:IP] now also displayed for PL0
exceptions.
- NMIs are masked while NMI exceptions are handled.
- fixed: Simulate_Int() cleared bits 16-31 of register ESP.
- JemmEx fix: if option XMSHANDLES was > 59 and Jemm wasn't allowed to move
its resident part into the upper memory region, it crashed.
- Linux.mak: GNU makefile added to create Jemm binaries on Linux.
- fixed JemmEx: unknown A20METHOD value caused a crash.
- AHCICD: driver now supports long reads in "raw mode".
25.01.2026: v5.86
- service table: added control proc member to allow Jemm to call out on
certain events; currently "device_reboot_notify" is the only call-out.
- service table: added v86faults member - allows programs to hook into
v86 faults; used by JLOAD.
- Simulate_Int: call an installed v86 hook proc before running the INT.
- JemmEx, XMS AH=0Eh: invalid handle error returned if size > 65535 kB;
this is MS Himem compatible.
- JLMs Reboot & FastBoot added.
- fixed debug displays in 16-bit part.
- fixed debug displays in Jemm16.asm, UnloadJemm.
- JemmEx: option NOE820 reintroduced; it's a noop unless MAXSEXT is 0.
- fixed option UNLOAD: on 80386/80486 cpus, it wasn't safe.
- JLM QPIEmu: added function ax=5000h.
- reintroduced compatibility with SB emulation drivers SB(E)INIT for SB PCI
cards by extending functionality of cmdline option SB.
- NMI stability increased.
10.01.2025: v5.85
- fixed: VDS func ax=810Ch: set ZF if disable cnt reaches zero.
- fixed: VDS: added several argument checks ( mostly DX ).
- fixed: ISA DMA ports 000A-000F must be handled by Jemm to detect FD accesss
even if external handler has trapped these ports.
- fixed: it was assumed that value for TR to be loaded in VCPI function
ax=DE0Ch ( switch from v86- to protected-mode) had bits 0-2 cleared.
- linear address region 110000-3FFFFF is now only mapped as far as needed by
the monitor program (looses SB(E)INIT compatibility).
- optional kernel-debugger-aware variant calls int 68h for deinitialization.
- cmdline switch NOVMW added.
- easier log displays via macro @dprintf.
- log displays redirected to kernel debugger if one has been detected.
- buffered output of log displays removed.
- switch ?SAFEKBD=1 is now default for JemmEx (restores IVT vector 15h before
reading a key press via int 16h during system errors).
- JemmDbg renamed to JDeb386 and removed from Jemm source package.
- building JemmExL.exe removed from Makefile; to create it, use JemmExL.mak.
- CPUSTAT: optionally displays interrupt redirection bitmap.
12.02.2024: v5.84
- fixed: Simulate_IO() no longer calls trap handler.
- QPIEMU: new JLM that partly implements Qemm's API (QPI).
- fixed: int 67h, ax=5B01h will return error code A3h if checksum invalid.
- JemmDbg: removed from binary package.
06.12.2022: v5.83
- AHCICD: new JLM for CD/DVD devices attached to a SATA controller running
in AHCI mode (cooked mode only).
- XDMA32, XCDROM32: now accepting "AHCI-disabled" SATA controllers.
- JemmEx: warning displayed if I15 memory blocks had to be ignored due
to insufficient XMS "static" handles (8); static handles increased to 10.
- JemmDbg: a PL0 debugger, based on Debug/X; may be used to debug JLMs.
- Makefile supports creating variants of Jemm386/JemmEx that are kernel
debugger aware.
- CPUSTAT: optionally displays IOPB (trapped ports).
09.08.2022: v5.82
- JemmEx: minor adjustment to always keep monitor stack dword-aligned.
- fixed: MOVEXBDA option didn't check that XBDA was adjacent to conv. mem.
- JLoad: fixed: hook int 2Fh (used to get JLM API entry) was incorrect.
- CPUID: fixed: feature information incorrect.
- CPUSTAT: fixed: options -g and -i if physical != linear address.
- XDMA32: fixed: did reject many disks if /M option wasn't set.
12.04.2022: v5.81
- JemmEx: XMS extension v3.51 (super-extended block moves) implemented.
18.06.2021: v5.80
- for exceptions other than page faults, the monitor will display register
CR4 instead of CR2, if it exists.
- Jemm might have reduced last MCB by 16 byte when loaded while UMBs
where already available and used by DOS.
- Jemm does again scan the region C000-EFFF for RAM. This avoids
a system crash if upper memory has been supplied by UMBPCI and is
used by DOS.
- new option MOVEXBDA for Jemm implemented.
- JemmEx will recognize memory blocks activated by UMBPCI and include them
into its UMB pool. Makes option S=start-end virtually obsolete.
- a warning is displayed if the extended memory block where Jemm386 will
reside is beyond the 16MB limit.
- strategy to realloc an EMB to increase its size has been changed and is
now smart enough to check if the block can be increased without moving
it.
- UMBM no longer requires the /I parameter; it will scan for blocks with
the UMBPCI signature.
- UMBM has new option /XBDA.
- UMBM now acts gracefully if line DOS=UMB is missing in CONFIG.SYS.
- MOVEXBDA has got option /A to make it align the new XBDA to a kB boundary.
- tool CPUSTAT split into CPUSTAT and CPUID.
- emulation of Int 15h, ah=87 (move extended memory) has been enhanced
to allow to access physical memory beyond the 4 GB border via PSE-36.
- JemmEx XMM now implements XMS v3.5 (extended memory > 4 GB). Default XMS
handles changed to 48 (previously 32). Added MAXSEXT option for JemmEx,
and also added JemmExL.exe, that still supports XMS v3.0 only.
- JemmEx: return DX=0 if XMS alloc functions fail (XMS spec).
- option I=TEST does now indeed what's documented. Previously it only
scanned regions of "external" ROMs ( i.e., the ROM of the VGA card ).
This means it's more "aggressive" now.
- ALTBOOT option sends "system reset" command to keyboard controller.
02/02/2020: v5.79
- if physical address of DMA buffer was beyond 16M, its size was reset
to zero. This is no longer done.
- default linker is now JWlink.
- debug displays added for mode switch calls.
- Jemm will now use info returned by Int 15h, ax=E820h to mark regions
in the upper memory area as reserved. If the call was successful,
Jemm won't scan the memory region C000-EFFF for RAM.
- VME (virtual mode extensions) is now off by default; there exist CPUs
that claim to support VME but actually don't.
- JemmEx's built-in XMS host will now use up to 8 memory blocks listed
by ACPI (int 0x15, ax=0xe820). Previously it could just use the one
with base address 0x100000.
- fixed: shrinking an EMB didn't work correctly.
07/15/2012: v5.78
- bugfix: if SPLIT option was set and there were 2 ROMs to be split on
adjacent 4K-pages, the latter one may have been overwritten with zeros
(problem found in Qemu v0.15.1).
- bugfix: MOVEXBDA didn't restore the XBDA at reboot. This may have been
a problem if the FASTBOOT option was active.
- a warning is displayed if the page frame isn't set to a segment address
divisible by 0x400 without remainder ( i.e, FRAME=DF00 will trigger the
warning ).
- MEMSTAT additionally displays location and size of XBDA.
- source package only: extrsect.exe replaced by bin2inc.exe; bin2inc.exe
is needed only if Masm is used to assemble the source.
06/20/2012: v5.77
- commandline option I=A000-B7FF didn't increase DOS low memory, the
region became just the first UMB.
- tool MOVEXBDA added.
05/25/2012: v5.76
- an 64kB EMS page frame may now be located inside address space included
with 'I=XXXX'.
05/21/2012: v5.75a
- no changes in JemmEx/Jemm386, just bugfixes in XDMA32.DLL and
XCDROM32.DLL.
05/31/2011: v5.75
- bugfix: when Jemm detected Ctrl-Alt-Del, it didn't reset the keyboard
status. This may have caused a locked keyboard if FASTBOOT was set.
04/14/2011: v5.74
- tool MEMSTAT added, which will display the size of the reserved
BIOS-ROM region.
- Make process simplified, all sources are assembly now.
12/02/2010: v5.73
- bugfix: int 67h, ah=51h didn't complain if handle was invalid in
v5.61-5.72.
- tool CPUSTAT added.
- for emulation of Int 15h, AH=87h (extended memory block move), the
region 100000h-10FFFFh is now handled similar to the rest of extended
memory. Previously it was handled as "real-mode" memory, which means
that access did depend on the A20 state. This new behavior matches
more closely the BIOS implementation of this interrupt.
- option V86EXC0D added.
03/13/2008: v5.72
- source has been made compatible with JWasm; OTOH, TASM compatibility
has been abandoned.
02/25/2008: v5.71
- bugfix: DMA buffer size of 0 (D=0) didn't work in v5.70.
- bugfix: JLOAD v5.70 made wrong assumptions about Jemm's TSS location,
which caused JLM sample JCLOCK2 to fail.
- some minor changes to make it compatible with JWasm.
01/30/2008: v5.70
- bugfix: the "copy memory" routine wasn't reentrant, making an XMS
"block move" or a call of Int 15h, ah=87h from within an ISR slightly
unsafe.
- bugfix: int 67h, ah=57h returned error 8Ah instead of 93h when a
region exceeded the size of the EMS handle.
- bugfix: int 67h, ah=57h accepted any region type (just 00 and 01 are
valid ones).
- bugfix: int 67h, ax=5701h accepted overlapping EMS regions. Now status
97h is returned.
- bugfix: since v5.61 (support for mappable pages in conventional memory)
option NODYN often failed to make all memory available which was
requested with the MIN=x option.
- bugfix: exception 11h in v86-mode caused a loop in Jemm's exception
handler.
- bugfix: due to an alignment problem the low byte of max. free memory
block for XMS v2 (X2MIN) was 0, as a result the default block size was
65280 (0xFF00) instead of 65535 kB (JemmEx only, bug since v5.64).
- int 67h,ax=5701h, "memory exchange" is now also done with interrupts
enabled if client's interrupt flag is set.
- port 60h access is now trapped only if the keyboard controller's output
port is accessed.
- tool XMSSTAT and source of EMSSTAT added.
01/07/2008: v5.69
- descriptions/changelogs for XDMA32 and XCDROM32 extracted from this
readme into separate files XDMA32.TXT and XCDROM32.TXT.
- memory block copies are now done with interrupts enabled - if client's
interrupt flag is set. This avoids interrupt latency and makes the
previously implemented "interrupt windows" obsolete. It also avoids
problems with Jemm's HLT emulation causing IRQs to be misinterpreted
as exceptions (08, 09, 74, ...) on some cpus.
- bugfix: VDS scatter/gather lock with region size 0 returned 0 entries,
but 1 entry must be returned in any case (MS Emm386 does as well).
- bugfix: there was a risk that a ROM located contiguously behind another
ROM in address space wasn't detected.
- bugfix: if SPLIT option was set and a split ROM page followed an UMB
page (which is possible if ROM size is < 4 kB), the ROM part of this
page was added to the UMB.
- bugfix: synchronization of VCPI and EMS free memory count did work
for VCPI only, that is, allocating all VCPI memory didn't reduce free
EMS memory to zero.
- bugfix: the last XMS memory block allocated for EMS/VCPI memory was
likely to be too large, thus wasting XMS memory.
- VCPI/EMS memory alloc/release speed-up.
- EMSSTAT -v displays more VCPI infos.
- v86 exceptions >= 8 are routed to v86 interrupt 06h only if this vector
has been changed by another program.
- exception 10h (floating point) is now detected and displayed, thus avoiding
the hazardous call of video interrupt 10h (MS Emm386 also detects
exception 10h, but just allows to reboot then).
12/03/2007: v5.68
- bugfix: JLOAD's "Lock DMA" function ignored flag to check for 64 kB
border crossing.
- NMIs occuring inside the monitor are now silently routed to v86-mode.
Previous Jemm versions displayed an exception dump.
- XDMA32 v1.0 added.
- XCDROM32 changed to v1.1.
10/13/2007: v5.67
- bugfix: I=TEST always scanned 4 kB chunks, although the last page
of a ROM might be smaller (512, 1024, ... bytes).
- bugfix: if I=TEST found an "unused" page in a ROM, v5.64-5.66 messed
up an internal counter. As a result, there was a small risk that the
begin of another ROM following this one in the address space wasn't
detected.
- error code displayed in exception dump.
- selected A20 method now displayed in "verbose" mode only.
- tool EMSSTAT added.
08/24/2007: v5.66
- bugfix: GDT, which has been moved to nonshared space in v5.6, moved
to shared space again. Required by applications written for the Phar
Lab TNT DOS extender.
08/19/2007: v5.65
- Standard reboot handler made fully MS Emm386 compatible. The ALTBOOT
option is now a dummy.
- auto-scanning for a page frame will now ensure that the frame begins
on a 16 kB boundary. This is MS Emm386 compatible.
07/12/2007: v5.64
- bugfix: for FASTBOOT, IVT vectors 78h-7Fh should be reset to 0000:0000.
This wasn't done.
- SPLIT option added.
06/22/2007: v5.63
- bugfix: NOEMS didn't disable EMS in v5.62
- bugfix [JemmEx only]: MAXEXT option wasn't displayed in help screen.
06/19/2007: v5.62
- bugfix: int 67h, ah=5301h (set handle name) didn't check if this name
was already assigned (and return status A1h if yes).
- bugfix: using I=TEST might have reduced amount of UMBs by 4 kB.
- bugfix: in v5.61, Int 67h, ax=5900h still returned 8 as mapping context
size, which usually is too small now (# of physical pages are > 4).
- bugfix: in v5.61, if Jemm was loaded from the command line and
remained in low memory, it didn't hook into the driver chain.
- bugfix: in v5.61, there was a risk that Jemm386 didn't install an
UMB handler (and then the UMBs were "lost").
- int 67h, ah=5Bh implemented (alternate map register sets).
- 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).
06/04/2007: v5.61
- bugfix: Int 67h, ah=51h (EMS reallocate) might have failed to increase
the handle's pages although there were enough free pages available.
This was a design flaw. Now for each EMS handle a linked lists of
allocated pages is maintained.
- bugfix: trying to release the NULL handle will now reallocate it with
size 0. This is the behavior specified in the EMS docs.
- bugfix: there was a chance that 4 VCPI pages got lost. They could be
allocated, but weren't found anymore when trying to release them.
- bugfix: memory for UMBs is no longer contained in EMS system handle 0.
This handle should only contain pages which "backfill" conventional
memory (segment addresses below A000h).
- bugfix: int 67h, ah=56h (alter page map and call) ignored the "old"
member in the "map_and_call" parameter.
- value of GDTR, IDTR and TR exposed by Jemm. This allows JLoad to avoid
usage of opcodes SGDT/SIDT, which caused problems with most virtualizers.
- allocating a 4kB page with VCPI is now significantly faster.
- B=xxxx parameter supported. Pages 4000-9FFF are mappable by default.
05/24/2007: v5.6
- bugfix: if Jemm had to emulate an IRET in v86-mode and the copy of the
flag register onto the stack was "invalid" (IOPL != 3), a GPF occured
at the next IO-sensitive instruction in v86-mode.
- bugfix [JemmEx only]: NODYN option caused a GPF on initialization.
- dword and string I/O now simulated correctly for trapped port access.
- GDT and IDT moved to nonshared memory.
- the ring 0 stack has been increased to 4 kB and moved to nonshared space.
This allows "nested execution" without using the client's v86-stack.
- JLOAD.EXE added. Jemm splitted in 2 packages: binaries and source.
Some sample JLMs added (XCDROM32, KEYBGR, ...).
- new EMMXXXX0 function exposes some of Jemm's internal call tables,
thus allowing external modules (JLOAD) to implement a 32bit ring 0 API.
- switched to a table-oriented IO-port trapping implementation, which
allows external modules (JLOAD) to hook/take over port trapping.
05/04/2007: v5.52
- bugfix: a bug introduced in v5.5 caused garbage to be displayed if
option I=B000-B7FF was used.
05/03/2007: v5.51
- bugfix [JemmEx only]: XMS memory realloc function (ah=0Fh) caused the
stack not to be dword-aligned, which slows things down and might cause
troubles if an interrupt occurs during a memory block move.
- JemmEx: EMS block moves (int 67h, ah=57h) now also done with interrupt
window if client's IF is set.
04/29/2007: v5.5
- bugfix: if Ctrl-Alt-Del was pressed with FASTBOOT active and an event
proc for the PS/2 mouse was set, a crash might have occured. Now the
PS/2 mouse is reset by Jemm before rebooting.
- bugfix: S=XXXX was ignored if it was the only region to be added as UMBs.
- in v5.46, FASTBOOT only worked by pressing Ctrl-Alt-Del. Now
it should work as well if int 19h is called.
- in v5.46, FASTBOOT always needed ALTBOOT to be set and therefore has set
this option internally. This is no longer done.
- JEMMEX.EXE added.
- JemmEx opens interrupt window in block moves (int 15h, ah=87h and
XMS function ah=0Bh) each 8 kB if client's IF is set.
03/27/2007: v5.46
- bugfix: free EMS pages not always reported correctly.
- bugfix: translation DMA for 16-bit controller (channels 4-7) didn't work.
- bugfix: Jemm always displayed "can't continue, please reboot" on
invalid opcode exceptions in v5.45.
- MIN= no longer restricted to a maximum of 512 MB (EMS pages still are).
- FASTBOOT option implemented, JEMFBHLP.EXE added.
03/02/2007: v5.45
- bugfix: in v5.40, if no option was entered when installing Jemm, it
might have displayed some garbage.
- bugfix: invalid opcode generated by Jemm if running on a cpu < 80386.
- bugfix: XMS function 11h (free UMB) always returned an error.
- option UNLOAD added.
- option RAM/NORAM implemented.
- valid range for page frame set with FRAME=xxxx now 8000-E000.
- the MAX= prefix can be omitted now. Makes the cmdline more MS Emm386
compatible.
- memory required for UMBs will no longer reduce the memory available for
EMS. This is similiar to what MS Emm386 does.
- installing Jemm from the command line now prohibited if a DPMI host
is detected.
02/20/2007: v5.4
- some minor bugfixes.
- Jemm now moves its resident part to the first UMB which it supplies.
- NOHI option implemented.
- Jemm now uses the true (=zero-based) flat memory model.
01/11/2007: v5.34
- bugfix: Jemm always hooked int 15h, ah=4Fh, thus always acting as
if option ALTBOOT was set (bug introduced in v5.25).
01/06/2007: v5.33
- bugfix: Jemm erroneously might have disabled EMS
- reboot code slightly changed, there were still some machines (old 80486?)
were Ctrl-Alt-Del didn't work.
11/13/2006: v5.32
- removed an optimisation which PKZIP didn't like.
11/09/2006: v5.31
- some minor bugfixes in function int 67h, ah=57h.
- bugfix: wrong register contents were displayed in v5.30 for exceptions
occuring in protected-mode.
- v86-mode int 06 handler moved to protected-mode, thus further reducing
Jemm's conventional memory usage.
10/27/2006: v5.30
- bugfix: int 67h, ah=57h (move/exchange memory region) didn't always
invalidate the TLB cache for the EMS memory to copy/exchange.
- bugfix: int 67h, ax=4F01h didn't work.
- int 67h, ah=55h/56h implemented.
- int 67h, ah=57h now works with overlapping memory regions. Furthermore
it is now ensured that all EMS pages involved in the copy operation are
valid before copy actually begins.
10/24/2006: v5.29
- bugfix: the error msg when the EMS call to map UMBs failed contained
garbage as "function".
- int 67h, AH=58h will now return success even with NOEMS.
- now error code 80h, not 91h is returned if functions int 67h,
ah=41h or 47h or 48h are called and no page frame is defined.
- NOINVLPG option added.
- I=TEST is now a bit less restrictive and will increase compatibility
with MS-Emm386.
- help text displayed by Jemm adjusted where it was wrong or unclear.
10/13/2006: v5.28
- bugfix, VDS function scatter/gather lock (int 4Bh, ax=8105h): if lower
12 bits of offset in EDDS were <> 000h, this function always returned
the first page as a separate region.
- bugfix, VDS function scatter/gather lock: if this function failed with
AL=9, it did not always set the correct value for items required to
describe the full region.
- bugfix: int 67h, ah=53h (get/set handle name) and ah=54h (get handle
directory) wrongly assumed that they won't be called with handles other
than 0000 if NOEMS is set.
- bugfix: int 67h, ah=57h (move/exchange memory region) didn't work without
a page frame (NOEMS or FRAME=NONE).
10/07/2006: v5.27
- bugfix: allocating a EMS block with zero pages (int 67h, ah=5Ah, bx=0)
returned with AH=0, but did not return a valid handle in DX.
- bugfix: calling int 67h, AH=51h modified AL register.
09/30/2006: v5.26
- bugfix: VDS functions 03, 04, 07 and 08 may have failed if bit 1 of DX
was set (request to copy in/out of DMA buffer) and registers BX,CX
were <> 0.
- bugfix: 1 kB of DMA buffer may have been inaccessible.
- bugfix: releasing a DMA buffer with size > 0 and < 1 kB always failed.
09/22/2006: v5.25
- bugfix: if option ALTBOOT is set and Ctrl-Alt-Del being pressed has
been detected, then the real-mode int 15h chain is called first before
rebooting. This gives other hookers (SmartDrv) a chance to cleanup.
09/19/2006: v5.24
- bugfix: int 67h, ax=5001h (implemented in v5.2) didn't work.
- bugfix: setting Jemm options from the command line did reset
the options which were not explicitely entered.
- PGE/NOPGE options added.
09/14/2006: v5.23
- bugfix: if the amount of preallocated EMS memory (MIN=xxxx) was
not below largest XMS memory block - 384 kB, the amount of free/
available EMS pages reported by Jemm was up to 384 kB too large.
- implemented VDS function 05 (scatter lock) returning PTEs instead of
"regions". This makes Jemm fully support the VDS API.
- some message texts adjusted to make it clear what is an error, a
warning or just informational.
- warning about detected system memory region now displays all such
regions, start and size.
- if wanted EMS memory has to be reduced, a warning is displayed.
- UMBM.EXE added.
- EMX option added.
09/09/2006: v5.22
- bugfix: the DMA buffer 64kb alignment may cause up to 32 kB to be lost
for EMS/VCPI memory. This wasn't taken into account, and may have
resulted in Jemm unable to alloc UMBs if options NODYN and
MIN=<value below size of UMBs+32> were set.
- bugfix: in displayed text "wanted preallocated EMS memory <nnn> kB"
<nnn> was always blank.
- space for UMBs now rounded up to next 16 kB boundary (previously it
was rounded to 32 kB).
09/07/2006: v5.21
- bugfix: in v5.2 if an invalid command line parameter was entered, the
program displayed garbage.
- bugfix: in v5.2 options setting both options NOEMS and NOVCPI might
have caused Jemm to run out of memory for UMBs.
- XMS dynamic memory allocation was automatically disabled if NOEMS and
NOVCPI options were set, but this is no longer useful since option NODYN
exists and VCPI can be dynamically set/reset from the command line.
- DMA buffer size now always rounded up to a full 4 kB boundary.
- LOAD option added which allows to install Jemm from the command line.
09/06/2006: v5.2
- bugfix: writing to "ROM" page FF000 if ALTBOOT wasn't set caused a crash.
- bugfix: if XMS handle array was in HMA and A20 got disabled results may
have been "unexpected".
- bugfix: "disable A20 local" emulation did not return an error code if
count was already 0.
- there was slightly more XMS memory allocated than required.
- support for Int 67h, ax=5001h implemented.
- option MIN= no longer deactivates XMS dynamic memory allocation.
option NODYN added, option EMM= discarded.
- If XMS memory must be preallocated (because XMS host doesn't export its
handle table) and MIN= option is not set, Jemm allocates half of
extended memory (but not more than 32 MB) for EMS/VCPI memory.
- Assembler: MASM may be used instead of TASM.
- Compiler: Open Watcom WCC or MS VC 1.5 may be used instead of TC.
- Linker: Digital Mars OPTLINK may be used instead of TLINK.
- protected-mode code switched to 32-bit.
- port trapping added to the A20 enable/disable emulation. XMS hook is
still required due to the "A20 always on" case, which causes most XMS
hosts not to touch the ports at all.
08/30/2006: v5.1
- bugfix: the DMA master mask register was read, which doesn't work
on all machines and may have caused an "illegal instruction exception"
if the floppy disk was accessed. This bug was introduced in v5.00.
- bugfix in EMS function 4Eh.
- bugfix: A20 emulation works now if no UMB handler has been installed.
- DMA buffer size may be set by commandline option.
- VDS functions 07/08 (request/release DMA buffer) and 09/0A (copy
into/out of DMA buffer) implemented. VDS functions 03/04 (lock/unlock
region) extended so that they call functions 07/08 if needed.
- NOVCPI does no longer require NOEMS.
- ALTBOOT (re)implemented, it hooks int 15h, ah=4Fh now.
- VME mode may now be set/reset with VME/NOVME options.
- LIBM.LIB no longer needed to create the JEMM386.EXE binary.
08/25/2006: v5.01
- bugfix: "A20 enabled"-count was 0 on startup, should have been 1.
- bugfix: unsupported VDS functions caused a debug display, which didn't
work and may have caused corruption of monitor data. Debug displays
removed.
- bugfix: original int 4Bh vector may have been 0000:0000 - if this is
true, it must never be chained to of course. Instead carry flag is set.
- VDS functions 0Bh and 0Ch (disable/enable translation) implemented.
08/23/2006: v5.00
- EMMXXXX0 device communication implemented
- bugfix: DMA buffer is ensured to begin on a 64 kB physical address
boundary.
- bugfix: XMS handles which are no longer used now get the "in pool" flag
set, not the "free" flag.
- Pentium+ VME extensions supported.
- A20 disable emulation activated.
08/17/2006: v5.00pre
- bugfix: in VCPI protected mode entry switch to host stack before
context is switched.
- command line option S=xxxx added.
- option NOALTBOOT deleted.
- the full physical memory is no longer mapped in the address space.
This reduces extended memory usage a lot on machines with large amounts
or RAM, since no page tables are needed.
- VDS code moved to extended memory, reducing conventional memory usage
by about 1 kB.
---------------------------------------------------------------------
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.
================================================
FILE: Html/Readme.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 FINAL//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=IBM-850">
<META NAME="author" CONTENT="Japheth">
<META NAME="keywords" content="Jemm386, JemmEx">
</HEAD>
<BODY>
<TABLE BORDER=0 CELLSPACING=4 CELLPADDING=4 WIDTH="100%" HEIGHT="100%">
<TR BGCOLOR=#E0E0E0>
<TD>
<pre>
Contents
1. About Jemm
2. Features
3. Commandline Options
4. Technical Details
4.1 EMS Implementation Notes
4.2 Emulation of privileged Opcodes
4.3 IOPL Sensitive Instructions
4.4 VMWare Detection
4.5 Option FASTBOOT
4.6 Option MAXSEXT
4.7 Option NOEMS
4.8 Option SB
5. Compatibility
6. Errors and Warnings
7. Troubleshooting, Hints
8. Additional Tools
8.1 UMBM
8.2 JEMFBHLP
8.3 CPUSTAT
8.4 MEMSTAT
8.5 XMSSTAT
8.6 EMSSTAT
8.7 VCPI
8.8 MOVEXBDA
8.9 CPUID
9. License
1. About Jemm
Jemm is an "Expanded Memory Manager" (EMM), based on the source of FreeDOS
Emm386. It should work with MS-DOS and compatible DOSes, including FreeDOS.
Like other EMMs it installs the following services:
- uses extended memory to simulate expanded memory (EMS) according to
EMS v3.2 and EMS v4.0.
- upper memory blocks (UMB) where drivers and resident programs may
be loaded, thus increasing available free DOS memory.
- mapping RAM to the video address segments A000-AFFF and B000-B7FF.
- VCPI services to allow DOS applications running in V86-mode to
switch to protected mode. VCPI also implements a simple memory management.
- VDS API to give drivers/applications some control over DMA and physical
addresses in V86-mode.
There exist 2 versions of Jemm:
- Jemm386: standard version which needs an external eXtended Memory Manager
(XMM; examples: Himem[S]X, MS Himem, XMGR ) to be loaded.
- JemmEx: extended version which has an XMM already included.
JemmEx most likely is the better choice because it will need less DOS
memory than an external XMM + Jemm386.
2. Features
The main purpose of making Jemm was to make it use less resources than
other EMMs, without making compromises regarding speed or compatibility.
The results currently are:
- Jemm386 needs just 128 bytes DOS upper memory. JemmEx uses more, mostly
because it includes the XMS handle array which is located in DOS memory.
With 32 XMS handles JemmEx needs 496 bytes DOS memory.
- Jemm's extended memory usage is:
+ 44 kB for Jemm itself
+ 64 kB for the DMA buffer (default size)
+ xx kB for UMBs mapped in the first MB
+ 4 kB fixed amount for EMS handle management.
+ xx kB variable amount for EMS/VCPI memory management. For each 1.5 MB
VCPI memory 64 bytes are needed, for each EMS page 5 bytes are needed.
For the default values (120 MB VCPI, 2048 EMS pages) this is 16 kB.
- VCPI shared address space in extended memory is just 4 kB.
Other features are:
- Jemm can be loaded and unloaded from the command line. Disadvantage:
DOS won't care about UMBs supplied this way.
- CPUs which provide the Virtual-8086 Mode Extensions (Pentium+) are
actively supported, which increases the emulation speed.
- the FASTBOOT option shortens reboot time.
- the SPLIT option can gain additional DOS high memory.
- all "lengthy" memory copy operations ( EMS, VDS, Int 15h, JemmEx: XMS )
are done with interrupts enabled.
- Exceptions in protected-mode are detected and displayed.
- a (rudimentary) API is supplied which allows to extend Jemm. [ JLoad
uses this API to add support for 32bit protected-mode extensions (JLMs). ]
- JemmEx supports XMS v3.5, allowing access to extended memory beyond the
4 GB barrier. See XMS35.txt for technical details.
3. Commandline Options
For a list of available options enter:
JEMM386/JEMMEX -?
Option Comment
----------------------------------------------------------
A20/NOA20 will set the A20 enable/disable emulation accordingly.
ALTBOOT this option is meant to select an alternate reboot handler,
if the standard handler doesn't work. The current implementation
sends a "system reset" command to the keyboard controller.
B=xxxx specify lowest segment address for EMS banking (default=4000,
min=1000).
D=nnn this option will set the size of the DMA buffer to <nnn> kB.
The default size is 64 kB, max size is 128 kB. Will always be
rounded up to next 4 kB.
EMX option to prevent EMX DOS extender from quickly terminating with
message "out of memory (RM)" on machines with large amounts
of RAM (> 256 MB). This is optionally because it makes Jemm
behave not fully VCPI compliant, but shouldn't hurt usually.
FASTBOOT option might allow a fast reboot. There is no guarantee that it
will work, though, see the "Option FASTBOOT" chapter below.
FRAME=nnn instructs Jemm to use a certain page frame. Accepted are frame
values from 8000 to E000 or NONE. The page frame should start
at the beginning of a physical EMS page, that is, the frame
address should be divisible by 0x400 without remainder. FRAME=NONE
disables the page frame, but there are quite some programs which
won't run with this setting. A page frame below A000 should
be set only on computers with 512 kB of conventional memory.
Usually it's better to let Jemm find a page frame on its own,
because choosing an address which is not free might cause troubles.
I=mmmm-nnnn force Jemm to use a memory range for UMBs (or page frame).
<mmmm> must be >= A000. Specifying a range which is not
really free may give "unexpected" results.
I=TEST scan ROMs for unused address space. This option will regard any
4 kB page containing identical byte values in read-only memory as
"unused".
LOAD installs Jemm from the command line. Be aware that UMBs
cannot be provided this way, since DOS will ignore them.
[MAX=]nnn limit the maximum amount of memory to be allocated for VCPI (and
EMS, if <nnn> is below 32 MB). The MAX= prefix is optional (a
number found as option will be handled as if it has a MAX=
prefix). Default value is 120 MB.
MIN=nnn preallocates <nnn> kB of XMS memory thus making sure this
memory is truly available for EMS/VCPI. If MIN is higher than
MAX, MAX will be adjusted accordingly. Default for <nnn> is 0.
MOVEXBDA move XBDA into UMB, thus increasing low DOS memory. This option
may cause a system "lock" because the XBDA might contain buffers
used for DMA operations. In such cases either use MOVEXBDA.EXE or
UMBPCI+UMBM instead.
NOCHECK disallows access via Int 15h, AH=87h to address regions which
aren't backuped by RAM. As for Jemm386: be aware that some old
XMMs return wrong values for highest physical RAM - then this
option may cause strange results. Also, this option may prevent
real-mode programs from using the VESA LFB.
NODYN disables XMS dynamic memory allocation. Jemm will allocate
XMS memory for EMS/VCPI on initialization. Default is size
of largest XMS block/2, but max. 32MB. With option MIN=xxx one
may override this.
NOEMS disables EMS support.
NOHI this option will prevent Jemm from moving its resident part
into upper memory. If no UMBs are installed by Jemm, NOHI
has no effect.
NOINVLPG disables usage of INVLPG opcode on 80486+ cpus. Might be useful
if Jemm runs in a virtual environment (see "Troubleshooting").
NOVCPI disables VCPI. Option can be set from the command line.
NOVMW disables VMWare detection.
PGE/NOPGE options will enable/disable the Page Global Enable feature
on Pentium Pro+ cpus. This allows to mark all PTEs for the
real-mode address space 0-110000h as "global", which gives
a slight speed benefit for VCPI applications. Option is off by
default because some DOS extenders will not work with PGE
enabled. Also setting both PGE + NOINVLPG will not work.
RAM/NORAM will instruct Jemm to supply UMBs or not. RAM is the default.
NORAM is intended to be used when loading Jemm from the
cmdline, in which case adding UMBs might be less useful.
S=mmmm-nnnn add a memory region (which must be in range C800-EFFF) as UMB.
The memory region has to be filled with Shadow-RAM activated by
UMBPCI, which must have been loaded *before* Himem/JemmEx.
NOTE: since v5.80, this option is virtually obsolete, because
either Jemm should find RAM activated by UMBPCI automatically, or,
if UMBM.EXE has been loaded in CONFIG.SYS, the RAM is already used
by DOS.
SB Soundblaster driver compatibility mode on.
SPLIT if ROMs are found which don't end exactly at a 4 kB boundary
then setting this option will increase available UMB space. ROM
sizes are defined in 0.5 kB units, so there might be up to 3.5 kB
wasted in the ROM's last 4 kB page. There is a small catch: the
full 4k page will be made writeable, including the ROM part.
UNLOAD uninstalls Jemm from the command line. Uninstalling the EMM
might confuse resident programs which rely on EMS or VCPI but
didn't ensure this configuration to keep unchanged (by allocating
an EMS page) while they are running.
V86EXC0D makes Jemm route General Protection Faults (GPF) that occur in
V86-mode to Int 0Dh. Without this option they are routed to
Int 06h. This option should only be set if a resident program
is to be installed that can handle GPFs in V86-mode.
VCPI (re)enables VCPI. Option can be set from the command line.
VERBOSE talk a bit more during the load process (abbreviation: /V).
VME/NOVME options will enable/disable using the V86 Mode Extensions
on Pentium+ CPUs. These options can be set from the command line.
NOVME is the default.
X=mmmm-nnnn exclude a memory range to be used as UMBs or page frame.
<mmmm> must be >= A000.
X=TEST will exclude all upper memory regions which contain byte values
other than 00 or FF.
JemmEx additionally understands:
A20METHOD:x select A20 switch method.
Possible values for <x>:
ALWAYSON Assume that A20 line is permanently ON
BIOS Use BIOS to toggle the A20 line
FAST Use port 92h, bypass INT 15h test
PS2 Use port 92h, bypass PS/2 test
KBC Use the keyboard controller
PORT92 Use port 92h always
HMAMIN=k set minimum amount in kB to get the HMA (default=0, max=63).
MAXEXT=l limit extended memory controlled by XMM to <l> kB.
MAXSEXT=l limit extended memory beyond 4GB barrier ("super-extended") to
<l> kB; setting MAXSEXT=0 will make JemmEx behave like a
v3.0 XMM.
NOE801 don't use int 15h, ax=E801h to get amount of extended memory.
NOE820 don't use int 15h, ax=E820h to get amount of extended memory;
option is ignored unless MAXSEXT=0 is set.
X2MAX=m limit for free extended memory in kB reported by XMS V2
(default 65535). It is reported that some old applications
need a value of <m>=32767.
XMSHANDLES=n set number of XMS handles (default=48, min=10, max=128).
4. Technical Details
4.1 EMS Implementation Notes
- The number of EMS pages is limited to 2048 (= 32 MB). It can be increased
up to 32768 pages (= 512 MB) by setting MIN=<nnn> to a value higher than
32 MB. However, this memory will then be preallocated, and not be available
as XMS memory. Some applications will not work if EMS > 32 MB.
- There is one memory pool, which is shared by EMS and VCPI.
- The following EMS 4.0 functions aren't implemented. Calling these
functions will return error code 84h in register AH:
+ Int 67h, AH=5Ch, prepare expanded memory manager hardware for warm boot
+ Int 67h, AH=5Dh, enable/disable OS/E
4.2 Emulation of privileged Opcodes
To provide Expanded Memory an EMM Emulator like Jemm runs the cpu in
so-called V86-mode. This mode does not allow to run privileged opcodes.
Some of these opcodes which might be useful for application programs
are emulated by Jemm. These are:
- mov <special_reg>, <reg> ;special_reg = CRn, DRn, TRn
- mov <reg>, <special_reg> ;reg = eax, ebx, ecx, edx, esi, edi, ebp
- WBINVD
- INVD
- WRMSR
- RDMSR
- RDTSC
- HLT
Those instructions may generate an exception 0x0D if they occur in V86-mode
( for RDTSC, this depends on a bit in register CR4 ). Jemm's exception handler
examines the opcode causing the exception and - if the instruction is to be
"emulated" - runs it in ring 0.
4.3 IOPL Sensitive Instructions
Jemm runs V86-mode code with IOPL 3. That means, the instructions that are
sensitive to IOPL in V86-mode - CLI, STI, PUSHF, POPF, INT xx, IRET - will
run at full speed, without causing a GPF.
4.4 VMWare Detection
As default, Jemm tries to detect if it's running under VMWare. This is done
by reading port 0x5658 with value "VMXh" in register EAX. If the detection
is successful, Jemm assumes that address range E8000-EFFFF is not to be used.
However, range E8000-EBFFF may still be included with the "I=" option.
The VMWare detection can be disabled with option NOVMW.
4.5 Option FASTBOOT
The FASTBOOT option may work with many versions of DOS. However, there are
quite a few restrictions. To speed up the boot process, FASTBOOT tries to
avoid resetting the system. This implicates that the interrupt vector table
and at least the disk devices can be reset to the state before DOS has been
loaded. Resetting the interrupt vector table requires some cooperation from
DOS. Other things that may get in the way are:
- Moving the XBDA into an UMB with option MOVEXBDA is critical, because to
move it back into conventional memory might not work for various reasons.
- older FreeDOS versions may need JEMFBHLP.EXE to be installed prior to the
XMM (Himem). Possibly this might also be needed for MS-DOS versions < 5.
- UMBPCI allows to activate "Shadow RAM", but there's no option to deactivate
it. This may confuse Jemm, since it can only detect RAM activated by UMBPCI
if UMBPCI's signature is found.
- A boot loader (Grub) might have inserted code in conventional memory to
modify hard disks numbers. There's no guarantee that this code survives the
fastboot process.
4.6 Option MAXSEXT
JemmEx only: this option limits amount of "super-extended" memory. Setting
MAXSEXT=0 disables this feature. If enabled, JemmEx must exclusively manage
this type of memory; to achieve this, interrupt 15h, AX=0xE820 is hooked and
any memory region beyond 4 GB that's marked as available is changed to
"reserved" ( tool MEMSTAT may be used to verify this behavior ).
4.7 Option NOEMS
Despite its name, this option does not fully disable EMS. What's done is:
- device name changed from EMMXXXX0 to EMMQXXX0
- no page frame installed
- EMS memory pool is limited to 8 MB
The change of the device name makes the usual EMM detection routines fail.
OTOH, the interrupt 67h API is fully functional. Most of this is pretty
similar to what "recent" MS Emm386 versions do - the only difference is
that they won't limit the memory pool to 8 MB, but install it in its full
size (32 MB).
4.8 Option SB
Option SB is supposed to help Creative's SoundBlaster emulation drivers for
SB PCI devices. It does 2 things:
a) It translates an exception 0Dh with error code 0x1A that may have occured
in V86 mode to an INT 3. It's unclear what this is supposed to fix.
b) Since v5.86, it "identity maps" region 0-0x3fffff in the first page table.
This mapping was done generally until v5.85.
With b), Creative's SBINIT/SBEINIT tools should again be compatible with Jemm.
However, due to the rather hackish nature of those drivers ( they modify
Jemm's IDT/GDT and page tables ), one may experience negative effects on
stability.
5. Compatibility
Jemm is NOT an MS Emm386 clone. Differences are:
<UL>
<LI> - obviously commandline options differ.
</LI>
<LI> - the device driver API, accessed by opening file "EMMXXXX0" and
then issueing IOCTL cmds, differs.
</LI>
<LI> - Jemm doesn't support the so-called GEMMIS API.
</LI>
<LI> - Jemm doesn't support the IO port trapping API of MS Emm386.
</LI>
<LI> - Jemm supports UMBs (Upper Memory Blocks) accessed via the XMS API, but the
management is different: unlike MS Emm386, there's no chain of UMBs, linked
with a 16-byte header ( somewhat similar to DOS MCBs ). Instead, the UMB
addresses and sizes are stored in a table in extended memory, not accessible
by external programs. The table can hold up to 8 blocks.
</LI>
<LI> - MS Emm386 tries to map all of physical memory in its linear address space,
in such a way that linear and physical addresses are identical. This isn't
done by Jemm, because it may consume quite a lot of physical memory for paging
tables - at least if 4KB pages are used, as it is the case with MS Emm386.
See option SB, though, which triggers this kind of mapping for the first 4 MB.
</LI>
<LI> - Both Jemm and MS Emm386 supply the NOVCPI commandline option. However, the
effects differ: with Jemm, VCPI function DE01h will be deactivated by this
option, thus refusing to start any VCPI client. In contrast, MS Emm386's
NOVCPI makes the monitor still offer the full API, but no VCPI memory can
be allocated.
</LI>
</UL>
6. Errors and Warnings
Errors will make Jemm386/JemmEx abort the load process, while warnings
will be displayed and then the load process continues.
- "Error: no XMM found, required"
Jemm386 only. Jemm386 needs an XMM - try Himem(S)X.
- "Error: XMM already installed"
JemmEx only. Since JemmEx has its very own XMM, it cannot tolerate
another one in the system.
- "Error: DPMI host detected"
Both Jemm386 and JemmEx refuse to load if a DPMI host has been detected.
- "Error: No supported A20 method detected"
JemmEx only. JemmEx is NOT compatible with this system.
- "Error: enable A20 failed"
JemmEx only. JemmEx is NOT compatible with this system.
- "Error: can't get I15 memory status"
JemmEx only. Int 15h, AX=E820h ( and the fallbacks, Int 15h,
ax=E801h/ah=88h ) failed or returned an amount of 0 kB extended memory.
Tool memstat may help to find the problem.
- "Error: can't get XMS memory status"
Jemm386 only. The XMS host reports no extended memory. Tool xmsstat
may give a hint what's wrong.
- "Error: can't allocate enough I15 memory"
JemmEx only. Run tool memstat to see how much extended memory the
system is reporting.
- "Error: can't allocate enough XMS memory"
Jemm386 only. Run tool xmsstat to see how much extended memory the
XMM is reporting.
- "Error: can't lock XMS memory"
Jemm386 only. Well, this shouldn't happen. Jemm386 needs the physical
address of the memory block where it is to reside. The XMM most likely has
to be replaced.
- "Warning: unknown A20 method"
JemmEx only. Option A20METHOD was given with an invalid method.
- "Warning: option 'xxx=' rejected, invalid syntax"
The option is ignored.
- "Warning: E820 - too many ext memory blocks, block xxxxxxxx ignored!"
JemmEx only. Occurs if int 15h, ax=e820h returns more than 10 available
memory blocks. It's very well possible that super-extended memory isn't
available if this warning has occured. The only cure is to adjust constant
?XMS_STATICHDLS in file jemm16.inc and recompile JemmEx.
- "Warning: address of allocated EMB (=XXXXXX) is beyond 16MB"
Jemm386 only. Means that Jemm386 is forced to reside beyond the physical
16MB barrier. No problem for Jemm386 itself, but the VDS API requires a
DMA buffer that is located below that 16MB barrier. So one is better off not
to ignore this warning. To fix it: a) ensure that Jemm386 is loaded just
after the XMM; b) replace the XMM, use HimemX2.exe instead of HimemX.exe
(if an extended memory block is allocated, HimemX2 tries to return the
block with the lowest address that satisfies the request).
- "Warning: no suitable page frame found, EMS functions limited."
Most programs using EMS won't work without a page frame, so this warning
should not be ignored. To analyze the problem, a first step may be to load
Jemm from the command line, with the /V option to see why it cannot find a
64 kB region to be used as page frame. Possible reasons are:
- UMBPCI is used. Memory regions activated by UMBPCI are detected by Jemm
and hence won't be used for mapping the Page Frame.
- BIOS marks 128 kB ( E0000-FFFFF ) as reserved in Int 15h, ax=E820h.
Using the video segment A000 as page frame is useful only for very specific
applications and cannot be recommended. Using regions below A000 are even
more problematic on machines with 640 kB conventional memory, since the
address range is already "owned" by DOS.
If it's not possible to make Jemm use a valid page frame, it should be setup
with option NOEMS.
- "Warning: EMS banking start too low, set to 0x1000."
This warning only occurs if option B=xxxx has been used inappropriately.
- "Warning: MIN has been reduced to n kB"
Warning occurs if the amount given for MIN exceeds available free memory.
- "Warning: wanted DMA buffer size too large, set to 128 kB"
Warning occurs if option D=nnn has been used with a value larger than
the maximum of 128 (kb).
- "Warning: XMS host doesn't provide handle array, dynamic memory allocation off!"
Jemm386 only. Jemm wants the XMM to reveal its handle table. If this feature
isn't available, Jemm has to allocate its memory for EMS and VCPI statically
on startup.
7. Troubleshooting, Hints
- If Jemm halts or reboots the machine, the following combinations
of parameters may help to find the reason. Generally, Jemm386 should be
loaded immediately after the XMM (HIMEM[S]X.EXE, HIMEM.SYS), and the XMM
itself should be the first device driver to be loaded. For testing, it
might also help to prevent DOS from loading in the HMA and/or not to
use UMBs at all.
- X=A000-FFFF NOHI NOINVLPG
This is the safest combination. If this doesn't work, Jemm most
likely isn't compatible with the current DOS/BIOS; for example,
the BIOS might try to unconditionally use "unreal" mode to access
USB mass storage devices - with Jemm, this will cause an exception.
- X=TEST NOHI NOINVLPG
This is slightly less safe, since Jemm will scan the upper memory
region to find "unused" address ranges usable for UMBs. If this
doesn't work, one has to manually set X=xxxx-yyyy to finally
find the region which causes the troubles. Tool MEMSTAT may be used
to find the address region which is reserved for the ROM-BIOS.
- Jemm can be loaded from the command line with option LOAD. This may be
helpful if there are so many displays during the boot process that one
cannot read them carefully. Also, option /V should be added to make
Jemm talkative. To load Jemm386 from the command line, ensure that a
XMM has been loaded previously. For JemmEx, no XMM must be loaded, since
it is included.
- Jemm has been verified to run on the following virtual environments:
Qemu, VMware, VirtualPC, Bochs, VirtualBox
However, it might be necessary to set option NOINVLPG.
- Some DOS programs will not work if EMS is enabled without a page frame.
MS CodeView v4.1, for example, may refuse to start then.
- Some DOS programs will crash if too much VCPI memory is offered. Jemm's
default is 120 MB, it can be changed with option MAX=xxx. Popular
programs that may cause troubles are programs that use Borland's DPMI hosts
DPMI16BI.OVL/DPMI32VM.OVL (coupled with RTM.EXE/32RTM.EXE). Setting Jemm
option MAX=32752K ( that's 32MB minus 16kB) should help; alternately, try
setting environment variable "DPMIMEM=MAXMEM 16383".
- The JEMM ;-) DOS extender (used for "Strike Commander" and "Privateer")
isn't compatible with the VME option. This requirement is a strong sign
that this extender switches to V86 mode on its own, which is a bad idea
for a VCPI client.
- Unlike MS Emm386, Jemm does not try to identity-map extended memory in its
address space. This prevents the PL0 debugger 386SWAT from "intruding".
- If Jemm is installed from the commandline, loading the CTMOUSE driver
v1.9x and v2.0x might cause an exception. Adding option NOHI or NORAM
when installing Jemm should avoid that. In CTMOUSE v2.1 the bug has
been fixed.
- With some BIOSes disk access speed slows down significantly in V86-mode.
Most likely this is because the BIOS routines want to avoid using DMA in
this mode. Loading XDMA32 ( and XCDROM32 ) might fix that.
- FreeDOS regrettably accepts just one UMB provider. This makes it impossible
for example to use UMBM.EXE to supply UMB D000-DFFF and then tell Jemm to
additionally supply B000-B7FF as UMB. MS-DOS has no such problems.
- Although including the region B000-B7FF might work in most cases, one
should be aware that this region is not really free, it's used by the
VGA "monochrome" video modes.
- To make Jemm behave (almost) like MS Emm386 regarding UMBs one should
set both options X=TEST and I=TEST. For better MS Emm386 compatibility
one might also consider to restrict VCPI memory to 32 MB by adding
option MAX=32M. If NODYN is used, one should also set at least MIN=256K.
- The NOVCPI option may be used to setup an environment similiar to Windows
DOS boxes:
- install Jemm with VCPI enabled
- install a DPMI host residently (HDPMI, DPMIONE, ...)
- disable VCPI with the NOVCPI option
This forces any DOS extended application to either use DPMI or abort.
- If Jemm displays warning
System memory found at XXXX-XXXX, region might be in use
then that region is not used by Jemm. If you are sure that the region
is ok to be used, include it with 'I=XXXX-XXXX'.
- The I=XXXX commandline option may be used to include the VGA "graphics"
segment A000h. It might be possible to increase DOS conventional memory
up to 736 kB by option I=A000-B7FF. However, there are quite a few
hurdles that may cause unexpected results:
- conventional memory is increased only if the region to include is
adjacent to current memory. On newer machines, there's very often a
"hole", caused by the Extended BIOS Data Area (XBDA or EBDA); thus
the included region just becomes an UMB and won't increase lower memory.
Option MOVEXBDA or tool MOVEXBDA.EXE may fix this issue.
- Once address space A000h is remapped, any attempts to run programs that
use VGA graphics most likely will cause a crash.
- Depending on the VGA-BIOS it may happen that some non-graphics functions
won't work anymore and may also cause a crash. Not unusual is that the
current text font becomes corrupted ( text font bitmaps must be copied
from ROM to VGA memory when a video text mode is set ).
- DOS conventional memory cannot be increased anymore once UMB have been
added to the DOS memory pool. So you cannot use tool UMBM here!
- if MOVEXBDA.EXE causes a system lock during boot, add the /A option to
the line in CONFIG.SYS that loads the driver. This aligns the XBDA to
a kB boundary, which may cure the lock.
- the GRUB boot loader may, under certain conditions, allocate a chunk
of conventional memory BELOW the XBDA. In this case conventional memory
cannot be increased anymore, even if the XBDA is moved.
8. Additional Tools
8.1 UMBM
UMBM is a small tool only useful in conjunction with Uwe Sieber's UMBPCI.
The main purpose of UMBM is to allow DOS to load the XMM into upper memory.
This driver must be loaded before Jemm386 and therefore DOS can't use UMBs
provided by Jemm386. For JemmEx, UMBM is usually not needed, since the XMM is
included and needs no low memory.
How does UMBM work? It expects to find a "shadow" RAM region activated by
UMBPCI. Then it installs inself as a temporary XMS host which just provides
support for allocating UMBs. This is enough for most DOSes to grab the
memory (note: for this to work line DOS=UMB is required in CONFIG.SYS). After
the UMBs have been allocated, UMBM will be removed from memory automatically.
Additionally, UMBM understands the /XBDA option. This will cause UMBM
to move the XBDA into its first UMB, thus freeing even more low DOS memory.
UMBs based on "shadow" RAM, as it is supplied by UMBPCI+UMBM, may have
limitations depending on the motherboard's chipset. Sometimes the memory
is inaccessible for DMA (read the documentation coming with UMBPCI for more
details). OTOH, logical and physical addresses for these UMBs are identical,
which may be an advantage, especially for the XBDA.
Enter "UMBM" on the command line and read the example how to add UMBM
to CONFIG.SYS. UMBM has been tested to run with MS-DOS 6/7 and FreeDOS.
8.2 JEMFBHLP
JEMFBHLP is a tiny device driver only needed if both FreeDOS and Jemm's
FASTBOOT option are used. FreeDOS v1.0 does not provide the information
that Jemm needs for FASTBOOT to work, so this driver tries to cure FreeDOS'
incapability. It saves the values for interrupt vectors 15h and 19h at
0070h:0100h, which is the MS-DOS compatible way to do it.
In more recent FreeDOS versions this problem has been fixed.
8.3 CPUSTAT
CPUSTAT displays some system registers and tables. Most of the registers
aren't accessible in v86-mode, so - for Jemm - this program may be seen as
a test if the emulation of privileged opcodes works as expected.
Optionally, if cpu runs in V86-mode, CPUSTAT may display GDT, IDT, paging
tables and informations stored in the task state segment of the v86-monitor.
Run "CPUSTAT -?" for more details.
8.4 MEMSTAT
MEMSTAT may be used to display the machine's memory layout, as it is
returned by the BIOS. The most interesting infos are:
- address region reserved for the ROM-BIOS
- total amount of free memory
8.5 XMSSTAT
XMSSTAT can be used to display the current status of the installed XMM.
It allows to check current values of JemmEx options X2MAX, MAXEXT and
XMSHANDLES.
8.6 EMSSTAT
EMSSTAT can be used to display the current status of the installed EMM.
It works with any EMM, not just Jemm.
8.7 VCPI
VCPI may be used to display the VCPI status of the installed EMM.
With option -p it will display the page table entries for the conventional
memory.
8.8 MOVEXBDA
MOVEXBDA is a device driver supposed to move the Extended BIOS Data
Area ( XBDA or EBDA ) to low DOS memory. If an XBDA exists, it is usually
located just below the A000 video segment, with a size of 1-12 kB.
Some DOS versions will move the XBDA on their own - at least if its size
doesn't exceed 1 kB; then MOVEXBDA is not needed and will do nothing if
launched. Also, both JemmEx and UMBM have the ability to move the XBDA as
well; those tools move the XBDA to upper memory, thus increasing low DOS
memory. However, sometimes MOVEXBDA may be the best option available -
because moving the XBDA into an UMB supplied by Jemm (or UMBPCI) may cause
the system to "lock".
MOVEXBDA should work with any EMM.
8.9 CPUID
CPUID displays cpu features returned by the CPUID instruction.
9. License
- JEMM386/JEMMEX: partly Artistic License (see ARTISTIC.TXT for details)
- UMBM: Public Domain
- JEMFBHLP: Public Domain
- CPUSTAT: Public Domain
- MEMSTAT: Public Domain
- XMSSTAT: Public Domain
- EMSSTAT: Public Domain
- VCPI: Public Domain
- MOVEXBDA: Public Domain
- CPUID: Public Domain
Binaries and source are distributed in separate packages. The binaries'
package has a 'B' suffix in its name, the package containing the source
has a 'S'.
Japheth
</pre>
</TD></TR>
</TABLE>
</BODY>
</HTML>
================================================
FILE: Include/FILEACC.INC
================================================
;--- dos file access for JLMs
;--- although addresses are linear, they must
;--- be within 64 kB distance of v86 DS register.
w textequ <word ptr>
;--- open file (for reading)
;--- edx = file name
;--- out: ax=handle
OpenFile proc
movzx eax,word ptr [ebp].Client_Reg_Struc.Client_DS
shl eax, 4
sub edx, eax
mov w [ebp].Client_Reg_Struc.Client_EDX, dx
mov w [ebp].Client_Reg_Struc.Client_EAX, 3D00h
mov eax,21h
@VMMCall Exec_Int
mov ax,w [ebp].Client_Reg_Struc.Client_EAX
bt [ebp].Client_Reg_Struc.Client_EFlags,0
ret
OpenFile endp
;--- close file
;--- ebx = file handle
CloseFile proc
mov w [ebp].Client_Reg_Struc.Client_EBX, bx
mov w [ebp].Client_Reg_Struc.Client_EAX, 3E00h
mov eax,21h
@VMMCall Exec_Int
bt [ebp].Client_Reg_Struc.Client_EFlags,0
ret
CloseFile endp
;--- get file size
;--- ebx = file handle
;--- out: eax=file size
GetFileSize proc
mov w [ebp].Client_Reg_Struc.Client_EBX, bx
mov w [ebp].Client_Reg_Struc.Client_EAX, 4202h ;goto EOF
mov w [ebp].Client_Reg_Struc.Client_ECX, 0
mov w [ebp].Client_Reg_Struc.Client_EDX, 0
mov eax,21h
@VMMCall Exec_Int
bt [ebp].Client_Reg_Struc.Client_EFlags,0
jc exit
mov ax, w [ebp].Client_Reg_Struc.Client_EDX
shl eax, 16
mov ax, w [ebp].Client_Reg_Struc.Client_EAX
push eax
mov w [ebp].Client_Reg_Struc.Client_EAX, 4200h ;goto start
mov w [ebp].Client_Reg_Struc.Client_ECX, 0
mov w [ebp].Client_Reg_Struc.Client_EDX, 0
mov eax,21h
@VMMCall Exec_Int
pop eax
bt [ebp].Client_Reg_Struc.Client_EFlags,0
exit:
ret
GetFileSize endp
;--- Read file into buffer
;--- bx = file handle
;--- cx = bytes to read
;--- edx = buffer (in conv. memory)
;--- out: eax=bytes read
ReadFile proc
movzx eax,w [ebp].Client_Reg_Struc.Client_DS
shl eax, 4
sub edx, eax
mov w [ebp].Client_Reg_Struc.Client_EBX, bx
mov w [ebp].Client_Reg_Struc.Client_ECX, cx
mov w [ebp].Client_Reg_Struc.Client_EDX, dx
mov w [ebp].Client_Reg_Struc.Client_EAX, 3F00h
mov eax,21h
@VMMCall Exec_Int
movzx eax, w [ebp].Client_Reg_Struc.Client_EAX
bt [ebp].Client_Reg_Struc.Client_EFlags,0
ret
ReadFile endp
================================================
FILE: Include/FINDRES.INC
================================================
?NOCASEMAP equ 0 ;win32 std is 0
;--- eax = resource directory
;--- id may be an id (HIWORD=0) or a string pointer
;--- used by EnumResourceXXX as well !!
ScanResDir proc public uses esi pRes:DWORD, dwDir:DWORD, id:DWORD
mov esi, pRes
add esi, dwDir
movzx ecx, [esi].IMAGE_RESOURCE_DIRECTORY.NumberOfNamedEntries
mov eax, id
.if (eax & 0FFFF0000h)
.if (byte ptr [eax] == '#')
lea edx,[eax+1]
call GetNumber
jmp ok
.endif
lea esi, [esi + sizeof IMAGE_RESOURCE_DIRECTORY]
.while (ecx)
mov edx, [esi].IMAGE_RESOURCE_DIRECTORY_ENTRY.Name_
and edx, edx
.if (SIGN?)
and edx, 7FFFFFFFh
add edx, pRes
pushad
mov esi, edx
mov edi, eax
lodsw
movzx ecx, ax
@@:
if ?NOCASEMAP
lodsw
scasb
else
lodsw
call ToLower
mov ah,al
mov al,[edi]
inc edi
call ToLower
cmp al,ah
endif
loopz @B
popad
.if (ZERO? && (byte ptr [edi] == 0))
mov eax, [esi].IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData
jmp done
.endif
.endif
add esi, sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY
dec ecx
.endw
jmp error
.endif
ok:
push eax
mov eax, sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY
mul ecx
;-------------------- let esi point to resources with id entries
movzx ecx, [esi].IMAGE_RESOURCE_DIRECTORY.NumberOfIdEntries
lea esi, [esi + eax + sizeof IMAGE_RESOURCE_DIRECTORY]
pop eax
.while (ecx)
.if ((ax == [esi].IMAGE_RESOURCE_DIRECTORY_ENTRY.Id) || (ax == 0))
mov eax, [esi].IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData
jmp done
.endif
add esi, sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY
dec ecx
.endw
error:
xor eax, eax
done:
ret
ife ?NOCASEMAP
ToLower:
cmp al,'A'
jb @F
cmp al,'Z'
jae @F
or al,20h
@@:
retn
endif
GetNumber:
push ebx
xor eax, eax
.while (byte ptr [edx])
movzx ebx,byte ptr [edx]
inc edx
sub bl,'0'
add eax, eax
push eax
shl eax, 2
add eax, [esp]
add eax, ebx
pop ebx
.endw
pop ebx
retn
align 4
ScanResDir endp
;--- hiword of lpName and lpType may be NULL
;--- in this case it is an integer identifier
FindResourceA proc public uses esi edi hModule:DWORD, lpName:DWORD, lpType:DWORD
mov esi, hModule
.if (!esi)
invoke GetModuleHandle, esi
mov esi, eax
mov hModule, eax
.endif
add esi, [esi].IMAGE_DOS_HEADER.e_lfanew
mov edi, [esi].IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE * sizeof IMAGE_DATA_DIRECTORY].VirtualAddress
mov edx, [esi].IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE * sizeof IMAGE_DATA_DIRECTORY].Size_
.if (edi)
add edi, hModule
invoke ScanResDir, edi, 0, lpType
.if (eax)
and eax, eax
.if (SIGN?)
and eax, 7FFFFFFFh
invoke ScanResDir, edi, eax, lpName
.if (eax)
and eax, eax
.if (SIGN?)
and eax, 7FFFFFFFh
invoke ScanResDir, edi, eax, 0
.if (eax)
add eax, edi
jmp done
.endif
.else
add eax, edi
jmp done
.endif
.endif
.endif
.endif
.endif
error:
xor eax, eax
done:
if 0;def _DEBUG
@trace <"FindResourceA(">
@tracedw hModule
@trace <", ">
.if (word ptr lpName+2)
@trace lpName
.else
@tracedw lpName
.endif
@trace <", ">
.if (word ptr lpType+2)
@trace lpType
.else
@tracedw lpType
.endif
@trace <")=">
@tracedw eax
@trace <13,10>
endif
ret
align 4
FindResourceA endp
;--- attention: name and type are exchanged!
FindResourceExA proc public hModule:DWORD, lpType:DWORD, lpName:DWORD, wLanguage:DWORD
invoke FindResourceA, hModule, lpName, lpType
; @strace <"FindResourceExA(", hModule, ", ", lpType, ", ", lpName, ", ", wLanguage, ")=", eax>
ret
align 4
FindResourceExA endp
LoadResource proc public hModule:DWORD, hres:DWORD
.if (!hModule)
invoke GetModuleHandle, hModule
mov hModule, eax
.endif
mov eax, hres
.if (eax)
mov eax, [eax].IMAGE_RESOURCE_DATA_ENTRY.OffsetToData
add eax, hModule
.endif
; @strace <"LoadResource(", hModule, ", ", hres, ")=", eax>
ret
align 4
LoadResource endp
LockResource proc public hres:DWORD
mov eax,hres
; @strace <"LockResource(", hres, ")=", eax>
ret
align 4
LockResource endp
FreeResource proc public hres:DWORD
mov eax,1
; @strace <"FreeResource(", hres, ")=", eax>
ret
align 4
FreeResource endp
SizeofResource proc public hModule:DWORD, hres:DWORD
mov eax, hres
.if (eax)
mov eax, [eax].IMAGE_RESOURCE_DATA_ENTRY.Size_
.endif
; @strace <"SizeofResource(", hModule, ", ", hres, ")=", eax>
ret
align 4
SizeofResource endp
================================================
FILE: Include/JLM.H
================================================
/* Header file for Jemm JLMs which defines the subset of the Win3x/Win9x */
/* ring 0 API (VMM) that Jemm/JLoad exposes. */
/* The parameters and return values of the functions are the same as in */
/* the Windows implementation, register usage is as in Win32: EAX, ECX */
/* and EDX may be modified inside functions, the other registers are */
/* preserved (exception: Get_Cur_VM_Handle). */
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef unsigned long ULONG;
struct Pushad_Struc {
ULONG Pushad_EDI; /* Client's EDI */
ULONG Pushad_ESI; /* Client's ESI */
ULONG Pushad_EBP; /* Client's EBP */
ULONG Pushad_ESP; /* ESP before pushad */
ULONG Pushad_EBX; /* Client's EBX */
ULONG Pushad_EDX; /* Client's EDX */
ULONG Pushad_ECX; /* Client's ECX */
ULONG Pushad_EAX; /* Client's EAX */
};
#define VMM_DEVICE_ID 0x00001
#define VDMAD_DEVICE_ID 0x00004
#define GetVxDServiceOrdinal(service) __ ## service
#define Begin_Service_Table(device, seg) \
enum device##_SERVICES { \
device##_dummy = (device##_DEVICE_ID << 16) - 1,
#define Declare_Service(service) \
GetVxDServiceOrdinal(service),
#define Declare_SCService(service, args, local) \
GetVxDServiceOrdinal(service),
#define End_Service_Table(device, seg) \
Num_##device##_Services};
#define VXDINLINE static __inline
/* */
#define GetVxDServiceAddress(service) service
#ifdef __WATCOMC__
// Open Watcom C currently can't call the VMM services directly
// because ENUM values aren't accessible by the inline assembler.
#define VxDCall(service) \
_asm int 20h \
_asm dd (GetVxDServiceOrdinal(service) ) \
#define VxDJmp(service) \
_asm int 20h \
_asm dd (GetVxDServiceOrdinal(service) | 0x8000 ) \
#else
#define VxDCall(service) \
_asm _emit 0xcd \
_asm _emit 0x20 \
_asm _emit (GetVxDServiceOrdinal(service) & 0xff) \
_asm _emit (GetVxDServiceOrdinal(service) >> 8) & 0xff \
_asm _emit (GetVxDServiceOrdinal(service) >> 16) & 0xff \
_asm _emit (GetVxDServiceOrdinal(service) >> 24) & 0xff \
#define VxDJmp(service) \
_asm _emit 0xcd \
_asm _emit 0x20 \
_asm _emit (GetVxDServiceOrdinal(service) & 0xff) \
_asm _emit ((GetVxDServiceOrdinal(service) >> 8) & 0xff) | 0x80 \
_asm _emit (GetVxDServiceOrdinal(service) >> 16) & 0xff \
_asm _emit (GetVxDServiceOrdinal(service) >> 24) & 0xff \
#endif
#define VMMCall VxDCall
#define VMMJmp VxDJmp
#define SERVICE __cdecl
#define VMM_Service Declare_Service
Begin_Service_Table(VMM, VMM)
VMM_Service (Get_VMM_Version)
VMM_Service (Get_Cur_VM_Handle)
VMM_Service (Allocate_V86_Call_Back)
VMM_Service (Crash_Cur_VM)
VMM_Service (Hook_V86_Int_Chain)
VMM_Service (Get_V86_Int_Vector)
VMM_Service (Set_V86_Int_Vector)
VMM_Service (Get_PM_Int_Vector)
VMM_Service (Set_PM_Int_Vector)
VMM_Service (Simulate_Int)
VMM_Service (Simulate_Iret)
VMM_Service (Simulate_Far_Call)
VMM_Service (Simulate_Far_Jmp)
VMM_Service (Simulate_Far_Ret)
VMM_Service (Simulate_Far_Ret_N)
VMM_Service (Build_Int_Stack_Frame)
VMM_Service (Simulate_Push)
VMM_Service (Simulate_Pop)
VMM_Service (_PageFree)
VMM_Service (_PhysIntoV86)
VMM_Service (_LinMapIntoV86)
VMM_Service (Hook_V86_Fault)
VMM_Service (Hook_PM_Fault)
VMM_Service (Begin_Nest_Exec)
VMM_Service (Exec_Int)
VMM_Service (Resume_Exec)
VMM_Service (End_Nest_Exec)
VMM_Service (Save_Client_State)
VMM_Service (Restore_Client_State)
VMM_Service (Simulate_IO)
VMM_Service (Install_Mult_IO_Handlers)
VMM_Service (Install_IO_Handler)
VMM_Service (VMM_Add_DDB)
VMM_Service (VMM_Remove_DDB)
VMM_Service (Remove_IO_Handler)
VMM_Service (Remove_Mult_IO_Handlers)
VMM_Service (Unhook_V86_Int_Chain)
VMM_Service (Unhook_V86_Fault)
VMM_Service (Unhook_PM_Fault)
VMM_Service (_PageReserve)
VMM_Service (_PageCommit)
VMM_Service (_PageDecommit)
VMM_Service (_PageCommitPhys)
VMM_Service (Free_V86_Call_Back)
VMM_Service (Yield)
VMM_Service (MoveMemory)
VMM_Service (_Allocate_GDT_Selector)
VMM_Service (_Free_GDT_Selector)
VMM_Service (Get_DDB)
End_Service_Table(VMM, VMM)
struct cb_s {
ULONG CB_VM_Status; /* VM status flags */
ULONG CB_High_Linear; /* Address of VM mapped high */
ULONG CB_Client_Pointer;
ULONG CB_VMID;
ULONG CB_Signature;
};
struct Client_Reg_Struc {
ULONG Client_EDI; /* Client's EDI */
ULONG Client_ESI; /* Client's ESI */
ULONG Client_EBP; /* Client's EBP */
ULONG Client_res0; /* ESP at pushall */
ULONG Client_EBX; /* Client's EBX */
ULONG Client_EDX; /* Client's EDX */
ULONG Client_ECX; /* Client's ECX */
ULONG Client_EAX; /* Client's EAX */
ULONG Client_IntNo;
ULONG Client_Error; /* Dword error code */
ULONG Client_EIP; /* EIP */
USHORT Client_CS; /* CS */
USHORT Client_res1; /* (padding) */
ULONG Client_EFlags; /* EFLAGS */
ULONG Client_ESP; /* ESP */
USHORT Client_SS; /* SS */
USHORT Client_res2; /* (padding) */
USHORT Client_ES; /* ES */
USHORT Client_res3; /* (padding) */
USHORT Client_DS; /* DS */
USHORT Client_res4; /* (padding) */
USHORT Client_FS; /* FS */
USHORT Client_res5; /* (padding) */
USHORT Client_GS; /* GS */
USHORT Client_res6; /* (padding) */
};
================================================
FILE: Include/JLM.INC
================================================
;--- this is an assembler include file in MASM format,
;--- to be used for JLMs (Jemm Loadable Modules).
;--- it defines the API exposed by Jemm/JLoad.
;--- parameters, calling convention and return values are the same as
;--- for Win9x.
;--- the register usage usually is the same as for the Win32 stdcall
;--- convention: registers EAX, ECX and EDX may be changed inside a function,
;--- registers EBX, ESI, EDI, EBP are preserved.
;--- the exception of this rule is Get_Cur_VM_Handle, which returns the
;--- "handle" in EBX.
;--------------------------------------------------------------------------
;--- v5.83: VMMCall renamed to @VMMCall ( VMMCALL is a x86 instruction now )
ifndef __POASM__
@VMMCall macro name_
int 20h
dw VMM_&name_
dw 1
endm
else
@VMMCall macro name_
int 20h
dw VMM_ # name_
dw 1
endm
endif
ifndef __POASM__
VMMJmp macro name_
int 20h
dw VMM_&name_ + 8000h
dw 1
endm
else
VMMJmp macro name_
int 20h
dw VMM_ # name_ + 8000h
dw 1
endm
endif
VxDCall macro name_
int 20h
dd name_
endm
;--- macro to define a hook proc (Hook_V86_Int_Chain)
HookProc macro name_, oldvect
; jmp $+8 ; v5.85: removed
jmp dword ptr [oldvect]
name_ proc
endm
;--------------------------------------------------------------------------
;--- VMM API. This device is installed by JLoad. The name is misleading,
;--- though, VMs aren't supported.
;--- the following functions aren't implemented yet and will always return
;--- an error:
;--- Install_Mult_IO_Handlers, Remove_Mult_IO_Handlers
;--- Hook_V86_Fault, Unhook_V86_Fault
;--- Hook_PM_Fault, Unhook_PM_Fault
;--- Get_PM_Int_Vector, Set_PM_Int_Vector
@@VMM_Service_no = 0
ifndef __POASM__
VMM_Service macro name_
VMM_&name_ equ @@VMM_Service_no
@@VMM_Service_no = @@VMM_Service_no +1
endm
else
VMM_Service macro name_
VMM_#name_ equ @@VMM_Service_no
@@VMM_Service_no = @@VMM_Service_no +1
endm
endif
VMM_Service Get_VMM_Version
VMM_Service Get_Cur_VM_Handle
VMM_Service Allocate_V86_Call_Back
VMM_Service Crash_Cur_VM
VMM_Service Hook_V86_Int_Chain
VMM_Service Get_V86_Int_Vector
VMM_Service Set_V86_Int_Vector
VMM_Service Get_PM_Int_Vector
VMM_Service Set_PM_Int_Vector
VMM_Service Simulate_Int
VMM_Service Simulate_Iret
VMM_Service Simulate_Far_Call
VMM_Service Simulate_Far_Jmp
VMM_Service Simulate_Far_Ret
VMM_Service Simulate_Far_Ret_N
VMM_Service Build_Int_Stack_Frame
VMM_Service Simulate_Push
VMM_Service Simulate_Pop
VMM_Service _PageFree
VMM_Service _PhysIntoV86
VMM_Service _LinMapIntoV86
VMM_Service Hook_V86_Fault ;implemented in v5.86 - previously a stub only
VMM_Service Hook_PM_Fault
VMM_Service Begin_Nest_Exec
VMM_Service Exec_Int
VMM_Service Resume_Exec
VMM_Service End_Nest_Exec
VMM_Service Save_Client_State
VMM_Service Restore_Client_State
VMM_Service Simulate_IO
VMM_Service Install_Mult_IO_Handlers
VMM_Service Install_IO_Handler
VMM_Service VMM_Add_DDB
VMM_Service VMM_Remove_DDB
VMM_Service Remove_IO_Handler
VMM_Service Remove_Mult_IO_Handlers
VMM_Service Unhook_V86_Int_Chain
VMM_Service Unhook_V86_Fault ;implemented in v5.86 - previously a stub only
VMM_Service Unhook_PM_Fault
VMM_Service _PageReserve
VMM_Service _PageCommit
VMM_Service _PageDecommit
VMM_Service _PageCommitPhys
;--- the following functions are Jemm specific
VMM_Service Free_V86_Call_Back ;release v86 callback in EAX
VMM_Service Yield ;release cpu for IRQs
VMM_Service MoveMemory ;copy memory with ints enabled
;--- added in v5.83
VMM_Service _Allocate_GDT_Selector
VMM_Service _Free_GDT_Selector
VMM_Service Get_DDB
;--- added in v5.85
VMM_Service V86ToPM ; jump to VCPI client, esi->V86toPM struct, ebp->client regs
;--- added in v5.86
VMM_Service GetDOSBuffer; get linear address of 4kB DOS buffer in JLOAD (during init phase only)
;--- equates for the page memory functions
;_PageReserve() page parameter:
PR_PRIVATE EQU 80000400H
PR_SHARED EQU 80060000H
PR_SYSTEM EQU 80080000H
;_PageCommit() hpd parameter:
PD_ZEROINIT EQU 00000001H ;not supported
PD_NOINIT EQU 00000002H ;not supported
PD_FIXEDZERO EQU 00000003H
PD_FIXED EQU 00000004H
;_PageCommit() flags parameter:
PC_FIXED EQU 00000008H ;PC_FIXED and/or PC_LOCKED must be set
PC_LOCKED EQU 00000080H
PC_WRITEABLE EQU 00020000H ;also valid for _PageCommitPhys()
PC_USER EQU 00040000H ;also valid for _PageCommitPhys()
PC_CACHEWT EQU 00080000H ;write thru
PC_CACHEDIS EQU 00100000H ;cache disable
PC_INCR EQU 40000000H ;also valid for _PageCommitPhys()
; PTE bits
P_PRESBIT EQU 0
P_PRES EQU (1 SHL P_PRESBIT)
P_WRITEBIT EQU 1
P_WRITE EQU (1 SHL P_WRITEBIT)
P_USERBIT EQU 2
P_USER EQU (1 SHL P_USERBIT)
P_ACCBIT EQU 5
P_ACC EQU (1 SHL P_ACCBIT)
P_DIRTYBIT EQU 6
P_DIRTY EQU (1 SHL P_DIRTYBIT)
;--- equates for IO trapping functions
BYTE_INPUT EQU 000H
BYTE_OUTPUT EQU 004H
WORD_INPUT EQU 008H
WORD_OUTPUT EQU 00CH
DWORD_INPUT EQU 010H
DWORD_OUTPUT EQU 014H
OUTPUT_BIT EQU 2
WORD_IO_BIT EQU 3
DWORD_IO_BIT EQU 4
STRING_IO_BIT EQU 5
REP_IO_BIT EQU 6 ;rep prefix with "string io"
ADDR_32_IO_BIT EQU 7 ;ECX used instead of CX for "rep string io"
REVERSE_IO_BIT EQU 8
OUTPUT EQU (1 SHL OUTPUT_BIT)
WORD_IO EQU (1 SHL WORD_IO_BIT)
DWORD_IO EQU (1 SHL DWORD_IO_BIT)
STRING_IO EQU (1 SHL STRING_IO_BIT)
REP_IO EQU (1 SHL REP_IO_BIT)
;--- messages
SYSTEM_EXIT EQU 5
DEVICE_REBOOT_NOTIFY EQU 17h
;--------------------------------------------------------------------------
;--- VDMA device. This device is also installed by JLoad
@@VDMAD_Service_no = 0
VDMAD_Device equ 4
VDMAD_Service macro name_
name_ equ @@VDMAD_Service_no + VDMAD_Device shl 16
@@VDMAD_Service_no = @@VDMAD_Service_no +1
endm
VDMAD_Service VDMAD_Get_Version
VDMAD_Service VDMAD_Lock_DMA_Region
VDMAD_Service VDMAD_Unlock_DMA_Region
VDMAD_Service VDMAD_Scatter_Lock
VDMAD_Service VDMAD_Scatter_Unlock
VDMAD_Service VDMAD_Request_Buffer
VDMAD_Service VDMAD_Release_Buffer
VDMAD_Service VDMAD_Copy_To_Buffer ;new v5.69
VDMAD_Service VDMAD_Copy_From_Buffer ;new v5.69
;--------------------------------------------------------------------------
;--- VM control block structure
;--- since VMs aren't supported yet, the fields aren't that useful.
;--- CB_Client_Pointer will always contain a valid pointer.
cb_s STRUC
CB_VM_Status DD ?
CB_High_Linear DD ?
CB_Client_Pointer DD ?
CB_VMID DD ?
cb_s ENDS
;--- DDB (device description block)
;--- to be used for VMM_Add_DDB / VMM_Remove_DDB
UNDEFINED_INIT_ORDER EQU 080000000H
VxD_Desc_Block STRUC
DDB_Next DD ?
DDB_Version DW ?
DDB_Req_Device_Number DW 0
DDB_Dev_Major_Version DB 0
DDB_Dev_Minor_Version DB 0
DDB_Flags DW 0
ifndef __POASM__
DDB_Name DB 8 dup (20h)
else
DDB_Name DB 8 dup (?)
endif
DDB_Init_Order DD UNDEFINED_INIT_ORDER
DDB_Control_Proc DD ?
DDB_V86_API_Proc DD 0
DDB_PM_API_Proc DD 0
DDB_V86_API_CSIP DD 0
DDB_PM_API_CSIP DD 0
DDB_Reference_Data DD ?
DDB_Service_Table_Ptr DD 0
DDB_Service_Table_Size DD 0
DDB_Win32_Service_Table DD 0
DDB_Prev DD 0
DDB_Size DD SIZE(VxD_Desc_Block)
DDB_Reserved1 DD 0 ;holds PE module handle
DDB_Reserved2 DD 0
DDB_Reserved3 DD 0
VxD_Desc_Block ENDS
;--- client register structure
;--- note the "Client_Int" member, which is Jemm specific.
Client_Reg_Struc struc
Client_EDI dd ? ;+0
Client_ESI dd ? ;+4
Client_EBP dd ? ;+8
Client_res0 dd ? ;+12
Client_EBX dd ? ;+16
Client_EDX dd ? ;+20
Client_ECX dd ? ;+24
Client_EAX dd ? ;+28
Client_Int dd ? ;+32 (pushed as sign-extended byte - so check lowest byte only!)
Client_Error dd ? ;+36
Client_EIP dd ? ;+40
Client_CS dd ? ;+44
Client_EFlags dd ? ;+48
Client_ESP dd ? ;+52
Client_SS dd ? ;+56
Client_ES dd ? ;+60
Client_DS dd ? ;+64
Client_FS dd ? ;+68
Client_GS dd ? ;+72
Client_Reg_Struc ends
;--------------------------------------------------------------------------
;--- JLoad init/term structure
;--- this is 3. parameter for a JLM's DllMain entry
;--- lpRequest is set for LOAD
;--- lpDrivers is set for UNLOAD
JLCOMM struc
wLdrCS dw ? ;CS of JLOAD.EXE
wFlags dw ? ;flags (see below)
lpCmdLine dd ? ;linear address cmdline
union
lpRequest dd ? ;LOAD: linear address DOS request hdr
lpDrivers dd ? ;UNLOAD: linear address DOS device driver list start
ends
JLCOMM ends
JLF_UNLOAD equ 1 ;set if JLM is to be unloaded
JLF_DRIVER equ 2 ;set if JLoad is loaded as driver in config.sys
JLF_UNLOAD_BIT equ 0
JLF_DRIVER_BIT equ 1
================================================
FILE: Include/JLMFASM.INC
================================================
;--- this is an assembler include file in FASM format
;--- to be used for JLMs (Jemm Loadable Modules).
;--- it defines the API exposed by Jemm/JLoad.
;--- parameters, calling convention and return values are the same as
;--- for Win9x.
;--- the register usage usually is the same as for the Win32 stdcall
;--- convention: registers EAX, ECX and EDX may be changed inside a function,
;--- registers EBX, ESI, EDI, EBP are preserved.
;--- the exception of this rule is Get_Cur_VM_Handle, which returns the
;--- "handle" in EBX.
;--------------------------------------------------------------------------
macro @VMMCall name_ {
int 20h
dw VMM_#name_
dw 1
}
macro VMMJmp name_ {
int 20h
dw VMM_#name_ + 8000h
dw 1
}
macro VxDCall name_ {
int 20h
dd name_
}
;--- macro to define a hook proc (Hook_V86_Int_Chain)
macro HookProc name_, oldvect {
jmp $+8
jmp dword [oldvect]
name_ proc
}
;--------------------------------------------------------------------------
;--- VMM API. This device is installed by JLoad. The name is misleading,
;--- though, VMs aren't supported.
;--- not implemented yet:
;--- Install_Mult_IO_Handlers, Remove_Mult_IO_Handlers
;--- Hook_V86_Fault, Unhook_V86_Fault
;--- Hook_PM_Fault, Unhook_PM_Fault
;--- Get_PM_Int_Vector, Set_PM_Int_Vector
@VMM_Service_no = 0
macro VMM_Service name_ {
VMM_#name_ = @VMM_Service_no
@VMM_Service_no = @VMM_Service_no +1
}
VMM_Service Get_VMM_Version
VMM_Service Get_Cur_VM_Handle
VMM_Service Allocate_V86_Call_Back
VMM_Service Crash_Cur_VM
VMM_Service Hook_V86_Int_Chain
VMM_Service Get_V86_Int_Vector
VMM_Service Set_V86_Int_Vector
VMM_Service Get_PM_Int_Vector
VMM_Service Set_PM_Int_Vector
VMM_Service Simulate_Int
VMM_Service Simulate_Iret
VMM_Service Simulate_Far_Call
VMM_Service Simulate_Far_Jmp
VMM_Service Simulate_Far_Ret
VMM_Service Simulate_Far_Ret_N
VMM_Service Build_Int_Stack_Frame
VMM_Service Simulate_Push
VMM_Service Simulate_Pop
VMM_Service _PageFree
VMM_Service _PhysIntoV86
VMM_Service _LinMapIntoV86
VMM_Service Hook_V86_Fault
VMM_Service Hook_PM_Fault
VMM_Service Begin_Nest_Exec
VMM_Service Exec_Int
VMM_Service Resume_Exec
VMM_Service End_Nest_Exec
VMM_Service Save_Client_State
VMM_Service Restore_Client_State
VMM_Service Simulate_IO
VMM_Service Install_Mult_IO_Handlers
VMM_Service Install_IO_Handler
VMM_Service VMM_Add_DDB
VMM_Service VMM_Remove_DDB
VMM_Service Remove_IO_Handler
VMM_Service Remove_Mult_IO_Handlers
VMM_Service Unhook_V86_Int_Chain
VMM_Service Unhook_V86_Fault
VMM_Service Unhook_PM_Fault
VMM_Service _PageReserve
VMM_Service _PageCommit
VMM_Service _PageDecommit
VMM_Service _PageCommitPhys
;--- the following functions are Jemm specific
VMM_Service Free_V86_Call_Back ;release v86 callback in EAX
VMM_Service Yield ;release cpu for IRQs
VMM_Service MoveMemory ;copy memory with ints enabled
;--- added in v5.83
VMM_Service _Allocate_GDT_Selector
VMM_Service _Free_GDT_Selector
VMM_Service Get_DDB
;--- equates for the page memory functions
;_PageReserve() page parameter:
PR_PRIVATE EQU 80000400H
PR_SHARED EQU 80060000H
PR_SYSTEM EQU 80080000H
;_PageCommit() hpd parameter:
PD_ZEROINIT EQU 00000001H ;not supported
PD_NOINIT EQU 00000002H ;not supported
PD_FIXEDZERO EQU 00000003H
PD_FIXED EQU 00000004H
;_PageCommit() flags parameter:
PC_FIXED EQU 00000008H ;PC_FIXED and/or PC_LOCKED must be set
PC_LOCKED EQU 00000080H
PC_WRITEABLE EQU 00020000H ;also valid for _PageCommitPhys()
PC_USER EQU 00040000H ;also valid for _PageCommitPhys()
PC_INCR EQU 40000000H ;also valid for _PageCommitPhys()
; PTE bits
P_PRESBIT EQU 0
P_PRES EQU (1 SHL P_PRESBIT)
P_WRITEBIT EQU 1
P_WRITE EQU (1 SHL P_WRITEBIT)
P_USERBIT EQU 2
P_USER EQU (1 SHL P_USERBIT)
P_ACCBIT EQU 5
P_ACC EQU (1 SHL P_ACCBIT)
P_DIRTYBIT EQU 6
P_DIRTY EQU (1 SHL P_DIRTYBIT)
;--- equates for IO trapping functions
BYTE_INPUT EQU 000H
BYTE_OUTPUT EQU 004H
WORD_INPUT EQU 008H
WORD_OUTPUT EQU 00CH
DWORD_INPUT EQU 010H
DWORD_OUTPUT EQU 014H
OUTPUT_BIT EQU 2
WORD_IO_BIT EQU 3
DWORD_IO_BIT EQU 4
STRING_IO_BIT EQU 5
REP_IO_BIT EQU 6 ;rep prefix with "string io"
ADDR_32_IO_BIT EQU 7 ;ECX used instead of CX for "rep string io"
REVERSE_IO_BIT EQU 8
OUTPUT EQU (1 SHL OUTPUT_BIT)
WORD_IO EQU (1 SHL WORD_IO_BIT)
DWORD_IO EQU (1 SHL DWORD_IO_BIT)
STRING_IO EQU (1 SHL STRING_IO_BIT)
REP_IO EQU (1 SHL REP_IO_BIT)
;--------------------------------------------------------------------------
;--- VDMA device. This device is also installed by JLoad
@VDMAD_Service_no = 0
VDMAD_Device equ 4
macro VDMAD_Service name_ {
name_ equ @VDMAD_Service_no + VDMAD_Device shl 16
@VDMAD_Service_no = @VDMAD_Service_no +1
}
VDMAD_Service VDMAD_Get_Version
VDMAD_Service VDMAD_Lock_DMA_Region
VDMAD_Service VDMAD_Unlock_DMA_Region
VDMAD_Service VDMAD_Scatter_Lock
VDMAD_Service VDMAD_Scatter_Unlock
VDMAD_Service VDMAD_Request_Buffer
VDMAD_Service VDMAD_Release_Buffer
VDMAD_Service VDMAD_Copy_To_Buffer ;new v5.69
VDMAD_Service VDMAD_Copy_From_Buffer ;new v5.69
;--------------------------------------------------------------------------
;--- VM control block structure
;--- since VMs aren't supported yet, the fields aren't that useful.
;--- CB_Client_Pointer will always contain a valid pointer.
struct cb_s
CB_VM_Status DD ?
CB_High_Linear DD ?
CB_Client_Pointer DD ?
CB_VMID DD ?
ends
if 0
;--- DDB (device description block)
;--- to be used for VMM_Add_DDB / VMM_Remove_DDB
struct VxD_Desc_Block
DDB_Next dd ?
DDB_Version DW ?
DDB_Req_Device_Number DW ?
DDB_Dev_Major_Version DB ?
DDB_Dev_Minor_Version DB ?
DDB_Flags DW ?
DDB_Name rb 8
DDB_Init_Order DD ?
DDB_Control_Proc DD ?
DDB_V86_API_Proc DD ?
DDB_PM_API_Proc DD ?
DDB_V86_API_CSIP DD ?
DDB_PM_API_CSIP DD ?
DDB_Reference_Data DD ?
DDB_Service_Table_Ptr DD ?
DDB_Service_Table_Size DD ?
DDB_Win32_Service_Table DD ?
DDB_Prev DD ?
DDB_Size DD ?
DDB_Reserved1 DD ?
DDB_Reserved2 DD ?
DDB_Reserved3 DD ?
ends
end if
;--- client register structure
;--- note the "Client_Int" member, which is Jemm specific.
struct Client_Reg_Struc
Client_EDI dd ? ;+0
Client_ESI dd ? ;+4
Client_EBP dd ? ;+8
Client_res0 dd ? ;+12
Client_EBX dd ? ;+16
Client_EDX dd ? ;+20
Client_ECX dd ? ;+24
Client_EAX dd ? ;+28
Client_Int dd ? ;+32
Client_Error dd ? ;+36
Client_EIP dd ? ;+40
Client_CS dd ? ;+44
Client_EFlags dd ? ;+48
Client_ESP dd ? ;+52
Client_SS dd ? ;+56
Client_ES dd ? ;+60
Client_DS dd ? ;+64
Client_FS dd ? ;+68
Client_GS dd ? ;+72
ends
;--------------------------------------------------------------------------
;--- JLoad init/term structure
;--- this is 3. parameter for a JLM's DllMain entry
;--- lpRequest is set for LOAD
;--- lpDrivers is set for UNLOAD
struct JLCOMM
wLdrCS dw ? ;CS of JLOAD.EXE
wFlags dw ? ;flags (see below)
lpCmdLine dd ? ;linear address cmdline
lpRequest dd ? ;LOAD: linear address DOS request hdr
virtual at JLCOMM.lpRequest
lpDrivers dd ? ;UNLOAD: linear address DOS device driver list start
end virtual
ends
JLF_UNLOAD equ 1 ;set if JLM is to be unloaded
JLF_DRIVER equ 2 ;set if JLoad is loaded as driver in config.sys
JLF_UNLOAD_BIT equ 0
JLF_DRIVER_BIT equ 1
================================================
FILE: Include/JSYSTEM.INC
================================================
;--- constants used by Jemm & JLoad
?VERSIONHIGH equ 5
?VERSIONLOW equ 87
?BASE EQU 110000h ; base of Jemm 32bit code
?SYSBASE EQU 0F8000000h ; linear address system space
?PAGEDIR EQU ?SYSBASE+1000h ; linear address page dir
?PAGETABSYS EQU 3000h ; rel. offset (?SYSBASE) for system page table
;--- 3000 = 3 page tables ( pagedir, page tab0, system page tab )
?TOS EQU ?SYSBASE+1000h+3000h+1000h ;top of ring 0 stack
;--- this is the structure for a "Get VMM info" request
;--- v5.87: fields e08_pCallBack and e08_CallBackRM do now
;--- point to the *second* static breakpoint in Jemm32/Jemm16.
;--- Thus JLoad doesn't need to know anything about the breakpoint array.
EMX08 struct
e08_ServiceTable dd ? ;linear address service table
e08_pCallBack dd ? ;linear address callback BP in Jemm32
e08_CallBackRM dd ? ;segment:offset of callback BP in Jemm16
e08_GDTR df ?
e08_IDTR df ?
e08_TR dw ?
e08_FlatCS dw ?
EMX08 ends
================================================
FILE: Include/PRINTF.INC
================================================
;--- simple printf
;--- i64toa(long long n, char * s, int base);
;--- convert 64-bit long long to string
i64toa proc stdcall uses edi number:qword, outb:ptr, base:dword
mov ch,0
mov edi, base
mov eax, dword ptr number+0
mov esi, dword ptr number+4
cmp edi,-10
jne @F
neg edi
and esi,esi
jns @F
neg esi
neg eax
sbb esi,0
mov ch,'-'
@@:
mov ebx,outb
add ebx,22
mov byte ptr [ebx],0
@@nextdigit:
dec ebx
xor edx,edx
xchg eax,esi
div edi
xchg eax,esi
div edi
add dl,'0'
cmp dl,'9'
jbe @F
add dl,7+20h
@@:
mov [ebx],dl
mov edx, eax
or edx, esi
jne @@nextdigit
cmp ch,0
je @F
dec ebx
mov [ebx],ch
@@:
mov eax,ebx
ret
i64toa endp
printf proc c fmt:ptr, args:vararg
local flag:byte
local longarg:byte
local size_:dword
local fillchr:dword
local szTmp[24]:byte
local crs:Client_Reg_Struc
pushad
mov ebp, [ebp]
lea edi, crs
@VMMCall Save_Client_State
@VMMCall Begin_Nest_Exec
mov ebp, [esp+2*4] ;restore EBP
cld
lea edi,args
@@L335:
mov esi,fmt
nextchar:
lodsb
or al,al
je done
cmp al,'%'
je formatitem
call handle_char
jmp nextchar
done:
mov ebp, [ebp]
@VMMCall End_Nest_Exec
lea esi, crs
@VMMCall Restore_Client_State
popad
ret
formatitem:
push offset @@L335
xor edx,edx
mov [longarg],dl
mov bl,1
mov cl,' '
cmp BYTE PTR [esi],'-'
jne @F
dec bl
inc esi
@@:
mov [flag],bl
cmp BYTE PTR [esi],'0'
jne @F
mov cl,'0'
inc esi
@@:
mov [fillchr],ecx
mov ebx,edx
.while ( byte ptr [esi] >= '0' && byte ptr [esi] <= '9' )
lodsb
sub al,'0'
movzx eax,al
imul ecx,ebx,10 ;ecx = ebx * 10
add eax,ecx
mov ebx,eax
.endw
mov [size_],ebx
cmp BYTE PTR [esi],'l'
jne @F
mov [longarg],1
inc esi
@@:
lodsb
mov [fmt],esi
cmp al,'x'
je handle_x
cmp al,'X'
je handle_x
cmp al,'d'
je handle_d
cmp al,'u'
je handle_u
cmp al,'s'
je handle_s
cmp al,'c'
je handle_c
and al,al
jnz @F
pop eax
jmp done
handle_c:
mov eax,[edi]
add edi, 4
@@:
call handle_char
retn
handle_s:
mov esi,[edi]
add edi,4
jmp print_string
handle_d:
handle_i:
mov ebx,-10
jmp @F
handle_u:
mov ebx, 10
jmp @F
handle_x:
mov ebx, 16
@@:
xor edx,edx
mov eax,[edi]
add edi,4
cmp longarg,1
jnz @F
mov edx,[edi]
add edi,4
jmp printnum
@@:
and ebx,ebx
jns @F
cdq
@@:
printnum:
lea esi, szTmp
invoke i64toa, edx::eax, esi, ebx
mov esi, eax
print_string: ;print string ESI, size EAX
mov eax, esi
.while byte ptr [esi]
inc esi
.endw
sub esi, eax
xchg eax, esi
mov ebx,size_
sub ebx,eax
.if flag == 1
.while sdword ptr ebx > 0
mov eax, [fillchr]
call handle_char ;print leading filler chars
dec ebx
.endw
.endif
.while byte ptr [esi]
lodsb
call handle_char ;print char of string
.endw
.while sdword ptr ebx > 0
mov eax, [fillchr]
call handle_char ;print trailing spaces
dec ebx
.endw
retn
handle_char:
push ebp
mov ebp, [ebp]
mov ah, 0Eh
mov [ebp].Client_Reg_Struc.Client_EAX, eax
mov byte ptr [ebp].Client_Reg_Struc.Client_EBX+1, 0
mov eax, 10h
@VMMCall Exec_Int
pop ebp
retn
printf endp
================================================
FILE: Include/VDS.INC
================================================
;--- VDS definitions
;--- flags in DX used by various VDS functions
VDSF_COPY equ 02h ;bit 1 - copy in/out of DMA buffer (8107/8108)
VDSF_NOBUFFER equ 04h ;bit 2 - don't alloc DMA buffer (8103)
VDSF_NOREMAP equ 08h ;bit 3 - change PTEs; Jemm ignores this flag!
VDSF_64KALIGN equ 10h ;bit 4
VDSF_128KALIGN equ 20h ;bit 5
VDSF_PTE equ 40h ;bit 6 - 1=scatter_lock returns PTEs
VDSF_NPPTE equ 80h ;bit 7 - allow non-present pages for scatter/gather remap
;--- error codes returned in AL by lock (8103)
VDSERR_NOTCONTIGUOUS equ 1 ;region not in contiguous memory
VDSERR_CROSSEDBOUNDS equ 2 ;region crossed alignemnt boundary
VDSERR_CANTLOCKPAGES equ 3 ;
VDSERR_NOBUFFER equ 4 ; 8107
VDSERR_BUFFTOOSMALL equ 5 ; 8107
VDSERR_BUFFINUSE equ 6 ;
;--- other VDS error codes
VDSERR_07 equ 7 ; invalid memory region (8107)
VDSERR_REG_NOTLOCKED equ 8 ; region wasn't locked (8106)
VDSERR_NAVL_TOOSMALL equ 9 ; # of phys pages was > than table length (8105)
VDSERR_INVAL_BUFFID equ 10 ; invalid buffer ID (8108,8109,810A)
VDSERR_BNDVIOLATION equ 11 ; buffer boundary violated (8109,810A)
VDSERR_INVAL_DMACHN equ 12 ; invalid DMA channel # (810B, 810C)
VDSERR_DISCNTOVFL equ 13 ; disable cnt overflow (810B)
VDSERR_DISCNTUNFL equ 14 ; disable cnt underflow (810C)
VDSERR_FUNC_NOTSUPP equ 15 ; function not supported
VDSERR_DXRSVDBITSSET equ 16 ; reserved flag bits set in DX (8102,8106,8108,8109,810A,810B,810C)
;--- DDS, used by 03-04, 07-08, 09-0A
DDS struct
dwSize dd ? ;+0 size of region
dwOfs dd ? ;+4 offset virtual start address
wSeg dw ? ;+8 segment/selector virtual start address (or 0000)
wID dw ? ;+10 buffer ID
dwPhys dd ? ;+12 physical address
DDS ends
;--- EDDS, used by 05-06
EDDS struct
dwSize dd ? ;+0
dwOfs dd ? ;+4
wSeg dw ? ;+8
wRes dw ? ;+10
wNumAvail dw ? ;+12
wNumUsed dw ? ;+14
EDDS ends
;--- EDDS suffix for regions
EDDSRG struct
dwPhysAddr dd ? ;+16
dwSizeRg dd ? ;+20
EDDSRG ends
;--- EDDS suffix for PTEs
EDDSPT struct
dwPTE dd ? ;+16
EDDSPT ends
================================================
FILE: Include/X86.INC
================================================
;--- generic X86 definitions
;--- page table flags
PTF_PRESENT equ 001h
PTF_RW equ 002h
PTF_USER equ 004h
PTF_PWT equ 008h ; page write through
PTF_PCD equ 010h ; page cache disable
PTF_ACCESS equ 020h ; page accessed
PTF_DIRTY equ 040h ; page dirty
PTF_4MB equ 080h ; PDEs: 4MB PDE
PTF_GBL equ 100h ; page global (P3+)
;--- features, returned by CPUID in EDX
CF_FPU equ 0001h
CF_VME equ 0002h
CF_DE equ 0004h;debugging ext
CF_PSE equ 0008h;Page Size Ext (4MB)
CF_TSC equ 0010h;Time Stamp Counter
CF_MSR equ 0020h;RDMSR/WRMSR supported
CF_PAE equ 0040h;Physical Address Ext
CF_MCE equ 0080h;Machine Check Exceptions
CF_CX8 equ 0100h;CMPXCHG8B supported
CF_APIC equ 0200h;APIC exists
;rsvd equ 0400h;
CF_SEP equ 0800h;SYSENTER/SYSEXIT supported
CF_MTRR equ 1000h
CF_PGE equ 2000h
;--- flags in CR4
CR4_VME equ 01h
CR4_PVI equ 02h
CR4_TSD equ 04h;1=time stamp disable
CR4_DE equ 08h
CR4_PSE equ 10h;1=page size extensions enabled
CR4_PAE equ 20h
CR4_MCE equ 40h
CR4_PGE equ 80h
;--- descriptor
DESCRIPTOR struct
wLimit dw ? ;+0
wA0015 dw ? ;+2
bA1623 db ? ;+4
bAttr db ? ;+5
bLimEx db ? ;+6
bA2431 db ? ;+7
DESCRIPTOR ends
GATE struct
wOfsLo dw ?
wSeg dw ?
wAttr dw ?
wOfsHi dw ?
GATE ends
;--- TSS structure
;--- the only fields in the TSS which are needed are tsEsp0, tsSS0
;--- and tsOfs. Jemm386 will never switch tasks.
TSSSEG struct
dd ? ;+00 selector
tsEsp0 dd ? ;+04
tsSS0 dd ? ;+08
dq ? ;+0C
dq ? ;+14
tsCR3 dd ? ;+1C
tsEip dd ? ;+20
tsEfl dd ? ;+24
tsEax dd ? ;+28
tsEcx dd ? ;+2C
tsEdx dd ? ;+30
tsEbx dd ? ;+34
tsEsp dd ? ;+38
tsEbp dd ? ;+3C
tsEsi dd ? ;+40
tsEdi dd ? ;+44
tsES dd ? ;+48
tsCS dd ? ;+4C
tsSS dd ? ;+50
tsDS dd ? ;+54
tsFS dd ? ;+58
tsGS dd ? ;+5C
tsLDTR dd ? ;+60
tsFlags dw ? ;+64
tsOfs dw ? ;+66
TSSSEG ends
;--- stack frame for PUSHAD
PUSHADS struct
rEDI dd ?
rESI dd ?
rEBP dd ?
dd ? ;reserved
rEBX dd ?
rEDX dd ?
rECX dd ?
rEAX dd ?
PUSHADS ends
;--- RETF stack frame for 16bit
RETFWS struct
union
struct
_Ip dw ?
_Cs dw ?
ends
_CsIp dd ?
ends
RETFWS ends
;--- IRET stack frame for 16bit
IRETWS struct
RETFWS <>
_Fl dw ?
IRETWS ends
;--- IRET stack frame for 32bit protected-mode
IRETDS struct
_Eip dd ? ;+0
_Cs dd ? ;+4
_Efl dd ? ;+8
IRETDS ends
;--- stack frame expected by ring0-IRETD to switch to v86-mode
IRETDV86 struct
_Eip dd ? ;+0
_Cs dd ? ;+4
_Efl dd ? ;+8
_Esp dd ? ;+12
_Ss dd ? ;+16
_Es dd ? ;+20
_Ds dd ? ;+24
_Fs dd ? ;+28
_Gs dd ? ;+32
IRETDV86 ends
;--- bit positions of CPUID edx
CPUID_VME equ 1 ; =2
CPUID_PGE equ 13 ; =2000h
CPUID_PAT equ 16 ; =10000h
================================================
FILE: JLM/AHCICD/AHCICD.ASM
================================================
;--- JLM to read CD/DVD in AHCI mode.
;--- "cooked" mode is supported only.
.386
.model flat
option casemap:none
option proc:private
include jlm.inc
?OPTIONR equ 1 ; 1=enable /R option to relocate Port.CLB, Port.FB, Commandlist[0].CTBA
?IRQWND equ 1 ; 1=use Jemm's MoveMemory() that allows interrupts during copy op
REQOFS equ 16h ; must be at least "sizeof DOSDRV"
SLCOOKED equ 2048
SLRAW equ 2352 ;CD-ROM "raw" sector length.
;--- macros
CStr macro text:vararg
local sym
.const
sym db text,0
.code
exitm <offset sym>
endm
@dprintf macro text,args:vararg
local sym
ifdef _DEBUG
.const
sym db text,0
.code
ifnb <args>
invoke printf, offset sym, args
else
invoke printf, offset sym
endif
endif
endm
;--- structs
DOSDRV struct
dd ?
wAttr dw ?
ofsStr dw ?
ofsInt dw ?
name_ db 8 dup (?);+10
wRes1 dw ? ;+18 req. for cd drivers, init with 0
bRes2 db ? ;+20 req. for cd drivers, modified by mscdex
bUnits db ? ;+21 set by driver
DOSDRV ends
;--- DOS "Request Packet" Layouts.
RPH struct
RPHLen db ? ;+0 Header byte count.
bSubU db ? ;+1 Subunit number.
bOp db ? ;+2 Command code.
wStat dw ? ;+3 Status field.
db 8 dup (?);+5 .. +12 (reserved).
RPH ends
RPERR equ 8003h ;Packet "error" flags.
RPDON equ 0100h ;Packet "done" flag.
RPBUSY equ 0200h ;Packet "busy" flag.
;--- Init "Request Packet" Layout
RPInit struct
RPH <>
bUnit db ? ;+13 Number of units found.
dwFree dd ? ;+14 return: far16 ptr first free byte behind driver
CmdLine dd ? ;+18 Command-line data pointer.
RPInit ends
;--- IOCTL "Request Packet" Layout
RPIOC struct
RPH <>
db ? ;+13 Media descriptor byte (Unused by us).
dwAddr dd ? ;+14 Data-transfer address.
wLength dw ? ;+18 Data-transfer length.
dw ? ;+20 Starting sector (unused by us).
dd ? ;+22 Volume I.D. pointer (unused by us).
RPIOC ends
;--- Read Long "Request Packet" Layout
RPRL struct
RPH <>
bAMode db ? ;+13 Addressing mode.
dwAddr dd ? ;+14 Data-transfer address.
wSecCnt dw ? ;+18 Data-transfer sector count.
dwStart dd ? ;+20 Starting sector number.
bDMode db ? ;+24 Data-transfer mode (raw/cooked).
bILSize db ? ;+25 Interleave size.
bILSkip db ? ;+26 Interleave skip factor.
RPRL ends
;--- AHCI structures
HBA struct
dwCAP dd ? ;+0 HBA capabilities
dwGHC dd ? ;+4 global HBA control
dwIS dd ? ;+8 interrupt status
dwPI dd ? ;+12 ports implemented
HBA ends
PORT struct
dqCLB dq ? ;+0 Command list base addr ( 1 kB aligned )
dqFB dq ? ;+8 (received) FIS base addr ( 256 B aligned )
dwIS dd ? ;+16 interrupt status
dwIE dd ? ;+20 interrupt enable
dwCMD dd ? ;+24 command and status
dd ? ;+28
dwTFD dd ? ;+32 task file data
dwSIG dd ? ;+36 signature
dwSSTS dd ? ;+40 SATA status
dwSCTL dd ? ;+44 SATA control
dwSERR dd ? ;+48 SATA error
dwSACT dd ? ;+52 SATA active
dwCI dd ? ;+56 command issued
PORT ends
;--- flags dwIS field
PIS_CPDS equ 80000000h
PIS_TFES equ 40000000h
PIS_HBFS equ 20000000h
PIS_HBDS equ 10000000h
PIS_SDBS equ 00000008h ; set device bits interrupt
PIS_DSS equ 00000004h ; DMA setup FIS interrupt
PIS_PSS equ 00000002h ; PIO setup FIS interrupt
PIS_DHRS equ 00000001h ; device to host register FIS interrupt
;--- flags dwCMD field
PCMD_CR equ 8000h ; RO, 1=command list DMA engine running
PCMD_FR equ 4000h ; RO, 1=FIS Receive running
PCMD_FRE equ 0010h ; RW, 1=FIS Receive Enable
PCMD_CLO equ 0008h ; RW, 1=command list override
PCMD_POD equ 0004h ; RW, Power On Device
PCMD_SUD equ 0002h ; RW, Spin Up Device
PCMD_ST equ 0001h ; RW, Start (HBA may process the command list)
;--- AHCI command list header
CLH struct
flags1 db ? ;+0 P[7]=Prefetchable, W[6]=Write, A[5]=ATAPI, CFL[4:0]=Command FIS Length
flags2 db ? ;+1 PMP[15:12]=Port Multiplier Port, R[11]=Reserved, C[10]=Clear Busy, B[9]=BIST, R[8]=Reset
PRDTL dw ? ;+2 Physical Region Descriptor Table Length
PRDBC dd ? ;+4 Physical Region Descriptor Byte Count
dwCTBA dd ? ;+8 Command Table Base Address bits 0-31 (128 byte aligned)
dwCTBAU dd ? ;+12 Command Table Base Address bits 32-63
dd 4 dup (?)
CLH ends
PRDT struct
dwBase dd ? ;+0 base
dwBaseU dd ? ;+4 base upper
dwRsvd dd ? ;+8 reserved
dwCnt dd ? ;+12 cnt
PRDT ends
;--- AHCI command table
CT struct
cfis0 dd ?
cfis1 dd ?
cfis2 dd ?
cfis3 dd ?
db 30h dup (?) ; 40h=offset ATAPI in command table
Pkt0 dd ?
Pkt1 dd ?
Pkt2 dd ?
db 34h dup (?) ; 80h=offset PRDT in command table
p0 PRDT <>
CT ends
; packet commands:
; - 003h: request sense
; - 01Bh: start/stop unit
; - 01Eh: prevent/allow media removal
; - 025h: read capacity
; - 028h: read (cooked)
; - 02Bh: seek
; - 042h: read sub-channel
; - 043h: read TOC
; - 047h: play audio MSF
; - 04Ah: get event status notification
; - 04Bh: pause/resume
; - 05Ah: mode sense
; - 0BEh: read CD (raw)
if 0
Packet struct
PktOPC db 0 ;+0 packet command.
db 0 ;+1 Unused (LUN and reserved).
PktLBA dd 0 ;+2 CD-ROM logical block address.
PktLH db 0 ;+6 "Transfer length" (sector count).
PktLn dw 0 ;+7 Middle- and low-order sector count.
PktRM db 0 ;+9 Read mode ("Raw" Read Long only).
dw 0 ;+10 Unused ATAPI "pad" bytes (required).
Packet ends
endif
.data?
if ?OPTIONR
cmdlst CLH 32 dup (<>) ; must be 1024 B aligned
fis db 100h dup (?) ; must be 256 B aligned
cmdtab CT <> ; must be 128 B aligned
endif
buffer db SLCOOKED dup (?)
db SLRAW - SLCOOKED dup (?)
ppReq dd ? ; linear address where request header is stored
pRequest dd ? ; linear address request header
pBase dd ? ; linear address driver base
pDest dd ? ; linear address destination
pHBA dd ? ; linear address HBA
pBuff dd ? ; linear address sector buffer
dwBuffPh dd ? ; physical address sector buffer
dwSector dd ? ; current sector to read
if ?OPTIONR
pCLB dd ? ; linear address Port[x].CLB
pCTBA dd ? ; linear address CL[0].CTBA
endif
wPort dw 6 dup (?); port offsets of max. 6 CD/DVDs
wSecCnt dw ? ; #sectors to read
bUnits db ? ; found units (during init)
bCntOpt db ? ; /C option default value
bQuiet db ? ; /Q option
if ?OPTIONR
bReloc db ? ; /R option
endif
bBanner db ? ; 1=banner displayed
.const
ERRTAB db 12,12,2,4,12,0,15,8,8,12,12,12,12,12,12,12
rmcode label byte
db 2Eh, 89h, 1eh, REQOFS+0, 0 ;mov cs:[16h],bx
db 2Eh, 8Ch, 06h, REQOFS+2, 0 ;mov cs:[18h],es
db 0CBh ;retf
SIZERMCODE equ $ - offset rmcode
db 0EAh ;jmp ssss:oooo
.code
ifdef _DEBUG
include printf.inc
endif
DevInt proc
.const
align 4
;--- cmds 00-0E
Vector label dword
dd Init ; 0 Init
dd Error3 ; 1 media check (block devices)
dd Error3 ; 2 build bpb (block devices)
dd IOCtlInp ; 3 ioctl input
dd Error3 ; 4 input
dd Error3 ; 5 nondestr. input
dd Error3 ; 6 input status (char devices)
dd Error3 ; 7 input flush (char devices)
dd Error3 ; 8 output
dd Error3 ; 9 output with verify
dd Error3 ;10 output status (char devices)
dd Error3 ;11 output flush (char devices)
dd Error3 ;12 ioctl output
dd Exit ;13 device open
dd Exit ;14 device close
; dd Error3 ;15 removable media (block devices)
LVECTOR equ ($ - offset Vector) / sizeof dword
;--- cmds 128-13x
Vect2 label dword
dd ReadL ;128 CD read long
dd Error3 ;129 CD reserved
dd Exit ;130 CD read long prefetch
; dd Error3 ;131 CD seek
; dd Error3 ;132 CD play audio
; dd Error3 ;133 CD stop audio
; dd Error3 ;134 CD write long
; dd Error3 ;135 CD write long verify
; dd Error3 ;136 CD resume audio
LVECT2 equ ($ - offset Vect2) / sizeof dword
.code
mov ebx, [ppReq]
movzx eax, word ptr [ebx+0]
movzx ebx, word ptr [ebx+2]
shl ebx, 4
add ebx, eax ;Point to DOS request packet.
mov [pRequest], ebx ;linear address request header
mov al, [ebx].RPH.bOp
@dprintf <'DevInt enter, Op=%X, flags=%X',13,10>, eax, [ebp].Client_Reg_Struc.Client_EFlags
and al, al
jz @F
mov al, [bUnits]
cmp [ebx].RPH.bSubU, al
mov ax, 8101h
jnc ExitAX
@@:
mov esi, offset Vector
mov cl, LVECTOR
movzx eax, [ebx].RPH.bOp
and al, al
jns @F
mov esi, offset Vect2
and al, 7Fh
mov cl, LVECT2
@@:
cmp al, cl
jnc Error3X
push [ebp].Client_Reg_Struc.Client_EFlags
or byte ptr [ebp].Client_Reg_Struc.Client_EFlags+1, 2 ; set client IF so Yield will enable interrupts
call dword ptr [esi+eax*4]
pop [ebp].Client_Reg_Struc.Client_EFlags
ExitAX:
@dprintf <'DevInt exit, ax=%X',13,10>, ax
mov ebx, [pRequest]
mov [ebx].RPH.wStat, ax
@VMMCall Simulate_Far_Ret
ret
Error3X:
push ExitAX
Error3:
mov ax, 8103h
ret
Exit:
mov ax, RPDON
ret
DevInt endp
;--- IOCtl Input dispatcher
IOCtlInp proc
.const
align 4
;--- IOCTL input subcmds
IVect label dword
dd IOC_GetHdr ; 0 get device driver header address
dd IOC_Error3 ; 1 drive head location
dd IOC_Error3 ; 2 reserved
dd IOC_Error3 ; 3 error statistics
dd IOC_Error3 ; 4 audio channel info
dd IOC_Error3 ; 5 raw data bytes
dd IOC_DevSt ; 6 device status
dd IOC_SecSize ; 7 sector size
dd IOC_Error3 ; 8 volume size
dd IOC_Media ; 9 media change status
; dd IOC_Error3 ;10 audio disk info
; dd IOC_Error3 ;11 audio track info
; dd IOC_Error3 ;12 audio q-channel info
; dd IOC_Error3 ;13 audio sub-channel info
; dd IOC_Error3 ;14 UPC code
; dd IOC_Error3 ;15 audio status info
LIVECT equ ($ - offset IVect) shr 2
.code
movzx eax, word ptr [ebx].RPIOC.dwAddr+0
movzx esi, word ptr [ebx].RPIOC.dwAddr+2
shl esi, 4
add esi, eax
movzx eax, byte ptr [esi]
@dprintf <'DevInt, ioctl input, buffer=%X, al=%X',13,10>, esi, eax
cmp al, LIVECT
jnc IOC_Error3
jmp [eax*4][IVect]
IOC_Error3:
mov ax, 8103h
retn
IOC_Error12:
mov ax, 810Ch
retn
IOC_GetHdr:
mov eax, [pBase]
shl eax, 12
@dprintf <'DevInt, ioctl input, gethdr, return=%X',13,10>, eax
mov [esi+1], eax
IOC_done:
mov ax, RPDON
retn
;--- request "get device status"
;--- status flag bits:
;--- 001 - door opened
;--- 002 - door unlocked
;--- 004 - supports cooked AND raw
;--- 008 - read AND write
;--- 010 - data read AND play audio
;--- 020 - supports interleaving
;--- 040 - (res)
;--- 080 - supports prefetching
;--- 100 - supports audio channel manipulation
;--- 200 - supports HSG AND red book addressing modes
IOC_DevSt:
; mov dword ptr [esi+1], 2 ;set "door unlocked"
mov dword ptr [esi+1], 2+4 ;set "door unlocked" & "cooked AND raw"
jmp IOC_done
IOC_SecSize:
cmp byte ptr [esi+1],1 ;read mode "cooked" or "raw"?
ja IOC_Error12 ;No? Post "general failure" & exit.
mov ax, SLRAW
je @F
mov ax, SLCOOKED
@@:
mov [esi+2], ax
jmp IOC_done
IOCtlInp endp
IOC_Media proc
@dprintf <'DevInt, ioctl input, media',13,10>
xor edi, edi
call Setup ; set EDI=command table, ebx=port offset
;--- write packet data ( 12 bytes )
;--- 0: 4A - cmd "get event status notification"
;--- 1: 01 - bit 0=1 immediate
;--- 4: 10 - notification class request, bit 4=1 is "media"
;--- 7-8: 0008 - allocation length ( hibyte first )
;--- ACMD.00: 4A,01,00,00
;--- ACMD.04: 10,00,00,00
;--- ACMD.08: 08,00,00,00
mov [edi].CT.Pkt0, 14AH
mov [edi].CT.Pkt1, 10H
mov [edi].CT.Pkt2, 8
call Req8
and al, al
jnz MedChg
;--- request has returned 8 bytes,
;--- 0-3: event header (0-1 event data length, hibyte first)
;--- 4-7: event data ( 0=media event [bit 0-3], 1=media status [bit 0-1])
mov eax, [pBuff]
mov ax, [eax+4]
and al, al
jnz MedChg
test ah, 2 ; bit 1=1 if media present
jz MedChg
mov byte ptr [esi+1], 1
jmp MedEnd
MedChg:
mov byte ptr [esi+1], 0
MedEnd:
call Setup
call ReqSense
mov eax, [pBuff]
mov al, [eax+2]
and al, 15
jz @F
mov byte ptr [esi+1], 0
cmp al, 6
jz MedEnd
@@:
mov ax, RPDON
ret
IOC_Media endp
;--- read sector(s)
;--- in: ebx=RL
ReadL proc
mov al, 3
cmp [ebx].RPRL.bAMode, 0; High Sierra addressing mode?
jnz ErrorAL_AMode
cmp [ebx].RPRL.bDMode, 1; 0=cooked, 1=raw
ja ErrorAL_DMode
movzx eax, word ptr [ebx].RPRL.dwAddr+0
movzx edx, word ptr [ebx].RPRL.dwAddr+2
shl edx, 4
add eax, edx
mov [pDest], eax
mov cx, [ebx].RPRL.wSecCnt
mov eax, [ebx].RPRL.dwStart
mov [wSecCnt], cx
mov [dwSector], eax
@dprintf <'DevInt, readl, start=%X, sectors=%X, dst=%X',13,10>, eax, cx, pDest
xor edi, edi
mov esi, ebx
ReadLP: ;<----
cmp [wSecCnt], 0
jz Exit
call Setup ; set EDI=command table, ebx=port offset
;--- write packet data ( 12 bytes )
;--- 0: cmd 28/0BE ( read cooked/raw )
;--- 1: flags
;--- 2-5: LBA (high byte first)
;--- 6: group no
;--- 7-8: transfer length [sector count] ( high byte first )
;--- 9: control (0 for cooked, 0F8h for raw mode)
mov eax, [dwSector]
shld ecx, eax, 16
;--- ax=sect[0-15]
;--- cx=sect[16-31]
movzx eax, ax
xchg al, ah
xchg cl, ch
;--- al=sect[8-15], ah=sect[0-7], cl=sect[24-31], ch=sect[16-23]
shl ecx, 16
mov cl, 28H ; read cooked
;--- ACMD.00: 28h/0BEh (opcode "read cooked"),00,Sector.04,Sector.03
;--- ACMD.04: Sector.02, Sector.01, group#, length.02
;--- ACMD.08: length.01,00,00,00
mov [edi].CT.Pkt0, ecx
mov [edi].CT.Pkt1, eax
mov [edi].CT.Pkt2, 1
mov ecx, 800007FFH ; PRDT.0C: FF,07,00,80 (PRC=7FF transfer 2048 bytes, 80=I)
cmp [esi].RPRL.bDMode, 0
jz @F
;--- ACMD.00: 0BE (opcode "read raw"),00,Sector.04,Sector.03
mov byte ptr [edi].CT.Pkt0, 0BEh
mov byte ptr [edi].CT.Pkt2+1, 0F8h
mov ecx, 8000092FH ; PRDT.0C: 2F,09,00,80 (PRC=92F transfer 2352 bytes, 80=I)
@@:
call ReqECX
and al, al
jnz readerr
push edi
push esi
mov ecx, SLCOOKED
cmp [esi].RPRL.bDMode, 0
jz @F
mov ecx, SLRAW
@@:
push ecx
mov edi, [pDest]
mov esi, [pBuff]
cld
if ?IRQWND
@VMMCall MoveMemory
else
shr ecx, 2
rep movsd
@VMMCall Yield
endif
pop ecx
pop esi
pop edi
add [pDest], ecx
inc [dwSector]
dec [wSecCnt]
jmp ReadLP
readerr:
call Setup
call ReqSense
and al, al
jnz ErrorAL
mov eax, [pBuff]
mov al, [eax+2]
and al, 15
mov ebx, offset ERRTAB
xlat
ErrorAL_AMode:
ifdef _DEBUG
@dprintf <'DevInt, readl, error, addressing mode',13,10>
jmp ErrorAL
endif
ErrorAL_DMode:
ifdef _DEBUG
@dprintf <'DevInt, readl, error, data mode',13,10>
jmp ErrorAL
endif
ErrorAL:
mov ah, 81h
@dprintf <'DevInt, readl, error, ax=%X',13,10>, ax
ret
Exit:
ifdef _DEBUG
mov ebx, [pRequest]
@dprintf <'DevInt, readl, ok, sector=%X',13,10>, [ebx].RPRL.dwStart
endif
mov ax, RPDON
ret
ReadL endp
;--- in:
;--- ebx=RP if edi==0
;--- out:
;--- ebx=port offset
;--- edi=linear address ATAPI command table
Setup proc
cmp edi, 0 ; first call?
jnz @F
movzx eax, byte ptr [ebx+1]
movzx ebx, [eax*2][wPort]
add ebx, [pHBA]
;--- get command list/table bases.
;--- those are physical addresses and hence "should" be translated to linear ones.
if ?OPTIONR
mov eax, [pCLB] ; get command list base
mov edi, [pCTBA] ; get command table base address
@dprintf <'DevInt, setup, cmdlist=%X/%X, cmdtable=%X/%X',13,10>, eax, dword ptr [ebx].PORT.dqCLB, edi, [eax].CLH.dwCTBA
else
mov eax, dword ptr [ebx].PORT.dqCLB ; get command list base
mov edi, [eax].CLH.dwCTBA ; get command table base address
@dprintf <'DevInt, setup, cmdlist=%X, cmdtable=%X',13,10>, eax, edi
endif
;--- CLH.00: 25,00,01,00 [CFL=5 dwords, A=1, PRD table length=1]
;--- CLH.04: 00,00,00,00 [PRD byte count=0]
mov dword ptr [eax].CLH.flags1, 10025H
mov [eax].CLH.PRDBC, 0
@@:
;--- CT.00: 27,80,A0,01 [27=H2D register FIS,80=set command register,A0=ATAPI packet command,01=Features]
;--- CT.04: 00,FF,FF,00 [LBA low,mid,high,device]
;--- CT.08: 00,00,00,00 [LBA (exp) low,mid,high,features]
;--- CT.0C: 01,00,00,00 [sector count, sector count,res,control]
mov [edi].CT.cfis0, 1A08027H
mov [edi].CT.cfis1, 0FFFF00H
mov [edi].CT.cfis2, 0
mov [edi].CT.cfis3, 1
;--- set base; must be physical address
mov ecx, [dwBuffPh]
mov [edi].CT.p0.dwBase, ecx
xor ecx, ecx
mov [edi].CT.p0.dwBaseU, ecx
mov [edi].CT.p0.dwRsvd, ecx
xor ecx, ecx
mov [ebx].PORT.dwIE, ecx
or ecx, -1
mov [ebx].PORT.dwIS, ecx
mov [ebx].PORT.dwSERR, ecx
mov ecx, [ebx].PORT.dwCMD
or cl, PCMD_FRE ; enable FIS receive
mov [ebx].PORT.dwCMD, ecx
or cl, PCMD_ST ; start processing command list
mov [ebx].PORT.dwCMD, ecx
@dprintf <'DevInt, setup, port=%X, cmdtable=%X, waiting',13,10>, ebx, edi
@@:
mov eax, [ebx].PORT.dwCMD
test ax, PCMD_CR ; command list running?
if 0 ; changed 04/2023
jz @B
else
jnz @F
@VMMCall Yield
jmp @B
@@:
endif
ret
Setup endp
;--- initiate "request sense notification" cmd
ReqSense proc
;--- write packet data ( 12 bytes )
;--- 0: cmd 03 ( request sense )
;--- 1-3: reserved
;--- 4: allocation length
;--- 5: control
;--- ACMD.00: 03,00,00,00
;--- ACMD.04: 08,00,00,00
;--- ACMD.08: 00,00,00,00
mov [edi].CT.Pkt0, 3
mov [edi].CT.Pkt1, 8
mov [edi].CT.Pkt2, 0
ReqSense endp
;--- fall thru!!!
;--- Req8: read 8 bytes into buffer
Req8:
mov ecx, 80000007H ; PRDT.12: 07,00,00,80 (PRC=7; read 8 bytes, 80=I)
;--- ReqECX:
;--- in: ecx: read ECX+1 bytes ( bit 31 = 1, indicating end of table )
;--- edi: cmd table
;--- ebx: port
;--- out: AL=0 ok, AL=12 error
ReqECX proc
mov [edi].CT.p0.dwCnt, ecx
mov [ebx].PORT.dwCI, 1 ; bitmask, 1=slot 0 command issued
contwait:
cmp [ebx].PORT.dwCI, 0
jz done
test [ebx].PORT.dwIS, PIS_TFES
jnz error
@VMMCall Yield
cmp [ebx].PORT.dwSERR, 0
JZ contwait
error:
call Stop
mov al, 12
ret
done:
mov eax, [ebx].PORT.dwTFD
test al, 1
jnz error
call Stop
mov al, 0
ret
Stop:
mov ecx, [ebx].PORT.dwCMD
or cl, PCMD_CLO
and cl, 0EEH ; good idea to reset PCMD_ST and PCMD_FRE here?
mov [ebx].PORT.dwCMD, ecx
retn
ReqECX endp
;--- read PCI config address/data ports
;--- in: edx = addr+80000000h
;--- out: eax = value
GetPCI proc
push edx
mov eax, edx
mov dx, 0cf8h
out dx, eax
mov dl, 0fch
in eax, dx
pop edx
ret
GetPCI endp
SavePCI proc
mov dx, 0cf8h
in eax, dx
mov ebx, eax
ret
SavePCI endp
RestPCI proc
mov dx, 0cf8h
mov eax, ebx
out dx, eax
ret
RestPCI endp
if 0
;--- in: edx = addr+80000000h, eax = value
PutPCI proc
push edx
push eax
mov eax, edx
mov dx, 0cf8h
out dx, eax
mov dl, 0fch
pop eax
out dx, eax
pop edx
ret
PutPCI endp
endif
;--- display string EDX
dispString proc
push esi
mov esi, edx
@VMMCall Begin_Nest_Exec
nextitem:
lodsb
cmp al,0
jz done
mov byte ptr [ebp].Client_Reg_Struc.Client_EDX, al
mov byte ptr [ebp].Client_Reg_Struc.Client_EAX+1, 2
mov eax, 21h
@VMMCall Exec_Int
jmp nextitem
done:
@VMMCall End_Nest_Exec
pop esi
ret
dispString endp
dispBanner proc
cmp bQuiet, 0
jnz @F
cmp bBanner, 0
jnz @F
mov bBanner, 1
push edx
mov edx, CStr('AHCI Optical Disk Driver v1.2',13,10,"Inspired by Rudolph R. Loew's AHCICD",13,10)
call dispString
pop edx
@@:
ret
dispBanner endp
;--- ebp: client reg struct
;--- esi: cmdline
Init proc
;--- scan cmdline args
nextchar:
lodsb
cmp al, ' '
jz nextchar
cmp al, 9
jz nextchar
cmp al, 13
jz donecmdl
cmp al, 0
jz donecmdl
cmp al, '/'
jnz errcmdl
lodsb
mov ah, [esi]
or al, 20h
cmp ax, ':c'
jz isOptC
cmp ax, ':d'
jz isOptD
cmp AL, 'q'
jz isOptQ
if ?OPTIONR
cmp AL, 'r'
jz isOptR
endif
jmp errcmdl
isOptD:
inc esi
mov edi, [pBase]
add edi, DOSDRV.name_
mov dword ptr [edi+0], ' '
mov dword ptr [edi+4], ' '
mov ecx, sizeof DOSDRV.name_
nextdevchar:
lodsb
cmp al, ' '
jbe doneOptD
cmp al, 'a'
jb @F
cmp al, 'z'
ja @F
sub al, 20H
@@:
stosb
loop nextdevchar
inc esi
doneOptD:
dec esi
jmp nextchar
isOptC:
inc esi
lodsb
cmp al, '0'
jb errcmdl
cmp al, '9'
Ja errcmdl
sub al, '0'
mov [bCntOpt], al
jmp nextchar
isOptQ:
mov [bQuiet], 1
jmp nextchar
if ?OPTIONR
isOptR:
mov [bReloc], 1
jmp nextchar
endif
donecmdl:
;--- done cmdline processing
call dispBanner
;--- scan for AHCI devices
call SavePCI
mov edx, 80000008H
nextHBA:
call GetPCI
mov al, 0 ; clear bits 0-7 (interface doesn't matter)
cmp eax, 1060100H ; AHCI device?
jnz @F
dec [bCntOpt] ; /C:x option?
js foundHBA
@@:
@VMMCall Yield
add edx, 100H ; next "function"
cmp edx, 81000008H
jc nextHBA
call RestPCI
jmp errnodisk
foundHBA:
@dprintf <'found AHCI device at PCI=%X',13,10>, edx
mov dl, 24h ;get ABAR5
call GetPCI
mov edi, eax
call RestPCI
;--- HBA does not necessarily have to start at a page boundary
;--- so always reserve 2 pages.
@dprintf <'HBA physical addr=%X',13,10>, edi
push 0
push 2
push PR_SYSTEM
@VMMCall _PageReserve
add esp, 3*4
cmp eax, -1
jz errpr
mov ebx, eax
shr eax, 12 ; convert linear address to page#
mov ecx, edi
shr ecx, 12
push PC_WRITEABLE
push ecx
push 2 ; map 2 pages ( in theory even 3 might be needed )
push eax
@VMMCall _PageCommitPhys
add esp, 4*4
and edi, 0fffh
add ebx, edi
mov [pHBA], ebx
@dprintf <'HBA mapped at linear addr=%X',13,10>, ebx
mov eax, [ebx].HBA.dwGHC ; get Global HBA Control
@dprintf <'HBA.GHC=%X',13,10>, eax
test eax, 80000000H ; AHCI enabled?
jz errnoahci
mov ecx, [ebx].HBA.dwPI ; get ports implemented (bit mask)
@dprintf <'HBA.Ports=%X',13,10>, ecx
mov edx, 100h ; port offsets are 100h, 180h, 200h, 280h, ..., 1080h
mov edi, offset wPort
nextPort:
shr ecx, 1
jnc @F
mov eax, [ebx+edx].PORT.dwSIG ; get signature
cmp eax, 0EB140101H
jnz @F
@dprintf <'found ATAPI device at port=%X',13,10>, edx
mov eax, [ebx+edx].PORT.dwSSTS ; get SATA status
@dprintf <'device status=%X',13,10>, eax
and al, 0FH ; bits 0-3: device detection
cmp al, 3 ; device detected and communication established?
jnz @F
mov eax, edx
stosw
cmp edi, offset wPort + sizeof wPort; table end reached?
jz donePort
@@:
add edx, 80H
and ecx, ecx
Jnz nextPort
donePort:
sub edi, offset wPort
shr edi, 1
mov ecx, edi
cmp ecx, 0
jz errnodisk
mov [bUnits], cl
if ?OPTIONR
mov edi, offset wPort
cmp [bReloc], 0
jz noreloc
mov esi, offset cmdlst
mov [pCLB], esi
mov [pCTBA], offset cmdtab
mov [pBuff], offset buffer
push ecx
mov ecx, sizeof cmdlst + sizeof fis + sizeof cmdtab + sizeof buffer
mov edx, 1
VxDCall VDMAD_Lock_DMA_Region
pop ecx
@dprintf <'physical/logical address CLB=%X/%X',13,10>, edx, esi
mov esi, edx
.while ecx
movzx edx, word ptr [edi]
mov eax, esi
mov dword ptr [ebx+edx].PORT.dqCLB, eax
add eax, sizeof cmdlst
mov dword ptr [ebx+edx].PORT.dqFB, eax
add edi, sizeof WORD
dec ecx
.endw
mov eax, esi
add eax, sizeof cmdlst + sizeof fis
mov edx, [pCLB]
mov [edx].CLH.dwCTBA, eax
@dprintf <'CLB.CTBA=%X',13,10>, eax
add eax, sizeof cmdtab
mov [dwBuffPh], eax
jmp buffers_done
noreloc:
movzx edx, word ptr [edi]
mov eax, dword ptr [ebx+edx].PORT.dqCLB
mov edx, [eax].CLH.dwCTBA
mov [pCLB], eax
mov [pCTBA], edx
@dprintf <'linear address command list/table=%X/%X',13,10>, eax, edx
endif
mov esi, offset buffer
mov [pBuff], esi
mov ecx, SLCOOKED
mov edx, 1
VxDCall VDMAD_Lock_DMA_Region
mov [dwBuffPh], edx
@dprintf <'physical address sector buffer=%X',13,10>, edx
buffers_done:
mov ebx, [pBase]
mov al, [bUnits]
mov [ebx].DOSDRV.bUnits, al
cmp [bQuiet], 0
jnz @F
add al,'0'
movzx eax, al
push eax
mov edx, esp
call dispString
pop eax
mov edx, CStr(' AHCI Optical Disk(s) Found',13,10)
call dispString
@@:
mov ebx, [pRequest]
mov word ptr [ebx].RPInit.dwFree+0, REQOFS+4+SIZERMCODE+5
mov ax, RPDON
mov [ebx].RPInit.wStat, ax
mov [ebx].RPInit.bUnit, 0
ret
errpr:
mov edx, CStr('_PageReserve() failed',13,10)
jmp @F
errnoahci:
mov edx, CStr('AHCI Controller not in AHCI Mode',13,10)
jmp @F
errcmdl:
if ?OPTIONR
mov edx, CStr('SYNTAX: DEVICE=JLOAD.EXE AHCICD.DLL [/C:#] /D:devname [/Q][/R]',13,10)
else
mov edx, CStr('SYNTAX: DEVICE=JLOAD.EXE AHCICD.DLL [/C:#] /D:devname [/Q]',13,10)
endif
jmp @F
errnodisk:
MOV edx, CStr('No AHCI Optical Disk Found',13,10)
@@:
call dispBanner
call dispString
mov ax, RPERR
ret
Init endp
DllMain proc stdcall public uses esi edi hModule:dword, dwReason:dword, dwRes:dword
local pCmdLine:dword
mov eax, dwReason
cmp eax, 1
jnz done
mov esi, dwRes
test [esi].JLCOMM.wFlags, JLF_DRIVER
jz failed
movzx ecx, [esi].JLCOMM.wLdrCS
shl ecx, 4
mov [pBase], ecx
lea eax, [ecx+REQOFS]
mov [ppReq], eax
mov eax, [esi].JLCOMM.lpCmdLine
mov [pCmdLine], eax
mov eax, [esi].JLCOMM.lpRequest
mov [pRequest], eax
mov esi, offset DevInt
xor edx, edx
@VMMCall Allocate_V86_Call_Back
jc failed
mov edi, [pBase]
mov [edi].DOSDRV.wAttr, 0C800h ;driver attributes
mov [edi].DOSDRV.ofsStr, REQOFS+4
mov [edi].DOSDRV.ofsInt, REQOFS+4+SIZERMCODE
mov [edi].DOSDRV.wRes1, 0
mov [edi].DOSDRV.bRes2, 0
add edi, REQOFS+4
mov esi, offset rmcode
mov ecx, SIZERMCODE+1
cld
rep movsb
stosd
@VMMCall Get_Cur_VM_Handle
mov esi, [pCmdLine]
;--- set EBP to the client pointer before calling I_Init
push ebp
mov ebp, [ebx].cb_s.CB_Client_Pointer
call Init
pop ebp
cmp ax,RPDON
setz al
movzx eax,al
done:
ret
failed:
xor eax, eax
ret
DllMain endp
end DllMain
================================================
FILE: JLM/AHCICD/AHCICD.txt
================================================
1. About AHCICD
AHCICD is a JLM to access AHCI optical disks, "inspired" by Rudolph R. Loew's
AHCICD.SYS. To load it, add the following line to your CONFIG.SYS:
DEVICE=JLOAD.EXE AHCICD.DLL [options]
options are:
/C:device select AHCI controller if more than one exists.
/D:name set device name. Required.
/Q no displays unless errors occur.
/R relocate AHCI regions [CL/FIS/CT] to extended memory.
2. Hints
- AHCI uses tables that may be located in the XBDA - so if the XBDA is to
be moved, setting option /R is required.
- AHCICD.DLL needs JLOAD v5.83 - older versions won't disable caching
of the controller's memory-mapped registers.
================================================
FILE: JLM/AHCICD/MAKE.BAT
================================================
@echo off
jwasm -c -coff -nologo -Fl -Sg -I..\..\Include AHCICD.ASM
rem jwasm -coff -nologo -D_DEBUG -Fl -Sg -I..\..\Include AHCICD.ASM
jwlink format win pe hx dll ru native file AHCICD.obj name AHCICD.DLL op q,map
================================================
FILE: JLM/AHCICD/MAKEM.BAT
================================================
@echo off
ml -c -coff -nologo -Fl -Sg -I..\..\Include AHCICD.ASM
link /nologo /subsystem:native /dll AHCICD.obj /OUT:AHCICD.DLL /MAP
================================================
FILE: JLM/GENERIC/GENERIC.ASM
================================================
;--- JLM sample GENERIC
;--- use Makefile to create GENERIC.DLL
;--- GENERIC is a very simple JLM. It doesn't hook v86-interrupt vectors.
;--- To be called from v86-mode, its entry point must be obtained by the
;--- caller.
.386
.model flat, stdcall
.nolist
include jlm.inc
.list
DEVICE_ID equ 6660h
cr equ 13
lf equ 10
DLL_PROCESS_ATTACH equ 1
DLL_PROCESS_DETACH equ 0
.data
;--- the DDB must be make public. The linker will "export" this
;--- symbol. This is the simplest method to make JLoad know the
;--- device id.
public ddb
ddb VxD_Desc_Block <0,0,DEVICE_ID,1,0,0,"GENERIC",0, 0, v86_dispatch>
szHello db "Hello from JLM GENERIC",cr,lf,0
.code
;--- dispatcher for v86 services
v86_dispatch proc
@VMMCall Simulate_Far_Ret ;emulate a RETF in v86
and [ebp].Client_Reg_Struc.Client_EFlags,not 1 ;clear Carry flag
movzx eax, word ptr [ebp].Client_Reg_Struc.Client_EAX
cmp eax,0
jz getversion
cmp eax,1
jz display_hello
or [ebp].Client_Reg_Struc.Client_EFlags,1 ;set Carry flag
ret
align 4
v86_dispatch endp
getversion proc
mov word ptr [ebp].Client_Reg_Struc.Client_EAX, 0100h
ret
align 4
getversion endp
display_hello proc uses esi
@VMMCall Begin_Nest_Exec ;start nested execution
mov esi, offset szHello
@@:
lodsb
and al,al
jz done
;--- Call int 21h, ah=2 in v86-mode.
;--- Be aware that in Jemm's context is no DOS extender installed.
;--- So there is no translation for DOS functions which use pointers.
mov byte ptr [ebp].Client_Reg_Struc.Client_EDX,al
mov byte ptr [ebp].Client_Reg_Struc.Client_EAX+1,2
mov eax,21h
@VMMCall Exec_Int
jmp @B
done:
@VMMCall End_Nest_Exec ;end nested execution
ret
align 4
display_hello endp
;--- install the JLM: just set eax=1
;--- this tells JLOAD that it's ok to add GENERIC to the list of
;--- loaded modules.
install proc uses esi pcomm:ptr JLCOMM
mov eax,1
ret
align 4
install endp
;--- deinstall the JLM: just set eax=1.
;--- this tells JLOAD that it's ok to remove the module.
deinstall proc pcomm:ptr JLCOMM
mov eax,1
ret
align 4
deinstall endp
DllMain proc stdcall public hModule:dword, dwReason:dword, dwRes:dword
mov eax,dwReason
cmp eax,DLL_PROCESS_ATTACH
jnz @F
invoke install, dwRes
jmp exit
@@:
cmp eax,DLL_PROCESS_DETACH
jnz @F
invoke deinstall, dwRes
@@:
exit:
ret
align 4
DllMain endp
end DllMain
================================================
FILE: JLM/GENERIC/MAKEFILE
================================================
# NMake/WMake Makefile to create GENERIC.DLL
#
# tools alternatives
#----------------------------------------------------------
# JWasm Masm v6.x
# JWLink Link, WLink, ALink
NAME = GENERIC
OUTDIR=Release
AOPT=-nologo -c -coff -nologo -Fl$*.lst -Fo$*.obj -I..\..\Include
ASM=jwasm.exe
#LINK=link.exe /NOLOGO /SUBSYSTEM:NATIVE /DLL $*.obj /OUT:$*.DLL /MAP:$*.MAP /EXPORT:ddb /Entry:DllMain /OPT:NOWIN98
LINK=jwlink format win nt hx dll ru native file $*.obj name $*.DLL op q,map=$*.MAP export _ddb.1
ALL: $(OUTDIR) $(OUTDIR)\$(NAME).DLL $(OUTDIR)\TESTGEN.COM
$(OUTDIR):
@mkdir $(OUTDIR)
$(OUTDIR)\$(NAME).DLL: $(OUTDIR)\$(NAME).obj Makefile
@$(LINK)
$(OUTDIR)\$(NAME).obj: $(NAME).asm
@$(ASM) $(AOPT) $(NAME).asm
$(OUTDIR)\TESTGEN.COM: TESTGEN.ASM
@jwasm -nologo -bin -Fo$*.COM -Fl$* testgen.asm
================================================
FILE: JLM/GENERIC/README.TXT
================================================
1. About
GENERIC is a JLM sample which demonstrates how to implement a
protected-mode TSR.
2. How to install and uninstall GENERIC
GENERIC can be installed either as a device driver in CONFIG.SYS:
DEVICE=JLOAD.EXE GENERIC.DLL
or as a TSR from the command line:
JLOAD GENERIC.DLL
To uninstall, use JLOAD's -u option:
JLOAD -u GENERIC.DLL
3. How to use GENERIC
GENERIC doesn't hook real-mode interrupt vectors. If a real-mode program
wants to call a function provided by GENERIC, it first has to get the JLM's
entry point. This is done similiar to Windows 9x: a call of Int 2F,
AX=1684h with register BX containing the "device id". On return, if the
"device" has been found, ES:DI will contain its entry address:
mov ax, 1684h ;standard value to get VxD entry points
mov bx, 6660h ;6660h is the ID of GENERIC
int 2Fh
cmp al,0
jnz not_installed
mov word ptr [genpm+0],di
mov word ptr [genpm+2],es
The protected-mode TSR implements two functions, which are selected
by the value of register AX:
mov ax, 0000 ;0000=get version
call dword ptr [genpm]
mov ax, 0001 ;0001=display hello
call dword ptr [genpm]
There's a test program - TESTGEN.EXE - supplied which uses GENERIC.
4. License
GENERIC is Public Domain.
Japheth
================================================
FILE: JLM/GENERIC/TESTGEN.ASM
================================================
;--- test app which calls some "services" of JLM GENERIC.
;--- assemble: JWasm -bin -Fo testgen.com testgen.asm
.model tiny
.data
szOK db "GENERIC found!",13,10,'$'
szError db "GENERIC is NOT installed!",13,10,'$'
.code
org 100h
start:
mov ax, 1684h ;get GENERIC's entry point
mov bx, 6660h
int 2Fh
cmp al,0
jnz not_installed
push es
push di
mov bp,sp
mov dx,offset szOk
mov ah,9
int 21h
mov ax,0000 ;call "get version"
call dword ptr [bp]
mov ax,0001 ;call "display hello"
call dword ptr [bp]
add sp,4
int 20h
not_installed:
mov dx,offset szError
mov ah,9
int 21h
int 20h
end start
================================================
FILE: JLM/HELLO/HELLO.ASM
================================================
;--- a simple JLM which displays a message onto the screen
;--- with the help of v86-int 21h and nested execution
.386
.MODEL FLAT, stdcall
include jlm.inc
ifdef FMTPE
;--- since v2.19, JWasm's -pe option knows how to interpret linker directives supplied
;--- in the .drectve info section. Thus no extra link step is required.
option dotname
.drectve segment info ;linker directives
db "-subsystem:native -fixed:no"
.drectve ends
.hdr$1 segment use16
% incbin <STUB>
.hdr$1 ends
endif
.DATA
szText db "Hello, world!", 13,10,0
.CODE
_main proc
push esi
@VMMCall Begin_Nest_Exec ;start nested execution
mov esi, offset szText
@@nextitem:
lodsb
and al,al
jz @@done
;--- Call int 21h, ah=2 in v86-mode.
;--- Be aware that in Jemm's context is no DOS extender installed.
;--- So there is no translation for DOS functions that use pointers.
mov byte ptr [ebp].Client_Reg_Struc.Client_EDX,al
mov byte ptr [ebp].Client_Reg_Struc.Client_EAX+1,2
mov eax,21h
@VMMCall Exec_Int
jmp @@nextitem
@@done:
@VMMCall End_Nest_Exec ;end nested execution
pop esi
mov eax, 80000001h ;bit 31=1: suppress JLoad msg
ret
_main ENDP
END _main
================================================
FILE: JLM/HELLO/MAKE.BAT
================================================
@echo off
rem
rem use JWasm & JWlink
rem
jwasm -nologo -coff -Fl=Release\Hello -Fo=Release\Hello -I..\..\Include Hello.asm
jwlink format win pe hx ru native file Release\Hello.obj name Release\Hello.exe op q,m=Release\Hello,stack=0x1000
rem use JWasm - since JWasm v2.19, cmdline option -pe supports several linker features;
rem also, stub JLSTUB.BIN may be added. Then the program can be launched simply by typing its name.
rem
rem jwasm -nologo -pe -DFMTPE -DSTUB=..\JLSTUB\Build\jlstub.bin -Fl=Release\Hello -Fo=Release\Hello -I..\..\Include Hello.asm
rem patchPE -x -s:0x1000 Release\Hello.exe
rem use Masm & Link
rem
rem ml -c -coff -FlRelease\Hello -FoRelease\Hello -I..\..\Include Hello.asm
rem link /NOLOGO Release\HELLO.OBJ /subsystem:native /FIXED:NO /map /out:Release\Hello.exe /ENTRY:_main /OPT:NOWIN98
rem \hx\bin\patchpe -s:0x4000 -x Release\Hello.exe
================================================
FILE: JLM/HELLO/README.TXT
================================================
About
This is the inevitable "hello world" JLM, written for Masm/JWasm.
It displays a welcome message. After execution the module's resources
are released.
Usage: C:\>JLOAD -q HELLO.EXE
================================================
FILE: JLM/HELLO2/HELLO2.C
================================================
// for MS VC
#include <jlm.h>
struct Client_Reg_Struc * pcl;
struct cb_s * Get_Cur_VM_Handle()
{
VxDCall(Get_Cur_VM_Handle);
_asm mov eax,ebx;
}
ULONG Begin_Nest_Exec()
{
_asm mov ebp,pcl;
VxDCall(Begin_Nest_Exec);
}
ULONG End_Nest_Exec()
{
_asm mov ebp,pcl;
VxDCall(End_Nest_Exec);
}
ULONG Exec_Int(unsigned long intno)
{
_asm mov eax, intno;
_asm mov ebp,pcl;
VxDCall(Exec_Int);
}
int main()
{
struct cb_s * hVM;
unsigned char * psz = "Hello world\r\n";
hVM = Get_Cur_VM_Handle();
pcl = (struct Client_Reg_Struc *)hVM->CB_Client_Pointer;
Begin_Nest_Exec();
for (;*psz;psz++) {
pcl->Client_EAX = 0x0200;
pcl->Client_EDX = *psz;
Exec_Int(0x21);
}
End_Nest_Exec();
return 1;
};
================================================
FILE: JLM/HELLO2/HELLO2W.C
================================================
// for Open Watcom C
// OW inline assembly doesn't know values of enums!
// therefore it needs external module jlmw.asm
#include <JLM.H>
#include "JLMW.h"
struct Client_Reg_Struc * pcl;
int main()
{
struct cb_s * hVM;
unsigned char * psz = "Hello world\r\n";
hVM = Get_Cur_VM_Handle();
pcl = (struct Client_Reg_Struc *)hVM->CB_Client_Pointer;
Begin_Nest_Exec(pcl);
for (;*psz;psz++) {
pcl->Client_EAX = 0x0200;
pcl->Client_EDX = *psz;
Exec_Int(0x21, pcl);
}
End_Nest_Exec(pcl);
return 1;
};
================================================
FILE: JLM/HELLO2/JLMW.ASM
================================================
;--- helpers for (Watcom) C
.386
.model flat
include JLM.INC
.code
Get_Cur_VM_Handle proc stdcall public uses ebx
@VMMCall Get_Cur_VM_Handle
mov eax, ebx
ret
align 4
Get_Cur_VM_Handle endp
Begin_Nest_Exec proc stdcall public uses ebp pcl:ptr
mov ebp,pcl
@VMMCall Begin_Nest_Exec
ret
align 4
Begin_Nest_Exec endp
End_Nest_Exec proc stdcall public uses ebp pcl:ptr
mov ebp,pcl
@VMMCall End_Nest_Exec
ret
align 4
End_Nest_Exec endp
Exec_Int proc stdcall public uses ebp intno:dword, pcl:ptr
mov eax, intno
mov ebp,pcl
@VMMCall Exec_Int
ret
align 4
Exec_Int endp
end
================================================
FILE: JLM/HELLO2/JLMW.h
================================================
// helper procs needed by Open Watcom C
extern struct cb_s * _stdcall Get_Cur_VM_Handle( void );
extern ULONG _stdcall Begin_Nest_Exec(struct Client_Reg_Struc * pcl);
extern ULONG _stdcall End_Nest_Exec(struct Client_Reg_Struc * pcl);
extern ULONG _stdcall Exec_Int( unsigned long intno, struct Client_Reg_Struc * pcl );
================================================
FILE: JLM/HELLO2/MAKEJLMW.BAT
================================================
@echo off
rem assembles helper module jlmw for Open Watcom.
jwasm -I ..\..\Include jlmw.asm
================================================
FILE: JLM/HELLO2/MAKEOW.BAT
================================================
@echo off
rem uses Open Watcom C and WLink
rem OW needs a helper module: jlmw.obj
wcc386 -mf -zl -zls -s -I..\..\Include hello2w.c
jwlink format win nt hx ru native file hello2w.obj, jlmw.obj name hello2w.exe option start=main_, map
================================================
FILE: JLM/HELLO2/MAKEVC.BAT
================================================
@echo off
rem uses MS VC and MS Link
\msvc71\bin\cl -c -I..\..\Include hello2.c
link /LIBPATH:\msvc71\lib hello2.obj /subsystem:native /fixed:no /out:hello2.exe /entry:main
\hx\bin\patchpe hello2.exe
================================================
FILE: JLM/HELLO2/README.TXT
================================================
About
Another JLM "hello world", this time written in C.
MAKEVC.BAT: for MS VC (or Pelles C, CC386, ...)
MAKEOW.BAT: for Open Watcom.
to run it: jload /q hello2(w).exe
There is room for improvement.
================================================
FILE: JLM/HELLO2/makeow.sh
================================================
#!/bin/sh
set -e
# uses Open Watcom C, JWAsm and JWLink which must be in PATH
# OW needs a helper module: jlmw.obj
jwasm -I../../Include JLMW.ASM
wcc386 -mf -zl -zls -s -I../../Include HELLO2W.C
jwlink format win nt hx ru native file HELLO2W.o, JLMW.o name hello2w.exe option start=main_, map
================================================
FILE: JLM/IOTRAP/IOTRAP.ASM
================================================
;--- JLM sample IOTRAP
;--- use Makefile to create IOTRAP.DLL
;--- IOTRAP traps IO port 100h when the first client
;--- wants to register a callback.
;--- The client is notified whenever an IO access happens.
.386
.model flat, stdcall
PORT equ 100h ;port to trap
CODE16_SEL equ 20h
DATA16_SEL equ 28h
.nolist
include jlm.inc
.list
DEVICE_ID equ 6661h
cr equ 13
lf equ 10
DLL_PROCESS_ATTACH equ 1
DLL_PROCESS_DETACH equ 0
.data
;--- the DDB must be make public. The linker will "export" this
;--- symbol. This is the simplest method to make JLoad know the
;--- device id.
public ddb
ddb VxD_Desc_Block <0,0,DEVICE_ID,1,0,0,"IOTRAP",0,0, v86_dispatch >
szHello db "Hello from JLM IOTRAP",cr,lf,0
cntCB dd 0
callbacks label dword
dd 8*2 dup (0) ;allow 8 callbacks
.code
;--- dispatcher for v86 services
v86_dispatch proc
@VMMCall Simulate_Far_Ret ;emulate a RETF in v86
and [ebp].Client_Reg_Struc.Client_EFlags,not 1 ;clear Carry flag
movzx eax, word ptr [ebp].Client_Reg_Struc.Client_EAX
cmp eax,0
jz getversion
cmp eax,1
jz register_callback
or [ebp].Client_Reg_Struc.Client_EFlags,1 ;set Carry flag
ret
align 4
v86_dispatch endp
getversion proc
mov word ptr [ebp].Client_Reg_Struc.Client_EAX, 0100h
ret
align 4
getversion endp
register_callback proc
.if ( cntCB >= 8 )
or [ebp].Client_Reg_Struc.Client_EFlags,1 ;set Carry flag
mov word ptr [ebp].Client_Reg_Struc.Client_EAX, 8
ret
.endif
;--- when the first client registers, install an io handler
.if ( cntCB == 0 )
mov esi, offset iocb
mov edx, PORT
@VMMCall Install_IO_Handler
.if ( CARRY? )
or [ebp].Client_Reg_Struc.Client_EFlags,1 ;set Carry flag
mov word ptr [ebp].Client_Reg_Struc.Client_EAX, 9
ret
.endif
.endif
mov cx, word ptr [ebp].Client_Reg_Struc.Client_ECX ;callback's CS
shl ecx,16
mov cx, word ptr [ebp].Client_Reg_Struc.Client_EDX ;callback's IP
mov eax, cntCB
mov [eax*8+callbacks+0], ecx
mov ecx, [ebp].Client_Reg_Struc.Client_EBX ;callback's param
mov [eax*8+callbacks+4], ecx
inc cntCB
ret
align 4
register_callback endp
;--- io handler proc
;--- ecx=type of io
;--- edx=port
;--- ebp=client struct
;--- eax=io data
PF32 typedef ptr far32
iocb proc
if 0 ;if the client is to be called in v86-mode
push esi
push edi
sub esp, sizeof Client_Reg_Struc
mov edi, esp
push ecx
push edx
push eax
@VMMCall Save_Client_State
@VMMCall Begin_Nest_Exec ;start nested execution
mov esi, offset callbacks
mov ecx, cntCB
.while ecx
push ecx
mov eax,[esp+4]
mov edx,[esp+8]
mov ecx,[esp+12]
mov [ebp].Client_Reg_Struc.Client_EDX, edx
mov [ebp].Client_Reg_Struc.Client_ECX, ecx
mov [ebp].Client_Reg_Struc.Client_EAX, eax
lodsd
movzx edx,ax
shr eax,16
mov ecx, eax
@VMMCall Simulate_Far_Call
lodsd
mov [ebp].Client_Reg_Struc.Client_EBX, eax
@VMMCall Resume_Exec ;run the VM
pop ecx
dec ecx
.endw
@VMMCall End_Nest_Exec ;end nested execution
lea esi, [esp+3*4]
@VMMCall Restore_Client_State
pop eax
pop edx
pop ecx
add esp, sizeof Client_Reg_Struc
pop edi
pop esi
ret
else ;if the client is to be called in protected-mode
pushad
push ecx
push edx
push eax
sub esp,8
sgdt [esp]
mov eax,[esp+2]
add esp,8
mov esi, offset callbacks
mov ecx, cntCB
.while ecx
push ecx
push eax
lodsd
push CODE16_SEL
pushw 0
push ax
shr eax,16
shl eax, 4
mov edx,[esp+2*4]
mov [edx+CODE16_SEL+2],ax
mov [edx+DATA16_SEL+2],ax
shr eax,16
mov [edx+CODE16_SEL+4],al
mov [edx+DATA16_SEL+4],al
lodsd
mov ebx, eax
mov eax,[esp+4*4+0]
mov edx,[esp+4*4+4]
mov ecx,[esp+4*4+8]
push ds
push DATA16_SEL
pop ds
call PF32 ptr [esp+4]
pop ds
add esp,2*4
pop eax
pop ecx
dec ecx
.endw
add esp,3*4
popad
ret
endif
align 4
iocb endp
;--- install the JLM: just set eax=1
;--- this tells JLOAD that it's ok to add IOTRAP to the list of
;--- loaded modules.
install proc uses esi pcomm:ptr JLCOMM
mov eax,1
ret
align 4
install endp
;--- deinstall the JLM: just set eax=1.
;--- this tells JLOAD that it's ok to remove the module.
deinstall proc pcomm:ptr JLCOMM
.if ( cntCB )
mov edx, PORT
@VMMCall Remove_IO_Handler
.endif
mov eax,1
ret
align 4
deinstall endp
DllMain proc stdcall public hModule:dword, dwReason:dword, dwRes:dword
mov eax,dwReason
cmp eax,DLL_PROCESS_ATTACH
jnz @F
invoke install, dwRes
jmp exit
@@:
cmp eax,DLL_PROCESS_DETACH
jnz @F
invoke deinstall, dwRes
@@:
exit:
ret
align 4
DllMain endp
end DllMain
================================================
FILE: JLM/IOTRAP/MAKEFILE
================================================
# NMake/WMake Makefile to create IOTRAP.DLL
#
# tools alternatives
#----------------------------------------------------------
# JWasm Masm v6.x
# JWLink MS Link, WLink, ALink
# (PatchPE)
#
# PatchPE: HX tool to patch a PE binary to PX ( not required for jwlink ).
NAME = IOTRAP
OUTDIR=Release
AOPT=-c -coff -nologo -Fl$*.lst -Fo$*.obj -I..\..\Include
ASM=jwasm.exe
#LINK=link.exe /NOLOGO /SUBSYSTEM:NATIVE /DLL $*.obj /OUT:$*.DLL /MAP:$*.MAP /EXPORT:ddb /Entry:DllMain /OPT:NOWIN98
LINK=jwlink format win nt hx dll ru native file $*.obj name $*.DLL op q,MAP=$*.MAP export _ddb.1
ALL: $(OUTDIR) $(OUTDIR)\$(NAME).DLL $(OUTDIR)\TESTIOT.COM
$(OUTDIR):
@mkdir $(OUTDIR)
$(OUTDIR)\$(NAME).DLL: $(OUTDIR)\$(NAME).obj Makefile
@$(LINK)
# @..\patchpe $*.DLL
$(OUTDIR)\$(NAME).obj: $(NAME).asm
@$(ASM) $(AOPT) $(NAME).asm
$(OUTDIR)\TESTIOT.COM: TESTIOT.asm
@$(ASM) -nologo -bin -Fo=$*.COM TESTIOT.asm
================================================
FILE: JLM/IOTRAP/README.TXT
================================================
1. About
IOTRAP is a JLM sample which demonstrates how to trap IO port access.
Note: This is somewhat obsolete now; trapping I/O port access in V86-mode
is now better done with the help of JLM QPIEMU.
2. How to install and uninstall IOTRAP
IOTRAP can be installed either as a device driver in CONFIG.SYS:
DEVICE=JLOAD.EXE IOTRAP.DLL
or as a TSR from the command line:
JLOAD IOTRAP.DLL
To uninstall, use JLOAD's -u option:
JLOAD -u IOTRAP.DLL
3. How to test IOTRAP
- install IOTRAP: C:\>JLOAD iotrap.dll
- install TESTIOT: C:\>testiot
- start DEBUG: C:\>debug
- read port 100: -i 100
now a colored string '*#!+' should appear on line 25.
4. License
IOTRAP is Public Domain.
Japheth
================================================
FILE: JLM/IOTRAP/TESTIOT.ASM
================================================
;--- tsr to test JLM IOTRAP.
;--- it installs a callback which is called whenever port 100h
;--- is accessed.
;--- the callback displays some colored characters on line 25.
;--- assemble: JWasm -bin -Fo testiot.com testiot.asm
.286
.model tiny
.stack 2048
.dosseg
.386
.data
szOK1 db "IOTRAP found.",13,10,'$'
szOK2 db "TESTIOT installed.",13,10,'$'
szErr1 db "IOTRAP is NOT installed!",13,10,'$'
szErr2 db "IOTRAP has wrong version!",13,10,'$'
szErr3 db "register callback failed!",13,10,'$'
.code
org 100h
start:
mov ax, 1684h ;get IOTRAP's entry point
mov bx, 6661h
int 2Fh
cmp al,0 ;IOTRAP installed?
jnz not_installed
push es
push di
mov bp,sp
mov dx,offset szOK1
mov ah,9
int 21h
mov ax,0000 ;call "get version"
call dword ptr [bp]
;--- check version and exit if not ok
; cmp ax,???
; jc wrong_version
;--- API: CX:DX=CS:IP of callback, BX=param
mov cx,cs
mov dx,offset iocb
mov bx,0
mov ax,0001 ;call "register callback"
call dword ptr [bp]
jc register_failed
mov dx,offset szOK2
mov ah,9
int 21h
mov dx,offset resident
shr dx,4
inc dx
mov ax,3100h
int 21h
iocb:
;--- callback when i/o was detected.
;--- cpu is in 16-bit protected-mode, ring 0.
;--- EAX=data of IO
;--- DX=IO port
;--- CX=type of IO
;--- BX=value when callback was "registered"
;--- DS=data segment
;--- ES=flat segment
;--- SS:ESP=flat host stack!
push esi
mov esi,0B8000h
;--- display '*#!+' in colors at line 25
mov word ptr es:[esi+160*24+0],'*'+100h*40h
mov word ptr es:[esi+160*24+2],'#'+100h*51h
mov word ptr es:[esi+160*24+4],'!'+100h*62h
mov word ptr es:[esi+160*24+6],'+'+100h*73h
pop esi
retd ;a 32bit RETF is needed!!!
resident label byte
not_installed:
mov dx,offset szErr1
mov ah,9
int 21h
int 20h
wrong_version:
mov dx,offset szErr2
mov ah,9
int 21h
int 20h
register_failed:
mov dx,offset szErr3
mov ah,9
int 21h
int 20h
end start
================================================
FILE: JLM/JCLOCK/JCLOCK.ASM
================================================
;
; JCLOCK 1.1
;
; JLM example -- CLOCK for JEMM386/JEMMEX
; It is the first JLM with screen input/output :-)
;
; (C) 2007 Alexey Voskov
;
; Compile with FASM for WIN32
; and change PE signature into PX
;
format PE CONSOLE 4.0 DLL
entry DllEntryPoint
include '%FASMINC%\win32a.inc'
; Constants
; 1. Addresses
DispMode = 000449h ; BYTE - display mode
ColNum = 00044Ah ; WORD - number of columns
Timer = 00046Ch ; DWORD - timer of BIOS
CoVideo = 0B8000h ; Video buffer offset for MODE CO80/CO40
MoVideo = 0B0000h ; Video buffer offset for MODE MONO
; 2. Text properties
attr = 2Eh ; TEXT ATTRIBUTE
mask0 = attr*1000000h + attr*100h ; Masks for text field
mask1 = mask0 + ':' ; initialization
mask2 = mask0 + ':' * 10000h ;
;*********************************************************************
section '.code' code readable executable
;
; This procedure is a new INT 08h subroutine
;
proc newint08
; Initialization
pushad
mov ebp, esp
push ss
pop ds
push ss
pop es
; Timer check
mov eax, [Timer] ; Get BIOS timer
and eax, 7 ; eax % 8 == 0
test eax, eax ;
jnz intexit ; if not -- quit
; (we don't have to do IN/OUT every 1/19 sec!)
; Video mode check
mov al, [DispMode]
cmp al, 07h ; MODE MONO ?
jne color ; if not -- check color mode
mov ebx, MoVideo ; Load video buffer offset
jmp mono
color:
cmp al, 03h ; MODE CO80/CO40 ?
ja intexit ; if not -- quit
mov ebx, CoVideo ; Load video buffer offset
mono:
; Set up initial position
movzx esi, word [ColNum] ; ESI = 2*ColNum - 16 + EBX
shl esi, 1
sub esi, 16
add esi, ebx ; EBX == 0B8000h or 0B0000h
; Clock output
clkout: ; 1. Draw mask
mov dword [esi], mask0
mov dword [esi+4], mask1
mov dword [esi+8], mask2
mov dword [esi+12], mask0
; 2. Get current time
mov al, 4 ; Hours
call printBCDcell
add esi, 6
mov al, 2 ; Minutes
call printBCDcell
add esi, 6
mov al, 0 ; Seconds
call printBCDcell
; Call the old INT 08h subroutine
intexit:
popad ; Restore registers and stack
db 0EAh ; ASM command:
oldint08: db 6 dup 0 ; jmp far 0000:00000000
; (48-bit far call)
endp
; Procedure prints CMOS cell
; cell must be in BCD format
;
; AL - cell number
; EBX+ESI - video RAM address
;
proc printBCDcell
; Get byte from CMOS RTC
out 70h, al ; Set cell number in CMOS RTC
mov ecx, 02000h ; A short delay
@@dl: inc ecx ; CMOS RTC memory is slow
dec ecx ;
loop @@dl ;
in al, 71h ; Get byte from cell
; High half-byte of BCD
push ax
and al, 0F0h
shr al, 4
add al, '0'
mov [esi], al
pop ax
; Low half-byte of BCD
and al, 00Fh
add al, '0'
mov [esi+2], al
ret
endp
; This procedure hooks INT 08h
;
; WARNING -- it contains low-level work with IDT
; In newer versions of JEMM it probably
; will be replaced with special API
;
intn = 08h ; INTERRUPT NUMBER
proc install
; Beginning
sub esp,8 ; Reserve memory in stack
; Get pointer to IDT
sidt [esp] ; Write register of interrupt
; descriptor table to [ESP]
mov esi,[esp+2] ; Get IDT beginning address into ESI
; Save old interrupt descriptor
mov ax,[esi+6+intn*8] ; Get bits 31-16
shl eax,16 ; of offset
mov ax,[esi+0+intn*8] ; Get bits 15-0 of offset
mov dword ptr oldint08, eax ; Save offset
mov ax,[esi+2+intn*8] ; Get selector
mov word ptr oldint08+4,ax ; Save selector
; Set up new interrupt descriptor
mov eax, newint08 ; Get offset of new interrupt procedure
mov [esi+0+intn*8],ax ; And write it
shr eax, 16 ; into IDT
mov [esi+6+intn*8],ax ; (SELECTOR UNCHANGED!)
; Final
add esp,8 ; Free memory in stack
ret ; Exit
endp
; NOTE:
;
; Interrupt descriptor format (gate):
; | OFFSET(bits 31-16) | FLAGS | SEG SELECTOR | OFFSET (bits 15-0)
;
;
; DLL entry point
;
proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
cmp [fdwReason], DLL_PROCESS_ATTACH
jne @@exitDLL
call install
mov eax,TRUE
@@exitDLL:
ret
endp
;*********************************************************************
;
; * DON'T STRIP RELOCATIONS ! JLM MUST HAVE THEM ! *
;
section '.reloc' fixups data discardable
================================================
FILE: JLM/JCLOCK/JCLOCK2.ASM
================================================
; this is a modified JCLOCK version which uses the Jemm API to hook int 1Ch.
; Thus, it can be unloaded.
;
; (C) 2007 Alexey Voskov
;
; Compile with FASM for WIN32
; and change PE signature into PX
format PE CONSOLE 4.0 DLL
entry DllEntryPoint
include '%FASMINC%\win32a.inc'
include '%JLMINC%\jlmfasm.inc'
; Constants
; 1. Addresses
DispMode = 000449h ; BYTE - display mode
ColNum = 00044Ah ; WORD - number of columns
Timer = 00046Ch ; DWORD - timer of BIOS
CoVideo = 0B8000h ; Video buffer offset for MODE CO80/CO40
MoVideo = 0B0000h ; Video buffer offset for MODE MONO
; 2. Text properties
attr = 2Eh ; TEXT ATTRIBUTE
mask0 = attr*1000000h + attr*100h ; Masks for text field
mask1 = mask0 + ':' ; initialization
mask2 = mask0 + ':' * 10000h ;
;*********************************************************************
section '.code' code readable executable
;
; This procedure is a hook for INT 1Ch
;
oldvec dd 0
dd oldvec ; a hook procedure must be preceeded by a dword
; which contains the address where the old vector
; will be stored.
proc hookproc
; Initialization
; Timer check
pushad
mov eax, [Timer] ; Get BIOS timer
and eax, 7 ; eax % 8 == 0
test eax, eax ;
jnz intexit ; if not -- quit
; (we don't have to do IN/OUT every 1/19 sec!)
; Video mode check
mov al, [DispMode]
cmp al, 07h ; MODE MONO ?
jne color ; if not -- check color mode
mov ebx, MoVideo ; Load video buffer offset
jmp mono
color:
cmp al, 03h ; MODE CO80/CO40 ?
ja intexit ; if not -- quit
mov ebx, CoVideo ; Load video buffer offset
mono:
; Set up initial position
movzx esi, word [ColNum] ; ESI = 2*ColNum - 16 + EBX
shl esi, 1
sub esi, 16
add esi, ebx ; EBX == 0B8000h or 0B0000h
; Clock output
clkout: ; 1. Draw mask
mov dword [esi], mask0
mov dword [esi+4], mask1
mov dword [esi+8], mask2
mov dword [esi+12], mask0
; 2. Get current time
mov al, 4 ; Hours
call printBCDcell
add esi, 6
mov al, 2 ; Minutes
call printBCDcell
add esi, 6
mov al, 0 ; Seconds
call printBCDcell
intexit:
popad
stc ; signal this INT hasn't been handled yet
ret
endp
; Procedure prints CMOS cell
; cell must be in BCD format
;
; AL - cell number
; EBX+ESI - video RAM address
;
proc printBCDcell
; Get byte from CMOS RTC
out 70h, al ; Set cell number in CMOS RTC
mov ecx, 02000h ; A short delay
@@dl: inc ecx ; CMOS RTC memory is slow
dec ecx ;
loop @@dl ;
in al, 71h ; Get byte from cell
; High half-byte of BCD
if 1
db 0d4h,10h ;AAM 10h
add ax,3030h
mov [esi+0],ah
mov [esi+2],al
else
push ax
and al, 0F0h
shr al, 4
add al, '0'
mov [esi], al
pop ax
; Low half-byte of BCD
and al, 00Fh
add al, '0'
mov [esi+2], al
end if
ret
endp
; This procedure hooks INT 1Ch
;
intn = 1Ch ; INTERRUPT NUMBER
proc install
mov eax,intn
mov esi,hookproc
@VMMCall Hook_V86_Int_Chain
ret ; Exit
endp
proc deinstall
mov eax,intn
mov esi,hookproc
@VMMCall Unhook_V86_Int_Chain
ret ; Exit
endp
;
; DLL entry point
;
proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
cmp [fdwReason], DLL_PROCESS_ATTACH
jne @F
call install
mov eax,TRUE
jmp @@exitDLL
@@:
cmp [fdwReason], DLL_PROCESS_DETACH
jne @@exitDLL
call deinstall
mov eax,TRUE
@@exitDLL:
ret
endp
section '.data' data readable writeable
;--- Sorry, no idea how to create an instance of a structure in fasm ...
;ddb VxD_Desc_Block 0,0,6655h,1,0,0,0,0,0, 0, 0, 0, 0
ddb dd 0
dw 0
dw 6655h
db 1
db 0
db 0
db "JCLOCK2 "
dd 80000000h
dd 0
dd 0
dd 0
dd 0
rd 10
;--- to make the JLM unloadable, it must have a "device id". A "device id"
;--- is obtained by exporting a DDB
section '.edata' export data readable
export 'JCLOCK2.DLL',\
ddb,1
;*********************************************************************
;
; * DON'T STRIP RELOCATIONS ! JLM MUST HAVE THEM ! *
;
section '.reloc' fixups data discardable
================================================
FILE: JLM/JCLOCK/JCLOCK3.ASM
================================================
;--- JCLOCK2 in Masm/JWasm syntax
.386
.model flat
option casemap:none
include jlm.inc
; Constants
DLL_PROCESS_ATTACH equ 1
DLL_PROCESS_DETACH equ 0
; 1. Addresses
DispMode equ 000449h ; BYTE - display mode
ColNum equ 00044Ah ; WORD - number of columns
Timer equ 00046Ch ; DWORD - timer of BIOS
CoVideo equ 0B8000h ; Video buffer offset for MODE CO80/CO40
MoVideo equ 0B0000h ; Video buffer offset for MODE MONO
; 2. Text properties
attr = 2Eh ; TEXT ATTRIBUTE
mask0 = attr*1000000h + attr*100h ; Masks for text field
mask1 = mask0 + ':' ; initialization
mask2 = mask0 + ':' * 10000h ;
.data
public export ddb
ddb VxD_Desc_Block <0,0,6655h,1,0,0,"JCLOCK3 ",80000000h>
oldvec dd 0
option dotname
.drectve segment info
db "-dll -fixed:no -subsystem:native "
.drectve ends
.hdr$2 segment dword
db "PX"
.hdr$2 ends
.code
;
; This procedure is a hook for INT 1Ch
;
HookProc hookproc, oldvec
; Initialization
; Timer check
pushad
mov eax, ds:[Timer] ; Get BIOS timer
and eax, 7 ; eax % 8 == 0
test eax, eax ;
jnz intexit ; if not -- quit
; (we don't have to do IN/OUT every 1/19 sec!)
; Video mode check
mov al, ds:[DispMode]
cmp al, 07h ; MODE MONO ?
jne color ; if not -- check color mode
mov ebx, MoVideo ; Load video buffer offset
jmp mono
color:
cmp al, 03h ; MODE CO80/CO40 ?
ja intexit ; if not -- quit
mov ebx, CoVideo ; Load video buffer offset
mono:
; Set up initial position
movzx esi, word ptr ds:[ColNum] ; ESI = 2*ColNum - 16 + EBX
shl esi, 1
sub esi, 16
add esi, ebx ; EBX == 0B8000h or 0B0000h
; Clock output
clkout: ; 1. Draw mask
mov dword ptr [esi], mask0
mov dword ptr [esi+4], mask1
mov dword ptr [esi+8], mask2
mov dword ptr [esi+12], mask0
; 2. Get current time
mov al, 4 ; Hours
call printBCDcell
add esi, 6
mov al, 2 ; Minutes
call printBCDcell
add esi, 6
mov al, 0 ; Seconds
call printBCDcell
intexit:
popad
stc ; signal this INT hasn't been handled yet
ret
hookproc endp
; Procedure prints CMOS cell
; cell must be in BCD format
;
; AL - cell number
; EBX+ESI - video RAM address
;
printBCDcell proc
; Get byte from CMOS RTC
out 70h, al ; Set cell number in CMOS RTC
jmp $+2
jmp $+2
in al, 71h ; Get byte from cell
; High half-byte of BCD
if 1
db 0d4h,10h ;AAM 10h
add ax,3030h
mov [esi+0],ah
mov [esi+2],al
else
push ax
and al, 0F0h
shr al, 4
add al, '0'
mov [esi], al
pop ax
; Low half-byte of BCD
and al, 00Fh
add al, '0'
mov [esi+2], al
endif
ret
printBCDcell endp
; This procedure hooks INT 1Ch
;
intn = 1Ch ; INTERRUPT NUMBER
install proc
mov eax,intn
mov esi,hookproc
@VMMCall Hook_V86_Int_Chain
ret ; Exit
install endp
deinstall proc
mov eax,intn
mov esi,hookproc
@VMMCall Unhook_V86_Int_Chain
ret ; Exit
deinstall endp
;
; DLL entry point
;
DllEntryPoint proc stdcall hinstDLL:dword, fdwReason:dword, lpvReserved:dword
cmp [fdwReason], DLL_PROCESS_ATTACH
jne @F
call install
mov eax,1
jmp @@exitDLL
@@:
cmp [fdwReason], DLL_PROCESS_DETACH
jne @@exitDLL
call deinstall
mov eax,1
@@exitDLL:
ret
DllEntryPoint endp
end DllEntryPoint
================================================
FILE: JLM/JCLOCK/MAKE.BAT
================================================
@echo off
set FASMINC=\fasm\Include
set JLMINC=..\..\Include
fasm JCLOCK.ASM
fasm JCLOCK2.ASM
\hx\bin\patchpe JCLOCK.DLL
\hx\bin\patchpe JCLOCK2.DLL
================================================
FILE: JLM/JCLOCK/MAKE3.BAT
================================================
@echo off
rem make jclock3.dll - no link step required.
jwasm -pe -I..\..\Include -Fo=JCLOCK3.DLL JCLOCK3.ASM
================================================
FILE: JLM/JCLOCK/README.TXT
================================================
JCLOCK 1.4 -- Second JLM (JemmEx Loadable Module)
(C) 2007 Alexey Voskov
Shows clock in the text mode.
Usage
~~~~~
DEVICE=JEMMEX.EXE
DEVICE=JLOAD.EXE JCLOCK.DLL
History
~~~~~~~
Ver Date Changed
-----------------------------------------------------------------
1.4 17-APR-2009 JClock2 supports JLoad's -u switch.
1.3 19-FEB-2008 patchpe missed in MAKE.BAT
1.2 30-JAN-2008 environment variables FASMINC and JLMINC used
1.1 05-MAY-2007 VME compatibility added
Improved source code (easy change of clock color)
1.0 04-MAY-2007 Original release
================================================
FILE: JLM/JLSTUB/Build/JLSTUB.lst
================================================
JWasm v2.18, May 7 2024
JLSTUB.ASM
;--- MZ stub to run jload.exe
;--- to be assembled with Masm or JWasm
;--- it's a derivate of dpmildxx...
= 600 ?MINMEM = 600h ;min free paragraphs for JLOAD.EXE
= 44 MAXDIR = 64+4 ;max length of a directory path (including 00h)
= 50 MAXPATH = MAXDIR+12
= 1 ?BESAFE = 1 ;1=check if JLoad.exe looks ok.
= 1 ?DOSMEMCHK = 1 ;0=check for sufficient DOS memory
.286
ifdef __JWASM__
option MZ:40h
endif
= D cr equ 13
= A lf equ 10
00000000 mzhdr struct
00000000 e_magic WORD ? ;+0
00000002 e_cblp WORD ? ;+2
00000004 e_cp WORD ? ;+4
00000006 e_crlc WORD ? ;+6 number of relocation records
00000008 e_cparhdr WORD ? ;+8
0000000A e_minalloc WORD ? ;+10
0000000C e_maxalloc WORD ? ;+12
0000000E e_ss WORD ? ;+14
00000010 e_sp WORD ? ;+16
00000012 e_csum WORD ? ;+18
00000014 e_ip WORD ? ;+20
00000016 e_cs WORD ? ;+22
00000018 e_lfarlc WORD ? ;+24 begin relocation records
0000001A mzhdr ends
0000 _TEXT segment public 'CODE'
= [bp+00h] szPgm equ [bp+00h] ;execute program name ("JLOAD.EXE")
= [bp-MAXPATH] szParm equ [bp-MAXPATH] ;application name (from environment)
0000 launch proc
0000 33D2 xor DX,DX
0002 B120 mov cl,20h
0004 B43F mov ah,3Fh ;read the MZ header
0006 CD21 int 21h
0008 7303E9DD00 jc readerror
if ?BESAFE
;--- additional tests
000D 33F6 xor si,si
000F 8B04 mov ax, [si].mzhdr.e_magic
0011 3D4D5A cmp ax,"ZM"
0014 7403E9CC00 jnz formerror
0019 8B4406 mov ax, [si].mzhdr.e_crlc ; no of relocation entries
001C 8BF8 mov di,ax
001E 23C0 and ax,ax
0020 7420 jz norelocs
0022 50 push ax
0023 33C9 xor cx,cx
0025 8B5418 mov dx,[si].mzhdr.e_lfarlc ; begin relocations
0028 B80042 mov ax,4200h
002B CD21 int 21h
002D 59 pop cx
002E C1E102 shl cx,2 ; 4 byte each reloc
0031 2BE1 sub sp,cx
0033 8BD4 mov dx,sp
0035 1E push ds
0036 16 push ss
0037 1F pop ds
0038 B43F mov ah,3Fh ; read relocs at SS:SP
003A CD21 int 21h
003C 1F pop ds
003D 7303E9A300 jc formerror
0042 norelocs:
0042 8B4408 mov ax,[si].mzhdr.e_cparhdr ; size of header in paragraphs
0045 FF740E push [si].mzhdr.e_ss
0048 FF7410 push [si].mzhdr.e_sp
004B 8B7414 mov si, [si].mzhdr.e_ip
004E C1E004 shl ax,4
0051 8BD0 mov dx,ax
0053 33C9 xor cx,cx
0055 B80042 mov ax,4200h
0058 CD21 int 21h
005A 33D2 xor dx,dx
endif
;--- read JLoad.exe binary
005C B43F MOV AH,3Fh
005E B90060 mov cx,?MINMEM shl 4
0061 CD21 INT 21h
0063 7303E98200 JC readerror ;---> error "read error"
if ?BESAFE
0068 3BC1 cmp ax,cx ;JLOAD binary must be < 24 kB
006A 7379 jnc formerror
endif
006C B43E mov ah,3Eh
006E CD21 int 21h
0070 5A pop dx
0071 5D pop bp
if ?BESAFE
0072 8BCF mov cx,di ;some relocs to resolve?
0074 E317 jcxz norelocs2
0076 8BFC mov di,sp
0078 8CD8 mov ax,ds
007A @@:
007A 368B5D02 mov bx,ss:[di+2]
007E C1E304 shl bx,4 ;size of loader is <= 24 kB, so no overflow possible
0081 36031D add bx,ss:[di+0]
0084 0107 add [bx],ax
0086 83C704 add di,4
0089 E2EF loop @B
008B 8BE7 mov sp,di
008D norelocs2:
endif
;--- fill JLoad's PSP - don't overwrite possible cmdline arguments
008D B451 mov ah,51h
008F CD21 int 21h
0091 56 push si
0092 8BF4 mov si, sp
0094 83C602 add si, 2
0097 BF8000 mov di, 80h
009A 268A0D mov cl, es:[di]
009D B500 mov ch, 0
009F 47 inc di
00A0 E312 jcxz nocmdl
00A2 2BE1 sub sp, cx
00A4 8BDC mov bx, sp
00A6 51 push cx
00A7 57 push di
00A8 @@:
00A8 268A05 mov al, es:[di]
00AB 368807 mov ss:[bx], al
00AE 47 inc di
00AF 43 inc bx
00B0 E2F6 loop @B
00B2 5F pop di
00B3 59 pop cx
00B4 nocmdl:
00B4 B020 mov al,' '
00B6 AA stosb
00B7 @@:
00B7 36AC lodsb ss:[si]
00B9 AA stosb
00BA 22C0 and al, al
00BC 75F9 jnz @B
00BE 4F dec di
00BF E307 jcxz @F
00C1 8BF4 mov si, sp
00C3 F336A4 rep movsb es:[di], ss:[si]
00C6 8BE6 mov sp, si
00C8 @@:
00C8 26C6050D mov byte ptr es:[di],13
00CC 8BC7 mov ax, di
00CE BF8000 mov di, 80h
00D1 2BC7 sub ax, di ; might actually be larger than 127 bytes ... ignore for now.
00D3 AA stosb
00D4 5E pop si
;--- setup SS:SP
00D5 8CC0 mov ax, es
00D7 03C5 add ax, bp
00D9 83C010 add ax, 10h
00DC 8ED0 mov ss, ax
00DE 8BE2 mov sp, dx
00E0 1E push ds
00E1 56 push si
00E2 06 push es
00E3 1F pop ds
00E4 CB retf
00E5 launch endp
if ?BESAFE
00E5 formerror:
00E5 BA0000 mov dx,offset dFormError
00E8 EB03 jmp error1
endif
00EA readerror:
00EA BA0000 mov dx,offset dReadError
00ED error1:
if 0
endif
00ED errorX: ;<--- errors
00ED 0E push cs
00EE 1F pop ds
00EF E80B00 call DispError
00F2 BA0000 MOV DX,offset dFatal
00F5 E80500 call DispError
00F8 B8F04C mov ax,4CF0h ;error code F0h
00FB CD21 int 21h
00FD DispError: ;display error msg in DX
00FD B409 MOV AH,09h
00FF CD21 INT 21h
0101 C3 ret
0102 202D206C6F6164696E dFatal db ' - loading aborted',cr,lf,'$'
0117 72656164206572726F dReadError db "read error",'$'
if ?BESAFE
0122 696E76616C6964204A dFormError db "invalid JLoad.exe",'$'
endif
0134 endcopy label byte
0134 start proc
;--- setup stack at end of memory block
0134 FC cld
0135 A10200 mov ax,ds:[0002]
ife ?DOSMEMCHK
endif
0138 83E830 sub ax,30h
013B 8ED0 mov ss,ax
013D BCB002 mov sp,300h-MAXPATH
;--- setup BP stack frame
0140 8BEC mov BP,SP
0142 83EC50 sub SP,MAXPATH
;--- fill szParm with application name
0145 8BF4 mov SI,SP ;SI=szParm
0147 06 push es ;save PSP
0148 268E062C00 mov es,es:[002Ch] ;ES=environment
014D E82300 CALL GetAppName ;get name to SS:SI ( SI modified! )
0150 0E push cs
0151 1F pop ds
;--- search "PATH=", DI=NULL if it doesn't exist
0152 E83900 CALL SearchPath
0155 8BF7 MOV SI,DI ;set SI to start of PATH= value
;--- fill szPgm (search JLOAD)
0157 16 push SS
0158 1F pop DS
0159 E84C00 CALL SearchJLoad
015C BA0000 MOV DX,offset dNotFnd
015F 728C JB errorX ;---> error "not found"
;--- copy the final code to end of memory block
0161 B90000 mov cx,offset endcopy
0164 16 push ss
0165 07 pop es
0166 33FF xor di,di
0168 33F6 xor si,si
016A 2E db 2Eh ;CS prefix
016B F3A4 rep movsb
016D 07 pop es ;restore PSP
016E 1E push ds
016F 51 push cx ;CX is 0
0170 0E push cs
0171 1F pop ds
0172 CB retf
0173 start endp
;--- search name of app in environment
;--- the name may be a full path or not
;--- depending on caller
;--- in: ES=environment, SS:SI=dest
;--- modifies AX,CX,SI,DI
0173 GetAppName proc
0173 2BFF SUB DI,DI
0175 B000 mov al,00
0177 B9FFFF mov cx,-1
017A @@:
017A F2AE repnz scasb ;search end of environ (00,00)
017C AE scasb
017D 75FB jnz @B
017F 47 inc di ;skip 0001
0180 47 inc di
0181 @@:
0181 268A05 mov al,es:[di]
0184 368804 mov ss:[si],al
0187 46 inc si
0188 47 inc di
0189 22C0 and al,al
018B 75F4 jnz @B
018D C3 RET
018E GetAppName endp
;--- search PATH= in Environment
;--- In: ES=environment
;--- Out: DI-> behind "PATH=" or NULL
;--- modifies AX,CX,SI,DI
018E SearchPath proc
018E 2BFF SUB DI,DI
0190 nextitem:
0190 BE0000 MOV SI,offset szPath
0193 B90500 MOV CX,SIZPATH
0196 F3A6 REPZ CMPSB
0198 740D JZ found
019A B000 mov al,00
019C B57F mov ch,7Fh
019E F2AE repnz scasb
01A0 263A05 cmp al,es:[di]
01A3 75EB JNZ nextitem
01A5 2BFF sub di,di
01A7 found:
01A7 C3 RET
01A8 SearchPath endp
;--- search JLOAD, first in current Dir, then scan PATH
;--- Input: ES=environ, SI=address PATH variable or 0000 (no PATH exists)
;--- Output: NC if found, C if error
;--- full loader path in szPgm
;--- modifies AX,BX,CX,DX,SI,DI
01A8 SearchJLoad proc
01A8 8D7E00 lea DI,[bp+00h]
01AB 8BD7 mov dx,di
01AD nextentry: ;<----
01AD 56 PUSH SI
01AE BE0000 mov si,offset ldrname ;Name "JLOAD.EXE"
01B1 B90900 mov cx,SIZLDRNAME
01B4 @@:
01B4 2E db 2Eh ;CS prefix
01B5 AC lodsb
01B6 8805 mov [di],al
01B8 47 inc di
01B9 E2F9 loop @B
01BB 880D mov [di],cl
01BD B8003D MOV AX,3D00h ;open JLOAD.EXE
01C0 CD21 INT 21h
01C2 5E POP SI
01C3 7328 JNB ldrfound ;jmp if found!
01C5 23F6 AND SI,SI
01C7 F9 stc
01C8 7424 JZ notfound ;PATH not defined, so we are done
01CA 8BFA MOV DI,DX
01CC B94400 mov cx,MAXDIR
01CF @@:
01CF 268A04 mov al,es:[si]
01D2 8805 mov [di],al
01D4 46 inc si
01D5 47 inc di
01D6 3C3B CMP AL,';'
01D8 7406 JZ @F
01DA 3C00 CMP AL,00
01DC E0F1 LOOPNZ @B ;PATH done
01DE 33F6 XOR SI,SI
01E0 @@:
01E0 4F DEC DI
01E1 807DFF5C CMP Byte Ptr [DI-01],'\'
01E5 74C6 JZ nextentry
01E7 C6055C MOV Byte Ptr [DI],'\'
01EA 47 INC DI
01EB EBC0 JMP nextentry
01ED ldrfound:
01ED 93 XCHG ax,bx ;=MOV BX,AX
; MOV AH,3Eh ;close file
; INT 21h
; CLC
01EE notfound:
01EE C3 RET
01EF SearchJLoad endp
01EF 504154483D szPath db 'PATH='
= 5 SIZPATH equ $ - szPath
01F4 43616E27742066696E dNotFnd db "Can't find "
01FF ldrname label byte
01FF 4A4C4F41442E455845 db 'JLOAD.EXE'
= 9 SIZLDRNAME equ $ - ldrname
0208 24 db '$'
ife ?DOSMEMCHK
endif
0209 _TEXT ends
if ?DOSMEMCHK
0000 _BSS segment public 'DATA'
0000 000000000000000000 db (?MINMEM+14h) * 16 dup (?)
6140 _BSS ends
endif
0000 STACK segment stack 'STACK'
0000 STACK ends
end start
Binary Map:
Segment Pos(file) RVA Size(fil) Size(mem)
---------------------------------------------------------------
<header> 0 0 40 0
_TEXT 40 0 209 209
_BSS 0 210 0 6140
STACK 0 6350 0 0
---------------------------------------------------------------
249 6350
Macros:
N a m e Type
@CatStr . . . . . . . . . . . . Func
@Environ . . . . . . . . . . . . Func
@InStr . . . . . . . . . . . . . Func
@SizeStr . . . . . . . . . . . . Func
@SubStr . . . . . . . . . . . . Func
Structures and Unions:
N a m e Size/Ofs Type
mzhdr . . . . . . . . . . . . . 1A
e_magic . . . . . . . . . . . 0 Word
e_cblp . . . . . . . . . . . . 2 Word
e_cp . . . . . . . . . . . . . 4 Word
e_crlc . . . . . . . . . . . . 6 Word
e_cparhdr . . . . . . . . . . 8 Word
e_minalloc . . . . . . . . . . A Word
e_maxalloc . . . . . . . . . . C Word
e_ss . . . . . . . . . . . . . E Word
e_sp . . . . . . . . . . . . . 10 Word
e_csum . . . . . . . . . . . . 12 Word
e_ip . . . . . . . . . . . . . 14 Word
e_cs . . . . . . . . . . . . . 16 Word
e_lfarlc . . . . . . . . . . . 18 Word
Segments and Groups:
N a m e Size Length Align Combine Class
STACK . . . . . . . . . . . . . 16 Bit 0000 Para Stack 'STACK'
_BSS . . . . . . . . . . . . . . 16 Bit 6140 Para Public 'DATA'
_TEXT . . . . . . . . . . . . . 16 Bit 0209 Para Public 'CODE'
Procedures, parameters and locals:
N a m e Type Value Segment Length
GetAppName . . . . . . . . . . . P Near 0173 _TEXT 001B Public
L&_0006 . . . . . . . . . . . L Near 0181 _TEXT
L&_0005 . . . . . . . . . . . L Near 017A _TEXT
SearchJLoad . . . . . . . . . . P Near 01A8 _TEXT 0047 Public
L&_0008 . . . . . . . . . . . L Near 01CF _TEXT
notfound . . . . . . . . . . . L Near 01EE _TEXT
L&_0009 . . . . . . . . . . . L Near 01E0 _TEXT
L&_0007 . . . . . . . . . . . L Near 01B4 _TEXT
nextentry . . . . . . . . . . L Near 01AD _TEXT
ldrfound . . . . . . . . . . . L Near 01ED _TEXT
SearchPath . . . . . . . . . . . P Near 018E _TEXT 001A Public
found . . . . . . . . . . . . L Near 01A7 _TEXT
nextitem . . . . . . . . . . . L Near 0190 _TEXT
launch . . . . . . . . . . . . . P Near 0000 _TEXT 00E5 Public
L&_0004 . . . . . . . . . . . L Near 00C8 _TEXT
L&_0002 . . . . . . . . . . . L Near 00A8 _TEXT
L&_0003 . . . . . . . . . . . L Near 00B7 _TEXT
L&_0001 . . . . . . . . . . . L Near 007A _TEXT
nocmdl . . . . . . . . . . . . L Near 00B4 _TEXT
norelocs . . . . . . . . . . . L Near 0042 _TEXT
norelocs2 . . . . . . . . . . L Near 008D _TEXT
start . . . . . . . . . . . . . P Near 0134 _TEXT 003F Public
Symbols:
N a m e Type Value Attr
?BESAFE . . . . . . . . . . . . Number 1h
?DOSMEMCHK . . . . . . . . . . . Number 1h
?MINMEM . . . . . . . . . . . . Number 600h
DispError . . . . . . . . . . . L Near FDh _TEXT
MAXDIR . . . . . . . . . . . . . Number 44h
MAXPATH . . . . . . . . . . . . Number 50h
SIZLDRNAME . . . . . . . . . . . Number 9h
SIZPATH . . . . . . . . . . . . Number 5h
cr . . . . . . . . . . . . . . . Number Dh
dFatal . . . . . . . . . . . . . Byte[21] 102h _TEXT
dFormError . . . . . . . . . . . Byte[18] 122h _TEXT
dNotFnd . . . . . . . . . . . . Byte[11] 1F4h _TEXT
dReadError . . . . . . . . . . . Byte[11] 117h _TEXT
endcopy . . . . . . . . . . . . Byte 134h _TEXT
error1 . . . . . . . . . . . . . L Near EDh _TEXT
errorX . . . . . . . . . . . . . L Near EDh _TEXT
formerror . . . . . . . . . . . L Near E5h _TEXT
ldrname . . . . . . . . . . . . Byte 1FFh _TEXT
lf . . . . . . . . . . . . . . . Number Ah
readerror . . . . . . . . . . . L Near EAh _TEXT
szParm . . . . . . . . . . . . . Text [bp-MAXPATH]
szPath . . . . . . . . . . . . . Byte[5] 1EFh _TEXT
szPgm . . . . . . . . . . . . . Text [bp+00h]
JLSTUB.ASM: 418 lines, 2 passes, 2 ms, 0 warnings, 0 errors
================================================
FILE: JLM/JLSTUB/JLSTUB.ASM
================================================
;--- MZ stub to run jload.exe
;--- to be assembled with Masm or JWasm
;--- it's a derivate of dpmildxx...
?MINMEM = 600h ;min free paragraphs for JLOAD.EXE
MAXDIR = 64+4 ;max length of a directory path (including 00h)
MAXPATH = MAXDIR+12
?BESAFE = 1 ;1=check if JLoad.exe looks ok.
?DOSMEMCHK = 1 ;0=check for sufficient DOS memory
.286
ifdef __JWASM__
option MZ:40h
endif
cr equ 13
lf equ 10
mzhdr struct
e_magic WORD ? ;+0
e_cblp WORD ? ;+2
e_cp WORD ? ;+4
e_crlc WORD ? ;+6 number of relocation records
e_cparhdr WORD ? ;+8
e_minalloc WORD ? ;+10
e_maxalloc WORD ? ;+12
e_ss WORD ? ;+14
e_sp WORD ? ;+16
e_csum WORD ? ;+18
e_ip WORD ? ;+20
e_cs WORD ? ;+22
e_lfarlc WORD ? ;+24 begin relocation records
mzhdr ends
_TEXT segment public 'CODE'
szPgm equ [bp+00h] ;execute program name ("JLOAD.EXE")
szParm equ [bp-MAXPATH] ;application name (from environment)
launch proc
xor DX,DX
mov cl,20h
mov ah,3Fh ;read the MZ header
int 21h
jc readerror
if ?BESAFE
;--- additional tests
xor si,si
mov ax, [si].mzhdr.e_magic
cmp ax,"ZM"
jnz formerror
mov ax, [si].mzhdr.e_crlc ; no of relocation entries
mov di,ax
and ax,ax
jz norelocs
push ax
xor cx,cx
mov dx,[si].mzhdr.e_lfarlc ; begin relocations
mov ax,4200h
int 21h
pop cx
shl cx,2 ; 4 byte each reloc
sub sp,cx
mov dx,sp
push ds
push ss
pop ds
mov ah,3Fh ; read relocs at SS:SP
int 21h
pop ds
jc formerror
norelocs:
mov ax,[si].mzhdr.e_cparhdr ; size of header in paragraphs
push [si].mzhdr.e_ss
push [si].mzhdr.e_sp
mov si, [si].mzhdr.e_ip
shl ax,4
mov dx,ax
xor cx,cx
mov ax,4200h
int 21h
xor dx,dx
endif
;--- read JLoad.exe binary
MOV AH,3Fh
mov cx,?MINMEM shl 4
INT 21h
JC readerror ;---> error "read error"
if ?BESAFE
cmp ax,cx ;JLOAD binary must be < 24 kB
jnc formerror
endif
mov ah,3Eh
int 21h
pop dx
pop bp
if ?BESAFE
mov cx,di ;some relocs to resolve?
jcxz norelocs2
mov di,sp
mov ax,ds
@@:
mov bx,ss:[di+2]
shl bx,4 ;size of loader is <= 24 kB, so no overflow possible
add bx,ss:[di+0]
add [bx],ax
add di,4
loop @B
mov sp,di
norelocs2:
endif
;--- fill JLoad's PSP - don't overwrite possible cmdline arguments
mov ah,51h
int 21h
push si
mov si, sp
add si, 2
mov di, 80h
mov cl, es:[di]
mov ch, 0
inc di
jcxz nocmdl
sub sp, cx
mov bx, sp
push cx
push di
@@:
mov al, es:[di]
mov ss:[bx], al
inc di
inc bx
loop @B
pop di
pop cx
nocmdl:
mov al,' '
stosb
@@:
lodsb ss:[si]
stosb
and al, al
jnz @B
dec di
jcxz @F
mov si, sp
rep movsb es:[di], ss:[si]
mov sp, si
@@:
mov byte ptr es:[di],13
mov ax, di
mov di, 80h
sub ax, di ; might actually be larger than 127 bytes ... ignore for now.
stosb
pop si
;--- setup SS:SP
mov ax, es
add ax, bp
add ax, 10h
mov ss, ax
mov sp, dx
push ds
push si
push es
pop ds
retf
launch endp
if ?BESAFE
formerror:
mov dx,offset dFormError
jmp error1
endif
readerror:
mov dx,offset dReadError
error1:
if 0
;--- close file? Will be done by DOS.
mov ah,3Eh
int 21h
endif
errorX: ;<--- errors
push cs
pop ds
call DispError
MOV DX,offset dFatal
call DispError
mov ax,4CF0h ;error code F0h
int 21h
DispError: ;display error msg in DX
MOV AH,09h
INT 21h
ret
dFatal db ' - loading aborted',cr,lf,'$'
dReadError db "read error",'$'
if ?BESAFE
dFormError db "invalid JLoad.exe",'$'
endif
endcopy label byte
start proc
;--- setup stack at end of memory block
cld
mov ax,ds:[0002]
ife ?DOSMEMCHK
mov bp,es
push ax
sub ax,bp
cmp ax,?MINMEM+30h ;enough free memory in this block?
pop ax
mov dx,offset dMemory
jc errorX
endif
sub ax,30h
mov ss,ax
mov sp,300h-MAXPATH
;--- setup BP stack frame
mov BP,SP
sub SP,MAXPATH
;--- fill szParm with application name
mov SI,SP ;SI=szParm
push es ;save PSP
mov es,es:[002Ch] ;ES=environment
CALL GetAppName ;get name to SS:SI ( SI modified! )
push cs
pop ds
;--- search "PATH=", DI=NULL if it doesn't exist
CALL SearchPath
MOV SI,DI ;set SI to start of PATH= value
;--- fill szPgm (search JLOAD)
push SS
pop DS
CALL SearchJLoad
MOV DX,offset dNotFnd
JB errorX ;---> error "not found"
;--- copy the final code to end of memory block
mov cx,offset endcopy
push ss
pop es
xor di,di
xor si,si
db 2Eh ;CS prefix
rep movsb
pop es ;restore PSP
push ds
push cx ;CX is 0
push cs
pop ds
retf
start endp
;--- search name of app in environment
;--- the name may be a full path or not
;--- depending on caller
;--- in: ES=environment, SS:SI=dest
;--- modifies AX,CX,SI,DI
GetAppName proc
SUB DI,DI
mov al,00
mov cx,-1
@@:
repnz scasb ;search end of environ (00,00)
scasb
jnz @B
inc di ;skip 0001
inc di
@@:
mov al,es:[di]
mov ss:[si],al
inc si
inc di
and al,al
jnz @B
RET
GetAppName en
gitextract_t40dgl9z/
├── Artistic.txt
├── History.txt
├── Html/
│ └── Readme.html
├── Include/
│ ├── FILEACC.INC
│ ├── FINDRES.INC
│ ├── JLM.H
│ ├── JLM.INC
│ ├── JLMFASM.INC
│ ├── JSYSTEM.INC
│ ├── PRINTF.INC
│ ├── VDS.INC
│ └── X86.INC
├── JLM/
│ ├── AHCICD/
│ │ ├── AHCICD.ASM
│ │ ├── AHCICD.txt
│ │ ├── MAKE.BAT
│ │ └── MAKEM.BAT
│ ├── GENERIC/
│ │ ├── GENERIC.ASM
│ │ ├── MAKEFILE
│ │ ├── README.TXT
│ │ └── TESTGEN.ASM
│ ├── HELLO/
│ │ ├── HELLO.ASM
│ │ ├── MAKE.BAT
│ │ └── README.TXT
│ ├── HELLO2/
│ │ ├── HELLO2.C
│ │ ├── HELLO2W.C
│ │ ├── JLMW.ASM
│ │ ├── JLMW.h
│ │ ├── MAKEJLMW.BAT
│ │ ├── MAKEOW.BAT
│ │ ├── MAKEVC.BAT
│ │ ├── README.TXT
│ │ └── makeow.sh
│ ├── IOTRAP/
│ │ ├── IOTRAP.ASM
│ │ ├── MAKEFILE
│ │ ├── README.TXT
│ │ └── TESTIOT.ASM
│ ├── JCLOCK/
│ │ ├── JCLOCK.ASM
│ │ ├── JCLOCK2.ASM
│ │ ├── JCLOCK3.ASM
│ │ ├── MAKE.BAT
│ │ ├── MAKE3.BAT
│ │ └── README.TXT
│ ├── JLSTUB/
│ │ ├── Build/
│ │ │ └── JLSTUB.lst
│ │ ├── JLSTUB.ASM
│ │ ├── JLStub.txt
│ │ └── Make.BAT
│ ├── KEYBGR/
│ │ ├── KEYBGR.ASM
│ │ ├── MAKE.BAT
│ │ ├── MAKEFILE
│ │ └── README.TXT
│ ├── QPIEMU/
│ │ ├── MAKE.BAT
│ │ ├── MAKEFILE
│ │ ├── QPIEMU.ASM
│ │ ├── QPIEMU.txt
│ │ └── Test/
│ │ ├── MAKEFILE
│ │ ├── PRINTF16.INC
│ │ ├── SETARGV.INC
│ │ ├── TESTDMA.ASM
│ │ └── TESTQPI.ASM
│ ├── README.TXT
│ ├── REBOOT/
│ │ ├── FASTBOOT.ASM
│ │ ├── FASTBOOT.txt
│ │ ├── FASTBRM.ASM
│ │ ├── FBOOT.ASM
│ │ ├── LDI13EXT.ASM
│ │ ├── MAKE.BAT
│ │ ├── REBOOT.ASM
│ │ └── REBOOT.txt
│ ├── XCDROM32/
│ │ ├── History.txt
│ │ ├── MAKE.BAT
│ │ ├── MAKEM.BAT
│ │ ├── XCDROM32.ASM
│ │ └── XCDROM32.txt
│ └── XDMA32/
│ ├── History.txt
│ ├── IDENTIFY.INC
│ ├── MAKE.BAT
│ ├── MAKEM.BAT
│ ├── XDMA32.ASM
│ └── XDMA32.txt
├── JemmExL.mak
├── Linux.mak
├── Makefile
├── Readme.txt
├── Test/
│ ├── BMINTRM.ASM
│ ├── EMS4E.ASM
│ ├── EMS4F.ASM
│ ├── EMS56.ASM
│ ├── EMS57.ASM
│ ├── EMS57A.ASM
│ ├── EMS5B.ASM
│ ├── EXC00.ASM
│ ├── EXC06.ASM
│ ├── FRAMERES.ASM
│ ├── HLTTEST.ASM
│ ├── HLTTEST2.ASM
│ ├── I15MOVE.ASM
│ ├── INT67.ASM
│ ├── INT88.ASM
│ ├── MACROS.INC
│ ├── MAKE.BAT
│ ├── PRINTF.INC
│ ├── README.TXT
│ ├── TEST0C.DEB
│ ├── TEST0C1.DEB
│ ├── TEST0D.DEB
│ ├── TEST10.DEB
│ ├── TEST11.DEB
│ ├── TESTDMA.ASM
│ ├── TESTDMA2.ASM
│ ├── TESTDMA3.ASM
│ ├── TESTVCPI.ASM
│ ├── TESTVDS.ASM
│ ├── TESTVDS2.ASM
│ ├── TESTVDS3.ASM
│ ├── TIMERMS.INC
│ ├── VCPI.INC
│ ├── XMSTEST.ASM
│ ├── XMSTEST2.ASM
│ ├── XMSTEST3.ASM
│ ├── XMSTEST4.ASM
│ └── XMSTEST5.ASM
├── Tools/
│ ├── CLEAR.BAT
│ ├── CPUID/
│ │ ├── CPUID.ASM
│ │ ├── MAKE.BAT
│ │ └── PRINTF.INC
│ ├── Cpustat/
│ │ ├── CPUSTAT.ASM
│ │ ├── MAKE.BAT
│ │ └── PRINTF.INC
│ ├── EMSSTAT/
│ │ ├── EMSSTAT.ASM
│ │ ├── MAKE.BAT
│ │ └── PRINTF.INC
│ ├── JEMFBHLP/
│ │ ├── JEMFBHLP.ASM
│ │ └── MAKE.BAT
│ ├── JLOAD/
│ │ ├── DEBUG.INC
│ │ ├── DPRINTF.INC
│ │ ├── DPRNTF16.INC
│ │ ├── History.txt
│ │ ├── JLOAD.ASM
│ │ ├── JLOAD.INC
│ │ ├── JLOAD.TXT
│ │ ├── JLOAD.txt
│ │ ├── JLOAD32.ASM
│ │ ├── JLOAD32.INC
│ │ ├── Linux.mak
│ │ ├── MAKEFILE
│ │ ├── VDMAD.ASM
│ │ ├── VIOOUT.INC
│ │ ├── VMM.ASM
│ │ ├── WINNT.INC
│ │ └── license.txt
│ ├── MAKE.BAT
│ ├── MEMSTAT/
│ │ ├── MAKE.BAT
│ │ ├── MEMSTAT.ASM
│ │ └── PRINTF.INC
│ ├── MoveXBDA/
│ │ ├── MAKE.BAT
│ │ └── MOVEXBDA.ASM
│ ├── UMBM/
│ │ ├── MAKE.BAT
│ │ └── UMBM.ASM
│ ├── VCPI/
│ │ ├── MAKE.BAT
│ │ ├── PRINTF.INC
│ │ ├── VCPI.ASM
│ │ ├── VCPI.INC
│ │ └── VIOOUT.INC
│ └── XMSSTAT/
│ ├── MAKE.BAT
│ ├── PRINTF.INC
│ └── XMSSTAT.ASM
├── XMS35.txt
└── src/
├── AUXIO.INC
├── DEBUG.ASM
├── DEBUG16.INC
├── DEBUG32.INC
├── DEBUGSYS.INC
├── DEV.ASM
├── DMA.INC
├── DPRINTF.INC
├── DPRNTF16.INC
├── EMS.ASM
├── EMS.INC
├── EMS32.INC
├── EMU.ASM
├── EXTERN32.INC
├── I15.ASM
├── INIT.ASM
├── INIT16.ASM
├── JEMM.INC
├── JEMM16.ASM
├── JEMM16.INC
├── JEMM32.ASM
├── JEMM32.INC
├── POOL.ASM
├── UMB.ASM
├── VCPI.ASM
├── VCPI.INC
├── VDMA.ASM
├── VDS.ASM
├── XMS.ASM
└── XMS.INC
SYMBOL INDEX (18 symbols across 4 files)
FILE: Include/JLM.H
type UCHAR (line 9) | typedef unsigned char UCHAR;
type USHORT (line 10) | typedef unsigned short USHORT;
type ULONG (line 11) | typedef unsigned long ULONG;
type Pushad_Struc (line 13) | struct Pushad_Struc {
function VMM_Service (line 92) | VMM_Service (Get_VMM_Version)
type Client_Reg_Struc (line 154) | struct Client_Reg_Struc {
FILE: JLM/HELLO2/HELLO2.C
type Client_Reg_Struc (line 6) | struct Client_Reg_Struc
type cb_s (line 8) | struct cb_s
function ULONG (line 14) | ULONG Begin_Nest_Exec()
function ULONG (line 20) | ULONG End_Nest_Exec()
function ULONG (line 26) | ULONG Exec_Int(unsigned long intno)
function main (line 33) | int main()
FILE: JLM/HELLO2/HELLO2W.C
type Client_Reg_Struc (line 9) | struct Client_Reg_Struc
function main (line 11) | int main()
FILE: JLM/HELLO2/JLMW.h
type cb_s (line 4) | struct cb_s
type Client_Reg_Struc (line 5) | struct Client_Reg_Struc
type Client_Reg_Struc (line 6) | struct Client_Reg_Struc
type Client_Reg_Struc (line 7) | struct Client_Reg_Struc
Condensed preview — 197 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,413K chars).
[
{
"path": "Artistic.txt",
"chars": 4922,
"preview": "The Artistic License Preamble\r\n\r\nThe intent of this document is to state the conditions under which a Package may \r\nbe c"
},
{
"path": "History.txt",
"chars": 28966,
"preview": "\r\n History\r\n\r\n __.__.____: v5.87\r\n\r\n - fixed regression in v5.86: exceptions in PL0 were displayed incorrectly.\r\n - fixe"
},
{
"path": "Html/Readme.html",
"chars": 33404,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 FINAL//EN\">\r\n<HTML>\r\n<HEAD>\r\n<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/h"
},
{
"path": "Include/FILEACC.INC",
"chars": 2158,
"preview": "\r\n;--- dos file access for JLMs\r\n;--- although addresses are linear, they must\r\n;--- be within 64 kB distance of v86 DS "
},
{
"path": "Include/FINDRES.INC",
"chars": 4726,
"preview": "\r\n?NOCASEMAP\tequ 0\t;win32 std is 0\r\n\r\n;--- eax = resource directory\r\n;--- id may be an id (HIWORD=0) or a string pointer"
},
{
"path": "Include/JLM.H",
"chars": 5658,
"preview": "\r\n/* Header file for Jemm JLMs which defines the subset of the Win3x/Win9x */\r\n/* ring 0 API (VMM) that Jemm/JLoad expos"
},
{
"path": "Include/JLM.INC",
"chars": 9225,
"preview": "\r\n;--- this is an assembler include file in MASM format,\r\n;--- to be used for JLMs (Jemm Loadable Modules).\r\n;--- it def"
},
{
"path": "Include/JLMFASM.INC",
"chars": 7925,
"preview": "\r\n;--- this is an assembler include file in FASM format\r\n;--- to be used for JLMs (Jemm Loadable Modules).\r\n;--- it defi"
},
{
"path": "Include/JSYSTEM.INC",
"chars": 1083,
"preview": "\r\n;--- constants used by Jemm & JLoad\r\n\r\n?VERSIONHIGH equ 5\r\n?VERSIONLOW equ 87\r\n\r\n?BASE EQU 110000h "
},
{
"path": "Include/PRINTF.INC",
"chars": 3236,
"preview": "\r\n;--- simple printf\r\n\r\n;--- i64toa(long long n, char * s, int base);\r\n;--- convert 64-bit long long to string\r\n\r\ni64toa"
},
{
"path": "Include/VDS.INC",
"chars": 2183,
"preview": "\r\n;--- VDS definitions\r\n\r\n;--- flags in DX used by various VDS functions\r\n\r\nVDSF_COPY equ 02h\t;bit 1 - copy in/out"
},
{
"path": "Include/X86.INC",
"chars": 3136,
"preview": "\r\n;--- generic X86 definitions\r\n\r\n;--- page table flags\r\n\r\nPTF_PRESENT equ 001h\r\nPTF_RW equ 002h\r\nPTF_USER equ 0"
},
{
"path": "JLM/AHCICD/AHCICD.ASM",
"chars": 24844,
"preview": "\n;--- JLM to read CD/DVD in AHCI mode.\n;--- \"cooked\" mode is supported only.\n\n\t.386\n\t.model flat\n\toption casemap:none\n\to"
},
{
"path": "JLM/AHCICD/AHCICD.txt",
"chars": 722,
"preview": "\r\n 1. About AHCICD\r\n\r\n AHCICD is a JLM to access AHCI optical disks, \"inspired\" by Rudolph R. Loew's\r\n AHCICD.SYS. To"
},
{
"path": "JLM/AHCICD/MAKE.BAT",
"chars": 221,
"preview": "@echo off\r\n\r\njwasm -c -coff -nologo -Fl -Sg -I..\\..\\Include AHCICD.ASM\r\nrem jwasm -coff -nologo -D_DEBUG -Fl -Sg -I..\\.."
},
{
"path": "JLM/AHCICD/MAKEM.BAT",
"chars": 138,
"preview": "@echo off\r\n\r\nml -c -coff -nologo -Fl -Sg -I..\\..\\Include AHCICD.ASM\r\nlink /nologo /subsystem:native /dll AHCICD.obj /OUT"
},
{
"path": "JLM/GENERIC/GENERIC.ASM",
"chars": 2480,
"preview": "\r\n;--- JLM sample GENERIC\r\n;--- use Makefile to create GENERIC.DLL\r\n\r\n;--- GENERIC is a very simple JLM. It doesn't hook"
},
{
"path": "JLM/GENERIC/MAKEFILE",
"chars": 898,
"preview": "\r\n# NMake/WMake Makefile to create GENERIC.DLL\r\n#\r\n# tools alternatives\r\n#------------------------"
},
{
"path": "JLM/GENERIC/README.TXT",
"chars": 1373,
"preview": "\r\n 1. About\r\n\r\n GENERIC is a JLM sample which demonstrates how to implement a\r\n protected-mode TSR.\r\n\r\n\r\n 2. How to inst"
},
{
"path": "JLM/GENERIC/TESTGEN.ASM",
"chars": 670,
"preview": "\r\n;--- test app which calls some \"services\" of JLM GENERIC.\r\n;--- assemble: JWasm -bin -Fo testgen.com testgen.asm\r\n\r\n\t."
},
{
"path": "JLM/HELLO/HELLO.ASM",
"chars": 1393,
"preview": "\r\n;--- a simple JLM which displays a message onto the screen\r\n;--- with the help of v86-int 21h and nested execution\r\n\r\n"
},
{
"path": "JLM/HELLO/MAKE.BAT",
"chars": 886,
"preview": "@echo off\r\nrem\r\nrem use JWasm & JWlink\r\nrem\r\njwasm -nologo -coff -Fl=Release\\Hello -Fo=Release\\Hello -I..\\..\\Include Hel"
},
{
"path": "JLM/HELLO/README.TXT",
"chars": 207,
"preview": "\r\n About\r\n\r\n This is the inevitable \"hello world\" JLM, written for Masm/JWasm.\r\n It displays a welcome message. After"
},
{
"path": "JLM/HELLO2/HELLO2.C",
"chars": 836,
"preview": "\r\n// for MS VC\r\n\r\n#include <jlm.h>\r\n\r\nstruct Client_Reg_Struc * pcl;\r\n\r\nstruct cb_s * Get_Cur_VM_Handle()\r\n{\r\n VxDCal"
},
{
"path": "JLM/HELLO2/HELLO2W.C",
"chars": 588,
"preview": "\r\n// for Open Watcom C\r\n// OW inline assembly doesn't know values of enums!\r\n// therefore it needs external module jlmw."
},
{
"path": "JLM/HELLO2/JLMW.ASM",
"chars": 690,
"preview": "\r\n;--- helpers for (Watcom) C\r\n\r\n\t.386\r\n .model flat\r\n \r\n\tinclude JLM.INC\r\n\r\n\t.code\r\n\r\nGet_Cur_VM_Handle proc stdc"
},
{
"path": "JLM/HELLO2/JLMW.h",
"chars": 330,
"preview": "\r\n// helper procs needed by Open Watcom C\r\n\r\nextern struct cb_s * _stdcall Get_Cur_VM_Handle( void );\r\nextern ULONG _std"
},
{
"path": "JLM/HELLO2/MAKEJLMW.BAT",
"chars": 95,
"preview": "@echo off\r\nrem assembles helper module jlmw for Open Watcom.\r\njwasm -I ..\\..\\Include jlmw.asm\r\n"
},
{
"path": "JLM/HELLO2/MAKEOW.BAT",
"chars": 238,
"preview": "@echo off\r\nrem uses Open Watcom C and WLink\r\nrem OW needs a helper module: jlmw.obj\r\nwcc386 -mf -zl -zls -s -I..\\..\\Incl"
},
{
"path": "JLM/HELLO2/MAKEVC.BAT",
"chars": 205,
"preview": "@echo off\r\nrem uses MS VC and MS Link\r\n\\msvc71\\bin\\cl -c -I..\\..\\Include hello2.c\r\nlink /LIBPATH:\\msvc71\\lib hello2.obj "
},
{
"path": "JLM/HELLO2/README.TXT",
"chars": 221,
"preview": "\r\n About\r\n \r\n Another JLM \"hello world\", this time written in C.\r\n MAKEVC.BAT: for MS VC (or Pelles C, CC386, ...)\r\n MAK"
},
{
"path": "JLM/HELLO2/makeow.sh",
"chars": 294,
"preview": "#!/bin/sh\nset -e\n# uses Open Watcom C, JWAsm and JWLink which must be in PATH\n# OW needs a helper module: jlmw.obj\njwasm"
},
{
"path": "JLM/IOTRAP/IOTRAP.ASM",
"chars": 4751,
"preview": "\r\n;--- JLM sample IOTRAP\r\n;--- use Makefile to create IOTRAP.DLL\r\n\r\n;--- IOTRAP traps IO port 100h when the first client"
},
{
"path": "JLM/IOTRAP/MAKEFILE",
"chars": 1004,
"preview": "\r\n# NMake/WMake Makefile to create IOTRAP.DLL\r\n#\r\n# tools alternatives\r\n#-------------------------"
},
{
"path": "JLM/IOTRAP/README.TXT",
"chars": 779,
"preview": "\r\n 1. About\r\n\r\n IOTRAP is a JLM sample which demonstrates how to trap IO port access.\r\n\r\n Note: This is somewhat obsolet"
},
{
"path": "JLM/IOTRAP/TESTIOT.ASM",
"chars": 2021,
"preview": "\r\n;--- tsr to test JLM IOTRAP.\r\n;--- it installs a callback which is called whenever port 100h\r\n;--- is accessed.\r\n;--- "
},
{
"path": "JLM/JCLOCK/JCLOCK.ASM",
"chars": 4677,
"preview": ";\r\n; JCLOCK 1.1\r\n;\r\n; JLM example -- CLOCK for JEMM386/JEMMEX\r\n; It is the first JLM with screen input/output :-)\r\n;\r\n;"
},
{
"path": "JLM/JCLOCK/JCLOCK2.ASM",
"chars": 4289,
"preview": "\r\n; this is a modified JCLOCK version which uses the Jemm API to hook int 1Ch.\r\n; Thus, it can be unloaded.\r\n;\r\n; (C) 20"
},
{
"path": "JLM/JCLOCK/JCLOCK3.ASM",
"chars": 3471,
"preview": "\r\n;--- JCLOCK2 in Masm/JWasm syntax\r\n\r\n\t.386\r\n\t.model flat\r\n\toption casemap:none\r\n\r\n\tinclude jlm.inc\r\n\r\n; Constants\r\n\r\nD"
},
{
"path": "JLM/JCLOCK/MAKE.BAT",
"chars": 156,
"preview": "@echo off\r\nset FASMINC=\\fasm\\Include\r\nset JLMINC=..\\..\\Include\r\nfasm JCLOCK.ASM\r\nfasm JCLOCK2.ASM\r\n\\hx\\bin\\patchpe JCLOC"
},
{
"path": "JLM/JCLOCK/MAKE3.BAT",
"chars": 113,
"preview": "@echo off\r\nrem make jclock3.dll - no link step required.\r\njwasm -pe -I..\\..\\Include -Fo=JCLOCK3.DLL JCLOCK3.ASM\r\n"
},
{
"path": "JLM/JCLOCK/README.TXT",
"chars": 584,
"preview": "JCLOCK 1.4 -- Second JLM (JemmEx Loadable Module)\r\n(C) 2007 Alexey Voskov\r\n\r\nShows clock in the text mode.\r\n\r\nUsage\r\n~~~"
},
{
"path": "JLM/JLSTUB/Build/JLSTUB.lst",
"chars": 23300,
"preview": "JWasm v2.18, May 7 2024\r\nJLSTUB.ASM\r\n\r\n ;--- MZ stub to run jload.exe\r\n "
},
{
"path": "JLM/JLSTUB/JLSTUB.ASM",
"chars": 7068,
"preview": "\r\n;--- MZ stub to run jload.exe\r\n;--- to be assembled with Masm or JWasm\r\n;--- it's a derivate of dpmildxx... \r\n\r\n?MINME"
},
{
"path": "JLM/JLSTUB/JLStub.txt",
"chars": 293,
"preview": "\r\n 1. About JLStub\r\n\r\n JLStub is NOT a JLM. It's a stub, supposed to be added to other JLMs.\r\n It's purpose is to avoid"
},
{
"path": "JLM/JLSTUB/Make.BAT",
"chars": 108,
"preview": "@echo off\r\nif not exist Build\\NUL mkdir Build\r\njwasm -nologo -mz -FlBuild\\ -Fo=Build\\jlstub.bin jlstub.asm\r\n"
},
{
"path": "JLM/KEYBGR/KEYBGR.ASM",
"chars": 9183,
"preview": "\r\n;*** german keyboard driver for MF keyboards\r\n;--- the first JLM (Jemm Loadable Module) ever.\r\n\r\n;--- v1.0: initial\r\n;"
},
{
"path": "JLM/KEYBGR/MAKE.BAT",
"chars": 231,
"preview": "@echo off\r\nrem\r\nrem JWasm v2.19: cmdline option -pe will create a JLM without external linker\r\nrem\r\njwasm -nologo -pe -D"
},
{
"path": "JLM/KEYBGR/MAKEFILE",
"chars": 745,
"preview": "\r\n# Makefile for NMAKE\r\n# tools Alternatives\r\n#---------------------------------------------------"
},
{
"path": "JLM/KEYBGR/README.TXT",
"chars": 302,
"preview": "\r\n Deutscher Tastaturtreiber fuer DOS der mit 48 Bytes DOS Speicher \r\n auskommt. Funktioniert nur in Verbindung mit Jemm"
},
{
"path": "JLM/QPIEMU/MAKE.BAT",
"chars": 264,
"preview": "@echo off\r\nrem create QPIEMU.DLL without linker, requires jwasm v2.19+\r\nrem Jemm's src directory has to be included sinc"
},
{
"path": "JLM/QPIEMU/MAKEFILE",
"chars": 900,
"preview": "\r\n# NMake/WMake Makefile to create QPIEMU.DLL\r\n#\r\n# tools alternatives\r\n#-------------------------"
},
{
"path": "JLM/QPIEMU/QPIEMU.ASM",
"chars": 5584,
"preview": "\r\n;--- JLM sample QPIEMU\r\n;--- use Makefile to create QPIEMU.DLL\r\n\r\n;--- QPIEMU installs a small subset of Qemm's QPI,\r\n"
},
{
"path": "JLM/QPIEMU/QPIEMU.txt",
"chars": 1584,
"preview": "\r\n 1. About\r\n\r\n QPIEMU is a JLM that partly emulates the Qemm API (QPI). Its\r\n purpose is to provide the IO trapping par"
},
{
"path": "JLM/QPIEMU/Test/MAKEFILE",
"chars": 370,
"preview": "\r\n# NMake/WMake Makefile to create TESTQPI.EXE & TESTDMA.EXE\r\n\r\nNAME1 = TESTQPI\r\nNAME2 = TESTDMA\r\nOUTDIR= .\r\nASM=jwasm.e"
},
{
"path": "JLM/QPIEMU/Test/PRINTF16.INC",
"chars": 2958,
"preview": "\r\n;--- simple printf() implementation\r\n\r\nhandle_char proc\r\n\r\n\tmov dl,al\r\n\tcmp al,10\r\n\tjnz @F\r\n\tmov dl,13\r\n\tcall @F\r\n\tmov"
},
{
"path": "JLM/QPIEMU/Test/SETARGV.INC",
"chars": 3094,
"preview": "\r\n;--- read the commandline at PSP:81h\r\n;--- and create an argc/argv structure on the stack.\r\n;--- in: ES=PSP, DS=DGROUP"
},
{
"path": "JLM/QPIEMU/Test/TESTDMA.ASM",
"chars": 4612,
"preview": "\r\n;--- test Qemm/QPIEMU ( IO trap part )\r\n;--- this time test ISA DMA ports\r\n\r\n\t.286\r\n\t.model small\r\n\t.dosseg\r\n\t.stack 1"
},
{
"path": "JLM/QPIEMU/Test/TESTQPI.ASM",
"chars": 5282,
"preview": "\r\n;--- test Qemm/QPIEMU ( IO trap part )\r\n\r\n\t.286\r\n\t.model small\r\n\t.dosseg\r\n\t.stack 1024\r\n\r\nlf equ 10\r\n\r\nCStr macro text"
},
{
"path": "JLM/README.TXT",
"chars": 1207,
"preview": "\r\n 1. About\r\n\r\n This directory contains some JLMs:\r\n\r\n AHCICD: AHCI Optical disk driver.\r\n GENERIC: protected-mode TS"
},
{
"path": "JLM/REBOOT/FASTBOOT.ASM",
"chars": 9946,
"preview": "\r\n;--- Sample how to handle DEVICE_REBOOT_NOTIFY control message;\r\n;--- handles fastboot only.\r\n;--- Requires Jemm v5.86"
},
{
"path": "JLM/REBOOT/FASTBOOT.txt",
"chars": 1386,
"preview": "\r\n About FastBoot JLM\r\n\r\n The FastBoot JLM allows some fine-tuning of Jemm's fast reboot behavior\r\n (which is activa"
},
{
"path": "JLM/REBOOT/FASTBRM.ASM",
"chars": 5147,
"preview": "\r\n;--- real-mode part of the fastboot JLM;\r\n;--- this code is moved to address 07E00h by the fastboot JLM;\r\n;--- on entr"
},
{
"path": "JLM/REBOOT/FBOOT.ASM",
"chars": 2711,
"preview": "\r\n;--- Set /D and /P option for currently loaded fastboot JLM.\r\n;--- This program uses the API installed by FASTBOOT.DLL"
},
{
"path": "JLM/REBOOT/LDI13EXT.ASM",
"chars": 3223,
"preview": "\r\n;--- sample how to load an int 13h extension into FASTBOOT JLM.\r\n;--- this sample just swaps HDs 0 and 1 in int 13h; i"
},
{
"path": "JLM/REBOOT/MAKE.BAT",
"chars": 186,
"preview": "@echo off\r\njwasm -nologo -pe -Fl -Fo=REBOOT.DLL -I..\\..\\Include REBOOT.ASM \r\njwasm -nologo -bin -Fl FASTBRM.ASM \r\njwasm"
},
{
"path": "JLM/REBOOT/REBOOT.ASM",
"chars": 1504,
"preview": "\r\n;--- sample how to handle DEVICE_REBOOT_NOTIFY control message\r\n;--- requires Jemm v5.86+\r\n\r\n\t.386\r\n\t.MODEL FLAT, stdc"
},
{
"path": "JLM/REBOOT/REBOOT.txt",
"chars": 220,
"preview": "\r\n About ReBoot\r\n\r\n Reboot is just a sample, supposed to be modified if Jemm's default\r\n way to reboot doesn't work o"
},
{
"path": "JLM/XCDROM32/History.txt",
"chars": 1122,
"preview": "\r\n History\r\n\r\n 10/2022: v1.5\r\n - fixed: the driver was unable to handle multiple controllers with\r\n identical cl"
},
{
"path": "JLM/XCDROM32/MAKE.BAT",
"chars": 193,
"preview": "@echo off\r\nrem add -D_DEBUG to create a debug version\r\njwasm -coff -nologo -Fl -I..\\..\\Include XCDROM32.ASM\r\njwlink form"
},
{
"path": "JLM/XCDROM32/MAKEM.BAT",
"chars": 217,
"preview": "@echo off\r\nrem add -D_DEBUG to create a debug version\r\nrem using MS tools\r\nml -c -coff -Fl -I..\\..\\Include XCDROM32.ASM\r"
},
{
"path": "JLM/XCDROM32/XCDROM32.ASM",
"chars": 75810,
"preview": ";\r\n; XCDROM32.ASM - a JLM driver for UltraDMA CD-ROMs/DVDs\r\n; based on XCDROM v1.9 by Jack R. Ellis\r\n; released under "
},
{
"path": "JLM/XCDROM32/XCDROM32.txt",
"chars": 2182,
"preview": "\r\n 1. About XCDROM32\r\n\r\n XCDROM32 is a JLM based on Jack R. Ellis' XCDROM Ultra-DMA CD-ROM driver.\r\n It supports PCI IDE"
},
{
"path": "JLM/XDMA32/History.txt",
"chars": 1179,
"preview": "\r\n 10/2022: v1.5\r\n\r\n - ensure that busmaster flag in PCI command register is set.\r\n - created .data segment with va"
},
{
"path": "JLM/XDMA32/IDENTIFY.INC",
"chars": 13283,
"preview": "\r\n;--- data returned by Identify Device from ATA disks\r\n;--- it's 256 * 16-bit words.\r\n\r\nIDENTIFY_DEVICE_DATA struct \r\ni"
},
{
"path": "JLM/XDMA32/MAKE.BAT",
"chars": 265,
"preview": "@echo off\r\nrem Assemble and link file for the XDMA32 JLM.\r\nrem jwasm: option -zzs is needed for OW WLink v1.8!\r\n\r\njwasm "
},
{
"path": "JLM/XDMA32/MAKEM.BAT",
"chars": 166,
"preview": "@echo off\r\nrem using MS tools\r\nml -c -coff -Fl -D_DEBUG -I..\\..\\Include XDMA32.ASM\r\nlink /NOLOGO /SUBSYSTEM:native /DLL "
},
{
"path": "JLM/XDMA32/XDMA32.ASM",
"chars": 52567,
"preview": ";\r\n; XDMA32.ASM - a JLM driver for UltraDMA hard-disks\r\n; based on XDMA v3.3 by Jack R. Ellis\r\n; released under the GNU"
},
{
"path": "JLM/XDMA32/XDMA32.txt",
"chars": 1924,
"preview": "\r\n 1. About XDMA32\r\n\r\n XDMA32 is a JLM based on Jack R. Ellis' XDMA Ultra-DMA HD driver.\r\n It supports PCI IDE controlle"
},
{
"path": "JemmExL.mak",
"chars": 3251,
"preview": "#\r\n# builds JemmExL, the \"legacy\" variant of JemmEx, without support\r\n# of XMS v3.5 ( super-extended memory )\r\n\r\nNAME3=J"
},
{
"path": "Linux.mak",
"chars": 4178,
"preview": "#\r\n# To build Jemm386 and JemmEx on Linux, you will need:\r\n#\r\n# Tool\r\n#---------------------------\r\n# Assembler: JWasm"
},
{
"path": "Makefile",
"chars": 7094,
"preview": "#\r\n# To build Jemm386 and JemmEx, you will need:\r\n#\r\n# Tool Default (recommended) Alternatives\r\n#----------------"
},
{
"path": "Readme.txt",
"chars": 32804,
"preview": "\r\n Contents\r\n\r\n 1. About Jemm\r\n 2. Features\r\n 3. Commandline Options\r\n 4. Technical Details\r\n 4.1 EMS Impl"
},
{
"path": "Test/BMINTRM.ASM",
"chars": 1212,
"preview": "\r\n;--- benchmark\r\n;*** call int 69h a number of times and count timer ticks\r\n;--- jwasm -mz bmintrm.asm\r\n\r\n\t.286\r\n\t.MODE"
},
{
"path": "Test/EMS4E.ASM",
"chars": 1655,
"preview": "\r\n;*** test EMS get/set page map \r\n\r\n\t.286\r\n\t.model small\r\n\toption casemap:none\r\n\t.stack 1024\r\n\t.dosseg\r\n\t.386\r\n\r\nCStr m"
},
{
"path": "Test/EMS4F.ASM",
"chars": 2303,
"preview": "\r\n;*** test EMS get/set partial page map \r\n\r\n\t.286\r\n\t.model small\r\n\toption casemap:none\r\n\t.stack 1024\r\n\t.dosseg\r\n\r\nCStr "
},
{
"path": "Test/EMS56.ASM",
"chars": 3628,
"preview": "\r\n;*** test int 67h, ah=56h (alter map and call)\r\n\r\n\t.286\r\n\t.model small\r\n\t.stack 2048\r\n\t.dosseg\r\n\toption casemap:none\r\n"
},
{
"path": "Test/EMS57.ASM",
"chars": 2829,
"preview": "\r\n;*** EMS move\r\n\r\n\t.286\r\n\t.model tiny\r\n\toption casemap:none\r\n\toption casemap:none\r\n\t.stack 1024\r\n\t.dosseg\r\n\r\nCStr macro"
},
{
"path": "Test/EMS57A.ASM",
"chars": 4351,
"preview": "\r\n;*** test EMS move (int 67h, ah=57h)\r\n;*** move 1024 kB conv to EMS memory\r\n;*** move 1024 kB EMS to EMS memory non-ov"
},
{
"path": "Test/EMS5B.ASM",
"chars": 1938,
"preview": "\r\n;*** test EMS 5B\r\n;--- 5b00: get alternate map register set ( if BL=0 on ret, es:di will be current pointer to context"
},
{
"path": "Test/EXC00.ASM",
"chars": 166,
"preview": "\r\n;*** EXC 00\r\n\r\n\t.286\r\n\t.model small\r\n\t.stack 2048\r\n\t.dosseg\r\n\t.386\r\n\r\n\t.code\r\n\r\nstart:\r\n\tmov dx, -1\r\n\tmov cx, 8000h\r\n\t"
},
{
"path": "Test/EXC06.ASM",
"chars": 155,
"preview": "\r\n;*** EXC 06 - requires a P6+ cpu\r\n\r\n\t.286\r\n\t.model small\r\n\t.stack 2048\r\n\t.dosseg\r\n\t.686\r\n\r\n\t.code\r\n\r\nstart:\r\n\tud2\r\n\tmo"
},
{
"path": "Test/FRAMERES.ASM",
"chars": 520,
"preview": "\r\n;--- create binary:\r\n;--- jwasm -bin -Fo frameres.com frameres.asm\r\n\r\n\t.286\r\n\t.MODEL tiny\r\n\r\n\t.CODE\r\n\r\n\torg 100h\r\n\r\nst"
},
{
"path": "Test/HLTTEST.ASM",
"chars": 1032,
"preview": "\r\n;*** HLT test (v86)\r\n\r\n\t.286\r\n\t.model tiny\r\n\t.stack 2048\r\n\t.dosseg\r\n\t.386\r\n\r\n\tinclude macros.inc\r\n\r\n\t.data\r\n\r\ndwOldInt"
},
{
"path": "Test/HLTTEST2.ASM",
"chars": 1033,
"preview": "\r\n;*** HLT test (v86) with IF=0\r\n\r\n\t.286\r\n\t.model tiny\r\n\t.stack 2048\r\n\t.dosseg\r\n\t.386\r\n\r\n\tinclude macros.inc\r\n\r\n\t.data\r\n"
},
{
"path": "Test/I15MOVE.ASM",
"chars": 2886,
"preview": "\r\n;*** move block by int 15h, ah=87h\r\n\r\n\t.286\r\n\t.model tiny\r\n\t.stack 2048\r\n\t.dosseg\r\n\t.386\r\n\r\nlf equ 10\r\n\r\nCStr macro te"
},
{
"path": "Test/INT67.ASM",
"chars": 484,
"preview": "\r\n;--- the EMS handler runs slightly differently if IVT vector 67h is hooked!\r\n\r\n\t.286\r\n\t.model tiny\r\n\t.stack 256\r\n\r\n\t.c"
},
{
"path": "Test/INT88.ASM",
"chars": 932,
"preview": "\r\n;--- test int# >= 0x80;\r\n;--- the monitor program uses the \"PUSH byte const\" instruction\r\n;--- to push a sign-extended"
},
{
"path": "Test/MACROS.INC",
"chars": 98,
"preview": "\r\nCStr macro text:VARARG\r\nlocal sym\r\n\t.const\r\nsym db text,0\r\n\t.code\r\n\texitm <offset sym>\r\nendm\r\n\r\n"
},
{
"path": "Test/MAKE.BAT",
"chars": 115,
"preview": "@echo off\r\nrem the programs may all be created without link step,\r\nrem using jwasm's -mz option\r\njwasm -mz %1.asm\r\n"
},
{
"path": "Test/PRINTF.INC",
"chars": 3057,
"preview": "\r\n;--- simple printf() implementation\r\n;--- assume ds=dgroup\r\n\r\nhandle_char proc\r\n\r\n\tmov dl,al\r\n\tcmp al,10\r\n\tjnz @F\r\n\tmo"
},
{
"path": "Test/README.TXT",
"chars": 1278,
"preview": "\r\nbmintrm: benchmark int 69h real-mode\r\nems4e: get/set page map\r\nems4f: get/set partial page map\r\nems56: "
},
{
"path": "Test/TEST0C.DEB",
"chars": 62,
"preview": "; test v86 exc 0C\r\na\r\nmov sp,ffff\r\npop ax\r\nint 3\r\n\r\ng=100\r\nq\r\n"
},
{
"path": "Test/TEST0C1.DEB",
"chars": 60,
"preview": "; test v86 exc 0C\r\na\r\nmov sp,1\r\npush ax\r\nint 3\r\n\r\ng=100\r\nq\r\n"
},
{
"path": "Test/TEST0D.DEB",
"chars": 56,
"preview": "; test v86 exc 0D\r\na\r\nmov ax,[ffff]\r\nint 3\r\n\r\ng=100\r\nq\r\n"
},
{
"path": "Test/TEST10.DEB",
"chars": 291,
"preview": "; test v86 exc 10\r\n; set CR0 NE bit\r\n; enable exceptions in FP control word\r\n; the do an FP pop\r\n; the exception occurs "
},
{
"path": "Test/TEST11.DEB",
"chars": 228,
"preview": "; test v86 exc 11\r\n; set CR0 AM bit\r\n; set EFL AC bit\r\n; then access stack unaligned\r\na\r\nmov eax,cr0\r\nor eax,40000\r\nmov "
},
{
"path": "Test/TESTDMA.ASM",
"chars": 1433,
"preview": "\r\n;--- test FD read in UMB\r\n;--- using Int 25h\r\n\r\n\t.286\r\n\t.model small\r\n\t.stack 2048\r\n\t.dosseg\r\n\t.386\r\n\r\nCStr macro text"
},
{
"path": "Test/TESTDMA2.ASM",
"chars": 1991,
"preview": "\r\n;--- test FD read in UMB\r\n;--- using Int 13h\r\n\r\n\t.286\r\n\t.model small\r\n\t.stack 2048\r\n\t.dosseg\r\n\t.386\r\n\r\n?SIZE equ 1000h"
},
{
"path": "Test/TESTDMA3.ASM",
"chars": 3194,
"preview": "\r\n;--- test FD read in UMB\r\n;--- using Int 13h\r\n;--- this variant ensures that a 64kb border is crossed,\r\n;--- forcing t"
},
{
"path": "Test/TESTVCPI.ASM",
"chars": 11250,
"preview": "\r\n;--- the purpose of the test is to see if page table 0, returned by int 67h, ax=DE01h\r\n;--- is updated by the VCPI hos"
},
{
"path": "Test/TESTVDS.ASM",
"chars": 13634,
"preview": "\r\n;--- VDS API test\r\n;--- 8103/8104: lock/unlock region\r\n;--- 8107/8108/8109/810A: request/release DMA buffer, copy"
},
{
"path": "Test/TESTVDS2.ASM",
"chars": 1609,
"preview": "\r\n;--- VDS API test; test disable/enable auto DMA translation (810B/810C)\r\n\r\n\t.286\r\n\t.model small\r\n\t.stack 2048\r\n\t.dosse"
},
{
"path": "Test/TESTVDS3.ASM",
"chars": 1309,
"preview": "\r\n;--- VDS API test; display ISA DMA translation status for channels 0-7\r\n\r\n\t.286\r\n\t.model small\r\n\t.stack 2048\r\n\t.dosseg"
},
{
"path": "Test/TIMERMS.INC",
"chars": 1456,
"preview": "\r\n;--- gettimer() returns timer in EAX in ms\r\n\r\n_GetTimerValue proc\r\n\tpush ds\r\n\tpush 0\r\n\tpop ds\r\ntryagain:\r\n\tmov edx,ds:"
},
{
"path": "Test/VCPI.INC",
"chars": 976,
"preview": "\r\ndesc struct\r\nlimit dw ?\r\nA0015 dw ?\r\nA1623 db ?\r\nattrib db ?\r\nlim_gr db ?\r\nA2431 db ?\r\ndesc ends\r\n\r\n;--- VCP"
},
{
"path": "Test/XMSTEST.ASM",
"chars": 4300,
"preview": "\r\n;--- XMSTEST: test xms memory moves\r\n;--- Public Domain.\r\n;--- to be assembled with JWasm or Masm v6.\r\n\r\n\t.model tiny\r"
},
{
"path": "Test/XMSTEST2.ASM",
"chars": 3393,
"preview": "\r\n;--- XMSTEST2: test max block allocation\r\n;--- Public Domain.\r\n;--- to be assembled with JWasm or Masm v6.\r\n\r\n\t.model "
},
{
"path": "Test/XMSTEST3.ASM",
"chars": 2214,
"preview": "\r\n;--- test ah=0Eh (get handle info)\r\n;--- Public Domain.\r\n;--- to be assembled with JWasm or Masm v6.\r\n\r\n\t.model tiny\r\n"
},
{
"path": "Test/XMSTEST4.ASM",
"chars": 2619,
"preview": "\r\n;--- XMSTEST4: test block resize (shrink)\r\n;--- Public Domain.\r\n;--- to be assembled with JWasm or Masm v6.\r\n\r\n\t.model"
},
{
"path": "Test/XMSTEST5.ASM",
"chars": 3111,
"preview": "\r\n;--- XMSTEST5: test block resize (shrink)\r\n;--- this variant allocates a 64MB block with xms v3,\r\n;--- but tries to re"
},
{
"path": "Tools/CLEAR.BAT",
"chars": 407,
"preview": "@echo off\r\nerase CPUID\\*.EXE\r\nerase CPUID\\*.lst\r\nerase CpuStat\\*.EXE\r\nerase CpuStat\\*.lst\r\nerase EMSSTAT\\*.EXE\r\nerase EM"
},
{
"path": "Tools/CPUID/CPUID.ASM",
"chars": 8210,
"preview": "\r\n;--- CPUID displays status of CPU. \r\n;--- Public Domain.\r\n;--- Masm syntax. To be assembled with JWasm or Masm.\r\n;--- "
},
{
"path": "Tools/CPUID/MAKE.BAT",
"chars": 85,
"preview": "@echo off\r\nrem creates CPUID.EXE with JWasm\r\njwasm -c -nologo -Fl -Sg -mz CPUID.ASM\r\n"
},
{
"path": "Tools/CPUID/PRINTF.INC",
"chars": 2881,
"preview": "\r\n;--- simple printf() implementation\r\n\r\nhandle_char proc\r\n\r\n\tmov dl,al\r\n\tcmp al,10\r\n\tjnz @F\r\n\tmov dl,13\r\n\tcall @F\r\n\tmov"
},
{
"path": "Tools/Cpustat/CPUSTAT.ASM",
"chars": 18364,
"preview": "\r\n;--- CPUSTAT displays status of CPU. \r\n;--- Public Domain.\r\n;--- Masm syntax. To be assembled with JWasm or Masm.\r\n;--"
},
{
"path": "Tools/Cpustat/MAKE.BAT",
"chars": 89,
"preview": "@echo off\r\nrem creates CPUSTAT.EXE with JWasm\r\njwasm -c -nologo -Fl -Sg -mz CPUSTAT.ASM\r\n"
},
{
"path": "Tools/Cpustat/PRINTF.INC",
"chars": 2881,
"preview": "\r\n;--- simple printf() implementation\r\n\r\nhandle_char proc\r\n\r\n\tmov dl,al\r\n\tcmp al,10\r\n\tjnz @F\r\n\tmov dl,13\r\n\tcall @F\r\n\tmov"
},
{
"path": "Tools/EMSSTAT/EMSSTAT.ASM",
"chars": 12251,
"preview": "\r\n;--- EMSSTAT: display EMS status.\r\n;--- Public Domain.\r\n;--- tools: JWasm/Masm v6 and WLink.\r\n\r\n\t.286\r\n\t.model small\r\n"
},
{
"path": "Tools/EMSSTAT/MAKE.BAT",
"chars": 81,
"preview": "@echo off\r\nrem creates EMSSTAT.EXE with JWasm\r\njwasm -c -nologo -mz EMSSTAT.ASM\r\n"
},
{
"path": "Tools/EMSSTAT/PRINTF.INC",
"chars": 2881,
"preview": "\r\n;--- simple printf() implementation\r\n\r\nhandle_char proc\r\n\r\n\tmov dl,al\r\n\tcmp al,10\r\n\tjnz @F\r\n\tmov dl,13\r\n\tcall @F\r\n\tmov"
},
{
"path": "Tools/JEMFBHLP/JEMFBHLP.ASM",
"chars": 2752,
"preview": "\r\n;*** save some interrupt vectors the way MS-DOS does\r\n;*** needed for FreeDOS if Jemm386's FASTBOOT option is used\r\n\r\n"
},
{
"path": "Tools/JEMFBHLP/MAKE.BAT",
"chars": 86,
"preview": "@echo off\r\nrem create JEMFBHLP.EXE with JWasm\r\njwasm -c -nologo -mz -Fl JEMFBHLP.ASM\r\n"
},
{
"path": "Tools/JLOAD/DEBUG.INC",
"chars": 986,
"preview": "\r\n;*** debug macros and equates\r\n\r\n?USEMONO equ 0\t;1=use monochrome video mode\r\n\r\nifndef ?RMDBG\r\n?RMDBG = 0\t;log real-"
},
{
"path": "Tools/JLOAD/DPRINTF.INC",
"chars": 3340,
"preview": "\r\n;--- printf for debug displays, 32-bit\r\n\r\n;--- i64toa(long long n, char * s, int base);\r\n;--- convert 64-bit long long"
},
{
"path": "Tools/JLOAD/DPRNTF16.INC",
"chars": 3304,
"preview": "\r\n;--- printf for debug displays, 16-bit\r\n\r\n;--- itoa(long n, char * s, int base);\r\n;--- convert 32-bit long to string\r\n"
},
{
"path": "Tools/JLOAD/History.txt",
"chars": 2076,
"preview": "\r\n v5.87:\r\n - Linux.mak added to create JLOAD.EXE on Linux.\r\n\r\n v5.86:\r\n - Jemm's control notifications handled (DEV"
},
{
"path": "Tools/JLOAD/JLOAD.ASM",
"chars": 24666,
"preview": "\r\n;--- 16-bit part of JLoad\r\n;--- JLoad loads a 32bit PE binary in Jemm's address space\r\n;--- best viewed with TABSIZE 4"
},
{
"path": "Tools/JLOAD/JLOAD.INC",
"chars": 694,
"preview": "\r\n;--- assembly conditionals\r\n\r\n;--- constants\r\n;--- ?SYSBASE is from JSYSTEM.INC (=0F8000000h)\r\n\r\n?SYSTEMADDR\t\tequ ?SYS"
},
{
"path": "Tools/JLOAD/JLOAD.TXT",
"chars": 4267,
"preview": "\r\n 1. About JLoad and JLMs\r\n\r\n JLoad is an extension for Jemm (both Jemm386 and JemmEx) which allows to\r\n load 32bit fl"
},
{
"path": "Tools/JLOAD/JLOAD.txt",
"chars": 4267,
"preview": "\r\n 1. About JLoad and JLMs\r\n\r\n JLoad is an extension for Jemm (both Jemm386 and JemmEx) which allows to\r\n load 32bit fl"
},
{
"path": "Tools/JLOAD/JLOAD32.ASM",
"chars": 11034,
"preview": "\r\n;--- JLoad's PE file loader\r\n;--- this code is copied to linear address ?SYSTEMADDR when\r\n;--- JLoad is running for th"
},
{
"path": "Tools/JLOAD/JLOAD32.INC",
"chars": 753,
"preview": "\r\n;--- macros\r\n\r\nCStr macro text:vararg\r\nlocal sym\r\n\t.const\r\n ifidni <text>,<\"\">\r\nsym db 0\r\n else\r\nsym db text,0\r\n endif"
},
{
"path": "Tools/JLOAD/Linux.mak",
"chars": 1939,
"preview": "\r\n# makefile that creates JLOAD.EXE\r\n# tools used:\r\n#------------------------\r\n# Assembler: jwasm\r\n# OMF linker: jw"
},
{
"path": "Tools/JLOAD/MAKEFILE",
"chars": 2340,
"preview": "\r\n# nmake makefile that creates JLOAD.EXE\r\n# tools used:\r\n# default alternate\r\n#---------------------"
},
{
"path": "Tools/JLOAD/VDMAD.ASM",
"chars": 5224,
"preview": "\r\n;--- VDMAD support\r\n;--- best viewed with TAB size 4\r\n\r\n\t.386\r\n\t.model flat\r\n\r\n\toption casemap:none\r\n\toption proc:priv"
},
{
"path": "Tools/JLOAD/VIOOUT.INC",
"chars": 1537,
"preview": "\r\n;--- low-level video access\r\n;--- no assumption about ds,es.\r\n;--- ss is supposed to be flat.\r\n\r\nVPUTCHR PROC\r\n\tpush d"
},
{
"path": "Tools/JLOAD/VMM.ASM",
"chars": 38586,
"preview": "\r\n;--- VMM functions\r\n;--- best viewed with TAB size 4\r\n\r\n\t.386\r\n\t.model flat\r\n\r\n\toption casemap:none\r\n\toption proc:priv"
},
{
"path": "Tools/JLOAD/WINNT.INC",
"chars": 19655,
"preview": "\r\nifndef WINNT_INCLUDED\r\n\r\n\tpushcontext listing\r\n\t.nolist\r\n\t.xcref\r\n\r\nifdef @list_on\r\n\t.list\r\n\t.cref\r\nendif\r\n\r\nWINNT_INC"
},
{
"path": "Tools/JLOAD/license.txt",
"chars": 1069,
"preview": "\nCopyright (c) 2021 Andreas Grech (japheth)\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
},
{
"path": "Tools/MAKE.BAT",
"chars": 307,
"preview": "@echo off\r\ncd CPUID\r\ncall MAKE\r\ncd ..\r\ncd CpuStat\r\ncall MAKE\r\ncd ..\r\ncd EMSSTAT\r\ncall MAKE\r\ncd ..\r\ncd JEMFBHLP\r\ncall MAK"
},
{
"path": "Tools/MEMSTAT/MAKE.BAT",
"chars": 85,
"preview": "@echo off\r\nrem creates MEMSTAT.EXE with JWasm\r\njwasm -c -nologo -mz -Fl MEMSTAT.ASM\r\n"
},
{
"path": "Tools/MEMSTAT/MEMSTAT.ASM",
"chars": 6379,
"preview": "\r\n;*** get extended memory status using int 15h\r\n;*** AH=88h\r\n;*** AH=C7h if supported\r\n;*** AX=E801h\r\n;*** AX=E820h\r\n\r\n"
},
{
"path": "Tools/MEMSTAT/PRINTF.INC",
"chars": 2881,
"preview": "\r\n;--- simple printf() implementation\r\n\r\nhandle_char proc\r\n\r\n\tmov dl,al\r\n\tcmp al,10\r\n\tjnz @F\r\n\tmov dl,13\r\n\tcall @F\r\n\tmov"
},
{
"path": "Tools/MoveXBDA/MAKE.BAT",
"chars": 83,
"preview": "@echo off\r\nrem create MOVEXBDA.EXE with JWasm\r\njwasm -nologo -mz -Fl MOVEXBDA.ASM\r\n"
},
{
"path": "Tools/MoveXBDA/MOVEXBDA.ASM",
"chars": 4840,
"preview": "\r\n;--- MOVEXBDA moves XBDA to low memory. If the XBDA is already moved\r\n;--- or if it is too large, nothing is done.\r\n;-"
},
{
"path": "Tools/UMBM/MAKE.BAT",
"chars": 86,
"preview": "@echo off\r\nrem BAT to create UMBM.EXE with JWasm\r\njwasm -mz -nologo -Fl -Sg UMBM.ASM\r\n"
},
{
"path": "Tools/UMBM/UMBM.ASM",
"chars": 12954,
"preview": "\r\n;*** UMBM is a DOS device driver, but will not install permanently:\r\n;*** if UMBs activated by UMBPCI are found, U"
},
{
"path": "Tools/VCPI/MAKE.BAT",
"chars": 80,
"preview": "@echo off\r\nrem creates VCPI.EXE with JWasm\r\njwasm -mz -nologo -Fl -Sg VCPI.ASM\r\n"
},
{
"path": "Tools/VCPI/PRINTF.INC",
"chars": 2809,
"preview": "\r\n;--- ltob(long n, char * s, int base);\r\n;--- convert long to string\r\n\r\nltob PROC stdcall uses edi edx number:dword, ou"
},
{
"path": "Tools/VCPI/VCPI.ASM",
"chars": 18526,
"preview": "\r\n;*** display VCPI information\r\n;*** and use VCPI to switch to protected mode and back\r\n\r\n;--- if segments are defined "
},
{
"path": "Tools/VCPI/VCPI.INC",
"chars": 976,
"preview": "\r\ndesc struct\r\nlimit dw ?\r\nA0015 dw ?\r\nA1623 db ?\r\nattrib db ?\r\nlim_gr db ?\r\nA2431 db ?\r\ndesc ends\r\n\r\n;--- VCP"
},
{
"path": "Tools/VCPI/VIOOUT.INC",
"chars": 1970,
"preview": "\r\n;--- vio output for 16-bit protected-mode\r\n\r\n@getcursorpos macro\r\n\tmovzx ebx, byte ptr ds:[462h];page\r\n\tmov bx, ds:[EB"
},
{
"path": "Tools/XMSSTAT/MAKE.BAT",
"chars": 84,
"preview": "@echo off\r\nrem create XMSSTAT.EXE\r\nrem uses JWasm\r\njwasm -nologo -mz XMSSTAT.ASM\r\n"
},
{
"path": "Tools/XMSSTAT/PRINTF.INC",
"chars": 2881,
"preview": "\r\n;--- simple printf() implementation\r\n\r\nhandle_char proc\r\n\r\n\tmov dl,al\r\n\tcmp al,10\r\n\tjnz @F\r\n\tmov dl,13\r\n\tcall @F\r\n\tmov"
},
{
"path": "Tools/XMSSTAT/XMSSTAT.ASM",
"chars": 9687,
"preview": "\r\n;--- XMSSTAT: display xms status.\r\n;--- Public Domain.\r\n;--- to be assembled with JWasm or Masm v6.\r\n\r\n\t.model small\r\n"
},
{
"path": "XMS35.txt",
"chars": 3033,
"preview": "\r\n 1. XMS v3.5 API\r\n \r\n XMS v3.5 has been created to allow accessing extended memory beyond the 4 GB\r\n barrier. \r\n\r"
},
{
"path": "src/AUXIO.INC",
"chars": 1560,
"preview": "\r\n;--- handle AUX I/O\r\n\r\nifndef COMNO\r\nCOMNO equ 1\r\nendif\r\n_XONXOFF_ equ 1\r\nXON equ 11h\r\nXOFF equ"
},
{
"path": "src/DEBUG.ASM",
"chars": 3485,
"preview": "\r\n;*** implements debug displays\r\n;--- written by japheth\r\n;--- public domain\r\n;--- to be assembled with JWasm or Masm v"
},
{
"path": "src/DEBUG16.INC",
"chars": 669,
"preview": "\r\n@dbgdef macro name_\r\nifndef name_\r\nname_ equ 0\r\nendif\r\n?DBGOUT = ?DBGOUT + name_\r\nendm\r\n\r\n?DBGOUT = 0\r\n@dbgdef ?INITRM"
},
{
"path": "src/DEBUG32.INC",
"chars": 2632,
"preview": "\r\n@dbgdef macro name_\r\nifndef name_\r\nname_ equ 0\r\nendif\r\n?DBGOUT = ?DBGOUT + name_\r\nendm\r\n\r\n?DBGOUT = 0\r\n@dbgdef ?V86DBG"
},
{
"path": "src/DEBUGSYS.INC",
"chars": 11929,
"preview": "\r\n;\r\n; Real mode Debugger services:\r\n;\r\n\r\nD386_RM_Int\t\tequ 68h\t; hooked by the debugger in real mode.\r\n\r\nD386_Id\t\t\tequ "
},
{
"path": "src/DEV.ASM",
"chars": 7785,
"preview": "\r\n;*** implements EMMXXXX0 device\r\n;--- public domain\r\n;--- to be assembled with JWasm or Masm v6.1+\r\n\r\n .386\r\n .m"
},
{
"path": "src/DMA.INC",
"chars": 1300,
"preview": "\n;--- ports ISA DMA controller\n\nDMA_STATUS_CMD equ 8\t; R status / W command\nDMA_REQUEST equ 9\t; W b0+1: chann"
},
{
"path": "src/DPRINTF.INC",
"chars": 3501,
"preview": "\r\n;--- printf for debug displays\r\n;--- assume CS and SS flat;\r\n;--- no assumptions about DS/ES\r\n\r\n;--- i64toa(long long "
},
{
"path": "src/DPRNTF16.INC",
"chars": 3361,
"preview": "\r\n;--- printf for debug displays, 16-bit\r\n\r\n;--- itoa(long n, char * s, int base);\r\n;--- convert 32-bit long to string\r\n"
},
{
"path": "src/EMS.ASM",
"chars": 47673,
"preview": "\r\n;--- EMS implementation\r\n;--- EMS 4.0 is Public Domain, originally written by Michael Devore,\r\n;--- extended and modif"
},
{
"path": "src/EMS.INC",
"chars": 1582,
"preview": "\r\n;--- EMS status codes\r\n\r\nEMSS_OK equ 00h\r\nEMSS_SOFTWARE_ERR equ 80h ;unexpected error\r\nEMSS_HARD"
},
{
"path": "src/EMS32.INC",
"chars": 13460,
"preview": "\r\n;--- this is the Jemm EMS 3.2 implementation (functions 40h - 4Eh)\r\n;--- since this part is copyright Harald Albrecht/"
},
{
"path": "src/EMU.ASM",
"chars": 2355,
"preview": "\r\n;--- privileged opcode emulation\r\n;--- copyright Tom Ehlert\r\n\r\n;--- to be assembled with JWasm or Masm v6.1+\r\n\r\n .3"
},
{
"path": "src/EXTERN32.INC",
"chars": 4401,
"preview": "\r\n;--- publics for Jemm32\r\n\r\n@seg macro name_, align_\r\nname_ SEGMENT align_ FLAT public 'CODE'\r\nendm\r\n\r\n;--- sections:\r\n"
},
{
"path": "src/I15.ASM",
"chars": 4458,
"preview": "\r\n;--- I15, ah=87 extended memory move \r\n;--- Public Domain\r\n;--- to be assembled with JWasm or Masm v6.1+\r\n\r\n .386\r\n"
},
{
"path": "src/INIT.ASM",
"chars": 37283,
"preview": "\r\n;--- Jemm's initialization part\r\n;--- Public Domain\r\n;--- to be assembled with JWasm or Masm v6.1+\r\n\r\n .386\r\n .m"
},
{
"path": "src/INIT16.ASM",
"chars": 67631,
"preview": "\r\n;--- 16-bit initialization part\r\n;--- to be assembled with JWasm or Masm v6.1+\r\n\r\n\t.model tiny\r\n\t.386\r\n\r\nCStr macro te"
},
{
"path": "src/JEMM.INC",
"chars": 7470,
"preview": "\r\n;--- common definitions for both Jemm32 and Jemm16\r\n\r\n\toption proc:private\r\n\toption casemap:none\r\n\r\nLF EQ"
},
{
"path": "src/JEMM16.ASM",
"chars": 30784,
"preview": "\r\n;--- 16 bit part of Jemm;\r\n;--- to be assembled with JWasm or Masm v6.1+\r\n\r\n;--- _RTEXT must be first segment; it has "
},
{
"path": "src/JEMM16.INC",
"chars": 1660,
"preview": "\r\n;--- globals for jemm16.asm and init16.asm\r\n\r\nif ?INTEGRATED\r\nNAMEEXE equ <\"JEMMEX\">\r\nNAMEMOD equ <\"JemmEx\">\r\nelse\r\nNA"
},
{
"path": "src/JEMM32.ASM",
"chars": 73242,
"preview": ";*****************************************************************************\r\n;** This is the main 32bit ASM part of J"
},
{
"path": "src/JEMM32.INC",
"chars": 8275,
"preview": "\r\n;--- these files contains things for 32-bit ONLY\r\n\r\n?RING0EXC EQU 1 ; 1=display more infos on exc in ring "
},
{
"path": "src/POOL.ASM",
"chars": 41006,
"preview": "\r\n;--- Jemm's memory pool implementation\r\n;--- originally written by Michael Devore\r\n;--- Public Domain\r\n;--- to be asse"
},
{
"path": "src/UMB.ASM",
"chars": 8733,
"preview": "\r\n;--- XMS UMB part implementation\r\n;--- Public Domain\r\n;--- to be assembled with JWasm or Masm v6.1+\r\n\r\n .386\r\n ."
},
{
"path": "src/VCPI.ASM",
"chars": 16528,
"preview": "\r\n;--- VCPI implementation\r\n;--- Public Domain\r\n;--- to be assembled with JWasm or Masm v6.1+\r\n;--- originally written b"
},
{
"path": "src/VCPI.INC",
"chars": 390,
"preview": "\r\n; structure for VCPI switch from V86 to protected mode\r\n\r\nV86TOPM STRUCT\r\ndwCR3 DD ? ; client's CR3 value\r\nd"
},
{
"path": "src/VDMA.ASM",
"chars": 18659,
"preview": "\r\n;--- DMA port trapping code\r\n;--- originally written by Harald Albrecht\r\n;--- modified for Jemm by Japheth\r\n;--- copyr"
},
{
"path": "src/VDS.ASM",
"chars": 26469,
"preview": "\r\n;--- Jemm's VDS implementation\r\n;--- Public Domain\r\n;--- to be assembled with JWasm or Masm v6.1+\r\n\r\n .386\r\n .mo"
},
{
"path": "src/XMS.ASM",
"chars": 37985,
"preview": "\r\n;--- XMS/A20 implementation\r\n;--- Public Domain\r\n;--- to be assembled with JWasm or Masm v6.1+\r\n\r\n .386\r\n .model"
},
{
"path": "src/XMS.INC",
"chars": 2483,
"preview": "\r\n;--- XMS definitions\r\n\r\nXMS_GETVERSION equ 0h\r\nXMS_ENABLEA20 equ 5h\r\nXMS_DISABLEA20 equ 6h\r\nXMS_V2_QUERYMEM "
}
]
About this extraction
This page contains the full source code of the Baron-von-Riedesel/Jemm GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 197 files (1.2 MB), approximately 431.9k tokens, and a symbol index with 18 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.