├── Tools ├── UMBM │ ├── UMBM.ASM │ └── MAKE.BAT ├── VCPI │ ├── MAKE.BAT │ ├── VCPI.INC │ ├── VIOOUT.INC │ └── PRINTF.INC ├── CPUID │ ├── MAKE.BAT │ └── PRINTF.INC ├── EMSSTAT │ ├── MAKE.BAT │ └── PRINTF.INC ├── MoveXBDA │ └── MAKE.BAT ├── Cpustat │ ├── MAKE.BAT │ └── PRINTF.INC ├── JEMFBHLP │ ├── MAKE.BAT │ └── JEMFBHLP.ASM ├── MEMSTAT │ ├── MAKE.BAT │ └── PRINTF.INC ├── XMSSTAT │ ├── MAKE.BAT │ └── PRINTF.INC ├── MAKE.BAT ├── CLEAR.BAT └── JLOAD │ ├── JLOAD.INC │ ├── JLOAD32.INC │ ├── license.txt │ ├── DEBUG.INC │ ├── VIOOUT.INC │ ├── History.txt │ ├── MAKEFILE │ ├── DPRINTF.INC │ └── DPRNTF16.INC ├── JLM ├── KEYBGR │ ├── KEYBGR.ASM │ ├── MAKE.BAT │ ├── README.TXT │ └── MAKEFILE ├── JLSTUB │ ├── Build │ │ └── jlstub.bin │ ├── Make.BAT │ └── JLStub.txt ├── HELLO2 │ ├── MAKEJLMW.BAT │ ├── MAKEVC.BAT │ ├── MAKEOW.BAT │ ├── README.TXT │ ├── JLMW.h │ ├── HELLO2W.C │ ├── JLMW.ASM │ └── HELLO2.C ├── AHCICD │ ├── MAKEM.BAT │ ├── MAKE.BAT │ └── AHCICD.txt ├── JCLOCK │ ├── MAKE.BAT │ └── README.TXT ├── XDMA32 │ ├── MAKEM.BAT │ ├── MAKE.BAT │ ├── History.txt │ └── XDMA32.txt ├── REBOOT │ ├── MAKE.BAT │ ├── REBOOT.txt │ ├── FASTBOOT.txt │ ├── REBOOT.ASM │ ├── FBOOT.ASM │ └── LDI13EXT.ASM ├── XCDROM32 │ ├── MAKE.BAT │ ├── MAKEM.BAT │ ├── History.txt │ └── XCDROM32.txt ├── HELLO │ ├── README.TXT │ ├── MAKE.BAT │ └── HELLO.ASM ├── QPIEMU │ ├── Test │ │ ├── MAKEFILE │ │ ├── SETARGV.INC │ │ └── PRINTF16.INC │ ├── MAKE.BAT │ ├── MAKEFILE │ └── QPIEMU.txt ├── GENERIC │ ├── TESTGEN.ASM │ ├── MAKEFILE │ ├── README.TXT │ └── GENERIC.ASM ├── IOTRAP │ ├── README.TXT │ ├── MAKEFILE │ └── TESTIOT.ASM └── README.TXT ├── Test ├── TEST0D.DEB ├── TEST0C1.DEB ├── TEST0C.DEB ├── MAKE.BAT ├── MACROS.INC ├── TEST11.DEB ├── TEST10.DEB ├── FRAMERES.ASM ├── README.TXT ├── VCPI.INC ├── BMINTRM.ASM ├── HLTTEST.ASM ├── HLTTEST2.ASM ├── TESTVDS3.ASM ├── TESTDMA.ASM ├── TESTVDS2.ASM ├── EMS4E.ASM ├── EMS5B.ASM ├── TESTDMA2.ASM ├── XMSTEST3.ASM ├── I15MOVE.ASM ├── EMS4F.ASM ├── XMSTEST4.ASM ├── EMS57.ASM ├── XMSTEST5.ASM ├── PRINTF.INC ├── TESTDMA3.ASM ├── XMSTEST2.ASM └── EMS56.ASM ├── src ├── VCPI.INC ├── DEBUG16.INC ├── DMA.INC ├── JEMM16.INC ├── EMS.INC ├── AUXIO.INC ├── VDS.INC ├── XMS.INC ├── DEBUG.INC ├── EMU.ASM ├── X86.INC ├── DEBUG.ASM ├── DPRINTF.INC └── DPRNTF16.INC ├── Include ├── FILEACC.INC └── PRINTF.INC ├── XMS35.txt └── JemmExL.mak /Tools/UMBM/UMBM.ASM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baron-von-Riedesel/Jemm/HEAD/Tools/UMBM/UMBM.ASM -------------------------------------------------------------------------------- /JLM/KEYBGR/KEYBGR.ASM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baron-von-Riedesel/Jemm/HEAD/JLM/KEYBGR/KEYBGR.ASM -------------------------------------------------------------------------------- /Test/TEST0D.DEB: -------------------------------------------------------------------------------- 1 | ; test v86 exc 0D 2 | a 3 | mov ax,[ffff] 4 | int 3 5 | 6 | g=100 7 | q 8 | -------------------------------------------------------------------------------- /Test/TEST0C1.DEB: -------------------------------------------------------------------------------- 1 | ; test v86 exc 0C 2 | a 3 | mov sp,1 4 | push ax 5 | 6 | int 3 7 | g=100 8 | q 9 | -------------------------------------------------------------------------------- /JLM/JLSTUB/Build/jlstub.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baron-von-Riedesel/Jemm/HEAD/JLM/JLSTUB/Build/jlstub.bin -------------------------------------------------------------------------------- /Test/TEST0C.DEB: -------------------------------------------------------------------------------- 1 | ; test v86 exc 0C 2 | a 3 | mov sp,ffff 4 | pop ax 5 | 6 | int 3 7 | g=100 8 | q 9 | -------------------------------------------------------------------------------- /Tools/VCPI/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem creates VCPI.EXE with JWasm 3 | jwasm -mz -nologo -Fl -Sg VCPI.asm 4 | -------------------------------------------------------------------------------- /Tools/CPUID/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem creates CPUID.EXE with JWasm 3 | jwasm -c -nologo -Fl -Sg -mz CPUID.asm 4 | -------------------------------------------------------------------------------- /Tools/EMSSTAT/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem creates EMSSTAT.EXE with JWasm 3 | jwasm -c -nologo -mz EMSSTAT.ASM 4 | -------------------------------------------------------------------------------- /Tools/MoveXBDA/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem create MOVEXBDA.EXE with JWasm 3 | jwasm -nologo -mz -Fl MOVEXBDA.ASM 4 | -------------------------------------------------------------------------------- /Tools/UMBM/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem BAT to create UMBM.EXE with JWasm 3 | jwasm -mz -nologo -Fl -Sg UMBM.ASM 4 | -------------------------------------------------------------------------------- /Tools/Cpustat/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem creates CPUSTAT.EXE with JWasm 3 | jwasm -c -nologo -Fl -Sg -mz CPUSTAT.asm 4 | -------------------------------------------------------------------------------- /Tools/JEMFBHLP/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem create JEMFBHLP.EXE with JWasm 3 | jwasm -c -nologo -mz -Fl JEMFBHLP.ASM 4 | -------------------------------------------------------------------------------- /Tools/MEMSTAT/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem creates MEMSTAT.EXE with JWasm 3 | jwasm -c -nologo -mz -Fl MEMSTAT.asm 4 | -------------------------------------------------------------------------------- /Tools/XMSSTAT/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem create XMSSTAT.EXE 3 | rem uses JWasm 4 | jwasm -nologo -mz XMSSTAT.asm 5 | -------------------------------------------------------------------------------- /JLM/HELLO2/MAKEJLMW.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem assembles helper module jlmw for Open Watcom. 3 | jwasm -I ..\..\Include jlmw.asm 4 | -------------------------------------------------------------------------------- /JLM/JLSTUB/Make.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | if not exist Build\NUL mkdir Build 3 | jwasm -nologo -mz -FlBuild\ -Fo=Build\jlstub.bin jlstub.asm 4 | -------------------------------------------------------------------------------- /Test/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem the programs may all be created without link step, 3 | rem using jwasm's -mz option 4 | jwasm -mz %1.asm 5 | -------------------------------------------------------------------------------- /Test/MACROS.INC: -------------------------------------------------------------------------------- 1 | 2 | CStr macro text:VARARG 3 | local sym 4 | .const 5 | sym db text,0 6 | .code 7 | exitm 8 | endm 9 | 10 | -------------------------------------------------------------------------------- /JLM/AHCICD/MAKEM.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | ml -c -coff -nologo -Fl -Sg -I..\..\Include AHCICD.ASM 4 | link /nologo /subsystem:native /dll AHCICD.obj /OUT:AHCICD.DLL /MAP 5 | -------------------------------------------------------------------------------- /JLM/JCLOCK/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | set FASMINC=\fasm\Include 3 | set JLMINC=..\..\Include 4 | fasm JCLOCK.ASM 5 | fasm JCLOCK2.ASM 6 | \hx\bin\patchpe JCLOCK.DLL 7 | \hx\bin\patchpe JCLOCK2.DLL 8 | -------------------------------------------------------------------------------- /JLM/XDMA32/MAKEM.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem using MS tools 3 | ml -c -coff -Fl -D_DEBUG -I..\..\Include XDMA32.ASM 4 | link /NOLOGO /SUBSYSTEM:native /DLL XDMA32.obj /OUT:XDMA32.DLL /OPT:NOWIN98 /MAP 5 | -------------------------------------------------------------------------------- /JLM/REBOOT/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | jwasm -nologo -pe -Fl -Fo=REBOOT.DLL -I..\..\Include REBOOT.ASM 3 | jwasm -nologo -bin -Fl FASTBRM.ASM 4 | jwasm -nologo -pe -Fl -Fo=FASTBOOT.DLL -I..\..\Include FASTBOOT.ASM 5 | -------------------------------------------------------------------------------- /JLM/XCDROM32/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem add -D_DEBUG to create a debug version 3 | jwasm -coff -nologo -Fl -I..\..\Include XCDROM32.ASM 4 | jwlink format win pe hx dll ru native file XCDROM32.obj name XCDROM32.DLL op q,map 5 | -------------------------------------------------------------------------------- /JLM/HELLO2/MAKEVC.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem uses MS VC and MS Link 3 | \msvc71\bin\cl -c -I..\..\Include hello2.c 4 | link /LIBPATH:\msvc71\lib hello2.obj /subsystem:native /fixed:no /out:hello2.exe /entry:main 5 | \hx\bin\patchpe hello2.exe 6 | -------------------------------------------------------------------------------- /JLM/AHCICD/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | jwasm -c -coff -nologo -Fl -Sg -I..\..\Include AHCICD.ASM 4 | rem jwasm -coff -nologo -D_DEBUG -Fl -Sg -I..\..\Include AHCICD.ASM 5 | jwlink format win pe hx dll ru native file AHCICD.obj name AHCICD.DLL op q,map 6 | -------------------------------------------------------------------------------- /JLM/HELLO/README.TXT: -------------------------------------------------------------------------------- 1 | 2 | About 3 | 4 | This is the inevitable "hello world" JLM, written for Masm/JWasm. 5 | It displays a welcome message. After execution the module's resources 6 | are released. 7 | 8 | Usage: C:\>JLOAD -q HELLO.EXE 9 | -------------------------------------------------------------------------------- /JLM/XCDROM32/MAKEM.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem add -D_DEBUG to create a debug version 3 | rem using MS tools 4 | ml -c -coff -Fl -I..\..\Include XCDROM32.ASM 5 | link XCDROM32.OBJ /NOLOGO /DLL /out:XCDROM32.DLL /map:XCDROM32.map /subsystem:native /Fixed:no 6 | -------------------------------------------------------------------------------- /JLM/KEYBGR/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem 3 | rem JWasm v2.19: cmdline option -pe will create a JLM without external linker 4 | rem 5 | jwasm -nologo -pe -DFMTPE -Fl=Release\ -Fo=Release\KEYBGR.DLL -I..\..\Include KeybGr.asm 6 | patchPE -x -s:0x1000 Release\KEYBGR.DLL 7 | -------------------------------------------------------------------------------- /JLM/HELLO2/MAKEOW.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem uses Open Watcom C and WLink 3 | rem OW needs a helper module: jlmw.obj 4 | wcc386 -mf -zl -zls -s -I..\..\Include hello2w.c 5 | jwlink format win nt hx ru native file hello2w.obj, jlmw.obj name hello2w.exe option start=main_, map 6 | -------------------------------------------------------------------------------- /JLM/REBOOT/REBOOT.txt: -------------------------------------------------------------------------------- 1 | 2 | About ReBoot 3 | 4 | Reboot is just a sample, supposed to be modified if Jemm's default 5 | way to reboot doesn't work on a machine. To load, add the following line 6 | to CONFIG.SYS: 7 | 8 | DEVICE=JLOAD.EXE REBOOT.DLL 9 | 10 | -------------------------------------------------------------------------------- /JLM/HELLO2/README.TXT: -------------------------------------------------------------------------------- 1 | 2 | About 3 | 4 | Another JLM "hello world", this time written in C. 5 | MAKEVC.BAT: for MS VC (or Pelles C, CC386, ...) 6 | MAKEOW.BAT: for Open Watcom. 7 | 8 | to run it: jload /q hello2(w).exe 9 | 10 | There is room for improvement. 11 | -------------------------------------------------------------------------------- /JLM/XDMA32/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem Assemble and link file for the XDMA32 JLM. 3 | rem jwasm: option -zzs is needed for OW WLink v1.8! 4 | 5 | jwasm -coff -nologo -Fl -Sg -I..\..\Include -Fo=XDMA32.obj XDMA32.ASM 6 | jwlink format win pe hx dll ru native file XDMA32.obj name XDMA32.DLL op q,map 7 | -------------------------------------------------------------------------------- /JLM/JLSTUB/JLStub.txt: -------------------------------------------------------------------------------- 1 | 2 | 1. About JLStub 3 | 4 | JLStub is NOT a JLM. It's a stub, supposed to be added to other JLMs. 5 | It's purpose is to avoid having to type "jload" before the JLM. Instead, 6 | the stub is added to the JLM. When the JLM is launched by DOS, the stub 7 | will run, searching and launching jload.exe. 8 | 9 | -------------------------------------------------------------------------------- /Test/TEST11.DEB: -------------------------------------------------------------------------------- 1 | ; test v86 exc 11 2 | ; set CR0 AM bit 3 | ; set EFL AC bit 4 | ; then access stack unaligned 5 | a 6 | mov eax,cr0 7 | or eax,40000 8 | mov cr0,eax 9 | and sp,FFFC 10 | pushfd 11 | pop eax 12 | or eax,40000 13 | push eax 14 | popfd 15 | push ax 16 | push eax 17 | int 3 18 | 19 | g=100 20 | q 21 | -------------------------------------------------------------------------------- /JLM/HELLO2/JLMW.h: -------------------------------------------------------------------------------- 1 | 2 | // helper procs needed by Open Watcom C 3 | 4 | extern struct cb_s * _stdcall Get_Cur_VM_Handle( void ); 5 | extern ULONG _stdcall Begin_Nest_Exec(struct Client_Reg_Struc * pcl); 6 | extern ULONG _stdcall End_Nest_Exec(struct Client_Reg_Struc * pcl); 7 | extern ULONG _stdcall Exec_Int( unsigned long intno, struct Client_Reg_Struc * pcl ); 8 | -------------------------------------------------------------------------------- /JLM/KEYBGR/README.TXT: -------------------------------------------------------------------------------- 1 | 2 | Deutscher Tastaturtreiber fuer DOS der mit 48 Bytes DOS Speicher 3 | auskommt. Funktioniert nur in Verbindung mit Jemm. 4 | 5 | Wird installiert durch Eintrag in config.sys: 6 | 7 | DEVICE=JEMMEX.EXE (oder DEVICE=JEMM386.EXE) 8 | ... 9 | DEVICE=JLOAD.EXE KEYBGR.DLL 10 | 11 | KEYBGR ist Public Domain. 12 | 13 | Japheth 14 | 15 | -------------------------------------------------------------------------------- /Test/TEST10.DEB: -------------------------------------------------------------------------------- 1 | ; test v86 exc 10 2 | ; set CR0 NE bit 3 | ; enable exceptions in FP control word 4 | ; the do an FP pop 5 | ; the exception occurs at the NEXT FP instruction (the finit)! 6 | a 7 | mov eax,cr0 8 | or al,20 9 | mov cr0,eax 10 | fstcw [180] 11 | and word [180],ffc0 12 | fldcw [180] 13 | fst double [200] 14 | finit 15 | int 3 16 | 17 | g=100 18 | q 19 | -------------------------------------------------------------------------------- /src/VCPI.INC: -------------------------------------------------------------------------------- 1 | 2 | ; structure for VCPI switch from V86 to protected mode 3 | 4 | V86TOPM STRUCT 5 | dwCR3 DD ? ; client's CR3 value 6 | dwGDTOFFS DD ? ; offset of client's GDTR value 7 | dwIDTOFFS DD ? ; offset of client's IDTR value 8 | wLDTR DW ? ; client's LDTR value 9 | wTR DW ? ; client's TR value 10 | dfCSEIP DF ? ; entry point in client 11 | DW ? 12 | V86TOPM ENDS 13 | 14 | -------------------------------------------------------------------------------- /JLM/QPIEMU/Test/MAKEFILE: -------------------------------------------------------------------------------- 1 | 2 | # NMake/WMake Makefile to create TESTQPI.EXE & TESTDMA.EXE 3 | 4 | NAME1 = TESTQPI 5 | NAME2 = TESTDMA 6 | OUTDIR= . 7 | ASM=jwasm.exe 8 | 9 | ALL: $(OUTDIR)\$(NAME1).EXE $(OUTDIR)\$(NAME2).EXE 10 | 11 | $(OUTDIR)\$(NAME1).EXE: $(NAME1).asm 12 | @$(ASM) -nologo -mz -Fl$* -Sg -Fo=$*.EXE $(NAME1).asm 13 | 14 | $(OUTDIR)\$(NAME2).EXE: $(NAME2).asm 15 | @$(ASM) -nologo -mz -Fl$* -Sg -Fo=$*.EXE $(NAME2).asm 16 | -------------------------------------------------------------------------------- /Tools/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | cd CPUID 3 | call MAKE 4 | cd .. 5 | cd CpuStat 6 | call MAKE 7 | cd .. 8 | cd EMSSTAT 9 | call MAKE 10 | cd .. 11 | cd JEMFBHLP 12 | call MAKE 13 | cd .. 14 | cd JLOAD 15 | nmake /nologo 16 | cd .. 17 | cd MEMSTAT 18 | call MAKE 19 | cd .. 20 | cd MoveXBDA 21 | call MAKE 22 | cd .. 23 | cd UMBM 24 | call MAKE 25 | cd .. 26 | cd VCPI 27 | call MAKE 28 | cd .. 29 | cd XMSSTAT 30 | call MAKE 31 | cd .. 32 | -------------------------------------------------------------------------------- /JLM/QPIEMU/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem create QPIEMU.DLL 3 | rem since jwasm v2.19, this can be done without using an (external) linker 4 | 5 | rem Jemm's src directory has to be included since qpiemu needs ?PAGEDIR equate! 6 | 7 | rem jwasm -c -pe -nologo -D?PE -FlRelease\QPIEMU.LST -FoRelease\QPIEMU.DLL -I..\..\Include QPIEMU.ASM 8 | jwasm -c -pe -nologo -D?PE -I..\..\src -FlRelease\QPIEMU.LST -FoRelease\QPIEMU.DLL -I..\..\Include QPIEMU.ASM 9 | patchpe Release\QPIEMU.DLL 10 | -------------------------------------------------------------------------------- /Tools/CLEAR.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | erase CPUID\*.exe 3 | erase CPUID\*.lst 4 | erase CpuStat\*.exe 5 | erase CpuStat\*.lst 6 | erase EMSSTAT\*.exe 7 | erase EMSSTAT\*.lst 8 | erase JEMFBHLP\*.exe 9 | erase JEMFBHLP\*.lst 10 | cd JLOAD 11 | nmake clean 12 | cd .. 13 | erase MEMSTAT\*.exe 14 | erase MEMSTAT\*.lst 15 | erase MoveXBDA\*.exe 16 | erase MoveXBDA\*.lst 17 | erase UMBM\*.exe 18 | erase UMBM\*.lst 19 | erase VCPI\*.exe 20 | erase VCPI\*.lst 21 | erase XMSSTAT\*.exe 22 | erase XMSSTAT\*.lst 23 | -------------------------------------------------------------------------------- /JLM/JCLOCK/README.TXT: -------------------------------------------------------------------------------- 1 | JCLOCK 1.4 -- Second JLM (JemmEx Loadable Module) 2 | (C) 2007 Alexey Voskov 3 | 4 | Shows clock in the text mode. 5 | 6 | Usage 7 | ~~~~~ 8 | DEVICE=JEMMEX.EXE 9 | DEVICE=JLOAD.EXE JCLOCK.DLL 10 | 11 | History 12 | ~~~~~~~ 13 | Ver Date Changed 14 | ----------------------------------------------------------------- 15 | 1.4 17-APR-2009 JClock2 supports JLoad's -u switch. 16 | 1.3 19-FEB-2008 patchpe missed in MAKE.BAT 17 | 1.2 30-JAN-2008 environment variables FASMINC and JLMINC used 18 | 1.1 05-MAY-2007 VME compatibility added 19 | Improved source code (easy change of clock color) 20 | 1.0 04-MAY-2007 Original release -------------------------------------------------------------------------------- /Test/FRAMERES.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- create binary: 3 | ;--- jwasm -bin -Fo frameres.com frameres.asm 4 | 5 | .286 6 | .MODEL tiny 7 | 8 | .CODE 9 | 10 | org 100h 11 | 12 | start: 13 | mov ax,3567h 14 | int 21h 15 | mov ax,es ;IV 67h set? 16 | or ax,bx 17 | jz exit 18 | mov ah,41h ;get page frame 19 | int 67h 20 | and ah,ah ;ok? 21 | jz exit 22 | mov cx,4 ;cx=size mapping array 23 | mov dx,0 ;dx=handle (0=system) 24 | mov si,offset map ;ds:si -> mapping array 25 | mov ax,5000h 26 | int 67h 27 | exit: 28 | mov ax,4c00h 29 | int 21h 30 | align 2 31 | map dw -1,0,-1,1,-1,2,-1,3 32 | 33 | end start 34 | 35 | -------------------------------------------------------------------------------- /JLM/HELLO2/HELLO2W.C: -------------------------------------------------------------------------------- 1 | 2 | // for Open Watcom C 3 | // OW inline assembly doesn't know values of enums! 4 | // therefore it needs external module jlmw.asm 5 | 6 | #include 7 | #include "jlmw.h" 8 | 9 | struct Client_Reg_Struc * pcl; 10 | 11 | int main() 12 | { 13 | struct cb_s * hVM; 14 | unsigned char * psz = "Hello world\r\n"; 15 | 16 | hVM = Get_Cur_VM_Handle(); 17 | pcl = (struct Client_Reg_Struc *)hVM->CB_Client_Pointer; 18 | Begin_Nest_Exec(pcl); 19 | 20 | for (;*psz;psz++) { 21 | pcl->Client_EAX = 0x0200; 22 | pcl->Client_EDX = *psz; 23 | Exec_Int(0x21, pcl); 24 | } 25 | 26 | End_Nest_Exec(pcl); 27 | 28 | return 1; 29 | }; 30 | -------------------------------------------------------------------------------- /Tools/JLOAD/JLOAD.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- assembly conditionals 3 | 4 | ?USEVCPIEXIT equ 0 ;std=0, 1=use VCPI ax=DE0Ch to return to v86-mode 5 | 6 | ;--- constants 7 | ;--- ?SYSLINEAR is from Jemm32.inc, value is ?SYSBASE+1000h (=0F8001000h) 8 | 9 | ?SYSTEMADDR equ ?SYSLINEAR +3FF000h ;linear address "system" region 10 | ?PRIVATEADDR equ 400000h ;linear address "private" region 11 | 12 | VMMS struc 13 | JLCOMM 14 | emx08 EMX08 15 | hFile dw ? ;file handle of JLM 16 | pszLdr dw ? ;points to full path of JLOAD.EXE 17 | pszJLM dw ? ;points to JLM name parameter 18 | pHdr dw ? ;points to PE header 19 | pBuffer dw ? ;points to a 4 kB buffer in conv. memory 20 | pDDB dw ? ;points to DDB (if module is to be unloaded) 21 | VMMS ends 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/DEBUG16.INC: -------------------------------------------------------------------------------- 1 | 2 | ifndef ?INITRMDBG 3 | ?INITRMDBG equ 0 ;log real-mode init 4 | endif 5 | ifndef ?XMSRMDBG 6 | ?XMSRMDBG equ 0 ;log XMS calls 7 | endif 8 | ifndef ?EMXRMDBG 9 | ?EMXRMDBG equ 0 ;log EMMXXXX0 calls 10 | endif 11 | ifndef ?UNLRMDBG 12 | ?UNLRMDBG equ 0 ;log unload 13 | endif 14 | ?RMDBG equ ?INITRMDBG + ?XMSRMDBG + ?EMXRMDBG + ?UNLRMDBG ; debug displays in real-mode 15 | 16 | ?USEMONO equ 0 ;1=use monochrome monitor for dbg displays 17 | 18 | ifdef _DEBUG 19 | 20 | dprintf proto c :ptr, :vararg 21 | 22 | @dprintf macro bCond, fmt, args:vararg 23 | if bCond 24 | ifnb 25 | invoke dprintf, CStr(fmt), args 26 | else 27 | invoke dprintf, CStr(fmt) 28 | endif 29 | endif 30 | endm 31 | else 32 | @dprintf textequ <;> 33 | endif 34 | -------------------------------------------------------------------------------- /JLM/AHCICD/AHCICD.txt: -------------------------------------------------------------------------------- 1 | 2 | 1. About AHCICD 3 | 4 | AHCICD is a JLM to access AHCI optical disks, "inspired" by Rudolph R. Loew's 5 | AHCICD.SYS. To load it, add the following line to your CONFIG.SYS: 6 | 7 | DEVICE=JLOAD.EXE AHCICD.DLL [options] 8 | 9 | options are: 10 | 11 | /C:device select AHCI controller if more than one exists. 12 | /D:name set device name. Required. 13 | /Q no displays unless errors occur. 14 | /R relocate AHCI regions [CL/FIS/CT] to extended memory. 15 | 16 | 17 | 2. Hints 18 | 19 | - AHCI uses tables that may be located in the XBDA - so if the XBDA is to 20 | be moved, setting option /R is required. 21 | - AHCICD.DLL needs JLOAD v5.83 - older versions won't disable caching 22 | of the controller's memory-mapped registers. 23 | 24 | -------------------------------------------------------------------------------- /JLM/KEYBGR/MAKEFILE: -------------------------------------------------------------------------------- 1 | 2 | # Makefile for NMAKE 3 | # tools Alternatives 4 | #---------------------------------------------------------- 5 | # JWasm Masm v6.x 6 | # JWLink MS Link, WLink 7 | # 8 | # PatchPE: HX tool to patch a PE binary to PX (not required for jwlink) 9 | 10 | NAME = KEYBGR 11 | AOPT=-c -nologo -coff -Fl$*.lst -Fo$*.obj -I..\..\Include 12 | OUTDIR=Release 13 | 14 | $(OUTDIR)\$(NAME).DLL: $(OUTDIR)\$(NAME).obj Makefile 15 | # @link /NOLOGO /SUBSYSTEM:NATIVE /DLL $*.obj /OUT:$*.DLL /MAP:$*.MAP /Entry:DllMain /OPT:NOWIN98 16 | # @\hx\bin\patchpe $*.DLL 17 | @jwlink format win pe hx dll ru native file $*.obj name $*.DLL op q,MAP=$*.MAP 18 | 19 | $(OUTDIR)\$(NAME).obj: $(NAME).asm 20 | # @ml $(AOPT) $(NAME).asm 21 | @jwasm $(AOPT) $(NAME).asm 22 | -------------------------------------------------------------------------------- /JLM/GENERIC/TESTGEN.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- test app which calls some "services" of JLM GENERIC. 3 | ;--- assemble: JWasm -bin -Fo testgen.com testgen.asm 4 | 5 | .model tiny 6 | 7 | .data 8 | 9 | szOK db "GENERIC found!",13,10,'$' 10 | szError db "GENERIC is NOT installed!",13,10,'$' 11 | 12 | .code 13 | 14 | org 100h 15 | 16 | start: 17 | mov ax, 1684h ;get GENERIC's entry point 18 | mov bx, 6660h 19 | int 2Fh 20 | cmp al,0 21 | jnz not_installed 22 | push es 23 | push di 24 | mov bp,sp 25 | mov dx,offset szOk 26 | mov ah,9 27 | int 21h 28 | mov ax,0000 ;call "get version" 29 | call dword ptr [bp] 30 | mov ax,0001 ;call "display hello" 31 | call dword ptr [bp] 32 | add sp,4 33 | int 20h 34 | not_installed: 35 | mov dx,offset szError 36 | mov ah,9 37 | int 21h 38 | int 20h 39 | 40 | end start 41 | 42 | -------------------------------------------------------------------------------- /JLM/HELLO2/JLMW.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- helpers for (Watcom) C 3 | 4 | .386 5 | .model flat 6 | 7 | include jlm.inc 8 | 9 | .code 10 | 11 | Get_Cur_VM_Handle proc stdcall public uses ebx 12 | @VMMCall Get_Cur_VM_Handle 13 | mov eax, ebx 14 | ret 15 | align 4 16 | Get_Cur_VM_Handle endp 17 | 18 | Begin_Nest_Exec proc stdcall public uses ebp pcl:ptr 19 | mov ebp,pcl 20 | @VMMCall Begin_Nest_Exec 21 | ret 22 | align 4 23 | Begin_Nest_Exec endp 24 | 25 | End_Nest_Exec proc stdcall public uses ebp pcl:ptr 26 | mov ebp,pcl 27 | @VMMCall End_Nest_Exec 28 | ret 29 | align 4 30 | End_Nest_Exec endp 31 | 32 | Exec_Int proc stdcall public uses ebp intno:dword, pcl:ptr 33 | mov eax, intno 34 | mov ebp,pcl 35 | @VMMCall Exec_Int 36 | ret 37 | align 4 38 | Exec_Int endp 39 | 40 | end 41 | -------------------------------------------------------------------------------- /Tools/JLOAD/JLOAD32.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- macros 3 | 4 | CStr macro text:vararg 5 | local sym 6 | .const 7 | ifidni ,<""> 8 | sym db 0 9 | else 10 | sym db text,0 11 | endif 12 | .code 13 | exitm 14 | endm 15 | 16 | ;--- constants 17 | 18 | ?PAGEMAP equ 3FEh ;page table for mapping page tables 19 | 20 | ;--- structs 21 | 22 | ;--- publics 23 | 24 | InitVMM proto 25 | FindDevice proto 26 | VMM_Add_DDB proto 27 | VMM_Remove_DDB proto 28 | _PageReserve proto 29 | _PageCommit proto 30 | _PageDecommit proto 31 | _PageFree proto 32 | Get_Cur_VM_Handle proto 33 | 34 | externdef Begin_Nest_Exec:dword 35 | externdef Exec_Int:dword 36 | externdef End_Nest_Exec:dword 37 | 38 | externdef VDS_Call_Table:dword 39 | externdef ddb_0004:VxD_Desc_Block 40 | externdef dfOldint20:fword 41 | externdef g_dwIDT:dword 42 | if ?KD 43 | externdef bKDdetected:byte 44 | endif 45 | 46 | -------------------------------------------------------------------------------- /JLM/HELLO/MAKE.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem 3 | rem use JWasm & JWlink 4 | rem 5 | jwasm -nologo -coff -Fl=Release\Hello -Fo=Release\Hello -I..\..\Include Hello.asm 6 | jwlink format win pe hx ru native file Release\Hello.obj name Release\Hello.exe op q,m=Release\Hello,stack=0x1000 7 | 8 | rem use JWasm - since JWasm v2.19, cmdline option -pe supports several linker features; 9 | rem also, stub JLSTUB.BIN may be added. Then the program can be launched simply by typing its name. 10 | rem 11 | rem jwasm -nologo -pe -DFMTPE -DSTUB=..\JLSTUB\Build\jlstub.bin -Fl=Release\Hello -Fo=Release\Hello -I..\..\Include Hello.asm 12 | rem patchPE -x -s:0x1000 Release\Hello.exe 13 | 14 | rem use Masm & Link 15 | rem 16 | rem ml -c -coff -FlRelease\Hello -FoRelease\Hello -I..\..\Include Hello.asm 17 | rem link /NOLOGO Release\HELLO.OBJ /subsystem:native /FIXED:NO /map /out:Release\Hello.exe /ENTRY:_main /OPT:NOWIN98 18 | rem \hx\bin\patchpe -s:0x4000 -x Release\Hello.exe 19 | -------------------------------------------------------------------------------- /JLM/IOTRAP/README.TXT: -------------------------------------------------------------------------------- 1 | 2 | 1. About 3 | 4 | IOTRAP is a JLM sample which demonstrates how to trap IO port access. 5 | 6 | Note: This is somewhat obsolete now; trapping I/O port access in V86-mode 7 | is now better done with the help of JLM QPIEMU. 8 | 9 | 10 | 2. How to install and uninstall IOTRAP 11 | 12 | IOTRAP can be installed either as a device driver in CONFIG.SYS: 13 | 14 | DEVICE=JLOAD.EXE IOTRAP.DLL 15 | 16 | or as a TSR from the command line: 17 | 18 | JLOAD IOTRAP.DLL 19 | 20 | To uninstall, use JLOAD's -u option: 21 | 22 | JLOAD -u IOTRAP.DLL 23 | 24 | 25 | 3. How to test IOTRAP 26 | 27 | - install IOTRAP: C:\>JLOAD iotrap.dll 28 | - install TESTIOT: C:\>testiot 29 | - start DEBUG: C:\>debug 30 | - read port 100: -i 100 31 | 32 | now a colored string '*#!+' should appear on line 25. 33 | 34 | 35 | 4. License 36 | 37 | IOTRAP is Public Domain. 38 | 39 | Japheth 40 | 41 | -------------------------------------------------------------------------------- /JLM/GENERIC/MAKEFILE: -------------------------------------------------------------------------------- 1 | 2 | # NMake/WMake Makefile to create GENERIC.DLL 3 | # 4 | # tools alternatives 5 | #---------------------------------------------------------- 6 | # JWasm Masm v6.x 7 | # JWLink Link, WLink, ALink 8 | 9 | NAME = GENERIC 10 | OUTDIR=Release 11 | AOPT=-nologo -c -coff -nologo -Fl$*.lst -Fo$*.obj -I..\..\Include 12 | ASM=jwasm.exe 13 | #LINK=link.exe /NOLOGO /SUBSYSTEM:NATIVE /DLL $*.obj /OUT:$*.DLL /MAP:$*.MAP /EXPORT:ddb /Entry:DllMain /OPT:NOWIN98 14 | LINK=jwlink format win nt hx dll ru native file $*.obj name $*.DLL op q,map=$*.MAP export _ddb.1 15 | 16 | ALL: $(OUTDIR) $(OUTDIR)\$(NAME).DLL $(OUTDIR)\TESTGEN.COM 17 | 18 | $(OUTDIR): 19 | @mkdir $(OUTDIR) 20 | 21 | $(OUTDIR)\$(NAME).DLL: $(OUTDIR)\$(NAME).obj Makefile 22 | @$(LINK) 23 | 24 | $(OUTDIR)\$(NAME).obj: $(NAME).asm 25 | @$(ASM) $(AOPT) $(NAME).asm 26 | 27 | $(OUTDIR)\TESTGEN.COM: TESTGEN.ASM 28 | @jwasm -nologo -bin -Fo$*.COM -Fl$* testgen.asm 29 | -------------------------------------------------------------------------------- /JLM/QPIEMU/MAKEFILE: -------------------------------------------------------------------------------- 1 | 2 | # NMake/WMake Makefile to create QPIEMU.DLL 3 | # 4 | # tools alternatives 5 | #---------------------------------------------------------- 6 | # JWasm Masm v6.x 7 | # JWLink MS Link, WLink, ALink 8 | # (PatchPE) 9 | # 10 | # PatchPE: HX tool to patch a PE binary to PX ( not required for jwlink ). 11 | 12 | NAME = QPIEMU 13 | OUTDIR=Release 14 | AOPT=-c -coff -nologo -Fl$*.lst -Fo$*.obj -I..\..\Include 15 | ASM=jwasm.exe 16 | #LINK=link.exe /NOLOGO /SUBSYSTEM:NATIVE /DLL $*.obj /OUT:$*.DLL /MAP:$*.MAP /EXPORT:ddb /Entry:DllMain /OPT:NOWIN98 17 | LINK=jwlink format win nt hx dll ru native file $*.obj name $*.DLL op q,MAP=$*.MAP export _ddb.1 18 | 19 | ALL: $(OUTDIR) $(OUTDIR)\$(NAME).DLL 20 | 21 | $(OUTDIR): 22 | @mkdir $(OUTDIR) 23 | 24 | $(OUTDIR)\$(NAME).DLL: $(OUTDIR)\$(NAME).obj Makefile 25 | @$(LINK) 26 | # @..\patchpe $*.DLL 27 | 28 | $(OUTDIR)\$(NAME).obj: $(NAME).asm 29 | @$(ASM) $(AOPT) $(NAME).asm 30 | 31 | -------------------------------------------------------------------------------- /Test/README.TXT: -------------------------------------------------------------------------------- 1 | 2 | bmintrm: benchmark int 69h real-mode 3 | ems4e: get/set page map 4 | ems4f: get/set partial page map 5 | ems56: alter map and call 6 | ems57: EMS copy 7 | ems57a: copy EMS to EMS, 1 MB 8 | ems5b: alternate map register set 9 | frameres: reset page frame mapping to a known value 10 | hlttest: emulation of HLT, IF=1 11 | hlttest2: emulation of HLT, IF=0 12 | i15move: move block using int 15h, ah=87h 13 | testdma: read FD in UMB, using int 25h 14 | testdma2: read FD in UMB, using int 13h 15 | testdma3: read FD in UMB, using int 13h, ensured that DMA buffer/PTE remap must be used. 16 | testvds: run various VDS API calls 17 | testvds2: test VDS API calls 810B/810C for DMA channel 2 18 | testvds3: test 810B/810C for all channels 19 | xmstest: XMS memory moves 20 | xmstest2: XMS block allocation 21 | xmstest3: test XMS functions 0Eh/8Eh (get handle information) 22 | xmstest4: test XMS resize function 8Fh 23 | xmstest5: test XMS resize function 0Fh 24 | -------------------------------------------------------------------------------- /JLM/HELLO2/HELLO2.C: -------------------------------------------------------------------------------- 1 | 2 | // for MS VC 3 | 4 | #include 5 | 6 | struct Client_Reg_Struc * pcl; 7 | 8 | struct cb_s * Get_Cur_VM_Handle() 9 | { 10 | VxDCall(Get_Cur_VM_Handle); 11 | _asm mov eax,ebx; 12 | } 13 | 14 | ULONG Begin_Nest_Exec() 15 | { 16 | _asm mov ebp,pcl; 17 | VxDCall(Begin_Nest_Exec); 18 | } 19 | 20 | ULONG End_Nest_Exec() 21 | { 22 | _asm mov ebp,pcl; 23 | VxDCall(End_Nest_Exec); 24 | } 25 | 26 | ULONG Exec_Int(unsigned long intno) 27 | { 28 | _asm mov eax, intno; 29 | _asm mov ebp,pcl; 30 | VxDCall(Exec_Int); 31 | } 32 | 33 | int main() 34 | { 35 | struct cb_s * hVM; 36 | unsigned char * psz = "Hello world\r\n"; 37 | 38 | hVM = Get_Cur_VM_Handle(); 39 | pcl = (struct Client_Reg_Struc *)hVM->CB_Client_Pointer; 40 | Begin_Nest_Exec(); 41 | 42 | for (;*psz;psz++) { 43 | pcl->Client_EAX = 0x0200; 44 | pcl->Client_EDX = *psz; 45 | Exec_Int(0x21); 46 | } 47 | 48 | End_Nest_Exec(); 49 | 50 | return 1; 51 | }; 52 | -------------------------------------------------------------------------------- /JLM/IOTRAP/MAKEFILE: -------------------------------------------------------------------------------- 1 | 2 | # NMake/WMake Makefile to create IOTRAP.DLL 3 | # 4 | # tools alternatives 5 | #---------------------------------------------------------- 6 | # JWasm Masm v6.x 7 | # JWLink MS Link, WLink, ALink 8 | # (PatchPE) 9 | # 10 | # PatchPE: HX tool to patch a PE binary to PX ( not required for jwlink ). 11 | 12 | NAME = IOTRAP 13 | OUTDIR=Release 14 | AOPT=-c -coff -nologo -Fl$*.lst -Fo$*.obj -I..\..\Include 15 | ASM=jwasm.exe 16 | #LINK=link.exe /NOLOGO /SUBSYSTEM:NATIVE /DLL $*.obj /OUT:$*.DLL /MAP:$*.MAP /EXPORT:ddb /Entry:DllMain /OPT:NOWIN98 17 | LINK=jwlink format win nt hx dll ru native file $*.obj name $*.DLL op q,MAP=$*.MAP export _ddb.1 18 | 19 | ALL: $(OUTDIR) $(OUTDIR)\$(NAME).DLL $(OUTDIR)\TESTIOT.COM 20 | 21 | $(OUTDIR): 22 | @mkdir $(OUTDIR) 23 | 24 | $(OUTDIR)\$(NAME).DLL: $(OUTDIR)\$(NAME).obj Makefile 25 | @$(LINK) 26 | # @..\patchpe $*.DLL 27 | 28 | $(OUTDIR)\$(NAME).obj: $(NAME).asm 29 | @$(ASM) $(AOPT) $(NAME).asm 30 | 31 | $(OUTDIR)\TESTIOT.COM: TESTIOT.asm 32 | @$(ASM) -nologo -bin -Fo=$*.COM TESTIOT.asm 33 | -------------------------------------------------------------------------------- /Tools/JLOAD/license.txt: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2021 Andreas Grech (japheth) 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /Tools/JLOAD/DEBUG.INC: -------------------------------------------------------------------------------- 1 | 2 | ;*** debug macros and equates 3 | 4 | ?USEMONO equ 0 5 | 6 | ifndef ?RMDBG 7 | ?RMDBG = 0 ;trace real-mode 8 | endif 9 | ifndef ?INITDBG 10 | ?INITDBG = 0 ;trace init 11 | endif 12 | ifndef ?PEDBG 13 | ?PEDBG = 0 ;trace PE loader 14 | endif 15 | ifndef ?IODBG 16 | ?IODBG = 0 ;trace IO trapping 17 | endif 18 | ifndef ?PAGEDBG 19 | ?PAGEDBG = 0 ;trace page memory 20 | endif 21 | ifndef ?JLMDBG 22 | ?JLMDBG = 0 ;trace jlm handling 23 | endif 24 | ifndef ?DMADBG 25 | ?DMADBG = 0 ;trace DMA handling 26 | endif 27 | ifndef ?V86HOOKDBG 28 | ?V86HOOKDBG = 0 ;trace v86 hook chain handling 29 | endif 30 | ifndef ?INT2FHOOKDBG 31 | ?INT2FHOOKDBG = 0 ;trace Int2F hook handling 32 | endif 33 | 34 | ifdef _DEBUG 35 | ?TRACE = ?INITDBG + ?PEDBG + ?IODBG + ?PAGEDBG + ?JLMDBG + ?DMADBG + ?V86HOOKDBG + ?INT2FHOOKDBG 36 | else 37 | ?TRACE = 0 38 | endif 39 | 40 | dprintf proto c :ptr, :vararg 41 | 42 | ifdef _DEBUG 43 | 44 | @dprintf macro bCond, fmt, args:vararg 45 | if bCond 46 | ifnb 47 | invoke dprintf, CStr(fmt), args 48 | else 49 | invoke dprintf, CStr(fmt) 50 | endif 51 | endif 52 | endm 53 | 54 | else 55 | 56 | @dprintf textequ <;> 57 | 58 | endif 59 | 60 | -------------------------------------------------------------------------------- /JLM/XCDROM32/History.txt: -------------------------------------------------------------------------------- 1 | 2 | History 3 | 4 | 10/2022: v1.5 5 | - fixed: the driver was unable to handle multiple controllers with 6 | identical class/subclass/interface values. 7 | - enable busmaster feature in PCI controller if not set (Qemu). 8 | - timeout for startup audio functions increased to 7 secs. 9 | - removed obsolete /P option. 10 | - SATA controllers in non-AHCI mode handled correctly. 11 | 12 | 06/20/2012: v1.4 13 | - function "get q-channel info" did return track number in binary. 14 | - function "get q-channel info" did return value of ADR as CONTROL 15 | and vice versa. 16 | - function "get audio status" did return start and end address as 17 | LBA sector numbers. 18 | 19 | 05/21/2012: v1.3 20 | - scan for native (=SATA) controllers didn't succeed usually. 21 | 22 | 12/28/2007: v1.2 23 | - /P, /W and /32 options added, /UF option changed to /F 24 | - Jemm's VDS DMA buffer used if user buffer cannot be used. 25 | - IDE/DMA ports are now displayed for each unit. 26 | 27 | 12/03/2007: v1.1 28 | - now both "legacy" and "native" IDE controllers are supported. 29 | - some bugfixes. 30 | 31 | 05/24/2007: v1.0 32 | - initial. Ported from XCDROM v1.9. 33 | 34 | -------------------------------------------------------------------------------- /Test/VCPI.INC: -------------------------------------------------------------------------------- 1 | 2 | desc struct 3 | limit dw ? 4 | A0015 dw ? 5 | A1623 db ? 6 | attrib db ? 7 | lim_gr db ? 8 | A2431 db ? 9 | desc ends 10 | 11 | ;--- VCPI structure for switch to protected mode 12 | 13 | V86toPM struct 14 | _CR3 dd ? ;CR3 15 | _Gdtr dd ? ;linear address PD for GDTR 16 | _Idtr dd ? ;linear address PD for IDTR 17 | _Ldtr dw ? ;LDTR 18 | _Tr dw ? ;TR 19 | _Eip dd ? ;EIP 20 | _Cs dd ? ;CS 21 | V86toPM ends 22 | 23 | IRETV86 struct 24 | _Eip dd ? 25 | _Cs dd ? 26 | _Efl dd ? 27 | _Esp dd ? 28 | _Ss dd ? 29 | _Es dd ? 30 | _Ds dd ? 31 | _Fs dd ? 32 | _Gs dd ? 33 | IRETV86 ends 34 | 35 | TSSSEG struct 36 | dwLink dd ? 37 | dfStk0 df ? ;+04 38 | dw ? 39 | dfStk1 df ? ;+0C 40 | dw ? 41 | dfStk2 df ? ;+14 42 | dw ? 43 | _CR3 dd ? ;+1C 44 | _Eip dd ? ;+20 45 | _Efl dd ? ;+24 46 | _Eax dd ? ;+28 47 | _Ecx dd ? ;+2C 48 | _Edx dd ? ;+30 49 | _Ebx dd ? ;+34 50 | _Esp dd ? ;+38 51 | _Ebp dd ? ;+3C 52 | _Esi dd ? ;+40 53 | _Edi dd ? ;+44 54 | _ES dd ? ;+48 55 | _CS dd ? ;+4C 56 | _SS dd ? ;+50 57 | _DS dd ? ;+54 58 | _FS dd ? ;+58 59 | _GS dd ? ;+5C 60 | _LDT dd ? ;+60 61 | wFlags dw ? ;+64 62 | wOffs dw ? ;+66 63 | TSSSEG ends 64 | 65 | -------------------------------------------------------------------------------- /Tools/VCPI/VCPI.INC: -------------------------------------------------------------------------------- 1 | 2 | desc struct 3 | limit dw ? 4 | A0015 dw ? 5 | A1623 db ? 6 | attrib db ? 7 | lim_gr db ? 8 | A2431 db ? 9 | desc ends 10 | 11 | ;--- VCPI structure for switch to protected mode 12 | 13 | V86toPM struct 14 | _CR3 dd ? ;CR3 15 | _Gdtr dd ? ;linear address PD for GDTR 16 | _Idtr dd ? ;linear address PD for IDTR 17 | _Ldtr dw ? ;LDTR 18 | _Tr dw ? ;TR 19 | _Eip dd ? ;EIP 20 | _Cs dd ? ;CS 21 | V86toPM ends 22 | 23 | IRETV86 struct 24 | _Eip dd ? 25 | _Cs dd ? 26 | _Efl dd ? 27 | _Esp dd ? 28 | _Ss dd ? 29 | _Es dd ? 30 | _Ds dd ? 31 | _Fs dd ? 32 | _Gs dd ? 33 | IRETV86 ends 34 | 35 | TSSSEG struct 36 | dwLink dd ? 37 | dfStk0 df ? ;+04 38 | dw ? 39 | dfStk1 df ? ;+0C 40 | dw ? 41 | dfStk2 df ? ;+14 42 | dw ? 43 | _CR3 dd ? ;+1C 44 | _Eip dd ? ;+20 45 | _Efl dd ? ;+24 46 | _Eax dd ? ;+28 47 | _Ecx dd ? ;+2C 48 | _Edx dd ? ;+30 49 | _Ebx dd ? ;+34 50 | _Esp dd ? ;+38 51 | _Ebp dd ? ;+3C 52 | _Esi dd ? ;+40 53 | _Edi dd ? ;+44 54 | _ES dd ? ;+48 55 | _CS dd ? ;+4C 56 | _SS dd ? ;+50 57 | _DS dd ? ;+54 58 | _FS dd ? ;+58 59 | _GS dd ? ;+5C 60 | _LDT dd ? ;+60 61 | wFlags dw ? ;+64 62 | wOffs dw ? ;+66 63 | TSSSEG ends 64 | 65 | -------------------------------------------------------------------------------- /JLM/XDMA32/History.txt: -------------------------------------------------------------------------------- 1 | 2 | 10/2022: v1.5 3 | 4 | - ensure that busmaster flag in PCI command register is set. 5 | - created .data segment with variables to separate them from code. 6 | - removed obsolete /P option. 7 | - fixed: under certain conditions, an IDE controllers might not have 8 | been detected. 9 | 10 | 08/2022: v1.4 11 | 12 | - fixed: option /M was implemented in such a way that it became obligatory 13 | to set it to make the driver work. 14 | 15 | 07/26/2011: v1.3 16 | 17 | - to determine the number of HDs in the system, an Int 13h, ah=08 18 | is issued. BIOS variable 0040:0075 is ignored. 19 | 20 | 04/20/2011: v1.2 21 | 22 | - bugfix: HDs attached to the "native" secondary channel were 23 | ignored. 24 | 25 | 12/28/2007: v1.1 26 | 27 | - bugfix: HDs attached to the "legacy" secondary channel didn't 28 | work (wrong DMA ports). 29 | - options /B, /M, /W and /P added, /UF option changed to /F. 30 | - now max. 8 HDs are supported. 31 | - usage of Jemm's new export 'MoveMemory' reduces interrupt latency, 32 | and also makes this version incompatible with Jemm v5.68 and below. 33 | 34 | 12/03/2007: v1.0 35 | 36 | - initial. Ported from XDMA v3.3. Added support for both "legacy" 37 | and "native" IDE controllers. 38 | -------------------------------------------------------------------------------- /JLM/README.TXT: -------------------------------------------------------------------------------- 1 | 2 | 1. About 3 | 4 | This directory contains some JLMs: 5 | 6 | AHCICD: AHCI Optical disk driver. 7 | GENERIC: protected-mode TSR sample in ASM (Masm/JWasm). 8 | HELLO: "hello world" JLM in ASM (Masm/JWasm) 9 | HELLO2: "hello world" JLM in C (MS VC, Open Watcom) 10 | IOTRAP: sample how to trap IO port access. 11 | JCLOCK: shows clock in text mode. 12 | KEYBGR: German keyboard driver. 13 | QPIEMU: emulates port trapping part of QPI. 14 | REBOOT: shows how control message DEVICE_REBOOT_NOTIFY may be handled. 15 | XCDROM32: UltraDMA DVD/CD-ROM driver (GNU GPL 2). 16 | XDMA32: UltraDMA HD driver (GNU GPL 2). 17 | 18 | GENERIC, HELLO, HELLO2, IOTRAP, JCLOCK, QPIEMU are Public Domain. 19 | 20 | 21 | 2. Tools that may be used 22 | 23 | tools version result 24 | ----------------------------------------- 25 | assembler: 26 | Masm 6.15 ok 27 | JWasm 2.15 ok 28 | Fasm 1.67 ok 29 | 30 | C compiler: 31 | MS VC 2/5/6 ok 32 | Borland C++ 5.5 ok 33 | Ladsoft CC386 3.8.1.18 ok 34 | Digital Mars C++ 8.49 ok 35 | Open Watcom WCC386 1.9 ok 36 | 37 | COFF linker: 38 | JWlink 1.9beta17 ok 39 | Open Watcom WLink 1.9 ok 40 | MS Link 6.00 ok 41 | 42 | -------------------------------------------------------------------------------- /src/DMA.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- ports ISA DMA controller 3 | 4 | DMA_STATUS_CMD equ 8 ; R status / W command 5 | DMA_REQUEST equ 9 ; W b0+1: channel, b2: 1=enable?, b3-7:rsvd 6 | DMA_SINGLEMASK equ 10 ; W b0+1: channel to mask, b2: 0=clear/1=mask, b3-7:rsvd 7 | DMA_MODE equ 11 ; W b0+1: channel, b2-7:see below 8 | DMA_FLIPFLOP equ 12 ; W 9 | DMA_IMM_RESET equ 13 ; R immediate / W master reset (masks all 4 channels) 10 | DMA_MASK_RESET equ 14 ; W master enable (unmasks all 4 channels) 11 | DMA_MULTIMASK equ 15 ; W b0-3: 1=channel[0-3] masked, 0=channel[0-3] unmasked 12 | 13 | ;--- bits in DMA_MODE 14 | DMA_MODE_OPERATION equ 1100b; "op" bits 2+3 15 | DMA_MODE_OP_VERIFY equ 0000b 16 | DMA_MODE_OP_WRITE equ 0100b 17 | DMA_MODE_OP_READ equ 1000b 18 | 19 | DMA_MODE_AUTO equ 10h ; b4 20 | DMA_MODE_DIRECTION equ 20h ; b5: direction 0=increment, 1=decrement 21 | ;--- b6-7: 00=demand,01=single,10=block,11=cascade 22 | 23 | DMA_BASE_16BIT equ 0C0h 24 | 25 | DMA_STATUS_CMD16 equ DMA_BASE_16BIT + DMA_STATUS_CMD*2 26 | DMA_SINGLEMASK16 equ DMA_BASE_16BIT + DMA_SINGLEMASK*2 27 | DMA_MODE16 equ DMA_BASE_16BIT + DMA_MODE*2 28 | DMA_FLIPFLOP16 equ DMA_BASE_16BIT + DMA_FLIPFLOP*2 29 | DMA_IMM_RESET16 equ DMA_BASE_16BIT + DMA_IMM_RESET*2 30 | DMA_MASK_RESET16 equ DMA_BASE_16BIT + DMA_MASK_RESET*2 31 | DMA_MULTIMASK16 equ DMA_BASE_16BIT + DMA_MULTIMASK*2 32 | 33 | MAXDMACHANNEL equ 8 34 | -------------------------------------------------------------------------------- /JLM/REBOOT/FASTBOOT.txt: -------------------------------------------------------------------------------- 1 | 2 | About FastBoot JLM 3 | 4 | The FastBoot JLM allows some fine-tuning of Jemm's fast reboot behavior 5 | (which is activated by Jemm's FASTBOOT option). 6 | 7 | DEVICE=JLOAD.EXE FASTBOOT.DLL [options] 8 | 9 | Valid options are: 10 | /Dn : select a HD to boot from (n=0-7; 0 is first HD and default). 11 | This will work for the DOS variants that are able to boot from 12 | any HD, without "remapping" them in the BIOS. 13 | /Pn : select a partition to boot from (n=1-8; if n > 4, the partition 14 | will be searched in the (first) extended partition. If this option 15 | is omitted, the FastBoot JLM will load & run the MBR's boot code. 16 | /B:file: select a "boot sector" file to be used for booting. This file is 17 | expected to have a size of 512 bytes and contain executable boot 18 | code. 19 | 20 | Additionally, the FastBoot JLM implements an API: 21 | 1. to load and activate the "boot variant" of Debug/X - DebugB. This allows 22 | to debug the DOS kernel during initialization without modifying the boot 23 | sector of the partition. 24 | 2. to load an "INT 13h BIOS extension". Sample LDI13Ext.asm is supplied, 25 | showing how this is supposed to be done - it just switches HDs 0 and 1. 26 | 27 | Jemm's FASTBOOT option is not guaranteed to work, please read the chapter 28 | about the requirements in Jemm's documentation. 29 | 30 | -------------------------------------------------------------------------------- /src/JEMM16.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- globals for jemm16.asm and init16.asm 3 | 4 | if ?INTEGRATED 5 | NAMEEXE equ <"JEMMEX"> 6 | NAMEMOD equ <"JemmEx"> 7 | else 8 | NAMEEXE equ <"JEMM386"> 9 | NAMEMOD equ <"Jemm386"> 10 | endif 11 | 12 | @XBDA equ 40Eh 13 | @MEM_SIZE equ 413h 14 | 15 | ;--- modes for mainex() 16 | EXECMODE_SYS equ 0 ;launched as dos device driver 17 | EXECMODE_EXE equ 1 ;launched as application 18 | 19 | InitJemm proto c 20 | IsJemmInstalled proto c 21 | EmmInstallcheck proto c 22 | XMSinit proto c 23 | CheckIntHooks proto stdcall :WORD 24 | UnloadJemm proto c 25 | if ?INTEGRATED 26 | ?XMS_STATICHDLS equ 10 ;free xms handles to be used for int 15h, ax=e820h 27 | I15SetHandle proto c 28 | I15AllocMemory proto stdcall :WORD, :DWORD 29 | GetEMBBase proto stdcall: word 30 | endif 31 | 32 | mainex proto c :WORD, :ptr BYTE 33 | 34 | printf proto c :ptr byte, :VARARG 35 | _memicmp proto c :ptr BYTE, :ptr BYTE, :WORD 36 | 37 | externdef c jemmini:JEMMINIT 38 | externdef c XMSdriverAddress:far16 ptr 39 | externdef c sig1:BYTE 40 | externdef c sig2:BYTE 41 | externdef bVerbose:byte 42 | 43 | if ?INTEGRATED 44 | externdef c xms_num_handles:WORD 45 | externdef c xms_max:dword 46 | if ?XMS35 47 | externdef c xms_smax:dword 48 | externdef c xms_maxhigh:dword 49 | externdef c xms_smax_noe820:byte 50 | externdef c xms_smem_used:byte 51 | ?XMS_DEFHDLS equ 48 52 | else 53 | ?XMS_DEFHDLS equ 32 54 | endif 55 | ?XMS_MAXHDLS equ 128 56 | externdef c xms_mem_free:dword 57 | externdef c xms_mem_largest:dword 58 | externdef c xms_mem_highest:dword 59 | endif 60 | -------------------------------------------------------------------------------- /JLM/GENERIC/README.TXT: -------------------------------------------------------------------------------- 1 | 2 | 1. About 3 | 4 | GENERIC is a JLM sample which demonstrates how to implement a 5 | protected-mode TSR. 6 | 7 | 8 | 2. How to install and uninstall GENERIC 9 | 10 | GENERIC can be installed either as a device driver in CONFIG.SYS: 11 | 12 | DEVICE=JLOAD.EXE GENERIC.DLL 13 | 14 | or as a TSR from the command line: 15 | 16 | JLOAD GENERIC.DLL 17 | 18 | To uninstall, use JLOAD's -u option: 19 | 20 | JLOAD -u GENERIC.DLL 21 | 22 | 23 | 3. How to use GENERIC 24 | 25 | GENERIC doesn't hook real-mode interrupt vectors. If a real-mode program 26 | wants to call a function provided by GENERIC, it first has to get the JLM's 27 | entry point. This is done similiar to Windows 9x: a call of Int 2F, 28 | AX=1684h with register BX containing the "device id". On return, if the 29 | "device" has been found, ES:DI will contain its entry address: 30 | 31 | mov ax, 1684h ;standard value to get VxD entry points 32 | mov bx, 6660h ;6660h is the ID of GENERIC 33 | int 2Fh 34 | cmp al,0 35 | jnz not_installed 36 | mov word ptr [genpm+0],di 37 | mov word ptr [genpm+2],es 38 | 39 | The protected-mode TSR implements two functions, which are selected 40 | by the value of register AX: 41 | 42 | mov ax, 0000 ;0000=get version 43 | call dword ptr [genpm] 44 | 45 | mov ax, 0001 ;0001=display hello 46 | call dword ptr [genpm] 47 | 48 | There's a test program - TESTGEN.EXE - supplied which uses GENERIC. 49 | 50 | 51 | 4. License 52 | 53 | GENERIC is Public Domain. 54 | 55 | Japheth 56 | 57 | -------------------------------------------------------------------------------- /Test/BMINTRM.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- benchmark 3 | ;*** call int 69h a number of times and count timer ticks 4 | 5 | .286 6 | .MODEL SMALL 7 | .stack 2048 8 | .dosseg 9 | .586 10 | 11 | cr equ 13 12 | lf equ 10 13 | 14 | include macros.inc 15 | 16 | ?USERDTSC equ 0 17 | 18 | .CODE 19 | 20 | include printf.inc 21 | 22 | main proc c 23 | 24 | local dwStart:dword 25 | local rmvec:dword 26 | local dwStartTSC:qword 27 | 28 | 29 | push 0 30 | pop es 31 | mov ebx,es:[69h*4] 32 | mov rmvec,ebx 33 | 34 | mov es:[69h*4+0],offset intproc 35 | mov es:[69h*4+2],cs 36 | 37 | mov eax,es:[46ch] 38 | mov dwStart,eax 39 | 40 | if ?USERDTSC 41 | rdtsc 42 | mov dword ptr dwStartTSC+0,eax 43 | mov dword ptr dwStartTSC+4,edx 44 | endif 45 | xor esi,esi 46 | @@: 47 | int 69h 48 | cmp esi,1000000 49 | jnz @B 50 | 51 | 52 | mov eax,es:[46ch] 53 | sub eax,dwStart 54 | invoke printf, CStr(<"time is %lu, counter is %lu",cr,lf>),eax,esi 55 | 56 | if ?USERDTSC 57 | rdtsc 58 | sub eax,dword ptr dwStartTSC+0 59 | sbb edx,dword ptr dwStartTSC+4 60 | mov dword ptr dwStartTSC+0,eax 61 | mov dword ptr dwStartTSC+4,edx 62 | invoke printf, CStr(<"TSC diff=%lX%08lX",cr,lf>),edx,eax 63 | endif 64 | 65 | push 0 66 | pop es 67 | mov ebx,rmvec 68 | mov es:[69h*4],ebx 69 | 70 | ret 71 | 72 | main endp 73 | 74 | intproc:: 75 | inc esi 76 | iret 77 | 78 | start: 79 | mov ax, @data 80 | mov ds, ax 81 | mov bx, ss 82 | sub bx, ax 83 | shl bx, 4 84 | mov ss, ax 85 | add sp, bx 86 | call main 87 | mov ah, 4Ch 88 | int 21h 89 | 90 | end start 91 | 92 | -------------------------------------------------------------------------------- /JLM/HELLO/HELLO.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- a simple JLM which displays a message onto the screen 3 | ;--- with the help of v86-int 21h and nested execution 4 | 5 | .386 6 | .MODEL FLAT, stdcall 7 | 8 | include jlm.inc 9 | 10 | ifdef FMTPE 11 | ;--- since v2.19, JWasm's -pe option knows how to interpret linker directives supplied 12 | ;--- in the .drectve info section. Thus no extra link step is required. 13 | option dotname 14 | .drectve segment info ;linker directives 15 | db "-subsystem:native -fixed:no" 16 | .drectve ends 17 | .hdr$1 segment use16 18 | % incbin 19 | .hdr$1 ends 20 | endif 21 | 22 | .DATA 23 | 24 | szText db "Hello, world!", 13,10,0 25 | 26 | .CODE 27 | 28 | _main proc 29 | 30 | push esi 31 | @VMMCall Begin_Nest_Exec ;start nested execution 32 | mov esi, offset szText 33 | @@nextitem: 34 | lodsb 35 | and al,al 36 | jz @@done 37 | 38 | ;--- Call int 21h, ah=2 in v86-mode. 39 | ;--- Be aware that in Jemm's context is no DOS extender installed. 40 | ;--- So there is no translation for DOS functions that use pointers. 41 | 42 | mov byte ptr [ebp].Client_Reg_Struc.Client_EDX,al 43 | mov byte ptr [ebp].Client_Reg_Struc.Client_EAX+1,2 44 | mov eax,21h 45 | @VMMCall Exec_Int 46 | 47 | jmp @@nextitem 48 | @@done: 49 | @VMMCall End_Nest_Exec ;end nested execution 50 | pop esi 51 | mov eax, 80000001h ;bit 31=1: suppress JLoad msg 52 | ret 53 | 54 | _main ENDP 55 | 56 | END _main 57 | 58 | -------------------------------------------------------------------------------- /Test/HLTTEST.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;*** HLT test (v86) 3 | 4 | .286 5 | .model small 6 | .stack 2048 7 | .dosseg 8 | .386 9 | 10 | include macros.inc 11 | 12 | .data 13 | 14 | bM21 db 0 15 | bIrq db 0 16 | 17 | .code 18 | 19 | dwOldInt9 dd 0 20 | cIrq db 0 21 | 22 | myint9 proc 23 | inc cs:[cIrq] 24 | jmp cs:[dwOldInt9] 25 | myint9 endp 26 | 27 | include printf.inc 28 | 29 | main proc c 30 | 31 | local mblock:word 32 | 33 | mov ecx,200000000 34 | @@: 35 | dec ecx 36 | jnz @B 37 | @@: 38 | mov ah,1 39 | int 16h 40 | jz @F 41 | mov ah,0 42 | int 16h 43 | jmp @B 44 | @@: 45 | mov ax,3509h 46 | int 21h 47 | mov word ptr cs:dwOldInt9+0,bx 48 | mov word ptr cs:dwOldInt9+2,es 49 | push ds 50 | push cs 51 | pop ds 52 | mov dx, offset myint9 53 | mov ax,2509h 54 | int 21h 55 | pop ds 56 | 57 | in al, 21h 58 | mov bM21, al 59 | mov al, 0FDh 60 | out 21h, al 61 | 62 | mov cs:[cIrq],0 63 | 64 | hlt 65 | cli 66 | nop 67 | 68 | mov al, cs:[cIrq] 69 | mov bIrq,al 70 | 71 | sti 72 | 73 | mov al,bM21 74 | out 21h,al 75 | 76 | push ds 77 | lds dx, cs:dwOldInt9 78 | mov ax,2509h 79 | int 21h 80 | pop ds 81 | 82 | mov al,bIrq 83 | mov ah,0 84 | invoke printf, CStr(<"%u interrupts counted",10>),ax 85 | 86 | ret 87 | main endp 88 | 89 | start: 90 | mov ax, @data 91 | mov ds, ax 92 | mov bx, ss 93 | sub bx, ax 94 | shl bx, 4 95 | mov ss, ax 96 | add sp, bx 97 | call main 98 | mov ah, 4Ch 99 | int 21h 100 | 101 | END start 102 | -------------------------------------------------------------------------------- /Test/HLTTEST2.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;*** HLT test (v86) with IF=0 3 | 4 | .286 5 | .model small 6 | .stack 2048 7 | .dosseg 8 | .386 9 | 10 | include macros.inc 11 | 12 | .data 13 | 14 | bM21 db 0 15 | bIrq db 0 16 | 17 | .code 18 | 19 | dwOldInt9 dd 0 20 | cIrq db 0 21 | 22 | myint9 proc 23 | inc cs:[cIrq] 24 | jmp cs:[dwOldInt9] 25 | myint9 endp 26 | 27 | include printf.inc 28 | 29 | main proc c 30 | 31 | mov ecx,200000000 32 | @@: 33 | dec ecx 34 | jnz @B 35 | 36 | @@: 37 | mov ah,1 38 | int 16h 39 | jz @F 40 | mov ah,0 41 | int 16h 42 | jmp @B 43 | @@: 44 | 45 | 46 | mov ax,3509h 47 | int 21h 48 | mov word ptr cs:dwOldInt9+0,bx 49 | mov word ptr cs:dwOldInt9+2,es 50 | push ds 51 | push cs 52 | pop ds 53 | mov dx, offset myint9 54 | mov ax,2509h 55 | int 21h 56 | pop ds 57 | 58 | in al, 21h 59 | mov bM21, al 60 | mov al, 0FDh 61 | out 21h, al 62 | 63 | mov cs:[cIrq],0 64 | 65 | cli 66 | nop 67 | hlt 68 | nop 69 | 70 | mov al, cs:[cIrq] 71 | mov bIrq,al 72 | 73 | sti 74 | 75 | mov al,bM21 76 | out 21h,al 77 | 78 | push ds 79 | lds dx, cs:dwOldInt9 80 | mov ax,2509h 81 | int 21h 82 | pop ds 83 | 84 | mov al,bIrq 85 | mov ah,0 86 | invoke printf, CStr(<"%u interrupts counted",10>),ax 87 | 88 | ret 89 | main endp 90 | 91 | start: 92 | mov ax, @data 93 | mov ds, ax 94 | mov bx, ss 95 | sub bx, ax 96 | shl bx, 4 97 | mov ss, ax 98 | add sp, bx 99 | call main 100 | mov ah, 4Ch 101 | int 21h 102 | 103 | END start 104 | -------------------------------------------------------------------------------- /Test/TESTVDS3.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- VDS API test; display ISA DMA translation status for channels 0-7 3 | 4 | .286 5 | .model small 6 | .stack 2048 7 | .dosseg 8 | .386 9 | 10 | CStr macro text:vararg 11 | local sym 12 | .const 13 | sym db text,0 14 | .code 15 | exitm 16 | endm 17 | 18 | lf equ 10 19 | 20 | .code 21 | 22 | include printf.inc 23 | 24 | main proc c 25 | 26 | local channel:word 27 | 28 | xor ax, ax 29 | mov es, ax 30 | test byte ptr es:[47bh],20h 31 | jz novds 32 | mov ax,8102h 33 | mov dx,0000 34 | int 4bh 35 | jnc @F 36 | novds: 37 | invoke printf, CStr("VDS not installed",lf) 38 | jmp exit 39 | @@: 40 | 41 | ;--- strategy: 42 | ;--- 1. call enable DMA translation 43 | ;--- should fail, since disable cnt should be zero 44 | 45 | mov channel, 0 46 | nextchannel: 47 | mov dx, 0 48 | mov bx, channel 49 | mov ax,810Ch 50 | int 4bh 51 | .if (CARRY?) 52 | invoke printf, CStr("channel %u: DMA translation is active",lf), bx 53 | .else 54 | invoke printf, CStr("channel %u: DMA translation is disabled",lf), bx 55 | 56 | ;--- restore disable cnt 57 | 58 | mov dx, 0 59 | mov bx, channel 60 | mov ax,810Bh 61 | int 4bh 62 | setz cl 63 | .if (CARRY?) 64 | cbw 65 | invoke printf, CStr("int 4B, ax=810Bh, BX=%u failed, AL=%X",lf), bx, ax 66 | .endif 67 | .endif 68 | 69 | inc channel 70 | cmp channel, 8 71 | jb nextchannel 72 | 73 | exit: 74 | ret 75 | main endp 76 | 77 | start: 78 | mov ax, @data 79 | mov ds, ax 80 | mov bx, ss 81 | sub bx, ax 82 | shl bx, 4 83 | mov ss, ax 84 | add sp, bx 85 | call main 86 | mov ah, 4Ch 87 | int 21h 88 | 89 | END start 90 | -------------------------------------------------------------------------------- /src/EMS.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- EMS status codes 3 | 4 | EMSS_OK equ 00h 5 | EMSS_SOFTWARE_ERR equ 80h ;unexpected error 6 | EMSS_HARDWARE_ERR equ 81h ;should never occur with EMM emulators 7 | EMSS_EMM_BUSY equ 82h ;should never occur with EMS 3.2+ 8 | EMSS_INVALID_HANDLE equ 83h 9 | EMSS_INVALID_FUNCTION equ 84h ;function code in AH not defined 10 | EMSS_NO_MORE_HANDLES equ 85h ;all handles in use 11 | EMSS_CONTEXT_EXISTS equ 86h ;45h: try to free a handle with saved context 12 | EMSS_OUT_OF_PAGES equ 87h ;43h, 51h, 5A00h, 5A01h 13 | EMSS_OUT_OF_FREE_PAGES equ 88h ;43h, 51h, 5A00h, 5A01h 14 | EMSS_ZERO_PAGES equ 89h ;43h 15 | EMSS_LOG_PAGE_INVALID equ 8Ah ;44h, 50h, 55h, 56h, 57h 16 | EMSS_PHYS_PAGE_INVALID equ 8Bh ;44h, 4Fh, 50h, 55h, 56h 17 | EMSS_CONTEXT_STACK_FULL equ 8Ch ;46h 18 | EMSS_STATE_ALREADY_SAVED equ 8Dh;47h 19 | EMSS_NO_STATE_IS_SAVED equ 8Eh ;48h 20 | EMSS_INVALID_SUBFUNC equ 8Fh ;4Eh, 4Fh, 50h, 52h, 53h, 54h, 57h, 58h, 59h, 5Bh 21 | EMSS_UNDEF_ATTR_TYPE equ 90h ; 22 | EMSS_FEATURE_UNSUPP equ 91h ;52h 23 | EMSS_OVERLAP_OCCURED equ 92h ;5700h 24 | EMSS_LENGTH_EXCEEDED equ 93h ;57h 25 | EMSS_CONVEMS_OVERLAPP equ 94h ;57h (jemm never returns this code) 26 | EMSS_OFFS_EXCEEDS_PGSIZ equ 95h ;57h 27 | EMSS_REGLEN_EXCEEDS_1MB equ 96h ;57h 28 | EMSS_REGIONS_OVERLAPP equ 97h ;5701h 29 | EMSS_TYPE_UNDEFINED equ 98h ;57h 30 | EMSS_ALT_MAPS_UNSUPP equ 9Ch ;5B01h, 5B04h, 5B06h, 5B07h, 5B08h 31 | EMSS_INVALID_ALT_MAP equ 9Dh ;5Bh (jemm never returns this code) 32 | EMSS_MBBOUNDARY_CROSSED equ 0A2h;57h 33 | EMSS_SRC_ARRAY_INVALID equ 0A3h;4E01h, 5B01h 34 | EMSS_ACCESS_DENIED equ 0A4h;5Bh 35 | 36 | -------------------------------------------------------------------------------- /JLM/QPIEMU/QPIEMU.txt: -------------------------------------------------------------------------------- 1 | 2 | 1. About 3 | 4 | QPIEMU is a JLM that partly emulates the Qemm API (QPI). Its 5 | purpose is to provide the IO trapping part of QPI, for better support 6 | of sound card emulation in DOS. 7 | 8 | 9 | 2. Install/Uninstall QPIEMU 10 | 11 | QPIEMU can be installed either as a device driver in CONFIG.SYS: 12 | 13 | DEVICE=JLOAD.EXE QPIEMU.DLL 14 | 15 | or as a TSR from the command line: 16 | 17 | JLOAD QPIEMU.DLL 18 | 19 | To uninstall, use JLOAD's -u option: 20 | 21 | JLOAD -u QPIEMU.DLL 22 | 23 | 24 | 3. Using QPIEMU 25 | 26 | Once QPIEMU is installed, tools that use the QPI ( i.e. SBEMU ) 27 | and hence usually require Qemm to be installed, should run with 28 | Jemm386/JemmEx. 29 | 30 | 31 | 4. Technical Details 32 | 33 | QPI is a "real-mode" API, hence if addresses are used, they are in 34 | segment:offset format. 35 | 36 | The part of the supported QPI is: 37 | 38 | AH=03h, QPI_GetVersion 39 | AX=1A00h, QPI_UntrappedIORead 40 | AX=1A01h, QPI_UntrappedIOWrite 41 | AX=1A04h, QPI_UntrappedIO 42 | AX=1A06h, QPI_GetIOCallback 43 | AX=1A07h, QPI_SetIOCallback 44 | AX=1A08h, QPI_GetPortTrap 45 | AX=1A09h, QPI_SetPortTrap 46 | AX=1A0Ah, QPI_ClearPortTrap 47 | 48 | Since v1.2, there's also AX=5000h, which isn't part of the original QPI. 49 | It returns physical address of Jemm's page table 0 in register EDX. 50 | 51 | The way to get the address of QPI itself differs for QPIEMU: 52 | an INT 2Fh, with AX=1684h, BX=4354h has to be called. If successful, 53 | It will return with AL==0 and the QPI entry point in ES:DI. 54 | 55 | 56 | History 57 | 58 | - v1.0: 03/2023: initial 59 | - v1.1: 07/2025: bit 1 of CH holds IF 60 | - v1.2: 09/2025: added function ax=5000h 61 | 62 | 63 | 5. License 64 | 65 | QPIEMU is Public Domain. 66 | 67 | Japheth 68 | 69 | -------------------------------------------------------------------------------- /JLM/REBOOT/REBOOT.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- sample how to handle DEVICE_REBOOT_NOTIFY control message 3 | ;--- requires Jemm v5.86+ 4 | 5 | .386 6 | .MODEL FLAT, stdcall 7 | option casemap:none 8 | 9 | include jlm.inc 10 | 11 | DLL_PROCESS_ATTACH equ 1 12 | DLL_PROCESS_DETACH equ 0 13 | 14 | DEVICE_ID equ 4435h 15 | 16 | ifdef @pe_file_flags ;-pe option set? 17 | option dotname 18 | .drectve segment info 19 | db "-dll " 20 | db "-subsystem:native " 21 | db "-fixed:no " 22 | .drectve ends 23 | 24 | .hdr$2 segment flat 25 | db "PX" 26 | .hdr$2 ends 27 | endif 28 | 29 | .const 30 | 31 | public export ddb 32 | 33 | ddb VxD_Desc_Block <0,0,DEVICE_ID,1,0,0,"REBOOT",0, ctrlproc > 34 | 35 | string1 db 13,10,"rebooting - press a key...",0 36 | 37 | .CODE 38 | 39 | ctrlproc proc 40 | cmp eax, DEVICE_REBOOT_NOTIFY 41 | jz reboot_notify 42 | clc 43 | ret 44 | reboot_notify: 45 | @VMMCall Begin_Nest_Exec ;start nested execution 46 | mov eax,offset string1 47 | call printstring 48 | mov byte ptr [ebp].Client_Reg_Struc.Client_EAX+1, 0 49 | mov eax,16h 50 | @VMMCall Exec_Int 51 | @VMMCall End_Nest_Exec ;end nested execution 52 | clc 53 | ret 54 | ctrlproc endp 55 | 56 | printstring proc uses esi 57 | mov esi, eax 58 | cld 59 | nextitem: 60 | lodsb 61 | and al,al 62 | jz done 63 | mov byte ptr [ebp].Client_Reg_Struc.Client_EAX, al 64 | mov byte ptr [ebp].Client_Reg_Struc.Client_EAX+1, 0Eh 65 | mov eax,10h 66 | @VMMCall Exec_Int 67 | jmp nextitem 68 | done: 69 | ret 70 | printstring endp 71 | 72 | DllMain PROC stdcall hModule:dword, dwReason:dword, dwRes:dword 73 | 74 | mov eax,dwReason 75 | cmp eax, DLL_PROCESS_ATTACH 76 | jnz @F 77 | mov eax,1 78 | jmp exit 79 | @@: 80 | cmp eax,DLL_PROCESS_DETACH 81 | jnz @F 82 | mov eax,1 83 | @@: 84 | exit: 85 | ret 86 | DllMain endp 87 | 88 | END DllMain 89 | 90 | -------------------------------------------------------------------------------- /Test/TESTDMA.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- test FD read in UMB 3 | ;--- using Int 25h 4 | 5 | .286 6 | .model small 7 | .stack 2048 8 | .dosseg 9 | .386 10 | 11 | CStr macro text:vararg 12 | local sym 13 | .const 14 | sym db text,0 15 | .code 16 | exitm 17 | endm 18 | 19 | lf equ 10 20 | 21 | .code 22 | 23 | include printf.inc 24 | 25 | main proc c 26 | 27 | local stat1:word 28 | local stat2:word 29 | local wSeg:word 30 | 31 | mov ax, 5802h ;get status umb 32 | int 21h 33 | xor ah,ah 34 | mov stat1, ax 35 | 36 | mov ax, 5800h ;get memory alloc strategy 37 | int 21h 38 | xor ah,ah 39 | mov stat2, ax 40 | 41 | mov bx, 81h ;first high,then low 42 | mov ax, 5801h ;set memory alloc strat 43 | int 21h 44 | mov bx, 1 ;include umbs 45 | mov ax, 5803h ;umb link restore 46 | int 21h 47 | 48 | 49 | mov bx, 100h ; allocate 4 kB 50 | mov ah, 48h 51 | int 21h 52 | jc exit 53 | mov wSeg, ax 54 | 55 | mov es, ax 56 | xor di, di 57 | mov cx, 1000h 58 | mov al, 00 59 | rep stosb 60 | 61 | push ds 62 | mov ds, wSeg ; ds:bx=transfer buffer 63 | mov bx, 0 64 | mov cx, 8 ; 8 sectors to read 65 | mov al, 0 ; al=0 -> A: 66 | mov dx, 0 ; start sector # 67 | int 25h 68 | jc error 69 | add sp, 2 70 | pop ds 71 | invoke printf, CStr("reading drive A: ok",10) 72 | jmp exit 73 | error: 74 | add sp, 2 75 | pop ds 76 | invoke printf, CStr("reading drive A: failed, error code=%X",10), ax 77 | exit: 78 | mov bx, stat1 79 | mov ax, 5803h 80 | int 21h 81 | mov bx, stat2 82 | mov ax, 5801h ; set memory alloc strag 83 | int 21h 84 | ret 85 | main endp 86 | 87 | start: 88 | mov ax, @data 89 | mov ds, ax 90 | mov bx, ss 91 | sub bx, ax 92 | shl bx, 4 93 | mov ss, ax 94 | add sp, bx 95 | call main 96 | mov ah, 4Ch 97 | int 21h 98 | 99 | END start 100 | -------------------------------------------------------------------------------- /src/AUXIO.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- handle AUX I/O 3 | 4 | ifndef COMNO 5 | COMNO equ 1 6 | endif 7 | _XONXOFF_ equ 1 8 | XON equ 11h 9 | XOFF equ 13h 10 | 11 | .text$01w segment dword flat public 'CODE' 12 | wCsrPos dw 0,0 13 | .text$01w ends 14 | 15 | ;--- display a char in AL 16 | 17 | AuxPutChar proc 18 | 19 | pushad 20 | movzx ebx, word ptr ds:[400h + (COMNO-1)*2] 21 | lea edx, [ebx+5] ;LSR - Line Status Register 22 | mov cx, -1 23 | movzx ecx, cx 24 | xchg al, ah 25 | @@: 26 | in al, dx 27 | test al, 40h ;TEMT - transmitter empty? 28 | loopz @B 29 | if _XONXOFF_ 30 | test al, 1 ;char received 31 | jz noxoff 32 | mov edx, ebx 33 | in al, dx 34 | cmp al, XOFF 35 | jnz noxoff 36 | waitxon: 37 | add edx, 5 38 | @@: ;wait till new char arrived 39 | in al, dx 40 | test al, 1 41 | jz @B 42 | mov edx, ebx 43 | in al, dx 44 | cmp al, XON ;wait till XON received 45 | jnz waitxon 46 | noxoff: 47 | endif 48 | xchg al, ah 49 | mov edx, ebx 50 | out dx, al 51 | call setcsrpos 52 | popad 53 | ret 54 | 55 | setcsrpos: 56 | cmp al, 13 57 | jz col00 58 | cmp al, 10 59 | jz nochg 60 | cmp al, 8 61 | jz back 62 | inc byte ptr [wCsrPos] 63 | retn 64 | back: 65 | dec byte ptr [wCsrPos] 66 | retn 67 | col00: 68 | mov byte ptr [wCsrPos], 0 69 | nochg: 70 | retn 71 | 72 | AuxPutChar endp 73 | 74 | ;--- get a char in AL 75 | 76 | AuxGetChar proc 77 | 78 | push ebx 79 | push ecx 80 | push edx 81 | 82 | movzx ebx, word ptr ds:[400h + (COMNO-1)*2] 83 | lea edx, [ebx+6] ;MSR - modem status register 84 | in al, dx ;DSR - modem(=DCE) ready? 85 | and al, 20h 86 | jz error 87 | dec edx ;LSR - Line Status Register 88 | @@: 89 | in al, dx 90 | test al, 01h ;DR - Data ready? 91 | jz @B 92 | mov edx, ebx 93 | in al, dx 94 | mov ah, 00 95 | jmp exit 96 | error: 97 | xor eax, eax 98 | exit: 99 | pop edx 100 | pop ecx 101 | pop ebx 102 | ret 103 | AuxGetChar endp 104 | 105 | -------------------------------------------------------------------------------- /Tools/JLOAD/VIOOUT.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- low-level video access 3 | ;--- no assumption about ds,es. 4 | ;--- ss is supposed to be flat. 5 | 6 | VPUTCHR PROC 7 | push ds 8 | pushad 9 | push ss 10 | pop ds 11 | if ?KD 12 | test bKDdetected,1 13 | jz @F 14 | mov dl, al 15 | xor ax, ax 16 | int 41h 17 | jmp exit 18 | @@: 19 | endif 20 | if ?USEMONO 21 | mov edi,0B0000h 22 | mov ebx,7 23 | else 24 | MOV EDI,0B8000h 25 | CMP BYTE ptr DS:[463h],0B4h 26 | JNZ @@IS_COLOR 27 | XOR DI,DI 28 | @@IS_COLOR: 29 | movzx EBX, WORD PTR DS:[44Eh] 30 | ADD EDI, EBX 31 | MOVZX EBX, BYTE PTR DS:[462h] 32 | endif 33 | mov esi, edi 34 | MOVZX ECX, BYTE PTR DS:[EBX*2+450h+1] ;ROW 35 | if ?USEMONO 36 | MOV EAX, 80 37 | else 38 | MOVZX EAX, WORD PTR DS:[44Ah] 39 | endif 40 | MUL ECX 41 | MOVZX EDX, BYTE PTR DS:[EBX*2+450h] ;COL 42 | ADD EAX, EDX 43 | MOV DH,CL 44 | LEA EDI, [EDI+EAX*2] 45 | MOV AL, [ESP+1Ch] 46 | CMP AL, 10 47 | JZ @@NEWLINE 48 | MOV [EDI], AL 49 | MOV byte ptr [EDI+1], 07 50 | INC DL 51 | if ?USEMONO 52 | cmp dl,80 53 | else 54 | CMP DL, BYTE PTR DS:[44Ah] 55 | endif 56 | JB @@OLDLINE 57 | @@NEWLINE: 58 | MOV DL, 00 59 | INC DH 60 | if ?USEMONO 61 | CMP DH, 24 62 | else 63 | CMP DH, BYTE PTR DS:[484h] 64 | endif 65 | JBE @@OLDLINE 66 | DEC DH 67 | CALL SCROLL_SCREEN 68 | @@OLDLINE: 69 | MOV DS:[EBX*2+450h],DX 70 | exit: 71 | POPAD 72 | pop ds 73 | RET 74 | align 4 75 | 76 | ;--- scroll screen up 1 line 77 | ;--- esi -> start screen 78 | 79 | SCROLL_SCREEN: 80 | push es 81 | push ds 82 | pop es 83 | CLD 84 | mov edi,esi 85 | if ?USEMONO 86 | mov eax,80 87 | else 88 | movzx eax,word ptr ds:[44Ah] 89 | endif 90 | push eax 91 | lea esi, [esi+2*eax] 92 | if ?USEMONO 93 | mov CL, 24 94 | else 95 | MOV CL, DS:[484h] 96 | endif 97 | mul cl 98 | mov ecx,eax 99 | rep movsw 100 | pop ecx 101 | mov ax,0720h 102 | rep stosw 103 | pop es 104 | retn 105 | align 4 106 | 107 | VPUTCHR ENDP 108 | 109 | -------------------------------------------------------------------------------- /JLM/XDMA32/XDMA32.txt: -------------------------------------------------------------------------------- 1 | 2 | 1. About XDMA32 3 | 4 | XDMA32 is a JLM based on Jack R. Ellis' XDMA Ultra-DMA HD driver. 5 | It supports PCI IDE controllers running in "legacy" or "native" mode. 6 | 7 | 8 | 2. Usage 9 | 10 | To load XDMA32, add the following line to your CONFIG.SYS: 11 | 12 | DEVICE=JLOAD.EXE XDMA32.DLL [options] 13 | 14 | options are: 15 | 16 | /B always use XMS buffer for file i/o. Might be useful in virtualized 17 | environments which can't handle DMA properly for all addresses. 18 | This switch is more restrictive than /L, and it disables /F. 19 | /F "fast", uses DMA "scatter/gather" method to allow transfers 20 | which cross a physical 64 kB boundary. Might not work with all 21 | controllers, so use with care! (The "fast" is a historical 22 | remnant, on modern systems there will be no significant difference 23 | in speed.) 24 | /L limits DMA to "low memory" below 640 kB. Addresses above are 25 | handled through the XMS buffer. 26 | /Mn set/restrict UDMA mode to n (0 <= n <= 7). 27 | /Q quiet mode. 28 | /W handle (non-UDMA) drives which are capable of Multiword-DMA. 29 | 30 | 31 | 3. Features & Restrictions 32 | 33 | - XDMA32 supports up to 4 PCI IDE controllers. May be changed in XDMA32.ASM 34 | ( NUMCTRL constant ). 35 | - XDMA32 supports up to 8 HDs. May be changed in XDMA32.ASM 36 | ( NUMDSK constant ). 37 | - HDs are accessed using either CHS, LBA28 or LBA48 addressing, so there's 38 | no (practical) size restriction. 39 | - XDMA32 has no device ID associated with it - hence jload cannot detect 40 | currently if the driver is already installed. 41 | - SATA controllers running in AHCI mode are ignored. 42 | - the XDMA32 driver needs just 48 bytes in conventional or upper memory. 43 | - a 128 kB extended memory block is allocated as a buffer to be used if the 44 | current transfer address is incompatible with DMA access. 45 | 46 | 47 | 4. License 48 | 49 | XDMA32 is released under the GNU GPL v2. See GNU_GPL.TXT for details. 50 | 51 | Japheth 52 | -------------------------------------------------------------------------------- /Test/TESTVDS2.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- VDS API test; test disable/enable auto DMA translation (810B/810C) 3 | 4 | .286 5 | .model small 6 | .stack 2048 7 | .dosseg 8 | .386 9 | 10 | CStr macro text:vararg 11 | local sym 12 | .const 13 | sym db text,0 14 | .code 15 | exitm 16 | endm 17 | 18 | lf equ 10 19 | 20 | .code 21 | 22 | include printf.inc 23 | 24 | main proc c 25 | 26 | local channel:word 27 | 28 | xor ax, ax 29 | mov es, ax 30 | test byte ptr es:[47bh],20h 31 | jz novds 32 | mov ax,8102h 33 | mov dx,0000 34 | int 4bh 35 | jnc @F 36 | novds: 37 | invoke printf, CStr("VDS not installed",lf) 38 | jmp exit 39 | @@: 40 | 41 | ;--- disable DMA translation for channel 2 42 | 43 | mov channel, 2 44 | nextchannel: 45 | mov dx, 0 46 | mov bx, channel 47 | mov ax,810Bh 48 | int 4bh 49 | .if (CARRY?) 50 | cbw 51 | invoke printf, CStr("int 4B, ax=810Bh, BX=%u failed, AL=%X",lf), bx, ax 52 | .else 53 | invoke printf, CStr("int 4B, ax=810Bh, BX=%u ok",lf), bx 54 | .endif 55 | 56 | ;--- reenable DMA translation 57 | 58 | mov dx, 0 59 | mov bx, channel 60 | mov ax,810Ch 61 | int 4bh 62 | setz cl 63 | .if (CARRY?) 64 | cbw 65 | invoke printf, CStr("int 4B, ax=810Ch, BX=%u failed, AL=%X",lf), bx, ax 66 | .else 67 | invoke printf, CStr("int 4B, ax=810Ch, BX=%u ok (ZF=%u)",lf), bx, cl 68 | .endif 69 | 70 | ;--- the second call should fail! 71 | 72 | mov dx, 0 73 | mov bx, channel 74 | mov ax,810Ch 75 | int 4bh 76 | setz cl 77 | .if (CARRY?) 78 | cbw 79 | invoke printf, CStr("int 4B, ax=810Ch, BX=%u failed, AL=%X",lf), bx, ax 80 | .else 81 | invoke printf, CStr("int 4B, ax=810Ch, BX=%u ok (ZF=%u)",lf), bx, cl 82 | .endif 83 | 84 | inc channel 85 | cmp channel, 4 86 | jb nextchannel 87 | 88 | exit: 89 | ret 90 | main endp 91 | 92 | start: 93 | mov ax, @data 94 | mov ds, ax 95 | mov bx, ss 96 | sub bx, ax 97 | shl bx, 4 98 | mov ss, ax 99 | add sp, bx 100 | call main 101 | mov ah, 4Ch 102 | int 21h 103 | 104 | END start 105 | -------------------------------------------------------------------------------- /Tools/JLOAD/History.txt: -------------------------------------------------------------------------------- 1 | 2 | v5.86: 3 | - Jemm's control notifications handled (DEVICE_REBOOT_NOTIFY). 4 | - fixed: 16-bit debug displays. 5 | - implemented Hook_V86_Fault/Unhook_V86_Fault, using Jemm's service 6 | table entry pV86Faults (v5.86). 7 | 8 | v5.85: 9 | - debug displays now done with @dprintf(). 10 | - V86 hooks won't modify IDT anymore. 11 | 12 | v5.84: 13 | - trap handling changed: Jemm's IO trap table is no longer imported, 14 | instead the old (=Jemm's) handler is called if the port isn't trapped 15 | by VMM. This allows to trap ISA DMA ports that are already trapped 16 | by Jemm. 17 | 18 | v5.83: 19 | - removed the option to link with MS COFF linker - current versions 20 | won't accept a base of 0xf8400000. 21 | - released under MIT license. 22 | - fixed: import of Jemm's IO port trap ranges did additionally trap 23 | "holes" in the DMA16 page register port range D0-DF. 24 | - flags PC_CACHEDIS and PC_CACHEWT supported for _PageCommitPhys(). 25 | - added _Allocate_GDT_Selector(), _Free_GDT_Selector(), Get_DDB(). 26 | - added possibility to suppress JLoad result msgs. 27 | v5.82: 28 | - fixed: JLMs with API didn't work correctly. 29 | - int 2Fh, ax=1684h: when a JLM entry point is returned ( in ES:DI ), 30 | AL is set to 0 to indicate success. 31 | v5.76: 32 | - linker changed from Digital Mars OPTLINK to jwlink 33 | - VMM.ASM: bugfix in _PageFree() 34 | v5.73: 35 | - bugfix: Hook_V86_Int_Chain might have messed the stack. 36 | - automatically alloc/free V86 breakpoint if v86 API is to be 37 | installed by a device. 38 | - when the first v86 API is installed, v86 int 2Fh is hooked to 39 | handle ax=1684h. 40 | - Option -u added. 41 | v5.72: 42 | - switched to JWasm assembler 43 | v5.71: 44 | - bugfix: in v5.70, JLoad's assumtion about location of Jemm's TSS 45 | was wrong. 46 | v5.69: 47 | - both '-' and '/' accepted for switches. 48 | - MoveMemory added to Jemm's service table. 49 | - DMA copy to/from buffer functions added. 50 | v5.68: 51 | - bugfix: DMA lock ignored flag to check for 64 kB border crossing. 52 | v5.60: 53 | - initial. 54 | 55 | -------------------------------------------------------------------------------- /Test/EMS4E.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;*** test EMS get/set page map 3 | 4 | .286 5 | .model small 6 | option casemap:none 7 | .stack 1024 8 | .dosseg 9 | .386 10 | 11 | CStr macro text:vararg 12 | local sym 13 | .const 14 | sym db text,0 15 | .code 16 | exitm 17 | endm 18 | 19 | lf equ 10 20 | 21 | .data 22 | mapstruct label byte 23 | dw 4 24 | dw 0A000h 25 | dw 0A400h 26 | dw 0A800h 27 | dw 0AC00h 28 | 29 | .data? 30 | 31 | buffer db 256 dup (?) 32 | 33 | .code 34 | 35 | include printf.inc 36 | 37 | emsstr1 db 'EMMXXXX0',0 38 | 39 | EMScheck proc uses si di 40 | 41 | mov ax, 3567h 42 | int 21h 43 | mov ax, es 44 | or ax, bx 45 | jz exit 46 | 47 | mov dx,1 48 | mov si,offset emsstr1 49 | mov di,000ah 50 | mov cx,8 51 | push ds 52 | push cs 53 | pop ds 54 | cld 55 | repz cmpsb 56 | pop ds 57 | jz found 58 | 59 | mov dx,0 60 | mov ah,46h 61 | int 67h 62 | and ah,ah 63 | jz found 64 | 65 | xor ax, ax 66 | jmp exit 67 | found: 68 | mov ax,1 69 | exit: 70 | ret 71 | 72 | EMScheck endp 73 | 74 | main proc c 75 | 76 | local handle:word 77 | 78 | call EMScheck 79 | and ax,ax 80 | jz sm1 81 | 82 | mov ax,4E03h 83 | int 67h 84 | cmp ah,00 85 | jnz sm2 86 | invoke printf, CStr("size to save all pages: %u",lf), ax 87 | 88 | mov di,offset buffer 89 | push ds 90 | pop es 91 | mov ax,4E00h 92 | int 67h 93 | cmp ah,00 94 | jnz sm3 95 | 96 | mov si,offset buffer 97 | mov ax,4E01h 98 | int 67h 99 | cmp ah,00 100 | jnz sm4 101 | invoke printf, CStr("Ok",lf) 102 | jmp exit 103 | 104 | sm1: 105 | invoke printf, CStr("EMM not found",lf) 106 | jmp exit 107 | sm2: 108 | movzx ax,ah 109 | invoke printf, CStr("int 67h, ax=4E03h failed, ah=%X",lf),ax 110 | jmp exit 111 | sm3: 112 | movzx ax,ah 113 | invoke printf, CStr("int 67h, ax=4E00h failed, ah=%X",lf),ax 114 | jmp exit 115 | sm4: 116 | movzx ax,ah 117 | invoke printf, CStr("int 67h, ax=4E01h failed, ah=%X",lf),ax 118 | exit: 119 | ret 120 | main endp 121 | 122 | start: 123 | mov ax,@data 124 | mov ds,ax 125 | mov cx,ss 126 | sub cx,ax 127 | shl cx,4 128 | mov ss,ax 129 | add sp,cx 130 | invoke main 131 | mov ah,4ch 132 | int 21h 133 | 134 | END start 135 | -------------------------------------------------------------------------------- /JLM/XCDROM32/XCDROM32.txt: -------------------------------------------------------------------------------- 1 | 2 | 1. About XCDROM32 3 | 4 | XCDROM32 is a JLM based on Jack R. Ellis' XCDROM Ultra-DMA CD-ROM driver. 5 | It supports PCI IDE controllers running in "legacy" or "native" mode. 6 | 7 | 8 | 2. Usage 9 | 10 | To load the driver, add the following line to your CONFIG.SYS: 11 | 12 | DEVICE=JLOAD.EXE XCDROM32.DLL [options] 13 | 14 | Options are: 15 | 16 | /32 use 32bit-IO in "PIO mode". This might not work with all devices, 17 | but if it does, it usually gives a speed boost for that mode. 18 | /AX disable "audio" functions. 19 | /D:name set device name. If this option is missing, the default device 20 | name is "XCDROM$$" 21 | /F "fast", uses DMA "scatter/gather" lists to allow transfers which 22 | cross a physical 64 kB address boundary. Might not work with all 23 | controllers. 24 | /L limits DMA to "low memory" below 640 kB. 25 | /Mn set/restrict UDMA mode to n (0 <= n <= 7). 26 | /Q quiet mode. 27 | /UX disables UltraDMA for all drives and uses "PIO mode" generally. 28 | /W handle (non-UDMA) drives which are capable of Multiword-DMA. 29 | 30 | 31 | 3. Details 32 | 33 | XCDROM32 has 3 modes of operation: 34 | 35 | 1. "direct" mode: the target address is used for DMA input. This usually 36 | is the fastest way and is used whenever possible. 37 | 2. "buffered" mode: the VDS DMA buffer is used for DMA input, then the 38 | content is copied to the target address. This mode is used if "direct 39 | mode" can't be used because target address is not aligned properly 40 | or - if option /F isn't set - because the target region crosses a 64 kB 41 | boundary. On modern CPUs the additional time needed for the memory copy 42 | should be negligible. 43 | 3. "PIO" mode: input is done without DMA. This mode should work with any 44 | IDE controller and CDROM/DVD. It is used if 45 | - /UX option is set. 46 | - the IDE controller doesn't support PCI Busmaster DMA. 47 | - the CD-ROM/DVD device is not in UDMA mode or /W option is set, but 48 | CD-ROM/DVD device has no valid Multiword-DMA mode set. 49 | - "buffered mode" cannot be used because VDS DMA buffer isn't 50 | accessible or is too small. 51 | 52 | 53 | 4. License 54 | 55 | XCDROM32 is released under the GNU GPL v2. See GNU_GPL.TXT for details. 56 | 57 | -------------------------------------------------------------------------------- /src/VDS.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- VDS definitions 3 | 4 | ;--- flags in DX used by various VDS functions 5 | 6 | VDSF_COPY equ 02h ;bit 1 - copy in/out of DMA buffer (8107/8108) 7 | VDSF_NOBUFFER equ 04h ;bit 2 - don't alloc DMA buffer (8103) 8 | VDSF_NOREMAP equ 08h ;bit 3 - change PTEs; Jemm ignores this flag! 9 | VDSF_64KALIGN equ 10h ;bit 4 10 | VDSF_128KALIGN equ 20h ;bit 5 11 | VDSF_PTE equ 40h ;bit 6 - 1=scatter_lock returns PTEs 12 | VDSF_NPPTE equ 80h ;bit 7 - allow non-present pages for scatter/gather remap 13 | 14 | ;--- error codes returned in AL by lock (8103) 15 | 16 | VDSERR_NOTCONTIGUOUS equ 1 ;region not in contiguous memory 17 | VDSERR_CROSSEDBOUNDS equ 2 ;region crossed alignemnt boundary 18 | VDSERR_CANTLOCKPAGES equ 3 ; 19 | VDSERR_NOBUFFER equ 4 ; 8107 20 | VDSERR_BUFFTOOSMALL equ 5 ; 8107 21 | VDSERR_BUFFINUSE equ 6 ; 22 | 23 | ;--- other VDS error codes 24 | 25 | VDSERR_07 equ 7 ; invalid memory region (8107) 26 | VDSERR_REG_NOTLOCKED equ 8 ; region wasn't locked (8106) 27 | VDSERR_NAVL_TOOSMALL equ 9 ; # of phys pages was > than table length (8105) 28 | VDSERR_INVAL_BUFFID equ 10 ; invalid buffer ID (8108,8109,810A) 29 | VDSERR_BNDVIOLATION equ 11 ; buffer boundary violated (8109,810A) 30 | VDSERR_INVAL_DMACHN equ 12 ; invalid DMA channel # (810B, 810C) 31 | VDSERR_DISCNTOVFL equ 13 ; disable cnt overflow (810B) 32 | VDSERR_DISCNTUNFL equ 14 ; disable cnt underflow (810C) 33 | VDSERR_FUNC_NOTSUPP equ 15 ; function not supported 34 | VDSERR_DXRSVDBITSSET equ 16 ; reserved flag bits set in DX (8102,8106,8108,8109,810A,810B,810C) 35 | 36 | ;--- DDS, used by 03-04, 07-08, 09-0A 37 | 38 | DDS struct 39 | dwSize dd ? ;+0 size of region 40 | dwOfs dd ? ;+4 offset virtual start address 41 | wSeg dw ? ;+8 segment/selector virtual start address (or 0000) 42 | wID dw ? ;+10 buffer ID 43 | dwPhys dd ? ;+12 physical address 44 | DDS ends 45 | 46 | ;--- EDDS, used by 05-06 47 | 48 | EDDS struct 49 | dwSize dd ? ;+0 50 | dwOfs dd ? ;+4 51 | wSeg dw ? ;+8 52 | wRes dw ? ;+10 53 | wNumAvail dw ? ;+12 54 | wNumUsed dw ? ;+14 55 | EDDS ends 56 | 57 | ;--- EDDS suffix for regions 58 | 59 | EDDSRG struct 60 | dwPhysAddr dd ? ;+16 61 | dwSizeRg dd ? ;+20 62 | EDDSRG ends 63 | 64 | ;--- EDDS suffix for PTEs 65 | 66 | EDDSPT struct 67 | dwPTE dd ? ;+16 68 | EDDSPT ends 69 | 70 | -------------------------------------------------------------------------------- /Include/FILEACC.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- dos file access for JLMs 3 | ;--- although addresses are linear, they must 4 | ;--- be within 64 kB distance of v86 DS register. 5 | 6 | w textequ 7 | 8 | ;--- open file (for reading) 9 | ;--- edx = file name 10 | ;--- out: ax=handle 11 | 12 | OpenFile proc 13 | movzx eax,word ptr [ebp].Client_Reg_Struc.Client_DS 14 | shl eax, 4 15 | sub edx, eax 16 | mov w [ebp].Client_Reg_Struc.Client_EDX, dx 17 | mov w [ebp].Client_Reg_Struc.Client_EAX, 3D00h 18 | mov eax,21h 19 | @VMMCall Exec_Int 20 | mov ax,w [ebp].Client_Reg_Struc.Client_EAX 21 | bt [ebp].Client_Reg_Struc.Client_EFlags,0 22 | ret 23 | OpenFile endp 24 | 25 | ;--- close file 26 | ;--- ebx = file handle 27 | 28 | CloseFile proc 29 | mov w [ebp].Client_Reg_Struc.Client_EBX, bx 30 | mov w [ebp].Client_Reg_Struc.Client_EAX, 3E00h 31 | mov eax,21h 32 | @VMMCall Exec_Int 33 | bt [ebp].Client_Reg_Struc.Client_EFlags,0 34 | ret 35 | CloseFile endp 36 | 37 | ;--- get file size 38 | ;--- ebx = file handle 39 | ;--- out: eax=file size 40 | 41 | GetFileSize proc 42 | mov w [ebp].Client_Reg_Struc.Client_EBX, bx 43 | mov w [ebp].Client_Reg_Struc.Client_EAX, 4202h ;goto EOF 44 | mov w [ebp].Client_Reg_Struc.Client_ECX, 0 45 | mov w [ebp].Client_Reg_Struc.Client_EDX, 0 46 | mov eax,21h 47 | @VMMCall Exec_Int 48 | bt [ebp].Client_Reg_Struc.Client_EFlags,0 49 | jc exit 50 | mov ax, w [ebp].Client_Reg_Struc.Client_EDX 51 | shl eax, 16 52 | mov ax, w [ebp].Client_Reg_Struc.Client_EAX 53 | push eax 54 | mov w [ebp].Client_Reg_Struc.Client_EAX, 4200h ;goto start 55 | mov w [ebp].Client_Reg_Struc.Client_ECX, 0 56 | mov w [ebp].Client_Reg_Struc.Client_EDX, 0 57 | mov eax,21h 58 | @VMMCall Exec_Int 59 | pop eax 60 | bt [ebp].Client_Reg_Struc.Client_EFlags,0 61 | exit: 62 | ret 63 | GetFileSize endp 64 | 65 | ;--- Read file into buffer 66 | ;--- bx = file handle 67 | ;--- cx = bytes to read 68 | ;--- edx = buffer (in conv. memory) 69 | ;--- out: eax=bytes read 70 | 71 | ReadFile proc 72 | movzx eax,w [ebp].Client_Reg_Struc.Client_DS 73 | shl eax, 4 74 | sub edx, eax 75 | mov w [ebp].Client_Reg_Struc.Client_EBX, bx 76 | mov w [ebp].Client_Reg_Struc.Client_ECX, cx 77 | mov w [ebp].Client_Reg_Struc.Client_EDX, dx 78 | mov w [ebp].Client_Reg_Struc.Client_EAX, 3F00h 79 | mov eax,21h 80 | @VMMCall Exec_Int 81 | movzx eax, w [ebp].Client_Reg_Struc.Client_EAX 82 | bt [ebp].Client_Reg_Struc.Client_EFlags,0 83 | ret 84 | ReadFile endp 85 | 86 | -------------------------------------------------------------------------------- /JLM/IOTRAP/TESTIOT.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- tsr to test JLM IOTRAP. 3 | ;--- it installs a callback which is called whenever port 100h 4 | ;--- is accessed. 5 | ;--- the callback displays some colored characters on line 25. 6 | ;--- assemble: JWasm -bin -Fo testiot.com testiot.asm 7 | 8 | .286 9 | .model tiny 10 | .stack 2048 11 | .dosseg 12 | .386 13 | 14 | .data 15 | 16 | szOK1 db "IOTRAP found.",13,10,'$' 17 | szOK2 db "TESTIOT installed.",13,10,'$' 18 | szErr1 db "IOTRAP is NOT installed!",13,10,'$' 19 | szErr2 db "IOTRAP has wrong version!",13,10,'$' 20 | szErr3 db "register callback failed!",13,10,'$' 21 | 22 | .code 23 | 24 | org 100h 25 | 26 | start: 27 | mov ax, 1684h ;get IOTRAP's entry point 28 | mov bx, 6661h 29 | int 2Fh 30 | cmp al,0 ;IOTRAP installed? 31 | jnz not_installed 32 | push es 33 | push di 34 | mov bp,sp 35 | mov dx,offset szOK1 36 | mov ah,9 37 | int 21h 38 | mov ax,0000 ;call "get version" 39 | call dword ptr [bp] 40 | ;--- check version and exit if not ok 41 | ; cmp ax,??? 42 | ; jc wrong_version 43 | ;--- API: CX:DX=CS:IP of callback, BX=param 44 | mov cx,cs 45 | mov dx,offset iocb 46 | mov bx,0 47 | mov ax,0001 ;call "register callback" 48 | call dword ptr [bp] 49 | jc register_failed 50 | mov dx,offset szOK2 51 | mov ah,9 52 | int 21h 53 | mov dx,offset resident 54 | shr dx,4 55 | inc dx 56 | mov ax,3100h 57 | int 21h 58 | 59 | iocb: 60 | 61 | ;--- callback when i/o was detected. 62 | ;--- cpu is in 16-bit protected-mode, ring 0. 63 | ;--- EAX=data of IO 64 | ;--- DX=IO port 65 | ;--- CX=type of IO 66 | ;--- BX=value when callback was "registered" 67 | ;--- DS=data segment 68 | ;--- ES=flat segment 69 | ;--- SS:ESP=flat host stack! 70 | 71 | push esi 72 | mov esi,0B8000h 73 | 74 | ;--- display '*#!+' in colors at line 25 75 | 76 | mov word ptr es:[esi+160*24+0],'*'+100h*40h 77 | mov word ptr es:[esi+160*24+2],'#'+100h*51h 78 | mov word ptr es:[esi+160*24+4],'!'+100h*62h 79 | mov word ptr es:[esi+160*24+6],'+'+100h*73h 80 | pop esi 81 | retd ;a 32bit RETF is needed!!! 82 | 83 | resident label byte 84 | 85 | not_installed: 86 | mov dx,offset szErr1 87 | mov ah,9 88 | int 21h 89 | int 20h 90 | wrong_version: 91 | mov dx,offset szErr2 92 | mov ah,9 93 | int 21h 94 | int 20h 95 | register_failed: 96 | mov dx,offset szErr3 97 | mov ah,9 98 | int 21h 99 | int 20h 100 | 101 | end start 102 | 103 | -------------------------------------------------------------------------------- /Test/EMS5B.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;*** test EMS 5B 3 | ;--- 5b00: get alternate map register set ( if BL=0 on ret, es:di will be current pointer to context save area ) 4 | ;--- 5b01: set alternate map register set in BL 5 | ;--- if BL=0, es:di will be current context save area 6 | ;--- 5b02: get size of alternate map register set in dx 7 | 8 | .286 9 | .model small 10 | option casemap:none 11 | option casemap:none 12 | .stack 1024 13 | .dosseg 14 | .386 15 | 16 | CStr macro text:vararg 17 | local sym 18 | .const 19 | sym db text,0 20 | .code 21 | exitm 22 | endm 23 | 24 | lf equ 10 25 | 26 | 27 | .data 28 | 29 | wCSize dw 0 30 | 31 | .data? 32 | 33 | buffer db 1024 dup (?) 34 | 35 | .code 36 | 37 | include printf.inc 38 | 39 | memset proc c uses di pMem:ptr, wValue:word, wSize:word 40 | mov di, pMem 41 | mov ax, wValue 42 | mov cx, wSize 43 | cld 44 | rep stosb 45 | ret 46 | memset endp 47 | 48 | main proc c 49 | 50 | mov ax,3567h 51 | int 21h 52 | mov ax,bx 53 | mov cx,es 54 | or ax,cx 55 | jnz @F 56 | invoke printf, CStr( "EMM not found",lf) 57 | jmp exit 58 | @@: 59 | mov dx, -1 60 | mov ax, 5B02h 61 | int 67h 62 | mov [wCSize], dx 63 | movzx ax, ah 64 | invoke printf, CStr("int 67h (ax=5B02h): ah=%X, dx=%X", lf), ax, dx 65 | cmp [wCSize], sizeof buffer 66 | ja error1 67 | 68 | push ds 69 | pop es 70 | invoke memset, addr buffer, 0, sizeof buffer 71 | 72 | mov ax, 5B00h 73 | int 67h 74 | movzx ax, ah 75 | movzx bx, bl 76 | invoke printf, CStr("int 67h (ax=5B00h): ah=%X, bl=%X, es:di=%X:%X", lf), ax, bx, es, di 77 | 78 | mov di, offset buffer 79 | push ds 80 | pop es 81 | push es 82 | push di 83 | mov ax, 5B01h 84 | mov bl, 0 85 | int 67h 86 | pop cx 87 | pop dx 88 | movzx ax, ah 89 | movzx bx, bl 90 | invoke printf, CStr("int 67h (ax=5B01h, bl=0, es:di=%X:%X): ah=%X, bl=%X, es:di=%X:%X", lf), dx, cx, ax, bx, es, di 91 | exit: 92 | ret 93 | error1: 94 | invoke printf, CStr("size of context save area too small", lf) 95 | jmp exit 96 | 97 | main endp 98 | 99 | start: 100 | mov ax,@data 101 | mov ds,ax 102 | mov cx,ss 103 | sub cx,ax 104 | shl cx,4 105 | mov ss,ax 106 | add sp,cx 107 | mov dx,es 108 | mov ax,ss 109 | sub ax,dx 110 | mov dx,sp 111 | shr dx,4 112 | add ax,dx 113 | mov bx,ax 114 | mov ah,4ah 115 | int 21h 116 | invoke main 117 | mov ah,4ch 118 | int 21h 119 | 120 | END start 121 | -------------------------------------------------------------------------------- /Test/TESTDMA2.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- test FD read in UMB 3 | ;--- using Int 13h 4 | 5 | .286 6 | .model small 7 | .stack 2048 8 | .dosseg 9 | .386 10 | 11 | ?SIZE equ 1000h 12 | 13 | CStr macro text:vararg 14 | local sym 15 | .const 16 | sym db text,0 17 | .code 18 | exitm 19 | endm 20 | 21 | lf equ 10 22 | 23 | .code 24 | 25 | include printf.inc 26 | 27 | writefile proc c pName:ptr, pBuffer:ptr far16, wSize:word 28 | mov dx, pName 29 | xor cx, cx 30 | mov ax,3c00h 31 | int 21h 32 | jc fail1 33 | mov bx, ax 34 | push ds 35 | lds dx, pBuffer 36 | mov cx, wSize 37 | mov ax, 4000h 38 | int 21h 39 | pop ds 40 | jc fail2 41 | mov ah, 3Eh 42 | int 21h 43 | ret 44 | fail1: 45 | invoke printf, CStr("create file failed",10) 46 | ret 47 | fail2: 48 | invoke printf, CStr("write file failed",10) 49 | ret 50 | writefile endp 51 | 52 | main proc c 53 | 54 | local stat1:word 55 | local stat2:word 56 | local wSeg:word 57 | 58 | mov ax, 5802h ;get status umb 59 | int 21h 60 | xor ah,ah 61 | mov stat1, ax 62 | 63 | mov ax, 5800h ;get memory alloc strategy 64 | int 21h 65 | xor ah,ah 66 | mov stat2, ax 67 | 68 | mov bx, 81h ;first high,then low 69 | mov ax, 5801h ;set memory alloc strat 70 | int 21h 71 | mov bx, 1 ;include umbs 72 | mov ax, 5803h ;umb link restore 73 | int 21h 74 | 75 | mov bx, ?SIZE shr 4 ; allocate mem block 76 | mov ah, 48h 77 | int 21h 78 | jc exit 79 | mov wSeg, ax 80 | 81 | mov es, ax 82 | xor di, di 83 | mov cx, ?SIZE 84 | mov al, 00 85 | rep stosb 86 | 87 | push es 88 | mov es, wSeg ; es:bx=transfer buffer 89 | mov bx, 0 90 | mov cx, 1 ; cl[0-5]: sector#; ch+cl[6-7]:cylinder 91 | mov dh, 0 ; dh=head 92 | mov dl, 0 ; dl=0 -> A: 93 | mov ax, 0200h or (?SIZE shr 9) ; al=# of sectors to read 94 | int 13h 95 | pop es 96 | jc error 97 | invoke printf, CStr("reading drive A: ok",10) 98 | mov ax, wSeg 99 | invoke writefile, CStr("~XXX.TMP"), ax::bx, (?SIZE shr 9)*200h 100 | jmp exit 101 | error: 102 | movzx ax, ah 103 | invoke printf, CStr("reading drive A: failed, error code=%X",10), ax 104 | exit: 105 | mov bx, stat1 106 | mov ax, 5803h 107 | int 21h 108 | mov bx, stat2 109 | mov ax, 5801h ; set memory alloc strag 110 | int 21h 111 | ret 112 | main endp 113 | 114 | start: 115 | mov ax, @data 116 | mov ds, ax 117 | mov bx, ss 118 | sub bx, ax 119 | shl bx, 4 120 | mov ss, ax 121 | add sp, bx 122 | call main 123 | mov ah, 4Ch 124 | int 21h 125 | 126 | END start 127 | -------------------------------------------------------------------------------- /Tools/VCPI/VIOOUT.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- vio output for 16-bit protected-mode 3 | 4 | @getcursorpos macro 5 | movzx ebx, byte ptr ds:[462h];page 6 | mov bx, ds:[EBX*2+450h] 7 | endm 8 | 9 | @setcursorpos macro 10 | movzx ebx, byte ptr ds:[462h];page 11 | mov ds:[EBX*2+450h], ax 12 | endm 13 | 14 | ;--- print a char 15 | ;--- no registers modified 16 | 17 | VioPutChar proc 18 | 19 | local wCols:word 20 | local bChar:byte 21 | local bRows:byte 22 | 23 | push ds 24 | pushad 25 | 26 | mov bChar, al 27 | mov dx, FLATSEL 28 | mov ds, dx 29 | mov ch, ds:[0484h] ; rows-1 30 | mov cl, ds:[044Ah] ; cols 31 | mov bRows, ch 32 | @getcursorpos ; bh=row, bl=col 33 | mov al, bh ;row pos 34 | mov ch, 0 35 | mov wCols, cx 36 | mul cl 37 | add ax, ax 38 | mov bh, 00 ; bx=col pos 39 | add bx, bx 40 | add bx, ax 41 | mov si, ds:[044Eh] ; page offset 42 | cmp word ptr ds:[0463H],3B4h 43 | jz @F 44 | add si, 8000h 45 | @@: 46 | movzx esi, si 47 | add esi, 0B0000h 48 | 49 | mov al, bChar 50 | 51 | cmp al, cr 52 | jnz @F 53 | mov ax, bx 54 | shr ax, 1 55 | div cl 56 | mov al, ah 57 | xor ah, ah 58 | add ax, ax 59 | sub bx, ax 60 | jmp char_done 61 | @@: 62 | cmp al, lf 63 | jnz @F 64 | add bx, cx 65 | add bx, cx 66 | jmp char_done 67 | @@: 68 | movzx ebx, bx 69 | mov ds:[ebx+esi], al 70 | inc bx 71 | inc bx 72 | char_done: 73 | mov al, bRows 74 | inc al 75 | mul cl 76 | add ax, ax 77 | cmp bx, ax 78 | jc @F 79 | call scrollup 80 | mov bx, ax 81 | @@: 82 | mov ax, bx 83 | push ax 84 | mov cx, wCols 85 | shr ax, 1 86 | div cl 87 | xchg al, ah 88 | @setcursorpos 89 | pop ax 90 | call cursorset 91 | popad 92 | pop ds 93 | ret 94 | 95 | cursorset: 96 | add ax, ds:[044EH] ;offset page 97 | mov dx, ds:[0463H] 98 | shr ax, 1 ;the CRT offset is one plane only, no attribute bytes 99 | mov cl, al ;first high byte 100 | mov al, 0eh 101 | out dx, ax 102 | mov ah, cl ;then low byte 103 | mov al, 0fh 104 | out dx, ax 105 | retn 106 | 107 | scrollup: ;scroll up one line 108 | push es 109 | push ds 110 | pop es 111 | mov edi, esi 112 | push di 113 | movzx esi, wCols 114 | lea esi, [esi*2+edi] 115 | mov cl, byte ptr wCols 116 | mov al, bRows 117 | mul cl 118 | movzx ecx, ax 119 | shr cx,1 120 | rep movsd es:[edi], ds:[esi] 121 | push di 122 | mov cx, wCols 123 | mov eax,07200720h 124 | shr cx, 1 125 | rep stosd es:[edi] 126 | pop ax 127 | pop di 128 | sub ax, di 129 | pop es 130 | retn 131 | 132 | VioPutChar endp 133 | 134 | -------------------------------------------------------------------------------- /src/XMS.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- XMS definitions 3 | 4 | XMS_GETVERSION equ 0h 5 | XMS_ENABLEA20 equ 5h 6 | XMS_DISABLEA20 equ 6h 7 | XMS_V2_QUERYMEM equ 8h 8 | XMS_V2_ALLOCEMB equ 9h 9 | XMS_FREEEMB equ 0Ah 10 | XMS_LOCKEMB equ 0Ch 11 | XMS_UNLOCKEMB equ 0Dh 12 | XMS_ALLOCUMB equ 10h 13 | XMS_V3_QUERYMEM equ 88h 14 | XMS_V3_ALLOCEMB equ 89h 15 | 16 | XMS_HANDLE struct 17 | xh_flags DB ? 18 | xh_locks DB ? 19 | xh_baseK DD ? 20 | xh_sizeK DD ? 21 | XMS_HANDLE ends 22 | 23 | LPXMS_HANDLE typedef ptr XMS_HANDLE 24 | 25 | ;--- XMS handle flags 26 | 27 | XMSF_FREE equ 1 ;handle describes a free EMB 28 | XMSF_USED equ 2 ;handle describes a used EMB 29 | XMSF_INPOOL equ 4 ;handle is free 30 | 31 | 32 | XMS_HANDLETABLE struct 33 | xht_sig DB ? 34 | xht_sizeof DB ? 35 | xht_numhandles DW ? 36 | xht_pArray DD ? ;converted to linear address for 32bit code! 37 | XMS_HANDLETABLE ends 38 | 39 | XMS_MOVE struct 40 | len dd ? ; +0 block length in bytes 41 | src_handle dw ? ; +4 source handle 42 | src_offset dd ? ; +6 offset into source 43 | dest_handle dw ? ; +10 destination handle 44 | dest_offset dd ? ; +12 offset into destination 45 | XMS_MOVE ends 46 | 47 | if ?INTEGRATED 48 | if ?XMS35 49 | XMS_MOVEX struct 50 | XMS_MOVE <> 51 | src_hi db ? ; bits 32-39 of src 52 | dest_hi db ? ; bits 32-39 of dst 53 | XMS_MOVEX ends 54 | endif 55 | endif 56 | 57 | ;--- XMS error codes 58 | 59 | XMS_NOT_IMPLEMENTED equ 80h 60 | XMS_VDISK_DETECTED equ 81h 61 | XMS_A20_FAILURE equ 82h 62 | XMS_DRIVER_FAILURE equ 8eh 63 | XMS_DRIVER_FATAL equ 8fh 64 | XMS_HMA_NOT_THERE equ 90h 65 | XMS_HMA_IN_USE equ 91h 66 | XMS_HMAREQ_TOO_SMALL equ 92h 67 | XMS_HMA_NOT_USED equ 93h 68 | XMS_A20_STILL_ENABLED equ 94h 69 | XMS_ALL_MEM_ALLOCATED equ 0a0h 70 | XMS_NO_HANDLE_LEFT equ 0a1h 71 | XMS_INVALID_HANDLE equ 0a2h 72 | XMS_INVALID_SOURCE_HANDLE equ 0a3h 73 | XMS_INVALID_SOURCE_OFFSET equ 0a4h 74 | XMS_INVALID_DESTINATION_HANDLE equ 0a5h 75 | XMS_INVALID_DESTINATION_OFFSET equ 0a6h 76 | XMS_INVALID_LENGTH equ 0a7h 77 | XMS_INVALID_OVERLAP equ 0a8h 78 | XMS_PARITY_ERROR equ 0a9h 79 | XMS_BLOCK_NOT_LOCKED equ 0aah 80 | XMS_BLOCK_LOCKED equ 0abh 81 | XMS_LOCK_COUNT_OVERFLOW equ 0ach 82 | XMS_LOCK_FAILED equ 0adh 83 | XMS_ONLY_SMALLER_UMB equ 0b0h 84 | XMS_NO_UMB_AVAILABLE equ 0b1h 85 | XMS_UMB_SEGMENT_NR_INVALID equ 0b2h 86 | 87 | -------------------------------------------------------------------------------- /Test/XMSTEST3.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- test ah=0Eh (get handle info) 3 | ;--- Public Domain. 4 | ;--- to be assembled with JWasm or Masm v6. 5 | 6 | .model small 7 | .386 8 | .dosseg 9 | .stack 2048 10 | 11 | cr equ 13 12 | lf equ 10 13 | 14 | BUFFSIZ equ 10000h 15 | 16 | ;--- define a string constant 17 | 18 | CStr macro string:vararg 19 | local xxx 20 | .const 21 | xxx db string 22 | db 0 23 | .code 24 | exitm 25 | endm 26 | 27 | .data 28 | 29 | xmsadr dd 0 ;XMS host call address 30 | 31 | .code 32 | 33 | include printf.inc 34 | 35 | runtest proc 36 | 37 | local handle:word 38 | local dwSize:dword 39 | 40 | mov edx,10000h ;allocate 65536 kB 41 | call runtest1 42 | mov edx,0ffffh ;allocate 65535 kB 43 | call runtest1 44 | ret 45 | runtest1: 46 | mov dwSize,edx 47 | mov ah,89h ;alloc ext. memory block (size EDX) 48 | mov bl,0 49 | call [xmsadr] 50 | cmp ax,1 51 | jz @F 52 | invoke printf, CStr("xms function 89h failed (bl=%X, edx=%lX)",lf), bl, edx 53 | jmp failed 54 | @@: 55 | mov handle,dx 56 | invoke printf, CStr("xms function 89h(size %lu kB): dx=%X",lf), dwSize, dx 57 | 58 | ;--- function 0Eh should fail, since size doesn't fit in 16-bit register 59 | mov edx,12340000h ;set hiword(edx) to a known value 60 | mov dx,handle 61 | mov bx,0 ;set bx to a known value 62 | mov ah,0eh ;get handle info (v2) 63 | call [xmsadr] 64 | invoke printf, CStr("xms function 0Eh: ax=%X, bx=%X, edx=%lX",lf), ax, bx, edx 65 | 66 | ;--- function 8Eh should succeed 67 | mov edx,12340000h ;set hiword(edx) to a known value 68 | mov dx,handle 69 | mov bx,0 ;set bx to a known value 70 | mov ah,8eh ;get handle info (v3) 71 | call [xmsadr] 72 | invoke printf, CStr("xms function 8Eh: ax=%X, bx=%X, edx=%lX",lf), ax, bx, edx 73 | 74 | mov dx,handle 75 | mov ah,0ah ;free handle 76 | call [xmsadr] 77 | failed: 78 | retn 79 | runtest endp 80 | 81 | ;--- main 82 | 83 | main proc c 84 | 85 | mov ax,4300h 86 | int 2fh 87 | test al,80h ;xms host found? 88 | jnz main1 89 | invoke printf, CStr("no XMS host found",lf) 90 | jmp exit 91 | main1: 92 | mov ax,4310h ;get XMS call address 93 | int 2fh 94 | mov word ptr xmsadr+0,bx 95 | mov word ptr xmsadr+2,es 96 | ; invoke printf, CStr("XMS call address: %X:%X",lf),word ptr [xmsadr+2],word ptr [xmsadr+0] 97 | call runtest 98 | exit: 99 | ret 100 | main endp 101 | 102 | ;--- init 103 | 104 | start proc 105 | 106 | mov ax,@data 107 | mov ds,ax 108 | mov cx,ss 109 | sub cx,ax 110 | shl cx,4 111 | mov ss,ax 112 | add sp,cx 113 | call main 114 | mov ah,4Ch 115 | int 21h 116 | start endp 117 | 118 | END start 119 | -------------------------------------------------------------------------------- /src/DEBUG.INC: -------------------------------------------------------------------------------- 1 | 2 | @dbgdef macro name_ 3 | ifndef name_ 4 | name_ equ 0 5 | endif 6 | endm 7 | 8 | @dbgdef ?V86DBG ;1=enable displays in V86 monitor 9 | @dbgdef ?V86XDBG ;1=enable more displays in V86 monitor (IRQs!) 10 | @dbgdef ?DMADBG ;1=enable DMA related displays 11 | @dbgdef ?VDSDBG ;1=enable VDS related displays 12 | @dbgdef ?EMSDBG ;1=enable EMS related displays 13 | @dbgdef ?UMBDBG ;1=enable UMB related displays 14 | @dbgdef ?A20DBG ;1=enable A20 related displays 15 | @dbgdef ?EMBDBG ;1=enable EMB related displays (?INTEGRATED only) 16 | @dbgdef ?EMUDBG ;1=enable opcode emulation related displays 17 | @dbgdef ?I15DBG ;1=enable INT 15h, AH=87h related displays 18 | @dbgdef ?VCPIDBG ;1=enable VCPI related displays 19 | @dbgdef ?VCPIXDBG;1=enable VCPI mode switch displays 20 | @dbgdef ?EMXDBG ;1=enable EMMXXXX0 related displays 21 | @dbgdef ?POOLDBG ;1=enable memory pool related displays 22 | @dbgdef ?INITDBG ;1=enable displays in protected-mode initialisation 23 | @dbgdef ?HLTDBG ;1=enable displays for true HLT emulation 24 | @dbgdef ?UNLDBG ;1=enable display for "unload" 25 | @dbgdef ?RBTDBG ;1=enable reboot debug 26 | @dbgdef ?EXCDBG ;1=enable displays in exception handler 27 | @dbgdef ?PHYSDBG ;1=enable displays in physical memory handling 28 | @dbgdef ?MAPDBG ;1=enable mapping handling 29 | 30 | ?USEMONO equ 0 ;1=use monochrome monitor for dbg displays 31 | 32 | ?DBGOUT equ ?V86DBG + ?DMADBG + ?VDSDBG + ?EMSDBG + ?UMBDBG + ?A20DBG + ?EMBDBG + ?EMUDBG + ?I15DBG + ?VCPIDBG + ?USEMONO + ?POOLDBG + ?INITDBG + ?HLTDBG + ?UNLDBG + ?RBTDBG + ?EXCDBG + ?PHYSDBG + ?MAPDBG 33 | 34 | CStr macro text:vararg 35 | local sym 36 | .text$03s segment byte flat 'CODE' 37 | sym db text,0 38 | .text$03s ends 39 | exitm 40 | endm 41 | 42 | @WaitKey macro keycode, bCond 43 | local sm1 44 | if bCond 45 | pushfd 46 | push eax 47 | sm1: 48 | in al,64h ;data from keyboard controller? 49 | test al,1 50 | jz sm1 51 | mov ah,al 52 | in al,60h 53 | test ah,20h ;mouse device? 54 | jnz sm1 55 | cmp al,keycode+80h ;wait for key released 56 | jnz sm1 57 | pop eax 58 | popfd 59 | endif 60 | endm 61 | 62 | ;--- formatted output ( since v5.83 ) 63 | ifdef _DEBUG 64 | 65 | dprintf proto c :ptr, :vararg 66 | 67 | @dprintf macro bCond, fmt, args:vararg 68 | if bCond 69 | ifnb 70 | invoke dprintf, CStr(fmt), args 71 | else 72 | invoke dprintf, CStr(fmt) 73 | endif 74 | endif 75 | endm 76 | else 77 | @dprintf textequ <;> 78 | endif 79 | 80 | @DebugBreak macro 81 | ifdef _DEBUG 82 | int 3 83 | endif 84 | endm 85 | 86 | @CheckBlockIntegrity macro 87 | if ?POOLDBG 88 | call CheckBlockIntegrity 89 | endif 90 | endm 91 | 92 | -------------------------------------------------------------------------------- /Test/I15MOVE.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;*** move block by int 15h, ah=87h 3 | 4 | .286 5 | .model small 6 | .stack 2048 7 | .dosseg 8 | .386 9 | 10 | lf equ 10 11 | 12 | CStr macro text:vararg 13 | local sym 14 | .const 15 | sym db text,0 16 | .code 17 | exitm 18 | endm 19 | 20 | .data 21 | 22 | gdt label byte 23 | dq 0 24 | dq 0 25 | 26 | dw -1 27 | wSrc dw 0 28 | bSrc db 0 29 | db 0F3h 30 | db 0 31 | db 0 32 | 33 | dw -1 34 | wDst dw 0 35 | bDst db 0 36 | db 0F3h 37 | db 0 38 | db 0 39 | 40 | dq 0 41 | dq 0 42 | 43 | .code 44 | 45 | include printf.inc 46 | 47 | main proc c 48 | 49 | local mblock:word 50 | 51 | mov ah,48h 52 | mov bx,4000h ;alloc 256 kB 53 | int 21h 54 | jc nomem 55 | mov mblock,ax 56 | movzx eax,ax 57 | shl eax, 4 ;get blocks linear address 58 | add eax, 0FFCh 59 | lea edx, [eax+20000h] 60 | mov wSrc, ax 61 | mov wDst, dx 62 | shr eax, 16 63 | shr edx, 16 64 | mov bSrc, al 65 | mov bDst, dl 66 | 67 | call clearblock 68 | mov cx,8000h 69 | push ds 70 | pop es 71 | mov si, offset gdt 72 | mov ah,87h 73 | stc 74 | int 15h 75 | jc error 76 | movzx ax,ah 77 | invoke printf, CStr("int 15h, ah=87, cx=%X ok, returned with ah=%X",lf),cx, ax 78 | call testblock 79 | 80 | call clearblock 81 | mov cx,4000h 82 | push ds 83 | pop es 84 | mov si, offset gdt 85 | mov ah,87h 86 | stc 87 | int 15h 88 | jc error 89 | movzx ax,ah 90 | invoke printf, CStr("int 15h, ah=87, cx=%X ok, returned with ah=%X",lf),cx, ax 91 | call testblock 92 | 93 | ;--- this call should fail, max words to copy is 8000h 94 | 95 | call clearblock 96 | mov cx,0C000h 97 | push ds 98 | pop es 99 | mov si, offset gdt 100 | mov ah,87h 101 | stc 102 | int 15h 103 | jc error 104 | invoke printf, CStr("int 15h, ah=87, cx=%X ok, returned with ah=%X",lf),cx, ax 105 | call testblock 106 | 107 | ret 108 | error: 109 | movzx ax,ah 110 | invoke printf, CStr("int 15h, ah=87, CX=%Xh returned with C, AH=%X",lf), cx, ax 111 | ret 112 | nomem: 113 | invoke printf, CStr("out of DOS memory",lf) 114 | ret 115 | 116 | clearblock: 117 | mov cl,4 118 | mov eax,11111111h 119 | mov es, mblock 120 | next64kb: 121 | push cx 122 | xor di, di 123 | mov cx, 4000h 124 | rep stosd 125 | mov dx, es 126 | add dx, 1000h 127 | mov es, dx 128 | add eax,11111111h 129 | pop cx 130 | dec cl 131 | jnz next64kb 132 | retn 133 | testblock: 134 | retn 135 | 136 | main endp 137 | 138 | start: 139 | mov bx, sp 140 | mov cx, ss 141 | mov dx, es 142 | sub cx, dx 143 | shr bx, 4 144 | add bx, cx 145 | mov ah, 4Ah 146 | int 21h 147 | mov ax,@data 148 | mov ds,ax 149 | mov cx,ss 150 | sub cx,ax 151 | shl cx,4 152 | mov ss,ax 153 | add sp,cx 154 | call main 155 | mov ax,4c00h 156 | int 21h 157 | 158 | END start 159 | -------------------------------------------------------------------------------- /src/EMU.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- privileged opcode emulation 3 | ;--- copyright Tom Ehlert 4 | 5 | ;--- to be assembled with JWasm or Masm v6.1+ 6 | 7 | .486P 8 | .model FLAT 9 | option proc:private 10 | option dotname 11 | 12 | include jemm.inc ;common declarations 13 | include jemm32.inc ;declarations for Jemm32 14 | include debug.inc 15 | 16 | EMUCLTS equ 0 ; 1=emulate CLTS ( resets TS bit in CR0 ) 17 | 18 | ;--- publics/externals 19 | 20 | include external.inc 21 | 22 | ; assume SS:FLAT,DS:FLAT,ES:FLAT 23 | 24 | .text$01 SEGMENT 25 | 26 | RunEmuInstr: 27 | DB 0Fh 28 | EmuInstr DB 90h,90h ; run self-modifying code here 29 | ret 30 | 31 | .text$01 ends 32 | 33 | .text$03 segment 34 | 35 | @v86popregX macro 36 | mov esp,ebp 37 | POPAD 38 | endm 39 | 40 | ;--- emulate some privileged 0Fh opcodes (not HLT) 41 | ;--- ebp -> client struct 42 | ;--- ESI -> linear address of CS:EIP 43 | ;--- AL==0Fh 44 | ;--- this is not called, but jumped to 45 | 46 | ExtendedOp proc public 47 | mov al,[esi+1] 48 | if EMUCLTS 49 | cmp al,6 50 | je @@clts 51 | endif 52 | cmp al,9 53 | je @@wbinvd 54 | cmp al,8 55 | je @@invd 56 | cmp al,30h 57 | je @@wrmsr 58 | cmp al,31h ; whether RDTSC is privileged depends on CR4, bit 2 (TSD) 59 | je @@rdtsc 60 | cmp al,32h 61 | je @@rdmsr 62 | cmp al,20h 63 | jb V86_Exc0D ; not an opcode we emulate 64 | cmp al,23h 65 | ja V86_Exc0D 66 | 67 | ; opcodes 0F 20 xx to 0F 23 xx emulated via self-modifying code 68 | 69 | mov ah,[esi+2] ; get third byte of opcode 70 | mov WORD PTR [EmuInstr+0],ax 71 | add [ebp].Client_Reg_Struc.Client_EIP,3 ; jump over emulated instruction 72 | @v86popregX 73 | call RunEmuInstr 74 | add esp,4+4 ; eat error code & "int#" 75 | iretd 76 | if EMUCLTS 77 | @@clts: 78 | clts ; 0f 06 is clts opcode 79 | jmp @@invdshare 80 | endif 81 | @@invd: 82 | invd ; 0f 08 is invd opcode 83 | jmp @@invdshare 84 | @@wbinvd: 85 | wbinvd ; 0f 09 is wbinvd opcode 86 | @@invdshare: 87 | @v86popregX 88 | jmp @@twoeat 89 | 90 | @@wrmsr: 91 | @v86popregX 92 | @wrmsr 93 | jmp @@twoeat 94 | 95 | ; early pentiums and such will throw an exception on rdtsc instruction in V86 96 | ; regardless of CR4 setting, later CPU versions won't 97 | 98 | @@rdtsc: 99 | @v86popregX 100 | @rdtsc 101 | jmp @@twoeat 102 | 103 | @@rdmsr: 104 | @v86popregX 105 | @rdmsr ; rdmsr opcode 106 | 107 | @@twoeat: 108 | add esp,4+4 ; eat return address and error code 109 | add [esp].IRETDV86._Eip,2 ; jump over instruction 110 | iretd 111 | 112 | align 4 113 | 114 | ExtendedOp endp 115 | 116 | .text$03 ends 117 | 118 | END 119 | -------------------------------------------------------------------------------- /JLM/GENERIC/GENERIC.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- JLM sample GENERIC 3 | ;--- use Makefile to create GENERIC.DLL 4 | 5 | ;--- GENERIC is a very simple JLM. It doesn't hook v86-interrupt vectors. 6 | ;--- To be called from v86-mode, its entry point must be obtained by the 7 | ;--- caller. 8 | 9 | .386 10 | .model flat, stdcall 11 | 12 | .nolist 13 | include jlm.inc 14 | .list 15 | 16 | DEVICE_ID equ 6660h 17 | 18 | cr equ 13 19 | lf equ 10 20 | 21 | DLL_PROCESS_ATTACH equ 1 22 | DLL_PROCESS_DETACH equ 0 23 | 24 | .data 25 | 26 | ;--- the DDB must be make public. The linker will "export" this 27 | ;--- symbol. This is the simplest method to make JLoad know the 28 | ;--- device id. 29 | 30 | public ddb 31 | 32 | ddb VxD_Desc_Block <0,0,DEVICE_ID,1,0,0,"GENERIC",0, 0, v86_dispatch> 33 | 34 | szHello db "Hello from JLM GENERIC",cr,lf,0 35 | 36 | .code 37 | 38 | ;--- dispatcher for v86 services 39 | 40 | v86_dispatch proc 41 | 42 | @VMMCall Simulate_Far_Ret ;emulate a RETF in v86 43 | 44 | and [ebp].Client_Reg_Struc.Client_EFlags,not 1 ;clear Carry flag 45 | movzx eax, word ptr [ebp].Client_Reg_Struc.Client_EAX 46 | cmp eax,0 47 | jz getversion 48 | cmp eax,1 49 | jz display_hello 50 | or [ebp].Client_Reg_Struc.Client_EFlags,1 ;set Carry flag 51 | ret 52 | align 4 53 | 54 | v86_dispatch endp 55 | 56 | getversion proc 57 | 58 | mov word ptr [ebp].Client_Reg_Struc.Client_EAX, 0100h 59 | ret 60 | align 4 61 | 62 | getversion endp 63 | 64 | display_hello proc uses esi 65 | 66 | @VMMCall Begin_Nest_Exec ;start nested execution 67 | mov esi, offset szHello 68 | @@: 69 | lodsb 70 | and al,al 71 | jz done 72 | 73 | ;--- Call int 21h, ah=2 in v86-mode. 74 | ;--- Be aware that in Jemm's context is no DOS extender installed. 75 | ;--- So there is no translation for DOS functions which use pointers. 76 | 77 | mov byte ptr [ebp].Client_Reg_Struc.Client_EDX,al 78 | mov byte ptr [ebp].Client_Reg_Struc.Client_EAX+1,2 79 | mov eax,21h 80 | @VMMCall Exec_Int 81 | jmp @B 82 | done: 83 | @VMMCall End_Nest_Exec ;end nested execution 84 | ret 85 | align 4 86 | 87 | display_hello endp 88 | 89 | ;--- install the JLM: just set eax=1 90 | ;--- this tells JLOAD that it's ok to add GENERIC to the list of 91 | ;--- loaded modules. 92 | 93 | install proc uses esi pcomm:ptr JLCOMM 94 | 95 | mov eax,1 96 | ret 97 | align 4 98 | 99 | install endp 100 | 101 | ;--- deinstall the JLM: just set eax=1. 102 | ;--- this tells JLOAD that it's ok to remove the module. 103 | 104 | deinstall proc pcomm:ptr JLCOMM 105 | 106 | mov eax,1 107 | ret 108 | align 4 109 | 110 | deinstall endp 111 | 112 | DllMain proc stdcall public hModule:dword, dwReason:dword, dwRes:dword 113 | 114 | mov eax,dwReason 115 | cmp eax,DLL_PROCESS_ATTACH 116 | jnz @F 117 | invoke install, dwRes 118 | jmp exit 119 | @@: 120 | cmp eax,DLL_PROCESS_DETACH 121 | jnz @F 122 | invoke deinstall, dwRes 123 | @@: 124 | exit: 125 | ret 126 | align 4 127 | 128 | DllMain endp 129 | 130 | end DllMain 131 | -------------------------------------------------------------------------------- /Test/EMS4F.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;*** test EMS get/set partial page map 3 | 4 | .286 5 | .model small 6 | option casemap:none 7 | .stack 1024 8 | .dosseg 9 | 10 | CStr macro text:vararg 11 | local sym 12 | .const 13 | sym db text,0 14 | .code 15 | exitm 16 | endm 17 | 18 | lf equ 10 19 | 20 | .data 21 | mapstruct label byte 22 | dw 4 23 | dw 0A000h 24 | dw 0A400h 25 | dw 0A800h 26 | dw 0AC00h 27 | 28 | mapstruct2 label byte 29 | dw 4 30 | dw 08000h 31 | dw 08400h 32 | dw 08800h 33 | dw 08C00h 34 | 35 | .data? 36 | 37 | buffer db 256 dup (?) 38 | 39 | .code 40 | 41 | .386 42 | include printf.inc 43 | 44 | emsstr1 db 'EMMXXXX0',0 45 | 46 | EMScheck proc uses si di 47 | 48 | mov ax, 3567h 49 | int 21h 50 | mov ax, es 51 | or ax, bx 52 | jz exit 53 | 54 | mov dx,1 55 | mov si,offset emsstr1 56 | mov di,000ah 57 | mov cx,8 58 | push ds 59 | push cs 60 | pop ds 61 | cld 62 | repz cmpsb 63 | pop ds 64 | jz found 65 | 66 | mov dx,0 67 | mov ah,46h 68 | int 67h 69 | and ah,ah 70 | jz found 71 | 72 | xor ax, ax 73 | jmp exit 74 | found: 75 | mov ax,1 76 | exit: 77 | ret 78 | 79 | EMScheck endp 80 | 81 | main proc c 82 | 83 | local handle:word 84 | 85 | call EMScheck 86 | and ax,ax 87 | jz sm1 88 | 89 | ;--- get size to save 4 pages 90 | 91 | mov bx,4 92 | mov ax,4F02h 93 | int 67h 94 | cmp ah,00 95 | jnz sm2 96 | mov ah,0 97 | invoke printf, CStr( "size to save 4 pages: %u", lf ), ax 98 | 99 | ;--- save 4 pages in mapstruct (A000,A400,A800,AC00) 100 | 101 | mov si,offset mapstruct 102 | mov di,offset buffer 103 | push ds 104 | pop es 105 | mov ax,4F00h 106 | int 67h 107 | cmp ah,00 108 | jz smx 109 | movzx ax,ah 110 | invoke printf, CStr( "int 67h, ax=4F00h (A000-AFFF) failed, error=%X", lf ), ax 111 | smx: 112 | 113 | ;--- save 4 pages in mapstruct (8000,8400,8800,8C00) 114 | 115 | mov si,offset mapstruct2 116 | mov di,offset buffer 117 | push ds 118 | pop es 119 | mov ax,4F00h 120 | int 67h 121 | cmp ah,00 122 | jnz sm31 123 | invoke printf, CStr( "int 67h, ax=4F00h (8000-8FFF) ok", lf ) 124 | 125 | ;--- restore 4 pages 126 | 127 | mov si,offset buffer 128 | mov ax,4F01h 129 | int 67h 130 | cmp ah,00 131 | jnz sm4 132 | invoke printf, CStr( "int 67h, ax=4F01h ok",lf ) 133 | jmp exit 134 | 135 | sm1: 136 | invoke printf, CStr( "EMM not found", lf ) 137 | jmp exit 138 | sm2: 139 | movzx ax,ah 140 | invoke printf, CStr( "int 67h, ax=4F02h failed, error=%X", lf ), ax 141 | jmp exit 142 | sm31: 143 | movzx ax,ah 144 | invoke printf, CStr( "int 67h, ax=4F00h (8000-8FFF) failed, error=%X", lf ), ax 145 | jmp exit 146 | sm4: 147 | movzx ax,ah 148 | invoke printf, CStr( "int 67h, ax=4F01h failed, error=%X",lf ), ax 149 | exit: 150 | ret 151 | main endp 152 | 153 | start: 154 | mov ax,@data 155 | mov ds,ax 156 | mov cx,ss 157 | sub cx,ax 158 | shl cx,4 159 | mov ss,ax 160 | add sp,cx 161 | invoke main 162 | mov ah,4ch 163 | int 21h 164 | 165 | END start 166 | -------------------------------------------------------------------------------- /XMS35.txt: -------------------------------------------------------------------------------- 1 | 2 | 1. XMS v3.5 API 3 | 4 | XMS v3.5 has been created to allow accessing extended memory beyond the 4 GB 5 | barrier. 6 | 7 | To achieve this, the XMS v3.0 API has been extended: 8 | 9 | AH=0C8h: query free super-extended memory. Returns in EAX largest free block 10 | in kB, in EDX the total amount (in kB) of free super-extended memory. 11 | AX=0 indicates an error. 12 | 13 | AH=0C9h: allocate block of super-extended memory. Expects in EDX the 14 | requested amount of memory in kB. Returns AX=0 if an error occured, 15 | else AX is 1 and the handle of the block is in DX. 16 | 17 | AH=0CCh: lock a (super-extended) memory block. Expects handle in DX. Returns 18 | 64-bit physical address of locked block in EDX:EBX. Returns AX=0 19 | if an error occured. 20 | 21 | XMS function 00 (Get Version) will return ax=0350h, that is version 3.50. 22 | 23 | 24 | 2. XMS v3.51 API 25 | 26 | XMS v3.51 extends the v3.50 API by another function: 27 | 28 | AH=0CBh: super-extended block move function. Register setup is like XMS 29 | function 0Bh. However, the structure that holds source and 30 | destination of the memory block to copy has been extended by two 31 | 1-byte fields that must be filled with bits 32-39 of the source 32 | and destination address. 33 | 34 | sxms_move struct 35 | len dd ? ; +0: block length in bytes 36 | src_handle dw ? ; +4: source handle 37 | src_offset dd ? ; +6: offset into source 38 | dst_handle dw ? ; +10: destination handle 39 | dst_offset dd ? ; +12: offset into destination 40 | src_high db ? ; +16: NEW: bits 32-39 of source offset 41 | dest_high db ? ; +17: NEW: bits 32-39 of destination offset 42 | sxms_move ends 43 | 44 | 45 | 3. BIOS Interrupt 15h, AX=E820h 46 | 47 | Since the memory beyond the 4 GB limit must be managed exclusively, 48 | Int 15h, ax=E820h should be intercepted in a way that all memory blocks with 49 | addresses >= 100000000h are changed from "available" to "reserved". 50 | 51 | 52 | 4. BIOS Interrupt 15h, AH=87h 53 | 54 | In V86 mode, the XMM's 'move extended memory' functions (AH=0Bh & AH=0CBh) 55 | will need the help of the Expanded Memory Manager (EMM), since privileged 56 | code has to be executed. The only EMMs that currently support accessing 57 | memory beyond 4 GB are Jemm386/JemmEx v5.80+. Their Int 15h API has been 58 | exhanced as well. 59 | 60 | Register setup for Int 15h, AH=87h: 61 | 62 | - AH: 87h 63 | - EAX[bits 16-31]: F00Fh 64 | - CX: F00Fh 65 | - ECX[bits 16-31]: size of block in words 66 | - DS:SI: same as the standard ( pointing to a GDT ), descriptors 2 & 3 67 | defining address bits 0-31 of source/destination region. 68 | - DX: address bits 32-47 of the source region. 69 | - BX: address bits 32-47 of the destination region. 70 | 71 | If the call succeeded, the carry flag is cleared and register AH is 0. 72 | If an error occured ( for example, CPU doesn't support PSE ), the carry 73 | flag is set and AH is != 0. 74 | 75 | Japheth 76 | -------------------------------------------------------------------------------- /Tools/JLOAD/MAKEFILE: -------------------------------------------------------------------------------- 1 | 2 | # nmake makefile that creates JLOAD.EXE 3 | # tools used: 4 | # default alternate 5 | #---------------------------------------------- 6 | # Assembler: jwasm MS masm (+Bin2Inc) 7 | # OMF linker: jwlink MS link16 8 | # COFF linker: jwlink - 9 | 10 | # the 32-bit part of jload must be linked with base 0xF8400000; 11 | # this isn't possible with (all?) MS link versions! 12 | 13 | # bin2inc translates binary files to assembly include files. 14 | # It's source is supplied with JWasm. 15 | 16 | !ifndef DEBUG 17 | DEBUG = 0 18 | !endif 19 | 20 | !if $(DEBUG) 21 | OUTDIR = DEBUG 22 | AOPTD=-D_DEBUG -D?PEDBG=1 -D?RMDBG=1 -D?INITDBG=1 -D?JLMDBG=1 23 | #AOPTD=-D_DEBUG -D?V86HOOKDBG=1 24 | !else 25 | OUTDIR = RELEASE 26 | AOPTD= 27 | !endif 28 | 29 | NAME = JLOAD 30 | NAME32= JLOAD32 31 | VXD1 = VMM 32 | VXD4 = VDMAD 33 | LIBS = 34 | 35 | !ifndef MASM 36 | MASM=0 37 | !endif 38 | 39 | !if $(MASM) 40 | ASM = ml.exe -c -nologo -Fo$* -Fl$* -Sg $(AOPTD) -I..\..\Include -I..\..\src -DOUTD=$(OUTDIR) 41 | ASM32 = ml.exe -c -nologo -coff -Fl$* -Sg $(AOPTD) -I..\..\Include -I..\..\src -DOUTD=$(OUTDIR) 42 | !else 43 | ASM = jwasm.exe -c -nologo -Fl$* -Fo$* -Sg $(AOPTD) -I..\..\Include -I..\..\src -DOUTD=$(OUTDIR) 44 | ASM32 = jwasm.exe -c -nologo -Fl$* -coff -Sg $(AOPTD) -I..\..\Include -I..\..\src -DOUTD=$(OUTDIR) 45 | !endif 46 | 47 | LINK32= 48 | INC32=jload.inc jload32.inc debug.inc ..\..\src\Jemm32.inc ..\..\Include\jlm.inc 49 | INC16=jload.inc debug.inc ..\..\src\Jemm32.inc ..\..\src\Jemm.inc ..\..\Include\jlm.inc 50 | 51 | ALL: $(OUTDIR) $(OUTDIR)\$(NAME).EXE 52 | 53 | $(OUTDIR): 54 | @mkdir $(OUTDIR) 55 | 56 | $(OUTDIR)\$(NAME).EXE: $(OUTDIR)\$(NAME).obj MAKEFILE 57 | # @link16.exe /MAP:FULL/NOE/NON/ONERROR:NOEXE $*.OBJ, $*.EXE, $*.MAP, $(LIBS); 58 | @jwlink.exe format dos file $*.OBJ name $*.EXE op q,m=$*.MAP 59 | 60 | !if $(MASM) 61 | 62 | $(OUTDIR)\$(NAME).OBJ: $(NAME).asm $(OUTDIR)\$(NAME32).inc $(INC16) 63 | @$(ASM) $(NAME).asm 64 | 65 | $(OUTDIR)\$(NAME32).INC: $(OUTDIR)\$(NAME32).obj $(OUTDIR)\$(VXD1).obj $(OUTDIR)\$(VXD4).obj 66 | @jwlink.exe format raw bin f { $*.obj $(OUTDIR)\$(VXD1).obj $(OUTDIR)\$(VXD4).obj } name $*.bin op q,map=$*,offset=0xF8400000,start='_start@0' 67 | @bin2inc.exe -q $*.bin $*.inc 68 | 69 | !else 70 | 71 | $(OUTDIR)\$(NAME).OBJ: $(NAME).asm $(OUTDIR)\$(NAME32).bin $(INC16) 72 | @$(ASM) $(NAME).asm 73 | 74 | $(OUTDIR)\$(NAME32).bin: $(OUTDIR)\$(NAME32).obj $(OUTDIR)\$(VXD1).obj $(OUTDIR)\$(VXD4).obj 75 | @jwlink.exe format raw bin f { $*.obj $(OUTDIR)\$(VXD1).obj $(OUTDIR)\$(VXD4).obj } name $*.bin op q,map=$*,offset=0xF8400000,start='_start@0' 76 | 77 | !endif 78 | 79 | $(OUTDIR)\$(NAME32).obj: $(NAME32).asm $(INC32) MAKEFILE 80 | @$(ASM32) -Fl$(OUTDIR)\$(NAME32).LST -Fo$(OUTDIR)\$(NAME32).OBJ $(NAME32).asm 81 | 82 | $(OUTDIR)\$(VXD1).obj: $(VXD1).asm $(INC32) MAKEFILE 83 | @$(ASM32) -Fl$(OUTDIR)\$(VXD1).LST -Fo$(OUTDIR)\$(VXD1).OBJ $(VXD1).asm 84 | 85 | $(OUTDIR)\$(VXD4).obj: $(VXD4).asm $(INC32) MAKEFILE 86 | @$(ASM32) -Fl$(OUTDIR)\$(VXD4).LST -Fo$(OUTDIR)\$(VXD4).OBJ $(VXD4).asm 87 | 88 | clean: 89 | @del $(OUTDIR)\*.exe 90 | @if exist $(OUTDIR)\*.inc del $(OUTDIR)\*.inc 91 | @del $(OUTDIR)\*.bin 92 | @del $(OUTDIR)\*.obj 93 | @del $(OUTDIR)\*.lst 94 | @del $(OUTDIR)\*.map 95 | -------------------------------------------------------------------------------- /Test/XMSTEST4.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- XMSTEST4: test block resize (shrink) 3 | ;--- Public Domain. 4 | ;--- to be assembled with JWasm or Masm v6. 5 | 6 | .model small 7 | .386 8 | .dosseg 9 | .stack 2048 10 | 11 | cr equ 13 12 | lf equ 10 13 | 14 | BUFFSIZ equ 10000h 15 | 16 | ;--- define a string constant 17 | 18 | CStr macro string:vararg 19 | local xxx 20 | .const 21 | xxx db string 22 | db 0 23 | .code 24 | exitm 25 | endm 26 | 27 | .data 28 | 29 | xmsadr dd 0 ;XMS host call address 30 | 31 | .code 32 | 33 | assume DS:DGROUP 34 | 35 | include printf.inc 36 | 37 | ;--- test xms block resize function 38 | 39 | testproc proc 40 | 41 | local handle:word 42 | 43 | ;--- allocate XMS block 44 | 45 | mov edx, 10000h ;64MB 46 | mov ah,89h 47 | call [xmsadr] 48 | mov handle, dx 49 | push ax 50 | invoke printf, CStr("xms alloc (ah=89h) of 64MB returned ax=%X, dx=%X",lf), ax, dx 51 | pop ax 52 | cmp ax,1 53 | jnz failed 54 | 55 | ;--- lock XMS block 56 | 57 | mov dx, handle 58 | mov ah,0Ch 59 | call [xmsadr] 60 | push ax 61 | invoke printf, CStr("xms lock (ah=0Ch) returned ax=%X, dx:bx=%X%04X",lf), ax, dx, bx 62 | pop ax 63 | cmp ax,1 64 | jnz failed2 65 | 66 | ;--- resize block; should fail since locked 67 | 68 | mov ebx, 8000h ;shrink block to 32MB 69 | mov dx, handle 70 | mov ah,8Fh 71 | call [xmsadr] 72 | mov bh,0 73 | invoke printf, CStr("xms resize (ah=8Fh) to 32MB returned ax=%X, bl=%X",lf), ax, bx 74 | 75 | ;--- unlock XMS block 76 | 77 | mov dx, handle 78 | mov ah,0Dh 79 | call [xmsadr] 80 | invoke printf, CStr("xms unlock (ah=0Dh) returned ax=%X",lf), ax 81 | 82 | failed2: 83 | ;--- free xms handle 84 | mov dx,handle 85 | mov ah,0ah 86 | mov bl,0 87 | call [xmsadr] 88 | invoke printf, CStr("xms release (ah=0Ah) returned ax=%X",lf), ax 89 | failed: 90 | ret 91 | testproc endp 92 | 93 | ;--- main 94 | 95 | main proc c 96 | 97 | mov ax,4300h 98 | int 2fh 99 | test al,80h ;xms host found? 100 | jnz main1 101 | invoke printf, CStr("no XMS host found",lf) 102 | jmp exit 103 | main1: 104 | mov ax,4310h ;get XMS call address 105 | int 2fh 106 | mov word ptr xmsadr+0,bx 107 | mov word ptr xmsadr+2,es 108 | invoke printf, CStr("XMS call address: %X:%X",lf), 109 | word ptr [xmsadr+2], word ptr [xmsadr+0] 110 | 111 | call testproc 112 | 113 | exit: 114 | ret 115 | main endp 116 | 117 | ;--- init 118 | 119 | start proc 120 | 121 | mov ax,@data 122 | mov ds,ax 123 | 124 | mov cx,ds 125 | mov ax,ss 126 | sub ax,cx 127 | shl ax,4 128 | add ax,sp 129 | push ds 130 | pop ss 131 | mov sp,ax 132 | 133 | ;--- free DOS mem 134 | mov ax, ds 135 | mov cx, es 136 | sub ax, cx 137 | mov bx, sp 138 | add bx, 15 139 | shr bx, 4 140 | add bx, ax 141 | mov ah, 4Ah 142 | int 21h 143 | 144 | pushf 145 | pushf 146 | pop ax 147 | or ah,70h ;a 80386 will have bit 15 cleared 148 | push ax ;if bits 12-14 are 0, it is a 80286 149 | popf ;or a bad emulation 150 | pushf 151 | pop ax 152 | popf 153 | and ah,0f0h 154 | js no386 ;bit 15 set? then its a 8086/80186 155 | jnz is386 156 | no386: 157 | invoke printf, CStr("a 80386 is needed",lf) 158 | jmp done 159 | is386: 160 | call main 161 | done: 162 | mov ah,4Ch 163 | int 21h 164 | start endp 165 | 166 | END start 167 | -------------------------------------------------------------------------------- /Tools/JEMFBHLP/JEMFBHLP.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;*** save some interrupt vectors the way MS-DOS does 3 | ;*** needed for FreeDOS if Jemm386's FASTBOOT option is used 4 | 5 | .286 6 | .MODEL SMALL 7 | 8 | IODAT struct 9 | cmdlen db ? ;+ 0:size 10 | unit db ? ;+ 1: 11 | cmd db ? ;+ 2 12 | status dw ? ;+ 3 13 | db 8 dup (?); reserved 14 | media db ? ;+ 0d 15 | trans dd ? ;+ 0e 16 | count dw ? ;+ 12 init:offset parameter line 17 | start dw ? ;+ 14 init:segment parameter line 18 | drive db ? ;+ 16 19 | IODAT ends 20 | 21 | .CODE 22 | 23 | dw -1 24 | dw -1 25 | dw 8000h ;attribute 26 | dw offset devstrat ;device strategy 27 | devc dw offset devintfirst ;device interrupt 28 | devname db 'JEMFBHP$' 29 | 30 | cmdptr dd 1 dup (?) 31 | 32 | devstrat proc far 33 | mov cs:word ptr[cmdptr+0],bx 34 | mov cs:word ptr[cmdptr+2],es 35 | ret 36 | devstrat endp 37 | 38 | devint proc far 39 | push ds 40 | push bx 41 | lds bx,cs:[cmdptr] 42 | mov word ptr [bx.IODAT.status],100h 43 | pop bx 44 | pop ds 45 | ret 46 | devint endp 47 | 48 | int19 proc 49 | cld 50 | push 70h 51 | pop ds 52 | xor ax,ax 53 | mov es,ax 54 | mov si,100h 55 | mov cx,NUMVECS 56 | nextitem: 57 | lodsb 58 | mov di,ax 59 | shl di,2 60 | movsw 61 | movsw 62 | loop nextitem 63 | int 19h 64 | int19 endp 65 | 66 | resident label byte 67 | 68 | vecstable db 15h,19h 69 | NUMVECS equ $ - vecstable 70 | 71 | devintfirst proc far 72 | pusha 73 | push ds 74 | push es 75 | lds bx,cs:[cmdptr] 76 | mov word ptr [bx.IODAT.status],100h 77 | cmp [bx.IODAT.cmd],0 ;init call? 78 | jnz exit 79 | mov word ptr [bx.IODAT.trans+0],0 80 | mov word ptr [bx.IODAT.trans+2],cs 81 | mov cs:[devc],offset devint 82 | mov ax,4300h 83 | int 2fh 84 | cmp al,80h ;Himem must not be installed yet 85 | jnz @F 86 | push cs 87 | pop ds 88 | mov dx,offset str2 89 | mov ah,9 90 | int 21h 91 | jmp exit 92 | @@: 93 | xor ax,ax 94 | mov es,ax 95 | mov ax, es:[19h*4+2] ;int 19h must be unmodified (segment >= E000) 96 | cmp ax, 0E000h 97 | jc exit 98 | mov word ptr [bx.IODAT.trans+0],offset resident 99 | 100 | push 0070h 101 | pop es 102 | xor ax,ax 103 | mov ds,ax 104 | mov di,100h 105 | mov bx,offset vecstable 106 | mov cx,NUMVECS 107 | nextitem: 108 | mov al,cs:[bx] 109 | inc bx 110 | mov ah,0 111 | mov si,ax 112 | shl si,2 113 | stosb 114 | movsw 115 | movsw 116 | loop nextitem 117 | mov word ptr ds:[19h*4+0],offset int19 118 | mov word ptr ds:[19h*4+2],cs 119 | exit: 120 | pop es 121 | pop ds 122 | popa 123 | ret 124 | devintfirst endp 125 | 126 | str2 db "JEMFBHLP.EXE must be installed *before* Himem",13,10,'$' 127 | 128 | str1 db "JEMFBHLP is needed for FreeDOS only. It saves some interrupt vectors",13,10 129 | db "the way MS-DOS does, thus allowing to set Jemm386's FASTBOOT option.",13,10 130 | db "It must be loaded in (FD)CONFIG.SYS before the XMS host. Example:",13,10 131 | db "DEVICE=JEMFBHLP.EXE",13,10 132 | db "DEVICE=HIMEM.EXE [or (Q)HIMEM.SYS]",13,10 133 | db "DEVICE=JEMM386.EXE FASTBOOT",13,10 134 | db '$' 135 | main: 136 | mov dx,offset str1 137 | push cs 138 | pop ds 139 | mov ah,9 140 | int 21h 141 | mov ax,4C00h 142 | int 21h 143 | 144 | .stack 1024 145 | 146 | END main 147 | 148 | -------------------------------------------------------------------------------- /src/X86.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- page table flags 3 | 4 | PTF_PRESENT equ 001h 5 | PTF_RW equ 002h 6 | PTF_USER equ 004h 7 | PTF_PWT equ 008h ; page write through 8 | PTF_PCD equ 010h ; page cache disable 9 | PTF_ACCESS equ 020h ; page accessed 10 | PTF_DIRTY equ 040h ; page dirty 11 | PTF_4MB equ 080h ; PDEs: 4MB PDE 12 | PTF_GBL equ 100h ; page global (P3+) 13 | 14 | ;--- features, returned by CPUID in EDX 15 | CF_FPU equ 0001h 16 | CF_VME equ 0002h 17 | CF_DE equ 0004h;debugging ext 18 | CF_PSE equ 0008h;Page Size Ext (4MB) 19 | CF_TSC equ 0010h;Time Stamp Counter 20 | CF_MSR equ 0020h;RDMSR/WRMSR supported 21 | CF_PAE equ 0040h;Physical Address Ext 22 | CF_MCE equ 0080h;Machine Check Exceptions 23 | CF_CX8 equ 0100h;CMPXCHG8B supported 24 | CF_APIC equ 0200h;APIC exists 25 | ;rsvd equ 0400h; 26 | CF_SEP equ 0800h;SYSENTER/SYSEXIT supported 27 | CF_MTRR equ 1000h 28 | CF_PGE equ 2000h 29 | 30 | ;--- flags in CR4 31 | CR4_VME equ 01h 32 | CR4_PVI equ 02h 33 | CR4_TSD equ 04h;1=time stamp disable 34 | CR4_DE equ 08h 35 | CR4_PSE equ 10h;1=page size extensions enabled 36 | CR4_PAE equ 20h 37 | CR4_MCE equ 40h 38 | CR4_PGE equ 80h 39 | 40 | ;--- descriptor 41 | 42 | DESCRIPTOR struct 43 | wLimit dw ? ;+0 44 | wA0015 dw ? ;+2 45 | bA1623 db ? ;+4 46 | bAttr db ? ;+5 47 | bLimEx db ? ;+6 48 | bA2431 db ? ;+7 49 | DESCRIPTOR ends 50 | 51 | GATE struct 52 | wOfsLo dw ? 53 | wSeg dw ? 54 | wAttr dw ? 55 | wOfsHi dw ? 56 | GATE ends 57 | 58 | ;--- TSS structure 59 | ;--- the only fields in the TSS which are needed are tsEsp0, tsSS0 60 | ;--- and tsOfs. Jemm386 will never switch tasks. 61 | 62 | TSSSEG struct 63 | dd ? ;+00 selector 64 | tsEsp0 dd ? ;+04 65 | tsSS0 dd ? ;+08 66 | dq ? ;+0C 67 | dq ? ;+14 68 | tsCR3 dd ? ;+1C 69 | tsEip dd ? ;+20 70 | tsEfl dd ? ;+24 71 | tsEax dd ? ;+28 72 | tsEcx dd ? ;+2C 73 | tsEdx dd ? ;+30 74 | tsEbx dd ? ;+34 75 | tsEsp dd ? ;+38 76 | tsEbp dd ? ;+3C 77 | tsEsi dd ? ;+40 78 | tsEdi dd ? ;+44 79 | tsES dd ? ;+48 80 | tsCS dd ? ;+4C 81 | tsSS dd ? ;+50 82 | tsDS dd ? ;+54 83 | tsFS dd ? ;+58 84 | tsGS dd ? ;+5C 85 | tsLDTR dd ? ;+60 86 | tsFlags dw ? ;+64 87 | tsOfs dw ? ;+66 88 | TSSSEG ends 89 | 90 | ;--- stack frame for PUSHAD 91 | 92 | PUSHADS struct 93 | rEDI dd ? 94 | rESI dd ? 95 | rEBP dd ? 96 | dd ? ;reserved 97 | rEBX dd ? 98 | rEDX dd ? 99 | rECX dd ? 100 | rEAX dd ? 101 | PUSHADS ends 102 | 103 | ;--- IRET stack frame for 32bit protected-mode 104 | 105 | IRETD32 struct 106 | _Eip dd ? ;+0 107 | _Cs dd ? ;+4 108 | _Efl dd ? ;+8 109 | IRETD32 ends 110 | 111 | ;--- stack frame expected by ring0-IRETD to switch to v86-mode 112 | 113 | IRETDV86 struct 114 | _Eip dd ? ;+0 115 | _Cs dd ? ;+4 116 | _Efl dd ? ;+8 117 | _Esp dd ? ;+12 118 | _Ss dd ? ;+16 119 | _Es dd ? ;+20 120 | _Ds dd ? ;+24 121 | _Fs dd ? ;+28 122 | _Gs dd ? ;+32 123 | IRETDV86 ends 124 | 125 | ;--- bit positions of CPUID edx 126 | CPUID_VME equ 1 ; =2 127 | CPUID_PGE equ 13 ; =2000h 128 | CPUID_PAT equ 16 ; =10000h 129 | 130 | -------------------------------------------------------------------------------- /JLM/REBOOT/FBOOT.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- Set /D and /P option for currently loaded fastboot JLM. 3 | ;--- This program uses the API installed by FASTBOOT.DLL; 4 | ;--- alternatively, one can unload & reload FASTBOOT.DLL. 5 | 6 | .286 7 | .model tiny 8 | .dosseg 9 | .stack 2048 10 | option casemap:none 11 | .386 12 | 13 | CStr macro text:vararg 14 | local sym 15 | .const 16 | sym db text,0 17 | .code 18 | exitm 19 | endm 20 | 21 | DStr macro text:vararg 22 | local sym 23 | .const 24 | sym db text,'$' 25 | .code 26 | exitm 27 | endm 28 | 29 | .data 30 | 31 | dopt db -1 32 | popt db -1 33 | 34 | .const 35 | helptxt label byte 36 | db "FBOOT: set FASTBOOT arguments.",13,10 37 | db "Usage: FBOOT [/Dn] [/Pm]",13,10 38 | db " /Dn: set disk to boot from to n [0-9]",13,10 39 | db " /Pm: set partition to boot from to m [0-9]",13,10 40 | db '$' 41 | 42 | .code 43 | 44 | getoption proc 45 | cld 46 | mov si,81h 47 | nextchr: 48 | lodsb es:[si] 49 | cmp al,13 50 | jz cmdl_done 51 | cmp al,20h 52 | jbe nextchr 53 | cmp al,'/' 54 | jz is_option 55 | cmp al,'-' 56 | jnz disp_help 57 | is_option: 58 | lodsb es:[si] 59 | cmp al,13 60 | jz disp_help 61 | or al,20h 62 | cmp al,'d' 63 | jz d_option 64 | cmp al,'p' 65 | jz p_option 66 | cmp al,'b' 67 | jz b_option 68 | jmp disp_help 69 | cmdl_done: 70 | clc 71 | ret 72 | d_option: 73 | lodsb es:[si] 74 | cmp al,'0' 75 | jb disp_help 76 | cmp al,'9' 77 | ja disp_help 78 | sub al,'0' 79 | mov dopt,al 80 | jmp nextchr 81 | p_option: 82 | lodsb es:[si] 83 | cmp al,'0' 84 | jb disp_help 85 | cmp al,'9' 86 | ja disp_help 87 | sub al,'0' 88 | mov popt,al 89 | jmp nextchr 90 | b_option: 91 | mov dx,DStr("not implemented yet",13,10) 92 | mov ah,9 93 | int 21h 94 | jmp nextchr 95 | disp_help: 96 | mov dx,offset helptxt 97 | mov ah,9 98 | int 21h 99 | stc 100 | ret 101 | getoption endp 102 | 103 | main proc 104 | 105 | local dwFB:dword 106 | 107 | call getoption 108 | jc exit 109 | mov bx,4435h ;FASTBOOT/REBOOT device ID 110 | mov ax,1684h ;get API entry point 111 | int 2Fh 112 | cmp al,0 113 | jnz not_installed 114 | mov word ptr dwFB+0,di 115 | mov word ptr dwFB+2,es 116 | mov ah,0 ;get version 117 | call dwFB 118 | jc not_installed 119 | test ah,1 ;FASTBOOT variant? 120 | jz not_installed 121 | 122 | mov al,dopt 123 | cmp al,-1 124 | jz no_dopt 125 | mov ah,1 126 | call dwFB 127 | jc fb_call_failed 128 | mov dx,DStr("setting HD succeeded",13,10) 129 | mov ah,9 130 | int 21h 131 | no_dopt: 132 | mov al,popt 133 | cmp al,-1 134 | jz no_popt 135 | mov ah,2 136 | call dwFB 137 | jc fb_call_failed 138 | mov dx,DStr("setting partition succeeded",13,10) 139 | mov ah,9 140 | int 21h 141 | no_popt: 142 | exit: 143 | ret 144 | 145 | not_installed: 146 | mov dx,DStr("FASTBOOT not installed or wrong version") 147 | mov ah,9 148 | int 21h 149 | call lfout 150 | ret 151 | fb_call_failed: 152 | mov dx,DStr("calling FASTBOOT failed") 153 | mov ah,9 154 | int 21h 155 | call lfout 156 | ret 157 | main endp 158 | 159 | lfout proc 160 | mov dx,DStr(13,10) 161 | mov ah,9 162 | int 21h 163 | ret 164 | lfout endp 165 | 166 | start: 167 | mov ax,cs 168 | mov ds,ax 169 | mov dx,ss 170 | sub dx,ax 171 | shl dx,4 172 | mov ss,ax 173 | add sp,dx 174 | mov bx,sp 175 | shr bx,4 176 | mov cx,es 177 | sub ax,cx 178 | add bx,ax 179 | mov ah,4Ah 180 | int 21h 181 | call main 182 | mov ah,4ch 183 | int 21h 184 | 185 | end start 186 | 187 | -------------------------------------------------------------------------------- /Test/EMS57.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;*** EMS move 3 | 4 | .286 5 | .model small 6 | option casemap:none 7 | option casemap:none 8 | .stack 1024 9 | .dosseg 10 | 11 | CStr macro text:vararg 12 | local sym 13 | .const 14 | sym db text,0 15 | .code 16 | exitm 17 | endm 18 | 19 | lf equ 10 20 | 21 | 22 | ?BUFSIZE equ 10000h 23 | ?SIZE equ ?BUFSIZE/4000h ;size in EMS pages 24 | 25 | 26 | .386 27 | 28 | EMM57 struct 29 | dwSize DD ? ; +0 size of region 30 | bSrcTyp DB ? ; +4 src memory type 31 | wSrcHdl DW ? ; +5 src handle 32 | wSrcOfs DW ? ; +7 src ofs 33 | wSrcSeg DW ? ; +9 src segm./log. page 34 | bDstTyp DB ? ; +11 dst memory type 35 | wDstHdl DW ? ; +12 dst handle 36 | wDstOfs DW ? ; +14 dst ofs 37 | wDstSeg DW ? ; +16 dst segm./log. page 38 | EMM57 ends 39 | 40 | .data 41 | 42 | emm57 EMM57 <> 43 | 44 | .code 45 | 46 | include printf.inc 47 | 48 | main proc c 49 | 50 | local handle:word 51 | local wPages:word 52 | local wMem:word 53 | local frame:word 54 | 55 | mov ax,3567h 56 | int 21h 57 | mov ax,bx 58 | mov cx,es 59 | or ax,cx 60 | jnz @F 61 | invoke printf, CStr( "EMM not found",lf) 62 | jmp exit 63 | @@: 64 | mov ah,48h 65 | mov bx,?BUFSIZE/10h 66 | int 21h 67 | jnc @F 68 | invoke printf, CStr( "DOS memory allocation failed",lf) 69 | jmp exit 70 | @@: 71 | mov wMem, ax 72 | mov bx,?SIZE 73 | mov ah,43h ;alloc pages 74 | int 67h 75 | and ah,ah 76 | jnz error2 77 | mov handle,dx 78 | 79 | invoke printf, CStr("Handle %u allocated, clearing content ... ", lf), handle 80 | 81 | xor di, di 82 | mov es, wMem 83 | mov eax,12345678h 84 | mov cx,?BUFSIZE/4 85 | rep stosd 86 | 87 | mov si, offset emm57 88 | mov emm57.dwSize, ?BUFSIZE 89 | mov emm57.bSrcTyp, 0 90 | mov emm57.wSrcOfs, 0 91 | mov emm57.wSrcSeg, es 92 | mov emm57.bDstTyp, 1 93 | mov ax,handle 94 | mov emm57.wDstHdl, ax 95 | mov emm57.wDstOfs, 0 96 | mov emm57.wDstSeg, 0 97 | mov ax,5700h ;move memory region 98 | int 67h 99 | and ah,ah 100 | jnz error3 101 | invoke printf, CStr( "move to expanded memory ok",lf) 102 | 103 | xor di, di 104 | mov es, wMem 105 | xor eax, eax 106 | mov cx,?BUFSIZE/4 107 | rep stosd 108 | 109 | mov si, offset emm57 110 | mov emm57.dwSize, ?BUFSIZE 111 | mov ax,handle 112 | mov es,wMem 113 | mov emm57.wSrcHdl, ax 114 | mov emm57.bSrcTyp, 1 115 | mov emm57.wSrcOfs, 0 116 | mov emm57.wSrcSeg, 0 117 | mov emm57.bDstTyp, 0 118 | mov emm57.wDstOfs, 0 119 | mov emm57.wDstSeg, es 120 | mov ax,5700h ;move memory region 121 | int 67h 122 | and ah,ah 123 | jnz error3 124 | invoke printf, CStr( "move from expanded memory ok",lf) 125 | 126 | xor di, di 127 | mov es, wMem 128 | mov eax, 12345678h 129 | mov cx,?BUFSIZE/4 130 | repz scasd 131 | jz exit2 132 | invoke printf, CStr( "memory content has changed!",lf) 133 | 134 | exit2: 135 | mov dx,handle 136 | mov ah,45h ;free pages 137 | int 67h 138 | exit: 139 | ret 140 | error2: 141 | movzx ax,ah 142 | invoke printf, CStr( "int 67h, ah=43h, bx=%u failed, status=%X",lf), bx, ax 143 | jmp exit 144 | error3: 145 | movzx ax,ah 146 | invoke printf, CStr( "int 67h, ah=57h failed, status=%X",lf), ax 147 | jmp exit 148 | main endp 149 | 150 | start: 151 | mov ax,@data 152 | mov ds,ax 153 | mov cx,ss 154 | sub cx,ax 155 | shl cx,4 156 | mov ss,ax 157 | add sp,cx 158 | mov dx,es 159 | mov ax,ss 160 | sub ax,dx 161 | mov dx,sp 162 | shr dx,4 163 | add ax,dx 164 | mov bx,ax 165 | mov ah,4ah 166 | int 21h 167 | invoke main 168 | mov ah,4ch 169 | int 21h 170 | 171 | END start 172 | -------------------------------------------------------------------------------- /JLM/QPIEMU/Test/SETARGV.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- read the commandline at PSP:81h 3 | ;--- and create an argc/argv structure on the stack. 4 | ;--- in: ES=PSP, DS=DGROUP, SS=DGROUP 5 | ;--- out: _argc (=[bp-2]) 6 | ;--- _argv (=[bp-4]) 7 | ;--- all std registers modified (including SP) 8 | 9 | ?DUMMYFN equ 1 10 | ?QUOTES equ 1 11 | 12 | _setargv proc 13 | 14 | mov bp, sp 15 | sub sp, 256 ; just make enough room for argc/argv 16 | 17 | xor di, di ; init argc 18 | xor dx, dx ; init size of mem block 19 | mov si, 81H 20 | push es 21 | pop ds 22 | ; assume ds:nothing ; no need for assumes, since no global vars are accessed 23 | jmp scanarg 24 | 25 | ;--- DI = argc 26 | ;--- DX = block size (not including null terminators) 27 | nextarg: 28 | push bx ; save argument size 29 | scanarg: 30 | @@: 31 | lodsb 32 | cmp al, ' ' 33 | je @B 34 | cmp al, 9 35 | je @B 36 | cmp al, 13 37 | jz doneargs ; exit if eol 38 | inc di ; another argument 39 | xor bx, bx ; init argument size 40 | if ?QUOTES 41 | cmp al, '"' 42 | jz handle_quote 43 | endif 44 | dec si ; back up to reload character 45 | push si ; save argument ofs 46 | @@: 47 | lodsb 48 | cmp al, ' ' ; end argument? 49 | je nextarg 50 | cmp al, 9 51 | je nextarg ; white space terminates argument 52 | cmp al, 13 53 | jz doneargs2 ; exit if eol 54 | inc bx 55 | inc dx 56 | jmp @B 57 | if ?QUOTES 58 | handle_quote: 59 | push si 60 | @@: 61 | lodsb 62 | cmp al, 13 63 | jz quoteerr 64 | cmp al, '"' 65 | jz @F 66 | inc dx 67 | inc bx 68 | jmp @B 69 | quoteerr: 70 | dec si ; "unread" the CR 71 | @@: 72 | jmp nextarg 73 | endif 74 | doneargs2: 75 | push bx ; last argument's size 76 | doneargs: 77 | 78 | ;--- address & size of arguments are pushed 79 | 80 | mov cx, di 81 | add dx, di ; DX=size arguments + terminator bytes 82 | inc di ; add one for NULL pointer 83 | if ?DUMMYFN 84 | inc di ; add one for filename 85 | endif 86 | shl di, 1 ; each ofs needs 2 bytes 87 | add dx, di ; DX=size args + size argv 88 | and dx, -2 ; ensure stack remains word aligned 89 | mov ax, [bp] 90 | sub bp, dx ; alloc the really needed space for argc/argv 91 | mov [bp-6], ax ; store return address 92 | 93 | _argc equ 94 | _argv equ 95 | 96 | mov [_argv], bp 97 | mov [_argc], cx 98 | 99 | add di, bp ; di -> behind vector table (strings) 100 | xor ax, ax 101 | lea bx, [di-2] 102 | mov ss:[bx], ax ; terminating 0000 _argv[x] 103 | sub bx, 2 104 | jcxz noargs 105 | push ss 106 | pop es 107 | 108 | ;--- copy the arguments from PSP onto the stack 109 | 110 | mov dx, cx 111 | @@: 112 | pop cx ; size 113 | pop si ; address 114 | mov ss:[bx], di ; store _argv[x] 115 | sub bx, 2 116 | rep movsb 117 | stosb ; AL still 0 118 | dec dx 119 | jnz @B 120 | 121 | noargs: 122 | push ss 123 | pop ds 124 | ; assume ds:DGROUP 125 | if ?DUMMYFN 126 | mov [bx], ax ; store 0 as dummy filename 127 | inc word ptr [_argc] 128 | endif 129 | lea sp, [bp-6] 130 | ret 131 | _setargv endp 132 | 133 | -------------------------------------------------------------------------------- /JemmExL.mak: -------------------------------------------------------------------------------- 1 | # 2 | # builds JemmExL, the "legacy" variant of JemmEx, without support 3 | # of XMS v3.5 ( super-extended memory ) 4 | 5 | NAME3=JEMMEXL 6 | 7 | !ifndef DEBUG 8 | DEBUG=0 9 | !endif 10 | 11 | # to create kernel debugger aware versions, add "kd=1" to nmake 12 | !ifndef KD 13 | KD=0 14 | !endif 15 | 16 | ASM=jwasm.exe 17 | 18 | # select 32-bit COFF linker, default JWLink 19 | 20 | !ifndef JWLINK32 21 | JWLINK32=0 22 | !endif 23 | !ifndef WLINK32 24 | WLINK32=0 25 | !endif 26 | !ifndef MSLINK32 27 | MSLINK32=0 28 | !endif 29 | !if $(JWLINK32)+$(WLINK32)+$(MSLINK32)==0 30 | JWLINK32=1 31 | !endif 32 | 33 | # select 16-bit OMF linker, default JWLink 34 | 35 | !ifndef JWLINK 36 | JWLINK=0 37 | !endif 38 | !ifndef WLINK 39 | WLINK=0 40 | !endif 41 | !ifndef MSLINK 42 | MSLINK=0 43 | !endif 44 | !if $(JWLINK)+$(WLINK)+$(MSLINK)==0 45 | JWLINK=1 46 | !endif 47 | 48 | !if $(DEBUG) 49 | AOPTD=-D_DEBUG $(DBGOPT) -Sg 50 | !else 51 | AOPTD= 52 | !endif 53 | 54 | # list of 32bit modules 55 | COFFMODS=.\jemm32.obj .\ems.obj .\vcpi.obj .\dev.obj .\xms.obj .\umb.obj .\vdma.obj .\i15.obj .\emu.obj .\vds.obj .\pool.obj .\init.obj .\debug.obj 56 | 57 | BUILD=build 58 | 59 | !if $(DEBUG) 60 | OUTD3=$(BUILD)\$(NAME3)D 61 | COFFDEP3=$(COFFMODS:.\=build\JEMMEXLD\) 62 | !else 63 | OUTD3=$(BUILD)\$(NAME3) 64 | COFFDEP3=$(COFFMODS:.\=build\JEMMEXL\) 65 | !endif 66 | 67 | 68 | !if $(JWLINK32) 69 | LINK32=jwlink format raw bin file {$(COFFMODS:.\=)} name jemm32.bin option offs=0x110000, start=_start, map=jemm32.map, quiet 70 | !elseif $(WLINK32) 71 | LINK32= wlink format raw bin file {$(COFFMODS:.\=)} name jemm32.bin option offs=0x110000, start=_start, map=jemm32.map, quiet 72 | !else 73 | COFFOPT=/fixed /driver /subsystem:native /entry:start /base:0x100000 /align:0x10000 /MAP /nologo 74 | # MS link (newer versions won't accept option FILEALIGN anymore) 75 | LINK32=link.exe /FileAlign:0x200 $(COFFOPT) $(COFFMODS:.\=) /OUT:jemm32.bin 76 | !endif 77 | 78 | !if $(JWLINK) 79 | LINK16=jwlink.exe format dos file jemm16.obj,init16.obj name $(*B).EXE option map=$(*B).MAP, quiet 80 | !elseif $(WLINK) 81 | LINK16=wlink.exe format dos file jemm16.obj,init16.obj name $@.EXE option map=$@.MAP, quiet 82 | #else 83 | LINK16=link16.exe /NOLOGO/MAP:FULL/NOD /NOI jemm16.obj init16.obj,$@.EXE,$@.MAP; 84 | !endif 85 | 86 | 32BITDEPS=src\jemm32.inc src\jemm.inc src\external.inc src\debug.inc Makefile 87 | 88 | {src\}.asm{$(OUTD3)}.obj: 89 | @$(ASM) -c -nologo -coff -D?INTEGRATED=1 -D?XMS35=0 $(AOPTD) -Fl$(OUTD3)\ -Fo$(OUTD3)\ $< 90 | 91 | ALL: $(BUILD) $(OUTD3) $(OUTD3)\$(NAME3).EXE 92 | 93 | $(BUILD) $(OUTD3): 94 | @mkdir $* 95 | 96 | $(OUTD3)\$(NAME3).EXE: $(OUTD3)\jemm16.obj $(OUTD3)\init16.obj 97 | @cd $(OUTD3) 98 | @$(LINK16) 99 | @cd ..\.. 100 | 101 | $(OUTD3)\init16.obj: src\init16.asm src\jemm16.inc src\jemm.inc Makefile 102 | @$(ASM) -c -nologo -D?INTEGRATED=1 -D?XMS35=0 $(AOPTD) -Sg -Fl$(OUTD3)\ -Fo$(OUTD3)\ src\init16.asm 103 | 104 | $(OUTD3)\jemm16.obj: src\jemm16.asm $(OUTD3)\jemm32.bin src\jemm.inc src\jemm16.inc src\debug.inc Makefile 105 | @cd $(OUTD3) 106 | @$(ASM) -c -nologo -D?INTEGRATED=1 -D?XMS35=0 $(AOPTD) -Fl ..\..\src\jemm16.asm 107 | @cd ..\.. 108 | 109 | $(OUTD3)\jemm32.bin: $(COFFDEP3) 110 | @cd $(OUTD3) 111 | @$(LINK32) 112 | @cd ..\.. 113 | 114 | $(COFFDEP3): $(32BITDEPS) 115 | 116 | clean: 117 | @if exist $(OUTD3)\*.obj erase $(OUTD3)\*.obj 118 | @if exist $(OUTD3)\*.lst erase $(OUTD3)\*.lst 119 | @if exist $(OUTD3)\*.map erase $(OUTD3)\*.map 120 | @if exist $(OUTD3)\*.exe erase $(OUTD3)\*.exe 121 | @if exist $(OUTD3)\*.bin erase $(OUTD3)\*.bin 122 | @if exist $(OUTD3)\_jemm32.inc erase $(OUTD3)\_jemm32.inc 123 | 124 | -------------------------------------------------------------------------------- /Tools/JLOAD/DPRINTF.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- printf for debug displays, 32-bit 3 | 4 | ;--- i64toa(long long n, char * s, int base); 5 | ;--- convert 64-bit long long to string 6 | 7 | i64toa proc stdcall uses edi number:qword, outb:ptr, base:dword 8 | 9 | mov ch,0 10 | mov edi, base 11 | mov eax, dword ptr number+0 12 | mov esi, dword ptr number+4 13 | cmp edi,-10 14 | jne @F 15 | neg edi 16 | and esi,esi 17 | jns @F 18 | neg esi 19 | neg eax 20 | sbb esi,0 21 | mov ch,'-' 22 | @@: 23 | mov ebx,outb 24 | add ebx,22 25 | mov byte ptr [ebx],0 26 | @@nextdigit: 27 | dec ebx 28 | xor edx,edx 29 | xchg eax,esi 30 | div edi 31 | xchg eax,esi 32 | div edi 33 | add dl,'0' 34 | cmp dl,'9' 35 | jbe @F 36 | add dl,7+20h 37 | @@: 38 | mov [ebx],dl 39 | mov edx, eax 40 | or edx, esi 41 | jne @@nextdigit 42 | cmp ch,0 43 | je @F 44 | dec ebx 45 | mov [ebx],ch 46 | @@: 47 | mov eax,ebx 48 | ret 49 | 50 | i64toa endp 51 | 52 | dprintf proc c public fmt:ptr, args:vararg 53 | 54 | local flag:byte 55 | local longarg:byte 56 | local size_:dword 57 | local fillchr:dword 58 | local szTmp[24]:byte 59 | 60 | pushad 61 | pushfd 62 | cld 63 | lea edi,args 64 | @@L335: 65 | mov esi,fmt 66 | nextchar: 67 | lodsb cs:[esi] 68 | or al,al 69 | je done 70 | cmp al,'%' 71 | je formatitem 72 | call VPUTCHR 73 | jmp nextchar 74 | done: 75 | popfd 76 | popad 77 | ret 78 | 79 | formatitem: 80 | push offset @@L335 81 | xor edx,edx 82 | mov [longarg],dl 83 | mov bl,1 84 | mov cl,' ' 85 | cmp BYTE PTR [esi],'-' 86 | jne @F 87 | dec bl 88 | inc esi 89 | @@: 90 | mov [flag],bl 91 | cmp BYTE PTR [esi],'0' 92 | jne @F 93 | mov cl,'0' 94 | inc esi 95 | @@: 96 | mov [fillchr],ecx 97 | mov ebx,edx 98 | 99 | .while ( byte ptr [esi] >= '0' && byte ptr [esi] <= '9' ) 100 | lodsb 101 | sub al,'0' 102 | movzx eax,al 103 | imul ecx,ebx,10 ;ecx = ebx * 10 104 | add eax,ecx 105 | mov ebx,eax 106 | .endw 107 | 108 | mov [size_],ebx 109 | cmp BYTE PTR [esi],'l' 110 | jne @F 111 | mov [longarg],1 112 | inc esi 113 | @@: 114 | lodsb 115 | mov [fmt],esi 116 | cmp al,'x' 117 | je handle_x 118 | cmp al,'X' 119 | je handle_x 120 | cmp al,'d' 121 | je handle_d 122 | cmp al,'u' 123 | je handle_u 124 | cmp al,'s' 125 | je handle_s 126 | cmp al,'c' 127 | je handle_c 128 | and al,al 129 | jnz @F 130 | pop eax 131 | jmp done 132 | handle_c: 133 | mov eax,cs:[edi] 134 | add edi, 4 135 | @@: 136 | call VPUTCHR 137 | retn 138 | 139 | handle_s: 140 | mov esi,cs:[edi] 141 | add edi,4 142 | jmp print_string 143 | handle_d: 144 | handle_i: 145 | mov ebx,-10 146 | jmp @F 147 | handle_u: 148 | mov ebx, 10 149 | jmp @F 150 | handle_x: 151 | mov ebx, 16 152 | @@: 153 | xor edx,edx 154 | mov eax,cs:[edi] 155 | add edi,4 156 | cmp longarg,1 157 | jnz @F 158 | mov edx,cs:[edi] 159 | add edi,4 160 | jmp printnum 161 | @@: 162 | and ebx,ebx 163 | jns @F 164 | cdq 165 | @@: 166 | printnum: 167 | lea esi, szTmp 168 | invoke i64toa, edx::eax, esi, ebx 169 | mov esi, eax 170 | 171 | print_string: ;print string ESI, size EAX 172 | mov eax, esi 173 | .while byte ptr cs:[esi] 174 | inc esi 175 | .endw 176 | sub esi, eax 177 | xchg eax, esi 178 | mov ebx,size_ 179 | sub ebx,eax 180 | .if flag == 1 181 | .while sdword ptr ebx > 0 182 | mov eax, [fillchr] 183 | call VPUTCHR ;print leading filler chars 184 | dec ebx 185 | .endw 186 | .endif 187 | 188 | .while byte ptr cs:[esi] 189 | lodsb cs:[esi] 190 | call VPUTCHR ;print char of string 191 | .endw 192 | 193 | .while sdword ptr ebx > 0 194 | mov eax, [fillchr] 195 | call VPUTCHR ;print trailing spaces 196 | dec ebx 197 | .endw 198 | retn 199 | 200 | dprintf endp 201 | -------------------------------------------------------------------------------- /Tools/VCPI/PRINTF.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- ltob(long n, char * s, int base); 3 | ;--- convert long to string 4 | 5 | ltob PROC stdcall uses edi edx number:dword, outb:ptr, base:word 6 | 7 | mov ch,0 8 | movzx edi, base 9 | mov eax, number 10 | cmp di,-10 11 | jne @F 12 | mov di,10 13 | and eax,eax 14 | jns @F 15 | neg eax 16 | mov ch,'-' 17 | @@: 18 | mov bx,outb 19 | add bx,10 20 | mov BYTE PTR ss:[bx],0 21 | dec bx 22 | @@nextdigit: 23 | xor edx, edx 24 | div edi 25 | add dl,'0' 26 | cmp dl,'9' 27 | jbe @F 28 | add dl,7+20h 29 | @@: 30 | mov ss:[bx],dl 31 | dec bx 32 | and eax, eax 33 | jne @@nextdigit 34 | cmp ch,0 35 | je @F 36 | mov ss:[bx],ch 37 | dec bx 38 | @@: 39 | inc bx 40 | mov ax,bx 41 | ret 42 | 43 | ltob ENDP 44 | 45 | ;--- hiword(eax) is modified if numbers are rendered! 46 | 47 | printf PROC c fmt:ptr, args:VARARG 48 | 49 | local size_:word 50 | local flag:byte 51 | local longarg:byte 52 | local fill:byte 53 | local szTmp[12]:byte 54 | 55 | pusha 56 | lea di,[fmt+2] 57 | @@L335: 58 | mov si,[fmt] 59 | nextchar: 60 | lodsb 61 | or al,al 62 | je done 63 | cmp al,'%' 64 | je formatitem 65 | call handle_char 66 | jmp nextchar 67 | done: 68 | popa 69 | ret 70 | 71 | formatitem: 72 | push @@L335 73 | xor dx,dx 74 | mov [longarg],dl 75 | mov bl,1 76 | mov cl,' ' 77 | cmp BYTE PTR [si],'-' 78 | jne @F 79 | dec bx 80 | inc si 81 | @@: 82 | mov [flag],bl 83 | cmp BYTE PTR [si],'0' 84 | jne @F 85 | mov cl,'0' 86 | inc si 87 | @@: 88 | mov [fill],cl 89 | mov bx,dx 90 | 91 | .while byte ptr [si] >= '0' && byte ptr [si] <= '9' 92 | lodsb 93 | sub al,'0' 94 | cbw 95 | imul cx,bx,10 ;cx = bx * 10 96 | add ax,cx 97 | mov bx,ax 98 | .endw 99 | 100 | mov [size_],bx 101 | cmp BYTE PTR [si],'l' 102 | jne @F 103 | mov [longarg],1 104 | inc si 105 | @@: 106 | lodsb 107 | mov [fmt],si 108 | cmp al,'x' 109 | je handle_x 110 | cmp al,'X' 111 | je handle_x 112 | cmp al,'c' 113 | je handle_c 114 | cmp al,'d' 115 | je handle_d 116 | cmp al,'i' 117 | je handle_i 118 | cmp al,'s' 119 | je handle_s 120 | cmp al,'u' 121 | je handle_u 122 | cmp al,0 123 | jnz @@L359 124 | pop ax 125 | jmp done 126 | handle_c: 127 | mov ax,ss:[di] 128 | add di,2 129 | @@L359: 130 | call handle_char 131 | retn 132 | 133 | handle_x: 134 | mov bx,16 135 | jmp @@lprt262 136 | handle_d: 137 | handle_i: 138 | mov bx,-10 139 | jmp @@lprt262 140 | handle_u: 141 | mov bx,10 142 | @@lprt262: 143 | mov ax,ss:[di] 144 | add di,2 145 | sub dx,dx 146 | cmp bx,0 ;signed or unsigned? 147 | jge @F 148 | cwd 149 | @@: 150 | cmp [longarg],0 151 | je @F 152 | mov dx,ss:[di] 153 | add di,2 154 | @@: 155 | lea cx,[szTmp] 156 | invoke ltob, dx::ax, cx, bx 157 | mov si,ax 158 | push ds 159 | push ss 160 | pop ds 161 | call output_string 162 | pop ds 163 | retn 164 | 165 | handle_s: 166 | mov si,ss:[di] 167 | add di,2 168 | 169 | output_string: ;display string at ds:si 170 | mov ax,si 171 | mov bx,size_ 172 | .while byte ptr [si] 173 | inc si 174 | .endw 175 | sub si,ax 176 | xchg ax,si 177 | sub bx,ax 178 | .if flag == 1 179 | .while sword ptr bx > 0 180 | mov al,[fill] 181 | call handle_char 182 | dec bx 183 | .endw 184 | .endif 185 | 186 | .while byte ptr [si] 187 | lodsb 188 | call handle_char 189 | .endw 190 | 191 | .while sword ptr bx > 0 192 | mov al,[fill] 193 | call handle_char 194 | dec bx 195 | .endw 196 | retn 197 | 198 | handle_char: 199 | cmp al,lf 200 | jnz @F 201 | mov al,cr 202 | call @F 203 | mov al,lf 204 | @@: 205 | mov dx, cs 206 | cmp dx, CSR0 207 | jnz @F 208 | call VioPutChar 209 | retn 210 | @@: 211 | mov dl, al 212 | mov ah, 2 213 | int 21h 214 | retn 215 | 216 | printf ENDP 217 | 218 | -------------------------------------------------------------------------------- /src/DEBUG.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;*** implements debug displays 3 | ;--- written by japheth 4 | ;--- public domain 5 | ;--- to be assembled with JWasm or Masm v6.1+ 6 | 7 | .486P 8 | .model FLAT 9 | option proc:private 10 | option dotname 11 | 12 | include jemm.inc ;common declarations 13 | include jemm32.inc ;declarations for Jemm32 14 | include debug.inc 15 | 16 | SLOWDOWN equ 256 ;to slow down debug displays 17 | 18 | ;--- publics/externals 19 | 20 | include external.inc 21 | 22 | if ?DBGOUT 23 | 24 | .text$03 segment 25 | 26 | ;--- make no assumptions about DS and ES here! 27 | ;--- also don't push/pop segment registers! 28 | 29 | VPUTCHR PROC public 30 | PUSHAD 31 | if ?KD 32 | cmp cs:[bKD],0 ; kernel debugger detected? 33 | jz @F 34 | mov edx, eax ; then redirect output to it 35 | xor eax, eax 36 | int 41h 37 | popad 38 | ret 39 | @@: 40 | endif 41 | if ?USEMONO 42 | mov edi,0B0000h 43 | mov ebx,7 44 | else 45 | MOV EDI,0B8000h 46 | CMP BYTE ptr SS:[463h],0B4h 47 | JNZ @@IS_COLOR 48 | XOR DI,DI 49 | @@IS_COLOR: 50 | movzx EBX, WORD PTR SS:[44Eh] 51 | ADD EDI, EBX 52 | MOVZX EBX, BYTE PTR SS:[462h] 53 | endif 54 | mov esi, edi 55 | MOVZX ECX, BYTE PTR SS:[EBX*2+450h+1] ;ROW 56 | if ?USEMONO 57 | MOV EAX, 80 58 | else 59 | MOVZX EAX, WORD PTR SS:[44Ah] 60 | endif 61 | MUL ECX 62 | MOVZX EDX, BYTE PTR SS:[EBX*2+450h] ;COL 63 | ADD EAX, EDX 64 | MOV DH,CL 65 | LEA EDI, [EDI+EAX*2] 66 | MOV AL, [ESP+1Ch] 67 | CMP AL, 10 68 | JZ @@NEWLINE 69 | MOV SS:[EDI], AL 70 | MOV byte ptr SS:[EDI+1], 07 71 | INC DL 72 | if ?USEMONO 73 | cmp dl,80 74 | else 75 | CMP DL, BYTE PTR SS:[44Ah] 76 | endif 77 | JB @@OLDLINE 78 | @@NEWLINE: 79 | MOV DL, 00 80 | INC DH 81 | if ?USEMONO 82 | CMP DH, 24 83 | else 84 | CMP DH, BYTE PTR SS:[484h] 85 | endif 86 | JBE @@OLDLINE 87 | DEC DH 88 | CALL @@SCROLL_SCREEN 89 | @@OLDLINE: 90 | MOV SS:[EBX*2+450h],DX 91 | POPAD 92 | RET 93 | 94 | ;--- scroll screen up 1 line 95 | ;--- esi -> start screen 96 | 97 | @@SCROLL_SCREEN: 98 | CLD 99 | mov edi,esi 100 | if ?USEMONO 101 | mov eax,80 102 | else 103 | movzx eax,word ptr ss:[44Ah] 104 | endif 105 | push eax 106 | lea esi, [esi+2*eax] 107 | if ?USEMONO 108 | mov CL, 24 109 | else 110 | MOV CL, SS:[484h] 111 | endif 112 | mul cl 113 | mov ecx,eax 114 | @@nextcell: 115 | lodsw cs:[esi] 116 | mov ss:[edi],ax 117 | add edi,2 118 | loop @@nextcell 119 | pop ecx 120 | mov ax,0720h 121 | @@nextcell2: 122 | mov ss:[edi],ax 123 | add edi,2 124 | loop @@nextcell2 125 | if SLOWDOWN 126 | mov ecx,SLOWDOWN 127 | @@: 128 | in al,61h 129 | cmp al,ah 130 | jz @B 131 | mov ah,al 132 | loop @B 133 | endif 134 | retn 135 | 136 | VPUTCHR ENDP 137 | 138 | ;--- print a string which is hard-coded behind the call to this function 139 | 140 | ifdef _DEBUG 141 | include dprintf.inc 142 | endif 143 | 144 | if 0 145 | 146 | ;--- 386SWAT isn't compatible with Jemm, because this debugger 147 | ;--- expects that extended memory is mapped into linear address space, 148 | ;--- at least those parts of XMS memory that 386SWAT uses for itself. 149 | ;--- Jemm simply doesn't do that; it maps the memory that it needs and 150 | ;--- nothing else. 151 | 152 | ;--- check if int 3 vector still points to 153 | ;--- the monitor code segment. If no, assume 386SWAT has intruded 154 | 155 | DebugBreak proc public 156 | cmp word ptr cs:[offset V86GDT+3*8+4],FLAT_CODE_SEL 157 | jz @@noswat 158 | pushfd 159 | or byte ptr [esp+1],1 ;set TF 160 | popfd 161 | @@noswat: 162 | ret 163 | DebugBreak endp 164 | 165 | endif 166 | 167 | .text$03 ends 168 | 169 | .text$04 segment 170 | 171 | ;--- init debug 172 | ;--- ESI -> Jemminit 173 | 174 | Debug_Init proc public 175 | ret 176 | Debug_Init endp 177 | 178 | .text$04 ends 179 | 180 | endif 181 | 182 | END 183 | -------------------------------------------------------------------------------- /src/DPRINTF.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- printf for debug displays 3 | ;--- assume CS and SS flat; 4 | ;--- no assumptions about DS/ES 5 | 6 | ;--- i64toa(long long n, char * s, int base); 7 | ;--- convert 64-bit long long to string 8 | 9 | i64toa proc stdcall uses edi number:qword, outb:ptr, base:dword 10 | 11 | mov ch,0 12 | mov edi, base 13 | mov eax, dword ptr number+0 14 | mov esi, dword ptr number+4 15 | cmp edi,-10 16 | jne @F 17 | neg edi 18 | and esi,esi 19 | jns @F 20 | neg esi 21 | neg eax 22 | sbb esi,0 23 | mov ch,'-' 24 | @@: 25 | mov ebx,outb 26 | add ebx,22 27 | mov byte ptr ss:[ebx],0 28 | @@nextdigit: 29 | dec ebx 30 | xor edx,edx 31 | xchg eax,esi 32 | div edi 33 | xchg eax,esi 34 | div edi 35 | add dl,'0' 36 | cmp dl,'9' 37 | jbe @F 38 | add dl,7+20h 39 | @@: 40 | mov ss:[ebx],dl 41 | mov edx, eax 42 | or edx, esi 43 | jne @@nextdigit 44 | cmp ch,0 45 | je @F 46 | dec ebx 47 | mov ss:[ebx],ch 48 | @@: 49 | mov eax,ebx 50 | ret 51 | 52 | i64toa endp 53 | 54 | dprintf proc c public fmt:ptr, args:vararg 55 | 56 | local flag:byte 57 | local longarg:byte 58 | local size_:dword 59 | local fillchr:dword 60 | local szTmp[24]:byte 61 | 62 | pushad 63 | pushfd 64 | cld 65 | lea edi,args 66 | @@L335: 67 | mov esi,fmt 68 | nextchar: 69 | lodsb cs:[esi] 70 | or al,al 71 | je done 72 | cmp al,'%' 73 | je formatitem 74 | call VPUTCHR 75 | jmp nextchar 76 | done: 77 | popfd 78 | popad 79 | ret 80 | 81 | formatitem: 82 | push offset @@L335 83 | xor edx,edx 84 | mov [longarg],dl 85 | mov bl,1 86 | mov cl,' ' 87 | cmp BYTE PTR cs:[esi],'-' 88 | jne @F 89 | dec bl 90 | inc esi 91 | @@: 92 | mov [flag],bl 93 | cmp BYTE PTR cs:[esi],'0' 94 | jne @F 95 | mov cl,'0' 96 | inc esi 97 | @@: 98 | mov [fillchr],ecx 99 | mov ebx,edx 100 | 101 | .while ( byte ptr cs:[esi] >= '0' && byte ptr cs:[esi] <= '9' ) 102 | lodsb cs:[esi] 103 | sub al,'0' 104 | movzx eax,al 105 | imul ecx,ebx,10 ;ecx = ebx * 10 106 | add eax,ecx 107 | mov ebx,eax 108 | .endw 109 | 110 | mov [size_],ebx 111 | cmp BYTE PTR cs:[esi],'l' 112 | jne @F 113 | mov [longarg],1 114 | inc esi 115 | @@: 116 | lodsb 117 | mov [fmt],esi 118 | cmp al,'x' 119 | je handle_x 120 | cmp al,'X' 121 | je handle_x 122 | cmp al,'d' 123 | je handle_d 124 | cmp al,'u' 125 | je handle_u 126 | cmp al,'s' 127 | je handle_s 128 | cmp al,'c' 129 | je handle_c 130 | and al,al 131 | jnz @F 132 | pop eax 133 | jmp done 134 | handle_c: 135 | mov eax,ss:[edi] 136 | add edi, 4 137 | @@: 138 | call VPUTCHR 139 | retn 140 | 141 | handle_s: 142 | mov esi,ss:[edi] 143 | add edi,4 144 | jmp print_string 145 | handle_d: 146 | handle_i: 147 | mov ebx,-10 148 | jmp @F 149 | handle_u: 150 | mov ebx, 10 151 | jmp @F 152 | handle_x: 153 | mov ebx, 16 154 | @@: 155 | xor edx,edx 156 | mov eax,ss:[edi] 157 | add edi,4 158 | cmp longarg,1 159 | jnz @F 160 | mov edx,ss:[edi] 161 | add edi,4 162 | jmp printnum 163 | @@: 164 | and ebx,ebx 165 | jns @F 166 | cdq 167 | @@: 168 | printnum: 169 | lea esi, szTmp 170 | invoke i64toa, edx::eax, esi, ebx 171 | mov esi, eax 172 | 173 | print_string: ;print string ESI, size EAX 174 | mov eax, esi 175 | .while byte ptr cs:[esi] 176 | inc esi 177 | .endw 178 | sub esi, eax 179 | xchg eax, esi 180 | mov ebx,size_ 181 | sub ebx,eax 182 | .if flag == 1 183 | .while sdword ptr ebx > 0 184 | mov eax, [fillchr] 185 | call VPUTCHR ;print leading filler chars 186 | dec ebx 187 | .endw 188 | .endif 189 | 190 | .while byte ptr cs:[esi] 191 | lodsb cs:[esi] 192 | call VPUTCHR ;print char of string 193 | .endw 194 | 195 | .while sdword ptr ebx > 0 196 | mov eax, [fillchr] 197 | call VPUTCHR ;print trailing spaces 198 | dec ebx 199 | .endw 200 | retn 201 | 202 | dprintf endp 203 | -------------------------------------------------------------------------------- /Tools/CPUID/PRINTF.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- simple printf() implementation 3 | 4 | handle_char proc 5 | 6 | mov dl,al 7 | cmp al,10 8 | jnz @F 9 | mov dl,13 10 | call @F 11 | mov dl,10 12 | @@: 13 | mov ah,2 14 | int 21h 15 | ret 16 | 17 | handle_char endp 18 | 19 | ;--- ltob(long n, char * s, int base); 20 | ;--- convert long to string 21 | ;--- outb is expected to be onto stack 22 | 23 | ltob PROC stdcall uses edi number:dword, outb:word, base:word 24 | 25 | mov ch,0 26 | movzx edi, base 27 | mov eax, number 28 | cmp di,-10 29 | jne @F 30 | mov di,10 31 | and eax,eax 32 | jns @F 33 | neg eax 34 | mov ch,'-' 35 | @@: 36 | mov bx,outb 37 | add bx,10 38 | mov BYTE PTR ss:[bx],0 39 | dec bx 40 | @@nextdigit: 41 | xor edx, edx 42 | div edi 43 | add dl,'0' 44 | cmp dl,'9' 45 | jbe @F 46 | add dl,7+20h 47 | @@: 48 | mov ss:[bx],dl 49 | dec bx 50 | and eax, eax 51 | jne @@nextdigit 52 | cmp ch,0 53 | je @F 54 | mov ss:[bx],ch 55 | dec bx 56 | @@: 57 | inc bx 58 | mov ax,bx 59 | ret 60 | 61 | ltob ENDP 62 | 63 | ;--- ds=dgroup, ss don't need to be dgroup 64 | 65 | printf PROC c uses si di bx fmt:ptr byte, args:VARARG 66 | 67 | local size_:word 68 | local flag:byte 69 | local longarg:byte 70 | local fill:byte 71 | local szTmp[12]:byte 72 | 73 | lea di,[fmt+2] 74 | @@L335: 75 | mov si,[fmt] 76 | nextchar: 77 | lodsb 78 | or al,al 79 | je done 80 | cmp al,'%' 81 | je formatitem 82 | call handle_char 83 | jmp nextchar 84 | done: 85 | xor ax,ax 86 | ret 87 | 88 | formatitem: 89 | push @@L335 90 | xor dx,dx 91 | mov [longarg],dl 92 | mov bl,1 93 | mov cl,' ' 94 | cmp BYTE PTR [si],'-' 95 | jne @F 96 | dec bx 97 | inc si 98 | @@: 99 | mov [flag],bl 100 | cmp BYTE PTR [si],'0' 101 | jne @F 102 | mov cl,'0' 103 | inc si 104 | @@: 105 | mov [fill],cl 106 | mov bx,dx 107 | 108 | nextdigit: 109 | cmp BYTE PTR [si],'0' 110 | jb digitsdone 111 | cmp BYTE PTR [si],'9' 112 | ja digitsdone 113 | lodsb 114 | sub al,'0' 115 | cbw 116 | imul cx,bx,10 ;cx = bx * 10 117 | add ax,cx 118 | mov bx,ax 119 | jmp nextdigit 120 | 121 | digitsdone: 122 | mov [size_],bx 123 | cmp BYTE PTR [si],'l' 124 | jne @F 125 | mov [longarg],1 126 | inc si 127 | @@: 128 | lodsb 129 | mov [fmt],si 130 | cmp al,'x' 131 | je handle_x 132 | cmp al,'X' 133 | je handle_x 134 | cmp al,'c' 135 | je handle_c 136 | cmp al,'d' 137 | je handle_d 138 | cmp al,'i' 139 | je handle_i 140 | cmp al,'s' 141 | je handle_s 142 | cmp al,'u' 143 | je handle_u 144 | mov al,'%' 145 | jmp @@L359 146 | handle_c: 147 | mov ax,ss:[di] 148 | add di,2 149 | @@L359: 150 | call handle_char 151 | retn 152 | 153 | handle_x: 154 | mov bx,16 155 | jmp @@lprt262 156 | handle_d: 157 | handle_i: 158 | mov bx,-10 159 | jmp @@lprt262 160 | handle_u: 161 | mov bx,10 162 | @@lprt262: 163 | mov ax,ss:[di] 164 | add di,2 165 | sub dx,dx 166 | cmp bx,0 ;signed or unsigned? 167 | jge @F 168 | cwd 169 | @@: 170 | cmp [longarg],0 171 | je @F 172 | mov dx,ss:[di] 173 | add di,2 174 | @@: 175 | lea cx,[szTmp] 176 | invoke ltob, dx::ax, cx, bx 177 | mov si,ax 178 | push ds 179 | push ss 180 | pop ds 181 | call output_string 182 | pop ds 183 | retn 184 | 185 | handle_s: 186 | mov si,ss:[di] 187 | add di,2 188 | 189 | output_string: ;display string at ds:si 190 | mov ax,si 191 | mov bx,size_ 192 | .while byte ptr [si] 193 | inc si 194 | .endw 195 | sub si,ax 196 | xchg ax,si 197 | sub bx,ax 198 | .if flag == 1 199 | .while sword ptr bx > 0 200 | mov al,[fill] 201 | call handle_char 202 | dec bx 203 | .endw 204 | .endif 205 | 206 | .while byte ptr [si] 207 | lodsb 208 | call handle_char 209 | .endw 210 | 211 | .while sword ptr bx > 0 212 | mov al,[fill] 213 | call handle_char 214 | dec bx 215 | .endw 216 | retn 217 | 218 | printf ENDP 219 | 220 | -------------------------------------------------------------------------------- /Tools/Cpustat/PRINTF.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- simple printf() implementation 3 | 4 | handle_char proc 5 | 6 | mov dl,al 7 | cmp al,10 8 | jnz @F 9 | mov dl,13 10 | call @F 11 | mov dl,10 12 | @@: 13 | mov ah,2 14 | int 21h 15 | ret 16 | 17 | handle_char endp 18 | 19 | ;--- ltob(long n, char * s, int base); 20 | ;--- convert long to string 21 | ;--- outb is expected to be onto stack 22 | 23 | ltob PROC stdcall uses edi number:dword, outb:word, base:word 24 | 25 | mov ch,0 26 | movzx edi, base 27 | mov eax, number 28 | cmp di,-10 29 | jne @F 30 | mov di,10 31 | and eax,eax 32 | jns @F 33 | neg eax 34 | mov ch,'-' 35 | @@: 36 | mov bx,outb 37 | add bx,10 38 | mov BYTE PTR ss:[bx],0 39 | dec bx 40 | @@nextdigit: 41 | xor edx, edx 42 | div edi 43 | add dl,'0' 44 | cmp dl,'9' 45 | jbe @F 46 | add dl,7+20h 47 | @@: 48 | mov ss:[bx],dl 49 | dec bx 50 | and eax, eax 51 | jne @@nextdigit 52 | cmp ch,0 53 | je @F 54 | mov ss:[bx],ch 55 | dec bx 56 | @@: 57 | inc bx 58 | mov ax,bx 59 | ret 60 | 61 | ltob ENDP 62 | 63 | ;--- ds=dgroup, ss don't need to be dgroup 64 | 65 | printf PROC c uses si di bx fmt:ptr byte, args:VARARG 66 | 67 | local size_:word 68 | local flag:byte 69 | local longarg:byte 70 | local fill:byte 71 | local szTmp[12]:byte 72 | 73 | lea di,[fmt+2] 74 | @@L335: 75 | mov si,[fmt] 76 | nextchar: 77 | lodsb 78 | or al,al 79 | je done 80 | cmp al,'%' 81 | je formatitem 82 | call handle_char 83 | jmp nextchar 84 | done: 85 | xor ax,ax 86 | ret 87 | 88 | formatitem: 89 | push @@L335 90 | xor dx,dx 91 | mov [longarg],dl 92 | mov bl,1 93 | mov cl,' ' 94 | cmp BYTE PTR [si],'-' 95 | jne @F 96 | dec bx 97 | inc si 98 | @@: 99 | mov [flag],bl 100 | cmp BYTE PTR [si],'0' 101 | jne @F 102 | mov cl,'0' 103 | inc si 104 | @@: 105 | mov [fill],cl 106 | mov bx,dx 107 | 108 | nextdigit: 109 | cmp BYTE PTR [si],'0' 110 | jb digitsdone 111 | cmp BYTE PTR [si],'9' 112 | ja digitsdone 113 | lodsb 114 | sub al,'0' 115 | cbw 116 | imul cx,bx,10 ;cx = bx * 10 117 | add ax,cx 118 | mov bx,ax 119 | jmp nextdigit 120 | 121 | digitsdone: 122 | mov [size_],bx 123 | cmp BYTE PTR [si],'l' 124 | jne @F 125 | mov [longarg],1 126 | inc si 127 | @@: 128 | lodsb 129 | mov [fmt],si 130 | cmp al,'x' 131 | je handle_x 132 | cmp al,'X' 133 | je handle_x 134 | cmp al,'c' 135 | je handle_c 136 | cmp al,'d' 137 | je handle_d 138 | cmp al,'i' 139 | je handle_i 140 | cmp al,'s' 141 | je handle_s 142 | cmp al,'u' 143 | je handle_u 144 | mov al,'%' 145 | jmp @@L359 146 | handle_c: 147 | mov ax,ss:[di] 148 | add di,2 149 | @@L359: 150 | call handle_char 151 | retn 152 | 153 | handle_x: 154 | mov bx,16 155 | jmp @@lprt262 156 | handle_d: 157 | handle_i: 158 | mov bx,-10 159 | jmp @@lprt262 160 | handle_u: 161 | mov bx,10 162 | @@lprt262: 163 | mov ax,ss:[di] 164 | add di,2 165 | sub dx,dx 166 | cmp bx,0 ;signed or unsigned? 167 | jge @F 168 | cwd 169 | @@: 170 | cmp [longarg],0 171 | je @F 172 | mov dx,ss:[di] 173 | add di,2 174 | @@: 175 | lea cx,[szTmp] 176 | invoke ltob, dx::ax, cx, bx 177 | mov si,ax 178 | push ds 179 | push ss 180 | pop ds 181 | call output_string 182 | pop ds 183 | retn 184 | 185 | handle_s: 186 | mov si,ss:[di] 187 | add di,2 188 | 189 | output_string: ;display string at ds:si 190 | mov ax,si 191 | mov bx,size_ 192 | .while byte ptr [si] 193 | inc si 194 | .endw 195 | sub si,ax 196 | xchg ax,si 197 | sub bx,ax 198 | .if flag == 1 199 | .while sword ptr bx > 0 200 | mov al,[fill] 201 | call handle_char 202 | dec bx 203 | .endw 204 | .endif 205 | 206 | .while byte ptr [si] 207 | lodsb 208 | call handle_char 209 | .endw 210 | 211 | .while sword ptr bx > 0 212 | mov al,[fill] 213 | call handle_char 214 | dec bx 215 | .endw 216 | retn 217 | 218 | printf ENDP 219 | 220 | -------------------------------------------------------------------------------- /Tools/EMSSTAT/PRINTF.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- simple printf() implementation 3 | 4 | handle_char proc 5 | 6 | mov dl,al 7 | cmp al,10 8 | jnz @F 9 | mov dl,13 10 | call @F 11 | mov dl,10 12 | @@: 13 | mov ah,2 14 | int 21h 15 | ret 16 | 17 | handle_char endp 18 | 19 | ;--- ltob(long n, char * s, int base); 20 | ;--- convert long to string 21 | ;--- outb is expected to be onto stack 22 | 23 | ltob PROC stdcall uses edi number:dword, outb:word, base:word 24 | 25 | mov ch,0 26 | movzx edi, base 27 | mov eax, number 28 | cmp di,-10 29 | jne @F 30 | mov di,10 31 | and eax,eax 32 | jns @F 33 | neg eax 34 | mov ch,'-' 35 | @@: 36 | mov bx,outb 37 | add bx,10 38 | mov BYTE PTR ss:[bx],0 39 | dec bx 40 | @@nextdigit: 41 | xor edx, edx 42 | div edi 43 | add dl,'0' 44 | cmp dl,'9' 45 | jbe @F 46 | add dl,7+20h 47 | @@: 48 | mov ss:[bx],dl 49 | dec bx 50 | and eax, eax 51 | jne @@nextdigit 52 | cmp ch,0 53 | je @F 54 | mov ss:[bx],ch 55 | dec bx 56 | @@: 57 | inc bx 58 | mov ax,bx 59 | ret 60 | 61 | ltob ENDP 62 | 63 | ;--- ds=dgroup, ss don't need to be dgroup 64 | 65 | printf PROC c uses si di bx fmt:ptr byte, args:VARARG 66 | 67 | local size_:word 68 | local flag:byte 69 | local longarg:byte 70 | local fill:byte 71 | local szTmp[12]:byte 72 | 73 | lea di,[fmt+2] 74 | @@L335: 75 | mov si,[fmt] 76 | nextchar: 77 | lodsb 78 | or al,al 79 | je done 80 | cmp al,'%' 81 | je formatitem 82 | call handle_char 83 | jmp nextchar 84 | done: 85 | xor ax,ax 86 | ret 87 | 88 | formatitem: 89 | push @@L335 90 | xor dx,dx 91 | mov [longarg],dl 92 | mov bl,1 93 | mov cl,' ' 94 | cmp BYTE PTR [si],'-' 95 | jne @F 96 | dec bx 97 | inc si 98 | @@: 99 | mov [flag],bl 100 | cmp BYTE PTR [si],'0' 101 | jne @F 102 | mov cl,'0' 103 | inc si 104 | @@: 105 | mov [fill],cl 106 | mov bx,dx 107 | 108 | nextdigit: 109 | cmp BYTE PTR [si],'0' 110 | jb digitsdone 111 | cmp BYTE PTR [si],'9' 112 | ja digitsdone 113 | lodsb 114 | sub al,'0' 115 | cbw 116 | imul cx,bx,10 ;cx = bx * 10 117 | add ax,cx 118 | mov bx,ax 119 | jmp nextdigit 120 | 121 | digitsdone: 122 | mov [size_],bx 123 | cmp BYTE PTR [si],'l' 124 | jne @F 125 | mov [longarg],1 126 | inc si 127 | @@: 128 | lodsb 129 | mov [fmt],si 130 | cmp al,'x' 131 | je handle_x 132 | cmp al,'X' 133 | je handle_x 134 | cmp al,'c' 135 | je handle_c 136 | cmp al,'d' 137 | je handle_d 138 | cmp al,'i' 139 | je handle_i 140 | cmp al,'s' 141 | je handle_s 142 | cmp al,'u' 143 | je handle_u 144 | mov al,'%' 145 | jmp @@L359 146 | handle_c: 147 | mov ax,ss:[di] 148 | add di,2 149 | @@L359: 150 | call handle_char 151 | retn 152 | 153 | handle_x: 154 | mov bx,16 155 | jmp @@lprt262 156 | handle_d: 157 | handle_i: 158 | mov bx,-10 159 | jmp @@lprt262 160 | handle_u: 161 | mov bx,10 162 | @@lprt262: 163 | mov ax,ss:[di] 164 | add di,2 165 | sub dx,dx 166 | cmp bx,0 ;signed or unsigned? 167 | jge @F 168 | cwd 169 | @@: 170 | cmp [longarg],0 171 | je @F 172 | mov dx,ss:[di] 173 | add di,2 174 | @@: 175 | lea cx,[szTmp] 176 | invoke ltob, dx::ax, cx, bx 177 | mov si,ax 178 | push ds 179 | push ss 180 | pop ds 181 | call output_string 182 | pop ds 183 | retn 184 | 185 | handle_s: 186 | mov si,ss:[di] 187 | add di,2 188 | 189 | output_string: ;display string at ds:si 190 | mov ax,si 191 | mov bx,size_ 192 | .while byte ptr [si] 193 | inc si 194 | .endw 195 | sub si,ax 196 | xchg ax,si 197 | sub bx,ax 198 | .if flag == 1 199 | .while sword ptr bx > 0 200 | mov al,[fill] 201 | call handle_char 202 | dec bx 203 | .endw 204 | .endif 205 | 206 | .while byte ptr [si] 207 | lodsb 208 | call handle_char 209 | .endw 210 | 211 | .while sword ptr bx > 0 212 | mov al,[fill] 213 | call handle_char 214 | dec bx 215 | .endw 216 | retn 217 | 218 | printf ENDP 219 | 220 | -------------------------------------------------------------------------------- /Tools/MEMSTAT/PRINTF.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- simple printf() implementation 3 | 4 | handle_char proc 5 | 6 | mov dl,al 7 | cmp al,10 8 | jnz @F 9 | mov dl,13 10 | call @F 11 | mov dl,10 12 | @@: 13 | mov ah,2 14 | int 21h 15 | ret 16 | 17 | handle_char endp 18 | 19 | ;--- ltob(long n, char * s, int base); 20 | ;--- convert long to string 21 | ;--- outb is expected to be onto stack 22 | 23 | ltob PROC stdcall uses edi number:dword, outb:word, base:word 24 | 25 | mov ch,0 26 | movzx edi, base 27 | mov eax, number 28 | cmp di,-10 29 | jne @F 30 | mov di,10 31 | and eax,eax 32 | jns @F 33 | neg eax 34 | mov ch,'-' 35 | @@: 36 | mov bx,outb 37 | add bx,10 38 | mov BYTE PTR ss:[bx],0 39 | dec bx 40 | @@nextdigit: 41 | xor edx, edx 42 | div edi 43 | add dl,'0' 44 | cmp dl,'9' 45 | jbe @F 46 | add dl,7+20h 47 | @@: 48 | mov ss:[bx],dl 49 | dec bx 50 | and eax, eax 51 | jne @@nextdigit 52 | cmp ch,0 53 | je @F 54 | mov ss:[bx],ch 55 | dec bx 56 | @@: 57 | inc bx 58 | mov ax,bx 59 | ret 60 | 61 | ltob ENDP 62 | 63 | ;--- ds=dgroup, ss don't need to be dgroup 64 | 65 | printf PROC c uses si di bx fmt:ptr byte, args:VARARG 66 | 67 | local size_:word 68 | local flag:byte 69 | local longarg:byte 70 | local fill:byte 71 | local szTmp[12]:byte 72 | 73 | lea di,[fmt+2] 74 | @@L335: 75 | mov si,[fmt] 76 | nextchar: 77 | lodsb 78 | or al,al 79 | je done 80 | cmp al,'%' 81 | je formatitem 82 | call handle_char 83 | jmp nextchar 84 | done: 85 | xor ax,ax 86 | ret 87 | 88 | formatitem: 89 | push @@L335 90 | xor dx,dx 91 | mov [longarg],dl 92 | mov bl,1 93 | mov cl,' ' 94 | cmp BYTE PTR [si],'-' 95 | jne @F 96 | dec bx 97 | inc si 98 | @@: 99 | mov [flag],bl 100 | cmp BYTE PTR [si],'0' 101 | jne @F 102 | mov cl,'0' 103 | inc si 104 | @@: 105 | mov [fill],cl 106 | mov bx,dx 107 | 108 | nextdigit: 109 | cmp BYTE PTR [si],'0' 110 | jb digitsdone 111 | cmp BYTE PTR [si],'9' 112 | ja digitsdone 113 | lodsb 114 | sub al,'0' 115 | cbw 116 | imul cx,bx,10 ;cx = bx * 10 117 | add ax,cx 118 | mov bx,ax 119 | jmp nextdigit 120 | 121 | digitsdone: 122 | mov [size_],bx 123 | cmp BYTE PTR [si],'l' 124 | jne @F 125 | mov [longarg],1 126 | inc si 127 | @@: 128 | lodsb 129 | mov [fmt],si 130 | cmp al,'x' 131 | je handle_x 132 | cmp al,'X' 133 | je handle_x 134 | cmp al,'c' 135 | je handle_c 136 | cmp al,'d' 137 | je handle_d 138 | cmp al,'i' 139 | je handle_i 140 | cmp al,'s' 141 | je handle_s 142 | cmp al,'u' 143 | je handle_u 144 | mov al,'%' 145 | jmp @@L359 146 | handle_c: 147 | mov ax,ss:[di] 148 | add di,2 149 | @@L359: 150 | call handle_char 151 | retn 152 | 153 | handle_x: 154 | mov bx,16 155 | jmp @@lprt262 156 | handle_d: 157 | handle_i: 158 | mov bx,-10 159 | jmp @@lprt262 160 | handle_u: 161 | mov bx,10 162 | @@lprt262: 163 | mov ax,ss:[di] 164 | add di,2 165 | sub dx,dx 166 | cmp bx,0 ;signed or unsigned? 167 | jge @F 168 | cwd 169 | @@: 170 | cmp [longarg],0 171 | je @F 172 | mov dx,ss:[di] 173 | add di,2 174 | @@: 175 | lea cx,[szTmp] 176 | invoke ltob, dx::ax, cx, bx 177 | mov si,ax 178 | push ds 179 | push ss 180 | pop ds 181 | call output_string 182 | pop ds 183 | retn 184 | 185 | handle_s: 186 | mov si,ss:[di] 187 | add di,2 188 | 189 | output_string: ;display string at ds:si 190 | mov ax,si 191 | mov bx,size_ 192 | .while byte ptr [si] 193 | inc si 194 | .endw 195 | sub si,ax 196 | xchg ax,si 197 | sub bx,ax 198 | .if flag == 1 199 | .while sword ptr bx > 0 200 | mov al,[fill] 201 | call handle_char 202 | dec bx 203 | .endw 204 | .endif 205 | 206 | .while byte ptr [si] 207 | lodsb 208 | call handle_char 209 | .endw 210 | 211 | .while sword ptr bx > 0 212 | mov al,[fill] 213 | call handle_char 214 | dec bx 215 | .endw 216 | retn 217 | 218 | printf ENDP 219 | 220 | -------------------------------------------------------------------------------- /Tools/XMSSTAT/PRINTF.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- simple printf() implementation 3 | 4 | handle_char proc 5 | 6 | mov dl,al 7 | cmp al,10 8 | jnz @F 9 | mov dl,13 10 | call @F 11 | mov dl,10 12 | @@: 13 | mov ah,2 14 | int 21h 15 | ret 16 | 17 | handle_char endp 18 | 19 | ;--- ltob(long n, char * s, int base); 20 | ;--- convert long to string 21 | ;--- outb is expected to be onto stack 22 | 23 | ltob PROC stdcall uses edi number:dword, outb:word, base:word 24 | 25 | mov ch,0 26 | movzx edi, base 27 | mov eax, number 28 | cmp di,-10 29 | jne @F 30 | mov di,10 31 | and eax,eax 32 | jns @F 33 | neg eax 34 | mov ch,'-' 35 | @@: 36 | mov bx,outb 37 | add bx,10 38 | mov BYTE PTR ss:[bx],0 39 | dec bx 40 | @@nextdigit: 41 | xor edx, edx 42 | div edi 43 | add dl,'0' 44 | cmp dl,'9' 45 | jbe @F 46 | add dl,7+20h 47 | @@: 48 | mov ss:[bx],dl 49 | dec bx 50 | and eax, eax 51 | jne @@nextdigit 52 | cmp ch,0 53 | je @F 54 | mov ss:[bx],ch 55 | dec bx 56 | @@: 57 | inc bx 58 | mov ax,bx 59 | ret 60 | 61 | ltob ENDP 62 | 63 | ;--- ds=dgroup, ss don't need to be dgroup 64 | 65 | printf PROC c uses si di bx fmt:ptr byte, args:VARARG 66 | 67 | local size_:word 68 | local flag:byte 69 | local longarg:byte 70 | local fill:byte 71 | local szTmp[12]:byte 72 | 73 | lea di,[fmt+2] 74 | @@L335: 75 | mov si,[fmt] 76 | nextchar: 77 | lodsb 78 | or al,al 79 | je done 80 | cmp al,'%' 81 | je formatitem 82 | call handle_char 83 | jmp nextchar 84 | done: 85 | xor ax,ax 86 | ret 87 | 88 | formatitem: 89 | push @@L335 90 | xor dx,dx 91 | mov [longarg],dl 92 | mov bl,1 93 | mov cl,' ' 94 | cmp BYTE PTR [si],'-' 95 | jne @F 96 | dec bx 97 | inc si 98 | @@: 99 | mov [flag],bl 100 | cmp BYTE PTR [si],'0' 101 | jne @F 102 | mov cl,'0' 103 | inc si 104 | @@: 105 | mov [fill],cl 106 | mov bx,dx 107 | 108 | nextdigit: 109 | cmp BYTE PTR [si],'0' 110 | jb digitsdone 111 | cmp BYTE PTR [si],'9' 112 | ja digitsdone 113 | lodsb 114 | sub al,'0' 115 | cbw 116 | imul cx,bx,10 ;cx = bx * 10 117 | add ax,cx 118 | mov bx,ax 119 | jmp nextdigit 120 | 121 | digitsdone: 122 | mov [size_],bx 123 | cmp BYTE PTR [si],'l' 124 | jne @F 125 | mov [longarg],1 126 | inc si 127 | @@: 128 | lodsb 129 | mov [fmt],si 130 | cmp al,'x' 131 | je handle_x 132 | cmp al,'X' 133 | je handle_x 134 | cmp al,'c' 135 | je handle_c 136 | cmp al,'d' 137 | je handle_d 138 | cmp al,'i' 139 | je handle_i 140 | cmp al,'s' 141 | je handle_s 142 | cmp al,'u' 143 | je handle_u 144 | mov al,'%' 145 | jmp @@L359 146 | handle_c: 147 | mov ax,ss:[di] 148 | add di,2 149 | @@L359: 150 | call handle_char 151 | retn 152 | 153 | handle_x: 154 | mov bx,16 155 | jmp @@lprt262 156 | handle_d: 157 | handle_i: 158 | mov bx,-10 159 | jmp @@lprt262 160 | handle_u: 161 | mov bx,10 162 | @@lprt262: 163 | mov ax,ss:[di] 164 | add di,2 165 | sub dx,dx 166 | cmp bx,0 ;signed or unsigned? 167 | jge @F 168 | cwd 169 | @@: 170 | cmp [longarg],0 171 | je @F 172 | mov dx,ss:[di] 173 | add di,2 174 | @@: 175 | lea cx,[szTmp] 176 | invoke ltob, dx::ax, cx, bx 177 | mov si,ax 178 | push ds 179 | push ss 180 | pop ds 181 | call output_string 182 | pop ds 183 | retn 184 | 185 | handle_s: 186 | mov si,ss:[di] 187 | add di,2 188 | 189 | output_string: ;display string at ds:si 190 | mov ax,si 191 | mov bx,size_ 192 | .while byte ptr [si] 193 | inc si 194 | .endw 195 | sub si,ax 196 | xchg ax,si 197 | sub bx,ax 198 | .if flag == 1 199 | .while sword ptr bx > 0 200 | mov al,[fill] 201 | call handle_char 202 | dec bx 203 | .endw 204 | .endif 205 | 206 | .while byte ptr [si] 207 | lodsb 208 | call handle_char 209 | .endw 210 | 211 | .while sword ptr bx > 0 212 | mov al,[fill] 213 | call handle_char 214 | dec bx 215 | .endw 216 | retn 217 | 218 | printf ENDP 219 | 220 | -------------------------------------------------------------------------------- /Test/XMSTEST5.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- XMSTEST5: test block resize (shrink) 3 | ;--- this variant allocates a 64MB block with xms v3, 4 | ;--- but tries to resize if with xms v2 to 32MB. 5 | ;--- Public Domain. 6 | ;--- to be assembled with JWasm or Masm v6. 7 | 8 | .model small 9 | .386 10 | .dosseg 11 | .stack 2048 12 | 13 | cr equ 13 14 | lf equ 10 15 | 16 | BUFFSIZ equ 10000h 17 | 18 | ;--- define a string constant 19 | 20 | CStr macro string:vararg 21 | local xxx 22 | .const 23 | xxx db string 24 | db 0 25 | .code 26 | exitm 27 | endm 28 | 29 | .data 30 | 31 | xmsadr dd 0 ;XMS host call address 32 | 33 | .code 34 | 35 | assume DS:DGROUP 36 | 37 | include printf.inc 38 | 39 | ;--- test xms block resize function 40 | 41 | testproc proc 42 | 43 | local handle:word 44 | local wRC:word 45 | 46 | ;--- allocate XMS block 47 | 48 | mov edx, 10000h ;64MB 49 | mov ah,89h 50 | call [xmsadr] 51 | mov handle, dx 52 | push ax 53 | invoke printf, CStr("xms alloc (ah=89h) of 64MB returned ax=%X, dx=%X",lf), ax, dx 54 | pop ax 55 | cmp ax,1 56 | jnz failed 57 | 58 | ;--- lock XMS block 59 | 60 | mov dx, handle 61 | mov ah,0Ch 62 | call [xmsadr] 63 | push ax 64 | invoke printf, CStr("xms lock (ah=0Ch) returned ax=%X, dx:bx=%X%04X",lf), ax, dx, bx 65 | pop ax 66 | cmp ax,1 67 | jnz failed2 68 | 69 | ;--- resize block; should fail since locked 70 | 71 | mov bx, 8000h ;shrink block to 32MB 72 | mov dx, handle 73 | mov ah,0Fh 74 | call [xmsadr] 75 | mov wRC, ax 76 | mov bh,0 77 | invoke printf, CStr("xms resize (ah=0Fh) to 32MB returned ax=%X, bl=%X",lf), ax, bx 78 | 79 | ;--- unlock XMS block 80 | 81 | mov dx, handle 82 | mov ah,0Dh 83 | call [xmsadr] 84 | invoke printf, CStr("xms unlock (ah=0Dh) returned ax=%X",lf), ax 85 | 86 | cmp wRC,1 87 | jz failed2 88 | 89 | ;--- try again to resize, this time with an unlocked block 90 | 91 | mov bx, 8000h ;shrink block to 32MB 92 | mov dx, handle 93 | mov ah,0Fh 94 | call [xmsadr] 95 | mov wRC, ax 96 | mov bh,0 97 | invoke printf, CStr("xms resize (ah=0Fh) to 32MB returned ax=%X, bl=%X",lf), ax, bx 98 | 99 | failed2: 100 | ;--- free xms handle 101 | mov dx,handle 102 | mov ah,0ah 103 | mov bl,0 104 | call [xmsadr] 105 | invoke printf, CStr("xms release (ah=0Ah) returned ax=%X",lf), ax 106 | failed: 107 | ret 108 | testproc endp 109 | 110 | ;--- main 111 | 112 | main proc c 113 | 114 | mov ax,4300h 115 | int 2fh 116 | test al,80h ;xms host found? 117 | jnz main1 118 | invoke printf, CStr("no XMS host found",lf) 119 | jmp exit 120 | main1: 121 | mov ax,4310h ;get XMS call address 122 | int 2fh 123 | mov word ptr xmsadr+0,bx 124 | mov word ptr xmsadr+2,es 125 | invoke printf, CStr("XMS call address: %X:%X",lf), 126 | word ptr [xmsadr+2], word ptr [xmsadr+0] 127 | 128 | call testproc 129 | 130 | exit: 131 | ret 132 | main endp 133 | 134 | ;--- init 135 | 136 | start proc 137 | 138 | mov ax,@data 139 | mov ds,ax 140 | 141 | mov cx,ds 142 | mov ax,ss 143 | sub ax,cx 144 | shl ax,4 145 | add ax,sp 146 | push ds 147 | pop ss 148 | mov sp,ax 149 | 150 | ;--- free DOS mem 151 | mov ax, ds 152 | mov cx, es 153 | sub ax, cx 154 | mov bx, sp 155 | add bx, 15 156 | shr bx, 4 157 | add bx, ax 158 | mov ah, 4Ah 159 | int 21h 160 | 161 | pushf 162 | pushf 163 | pop ax 164 | or ah,70h ;a 80386 will have bit 15 cleared 165 | push ax ;if bits 12-14 are 0, it is a 80286 166 | popf ;or a bad emulation 167 | pushf 168 | pop ax 169 | popf 170 | and ah,0f0h 171 | js no386 ;bit 15 set? then its a 8086/80186 172 | jnz is386 173 | no386: 174 | invoke printf, CStr("a 80386 is needed",lf) 175 | jmp done 176 | is386: 177 | call main 178 | done: 179 | mov ah,4Ch 180 | int 21h 181 | start endp 182 | 183 | END start 184 | -------------------------------------------------------------------------------- /Test/PRINTF.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- simple printf() implementation 3 | 4 | handle_char proc 5 | 6 | mov dl,al 7 | cmp al,10 8 | jnz @F 9 | mov dl,13 10 | call @F 11 | mov dl,10 12 | @@: 13 | mov ah,2 14 | int 21h 15 | ret 16 | 17 | handle_char endp 18 | 19 | ;--- ltob(long n, char * s, int base); 20 | ;--- convert long to string 21 | 22 | ltob PROC stdcall uses edi number:dword, outb:word, base:word 23 | 24 | mov ch,0 25 | movzx edi, base 26 | mov eax, number 27 | cmp di,-10 28 | jne @F 29 | mov di,10 30 | and eax,eax 31 | jns @F 32 | neg eax 33 | mov ch,'-' 34 | @@: 35 | mov bx,outb 36 | add bx,10 37 | mov BYTE PTR [bx],0 38 | dec bx 39 | @@nextdigit: 40 | xor edx, edx 41 | div edi 42 | add dl,'0' 43 | cmp dl,'9' 44 | jbe @F 45 | add dl,7+20h 46 | @@: 47 | mov [bx],dl 48 | dec bx 49 | and eax, eax 50 | jne @@nextdigit 51 | cmp ch,0 52 | je @F 53 | mov [bx],ch 54 | dec bx 55 | @@: 56 | inc bx 57 | mov ax,bx 58 | ret 59 | 60 | ltob ENDP 61 | 62 | printf PROC c uses si di fmt:ptr byte, args:VARARG 63 | 64 | local size_:word 65 | local flag:byte 66 | local longarg:byte 67 | local fill:byte 68 | local szTmp[12]:byte 69 | 70 | lea di,[fmt+2] 71 | @@L335: 72 | mov si,[fmt] 73 | nextchar: 74 | lodsb 75 | or al,al 76 | je done 77 | cmp al,'%' 78 | je formatitem 79 | call handle_char 80 | jmp nextchar 81 | done: 82 | xor ax,ax 83 | ret 84 | formatitem: 85 | xor dx,dx 86 | mov [longarg],dl 87 | mov bl,1 88 | mov cl,' ' 89 | cmp BYTE PTR [si],'-' 90 | jne @F 91 | dec bx 92 | inc si 93 | @@: 94 | mov [flag],bl 95 | cmp BYTE PTR [si],'0' 96 | jne @F 97 | mov cl,'0' 98 | inc si 99 | @@: 100 | mov [fill],cl 101 | mov [size_],dx 102 | mov bx,dx 103 | jmp @@L358 104 | @@FC250: 105 | cmp BYTE PTR [si],'9' 106 | jg @@L362 107 | lodsb 108 | sub al,'0' 109 | cbw 110 | imul cx,bx,10 ;cx = bx * 10 111 | add ax,cx 112 | mov bx,ax 113 | @@L358: 114 | cmp BYTE PTR [si],'0' 115 | jge @@FC250 116 | @@L362: 117 | mov [size_],bx 118 | cmp BYTE PTR [si],'l' 119 | jne @F 120 | mov [longarg],1 121 | inc si 122 | @@: 123 | lodsb 124 | mov [fmt],si 125 | cbw 126 | cmp al,'x' 127 | je handle_x 128 | ja @@L359 129 | or al,al 130 | je done ;\0? 131 | sub al,'X' 132 | je handle_x 133 | sub al,11 134 | je handle_c ;'c' 135 | dec al 136 | je handle_d ;'d' 137 | sub al,5 138 | je handle_i ;'i' 139 | sub al,10 140 | je handle_s ;'s' 141 | sub al,2 142 | je handle_u ;'u' 143 | jmp @@L359 144 | handle_c: ;'c' 145 | mov ax,[di] 146 | add di,2 147 | @@L359: 148 | call handle_char 149 | jmp @@L335 150 | 151 | handle_s: ;'s' 152 | mov si,[di] 153 | add di,2 154 | jmp @@do_outputstring260 155 | 156 | handle_x: ;'X' + 'x' 157 | mov bx,16 158 | jmp @@lprt262 159 | handle_d: ;'d' 160 | handle_i: ;'i' 161 | mov bx,-10 162 | jmp @@lprt262 163 | handle_u: ;'u' 164 | mov bx,10 165 | @@lprt262: 166 | mov ax,[di] 167 | add di,2 168 | sub dx,dx 169 | cmp bx,0 ;signed or unsigned? 170 | jge @F 171 | cwd 172 | @@: 173 | cmp [longarg],0 174 | je @F 175 | mov dx,[di] 176 | add di,2 177 | @@: 178 | lea cx,[szTmp] 179 | invoke ltob, dx::ax, cx, bx 180 | mov si,ax 181 | 182 | @@do_outputstring260: 183 | mov ax,si 184 | .while byte ptr [si] 185 | inc si 186 | .endw 187 | xchg ax, si 188 | sub ax, si 189 | 190 | sub [size_],ax 191 | cmp BYTE PTR [flag],1 192 | jne @@L360 193 | mov bx,[size_] 194 | jmp @@L363 195 | @@F270: 196 | mov al,[fill] 197 | call handle_char 198 | dec bx 199 | @@L363: 200 | or bx,bx 201 | jg @@F270 202 | mov [size_],bx 203 | jmp @@L360 204 | 205 | @@F273: 206 | mov al,[si] 207 | call handle_char 208 | inc si 209 | @@L360: 210 | cmp BYTE PTR [si],0 211 | jne @@F273 212 | mov bx,[size_] 213 | @@: 214 | or bx,bx 215 | jle @@L335 216 | mov al,[fill] 217 | call handle_char 218 | dec bx 219 | jmp @B 220 | 221 | printf ENDP 222 | 223 | -------------------------------------------------------------------------------- /JLM/QPIEMU/Test/PRINTF16.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- simple printf() implementation 3 | 4 | handle_char proc 5 | 6 | mov dl,al 7 | cmp al,10 8 | jnz @F 9 | mov dl,13 10 | call @F 11 | mov dl,10 12 | @@: 13 | mov ah,2 14 | int 21h 15 | ret 16 | 17 | handle_char endp 18 | 19 | ;--- ltob(long n, char * s, int base); 20 | ;--- convert long to string 21 | ;--- outb is expected to be onto stack 22 | ;--- hiwords or eax, edx, eax are used, but restored. 23 | 24 | ltob PROC stdcall uses edi edx number:dword, outb:word, base:word 25 | 26 | mov ch, 0 27 | movzx edi, base 28 | push eax 29 | mov eax, number 30 | cmp di, -10 31 | jne @F 32 | mov di, 10 33 | and eax, eax 34 | jns @F 35 | neg eax 36 | mov ch, '-' 37 | @@: 38 | mov bx, outb 39 | add bx, 10 40 | mov BYTE PTR ss:[bx], 0 41 | dec bx 42 | @@nextdigit: 43 | xor edx, edx 44 | div edi 45 | add dl, '0' 46 | cmp dl, '9' 47 | jbe @F 48 | add dl, 7+20h 49 | @@: 50 | mov ss:[bx], dl 51 | dec bx 52 | and eax, eax 53 | jne @@nextdigit 54 | cmp ch,0 55 | je @F 56 | mov ss:[bx], ch 57 | dec bx 58 | @@: 59 | inc bx 60 | pop eax 61 | mov ax, bx 62 | ret 63 | 64 | ltob ENDP 65 | 66 | ;--- ds=dgroup, ss don't need to be dgroup 67 | ;--- preserve all registers 68 | 69 | printf PROC c fmt:ptr byte, args:VARARG 70 | 71 | local size_:word 72 | local flag:byte 73 | local longarg:byte 74 | local fill:byte 75 | local szTmp[12]:byte 76 | 77 | pusha 78 | lea di,[fmt+2] 79 | @@L335: 80 | mov si,[fmt] 81 | nextchar: 82 | lodsb 83 | or al,al 84 | je done 85 | cmp al,'%' 86 | je formatitem 87 | call handle_char 88 | jmp nextchar 89 | done: 90 | popa 91 | ret 92 | 93 | formatitem: 94 | push @@L335 95 | xor dx,dx 96 | mov [longarg],dl 97 | mov bl,1 98 | mov cl,' ' 99 | cmp BYTE PTR [si],'-' 100 | jne @F 101 | dec bx 102 | inc si 103 | @@: 104 | mov [flag],bl 105 | cmp BYTE PTR [si],'0' 106 | jne @F 107 | mov cl,'0' 108 | inc si 109 | @@: 110 | mov [fill],cl 111 | mov bx,dx 112 | 113 | .while byte ptr [si] >= '0' && byte ptr [si] <= '9' 114 | lodsb 115 | sub al,'0' 116 | cbw 117 | imul cx,bx,10 ;cx = bx * 10 118 | add ax,cx 119 | mov bx,ax 120 | .endw 121 | 122 | mov [size_],bx 123 | cmp BYTE PTR [si],'l' 124 | jne @F 125 | mov [longarg],1 126 | inc si 127 | @@: 128 | lodsb 129 | mov [fmt],si 130 | cmp al,'x' 131 | je handle_x 132 | cmp al,'X' 133 | je handle_x 134 | cmp al,'c' 135 | je handle_c 136 | cmp al,'d' 137 | je handle_d 138 | cmp al,'i' 139 | je handle_i 140 | cmp al,'s' 141 | je handle_s 142 | cmp al,'u' 143 | je handle_u 144 | cmp al,0 145 | jnz @@L359 146 | pop ax 147 | jmp done 148 | handle_c: 149 | mov ax,ss:[di] 150 | add di,2 151 | @@L359: 152 | call handle_char 153 | retn 154 | 155 | handle_x: 156 | mov bx,16 157 | jmp @@lprt262 158 | handle_d: 159 | handle_i: 160 | mov bx,-10 161 | jmp @@lprt262 162 | handle_u: 163 | mov bx,10 164 | @@lprt262: 165 | mov ax,ss:[di] 166 | add di,2 167 | sub dx,dx 168 | cmp bx,0 ;signed or unsigned? 169 | jge @F 170 | cwd 171 | @@: 172 | cmp [longarg],0 173 | je @F 174 | mov dx,ss:[di] 175 | add di,2 176 | @@: 177 | lea cx,[szTmp] 178 | invoke ltob, dx::ax, cx, bx 179 | mov si,ax 180 | push ds 181 | push ss 182 | pop ds 183 | call output_string 184 | pop ds 185 | retn 186 | 187 | handle_s: 188 | mov si,ss:[di] 189 | add di,2 190 | 191 | output_string: ;display string at ds:si 192 | mov ax,si 193 | mov bx,size_ 194 | .while byte ptr [si] 195 | inc si 196 | .endw 197 | sub si,ax 198 | xchg ax,si 199 | sub bx,ax 200 | .if flag == 1 201 | .while sword ptr bx > 0 202 | mov al,[fill] 203 | call handle_char 204 | dec bx 205 | .endw 206 | .endif 207 | 208 | .while byte ptr [si] 209 | lodsb 210 | call handle_char 211 | .endw 212 | 213 | .while sword ptr bx > 0 214 | mov al,[fill] 215 | call handle_char 216 | dec bx 217 | .endw 218 | retn 219 | 220 | printf ENDP 221 | 222 | -------------------------------------------------------------------------------- /Tools/JLOAD/DPRNTF16.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- printf for debug displays, 16-bit 3 | 4 | ;--- itoa(long n, char * s, int base); 5 | ;--- convert 32-bit long to string 6 | 7 | ltoa PROC stdcall uses edx edi number:dword, outb:word, base:word 8 | 9 | mov ch,0 10 | movzx edi, base 11 | mov eax, number 12 | cmp di,-10 13 | jne @F 14 | mov di,10 15 | and eax,eax 16 | jns @F 17 | neg eax 18 | mov ch,'-' 19 | @@: 20 | mov bx,outb 21 | add bx,10 22 | mov BYTE PTR ss:[bx],0 23 | dec bx 24 | @@nextdigit: 25 | xor edx, edx 26 | div edi 27 | add dl,'0' 28 | cmp dl,'9' 29 | jbe @F 30 | add dl,7+20h 31 | @@: 32 | mov ss:[bx],dl 33 | dec bx 34 | and eax, eax 35 | jne @@nextdigit 36 | cmp ch,0 37 | je @F 38 | mov ss:[bx],ch 39 | dec bx 40 | @@: 41 | inc bx 42 | mov ax,bx 43 | ret 44 | 45 | ltoa ENDP 46 | 47 | ;--- it's assumed cs=DGROUP (model tiny) 48 | ;--- no assume for SS & DS, ES unused. 49 | 50 | dprintf proc c public uses ds fmt:ptr, args:vararg 51 | 52 | local flag:byte 53 | local longarg:byte 54 | local size_:word 55 | local fillchr:word 56 | local szTmp[12]:byte 57 | 58 | pusha 59 | pushf 60 | cld 61 | lea di,args 62 | push cs 63 | pop ds 64 | @@L335: 65 | mov si,fmt 66 | nextchar: 67 | lodsb 68 | or al,al 69 | je done 70 | cmp al,'%' 71 | je formatitem 72 | call VPUTCHR 73 | jmp nextchar 74 | done: 75 | popf 76 | popa 77 | ret 78 | 79 | formatitem: 80 | push offset @@L335 81 | xor dx,dx 82 | mov [longarg],dl 83 | mov bl,1 84 | mov cl,' ' 85 | cmp BYTE PTR [si],'-' 86 | jne @F 87 | dec bl 88 | inc si 89 | @@: 90 | mov [flag],bl 91 | cmp BYTE PTR [si],'0' 92 | jne @F 93 | mov cl,'0' 94 | inc si 95 | @@: 96 | mov [fillchr],cx 97 | mov bx,dx 98 | 99 | .while ( byte ptr [si] >= '0' && byte ptr [si] <= '9' ) 100 | lodsb 101 | sub al,'0' 102 | cbw 103 | imul cx,bx,10 ;ecx = ebx * 10 104 | add ax,cx 105 | mov bx,ax 106 | .endw 107 | 108 | mov [size_],bx 109 | cmp BYTE PTR [si],'l' 110 | jne @F 111 | mov [longarg],1 112 | inc si 113 | @@: 114 | lodsb 115 | mov [fmt],si 116 | cmp al,'x' 117 | je handle_x 118 | cmp al,'X' 119 | je handle_x 120 | cmp al,'d' 121 | je handle_d 122 | cmp al,'u' 123 | je handle_u 124 | cmp al,'s' 125 | je handle_s 126 | cmp al,'c' 127 | je handle_c 128 | and al,al 129 | jnz @F 130 | pop ax 131 | jmp done 132 | handle_c: 133 | mov ax,ss:[di] 134 | add di,2 135 | @@: 136 | call VPUTCHR 137 | retn 138 | 139 | handle_s: 140 | mov si,ss:[di] 141 | add di,2 142 | jmp print_string 143 | handle_d: 144 | handle_i: 145 | mov bx,-10 146 | jmp @F 147 | handle_u: 148 | mov bx, 10 149 | jmp @F 150 | handle_x: 151 | mov bx, 16 152 | @@: 153 | xor dx,dx 154 | mov ax,ss:[di] 155 | add di,2 156 | cmp longarg,1 157 | jnz @F 158 | mov dx,ss:[di] 159 | add di,2 160 | jmp printnum 161 | @@: 162 | and bx,bx 163 | jns @F 164 | cdq 165 | @@: 166 | printnum: 167 | lea si, szTmp 168 | push eax 169 | invoke ltoa, dx::ax, si, bx 170 | mov si, ax 171 | pop eax 172 | push ds 173 | push ss 174 | pop ds 175 | call print_string 176 | pop ds 177 | retn 178 | 179 | print_string: ;print string SI 180 | mov ax, si 181 | .while byte ptr [si] 182 | inc si 183 | .endw 184 | sub si, ax 185 | xchg ax, si 186 | mov bx,size_ 187 | sub bx, ax 188 | .if flag == 1 189 | .while sword ptr bx > 0 190 | mov ax, [fillchr] 191 | call VPUTCHR ;print leading filler chars 192 | dec bx 193 | .endw 194 | .endif 195 | 196 | .while byte ptr [si] 197 | lodsb [si] 198 | call VPUTCHR ;print char of string 199 | .endw 200 | 201 | .while sword ptr bx > 0 202 | mov ax, [fillchr] 203 | call VPUTCHR ;print trailing spaces 204 | dec bx 205 | .endw 206 | retn 207 | 208 | VPUTCHR: 209 | cmp al,10 210 | jnz @F 211 | mov al,13 212 | call @F 213 | mov al,10 214 | @@: 215 | push bx 216 | xor bx, bx 217 | mov ah, 0Eh 218 | int 10h 219 | pop bx 220 | retn 221 | 222 | dprintf endp 223 | -------------------------------------------------------------------------------- /Test/TESTDMA3.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- test FD read in UMB 3 | ;--- using Int 13h 4 | ;--- this variant ensures that a 64kb border is crossed, 5 | ;--- forcing the EMM to either "auto remap" PTEs (EMM386) or 6 | ;--- use the DMA buffer (Jemm). 7 | 8 | .286 9 | .model small 10 | .stack 2048 11 | .dosseg 12 | option casemap:none 13 | .386 14 | 15 | ?BSIZE equ 8000h 16 | 17 | CStr macro text:vararg 18 | local sym 19 | .const 20 | sym db text,0 21 | .code 22 | exitm 23 | endm 24 | 25 | lf equ 10 26 | 27 | DDS struct 28 | dwSize dd ? 29 | dwOfs dd ? 30 | wSeg dw ? 31 | wID dw ? 32 | dwPhys dd ? 33 | DDS ends 34 | 35 | .data? 36 | 37 | dds DDS <> 38 | 39 | .code 40 | 41 | include printf.inc 42 | 43 | writefile proc c pName:ptr, pBuffer:ptr far16, wSize:word 44 | mov dx, pName 45 | xor cx, cx 46 | mov ax,3c00h 47 | int 21h 48 | jc fail1 49 | mov bx, ax 50 | push ds 51 | lds dx, pBuffer 52 | mov cx, wSize 53 | mov ax, 4000h 54 | int 21h 55 | pop ds 56 | jc fail2 57 | mov ah, 3Eh 58 | int 21h 59 | ret 60 | fail1: 61 | invoke printf, CStr("create file failed",10) 62 | ret 63 | fail2: 64 | invoke printf, CStr("write file failed",10) 65 | ret 66 | writefile endp 67 | 68 | main proc c 69 | 70 | local stat1:word 71 | local stat2:word 72 | local wSeg:word 73 | 74 | ;--- requires VDS 75 | 76 | xor ax, ax 77 | mov es, ax 78 | test byte ptr es:[47bh],20h 79 | jz novds 80 | mov ax,8102h 81 | mov dx,0000 82 | int 4bh 83 | jnc @F 84 | novds: 85 | invoke printf, CStr("VDS not installed",lf) 86 | jmp exit 87 | @@: 88 | 89 | mov ax, 5802h ;get status umb 90 | int 21h 91 | xor ah,ah 92 | mov stat1, ax 93 | 94 | mov ax, 5800h ;get memory alloc strategy 95 | int 21h 96 | xor ah,ah 97 | mov stat2, ax 98 | 99 | mov bx, 81h ;first high,then low 100 | mov ax, 5801h ;set memory alloc strat 101 | int 21h 102 | mov bx, 1 ;include umbs 103 | mov ax, 5803h ;umb link restore 104 | int 21h 105 | 106 | mov bx, ?BSIZE shr 4; allocate mem block 107 | mov ah, 48h 108 | int 21h 109 | jnc @F 110 | invoke printf, CStr("no free %ukB block found in Upper Memory",10), ?BSIZE shr 10 111 | jmp exit 112 | @@: 113 | mov wSeg, ax 114 | mov es, ax 115 | xor di, di 116 | mov cx, ?BSIZE 117 | mov al, 00 118 | rep stosb 119 | 120 | ;--- call VDS to see when a 4 KB block isn't contiguous or crosses a 64kb border 121 | push ds 122 | pop es 123 | 124 | mov cx, ?BSIZE shr 12 125 | mov dds.wSeg, 0 126 | movzx eax, wSeg 127 | shl eax, 4 128 | nexttry: 129 | mov di, offset dds 130 | mov dds.dwSize, 1000h 131 | mov dds.dwOfs, eax 132 | push eax 133 | mov dx, (1 shl 2) or (1 shl 4) ; b2=1:don't alloc buffer, b4=1:64kb crossing disallowed 134 | mov ax, 8103h 135 | int 4Bh 136 | jc found ; found an address that requires remap/buffer 137 | xor dx, dx 138 | mov ax, 8104h ; unlock block 139 | int 4Bh 140 | pop eax 141 | add eax, 1000h 142 | loop nexttry 143 | invoke printf, CStr("no uncontiguous 4kB block found",10) 144 | jmp exit 145 | found: 146 | pop eax 147 | shr eax, 4 148 | mov wSeg, ax 149 | 150 | mov es, wSeg ; es:bx=transfer buffer 151 | mov bx, 0 152 | mov cx, 1 ; cl[0-5]: sector#; ch+cl[6-7]:cylinder 153 | mov dh, 0 ; dh=head 154 | mov dl, 0 ; dl=0 -> A: 155 | mov ax, 0208h ; al=# of sectors to read 156 | int 13h 157 | jc error 158 | invoke printf, CStr("reading drive A: ok",10) 159 | mov ax, wSeg 160 | invoke writefile, CStr("~XXX.TMP"), ax::bx, 200h*8 161 | jmp exit 162 | error: 163 | movzx ax, ah 164 | invoke printf, CStr("reading drive A: failed, error code=%X",10), ax 165 | exit: 166 | mov bx, stat1 167 | mov ax, 5803h 168 | int 21h 169 | mov bx, stat2 170 | mov ax, 5801h ; set memory alloc strag 171 | int 21h 172 | ret 173 | main endp 174 | 175 | start: 176 | mov ax, @data 177 | mov ds, ax 178 | mov bx, ss 179 | sub bx, ax 180 | shl bx, 4 181 | mov ss, ax 182 | add sp, bx 183 | call main 184 | mov ah, 4Ch 185 | int 21h 186 | 187 | END start 188 | -------------------------------------------------------------------------------- /src/DPRNTF16.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- printf for debug displays, 16-bit 3 | 4 | ;--- itoa(long n, char * s, int base); 5 | ;--- convert 32-bit long to string 6 | ;--- v5.86: removed eax from uses clause (since AX is used to return string ptr) 7 | 8 | ltoa PROC stdcall uses edx edi number:dword, outb:word, base:word 9 | 10 | mov ch,0 11 | movzx edi, base 12 | mov eax, number 13 | cmp di,-10 14 | jne @F 15 | mov di,10 16 | and eax,eax 17 | jns @F 18 | neg eax 19 | mov ch,'-' 20 | @@: 21 | mov bx,outb 22 | add bx,10 23 | mov BYTE PTR ss:[bx],0 24 | dec bx 25 | @@nextdigit: 26 | xor edx, edx 27 | div edi 28 | add dl,'0' 29 | cmp dl,'9' 30 | jbe @F 31 | add dl,7+20h 32 | @@: 33 | mov ss:[bx],dl 34 | dec bx 35 | and eax, eax 36 | jne @@nextdigit 37 | cmp ch,0 38 | je @F 39 | mov ss:[bx],ch 40 | dec bx 41 | @@: 42 | inc bx 43 | mov ax,bx 44 | ret 45 | 46 | ltoa ENDP 47 | 48 | dprintf proc c public fmt:ptr, args:vararg 49 | 50 | local flag:byte 51 | local longarg:byte 52 | local size_:word 53 | local fillchr:word 54 | local szTmp[12]:byte 55 | 56 | pusha 57 | pushf 58 | push ds 59 | push cs 60 | pop ds 61 | cld 62 | lea di,args 63 | @@L335: 64 | mov si,fmt 65 | nextchar: 66 | lodsb [si] 67 | or al,al 68 | je done 69 | cmp al,'%' 70 | je formatitem 71 | call VPUTCHR 72 | jmp nextchar 73 | done: 74 | pop ds 75 | popf 76 | popa 77 | ret 78 | 79 | formatitem: 80 | push offset @@L335 81 | xor dx,dx 82 | mov [longarg],dl 83 | mov bl,1 84 | mov cl,' ' 85 | cmp BYTE PTR [si],'-' 86 | jne @F 87 | dec bl 88 | inc si 89 | @@: 90 | mov [flag],bl 91 | cmp BYTE PTR [si],'0' 92 | jne @F 93 | mov cl,'0' 94 | inc si 95 | @@: 96 | mov [fillchr],cx 97 | mov bx,dx 98 | 99 | .while ( byte ptr [si] >= '0' && byte ptr [si] <= '9' ) 100 | lodsb 101 | sub al,'0' 102 | cbw 103 | imul cx,bx,10 ;ecx = ebx * 10 104 | add ax,cx 105 | mov bx,ax 106 | .endw 107 | 108 | mov [size_],bx 109 | cmp BYTE PTR [si],'l' 110 | jne @F 111 | mov [longarg],1 112 | inc si 113 | @@: 114 | lodsb 115 | mov [fmt],si 116 | cmp al,'x' 117 | je handle_x 118 | cmp al,'X' 119 | je handle_x 120 | cmp al,'d' 121 | je handle_d 122 | cmp al,'u' 123 | je handle_u 124 | cmp al,'s' 125 | je handle_s 126 | cmp al,'c' 127 | je handle_c 128 | and al,al 129 | jnz @F 130 | pop ax 131 | jmp done 132 | handle_c: 133 | mov ax,ss:[di] 134 | add di,2 135 | @@: 136 | call VPUTCHR 137 | retn 138 | 139 | handle_s: 140 | mov si,ss:[di] 141 | add di,2 142 | jmp print_string 143 | handle_d: 144 | handle_i: 145 | mov bx,-10 146 | jmp @F 147 | handle_u: 148 | mov bx, 10 149 | jmp @F 150 | handle_x: 151 | mov bx, 16 152 | @@: 153 | xor dx,dx 154 | mov ax,ss:[di] 155 | add di,2 156 | cmp longarg,1 157 | jnz @F 158 | mov dx,ss:[di] 159 | add di,2 160 | jmp printnum 161 | @@: 162 | and bx,bx 163 | jns @F 164 | cdq 165 | @@: 166 | printnum: 167 | lea si, szTmp 168 | push eax ;v5.86: added 169 | invoke ltoa, dx::ax, si, bx 170 | mov si, ax 171 | pop eax ;v5.86: added 172 | push ds 173 | push ss 174 | pop ds 175 | call print_string 176 | pop ds 177 | retn 178 | 179 | print_string: ;print string SI 180 | mov ax, si 181 | .while byte ptr [si] 182 | inc si 183 | .endw 184 | sub si, ax 185 | xchg ax, si 186 | mov bx,size_ 187 | sub bx, ax 188 | .if flag == 1 189 | .while sword ptr bx > 0 190 | mov ax, [fillchr] 191 | call VPUTCHR ;print leading filler chars 192 | dec bx 193 | .endw 194 | .endif 195 | 196 | .while byte ptr [si] 197 | lodsb 198 | call VPUTCHR ;print char of string 199 | .endw 200 | 201 | .while sword ptr bx > 0 202 | mov ax, [fillchr] 203 | call VPUTCHR ;print trailing spaces 204 | dec bx 205 | .endw 206 | retn 207 | 208 | VPUTCHR: 209 | cmp al,10 210 | jnz @F 211 | mov al,13 212 | call @F 213 | mov al,10 214 | @@: 215 | push bx 216 | xor bx, bx 217 | mov ah, 0Eh 218 | int 10h 219 | pop bx 220 | retn 221 | 222 | dprintf endp 223 | -------------------------------------------------------------------------------- /JLM/REBOOT/LDI13EXT.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- sample how to load an int 13h extension into FASTBOOT JLM. 3 | ;--- this sample just swaps HDs 0 and 1 in int 13h; int 41h/46h are NOT modified. 4 | ;--- assemble: JWasm -mz LDI13EXT.asm 5 | 6 | .286 7 | .model tiny 8 | .dosseg 9 | .stack 2048 10 | option casemap:none 11 | .386 12 | 13 | CStr macro text:vararg 14 | local sym 15 | .const 16 | sym db text,0 17 | .code 18 | exitm 19 | endm 20 | 21 | DStr macro text:vararg 22 | local sym 23 | .const 24 | sym db text,'$' 25 | .code 26 | exitm 27 | endm 28 | 29 | IRETS struct 30 | wIP dw ? 31 | wCS dw ? 32 | wFL dw ? 33 | IRETS ends 34 | 35 | .const 36 | helptxt label byte 37 | db "LDI13EXT: sample how to load an int 13h extension to FASTBOOT JLM.",13,10 38 | db "Required:",13,10 39 | db " - Jemm v5.86+",13,10 40 | db " - Jemm loaded with option FASTBOOT",13,10 41 | db " - FASTBOOT.DLL be loaded",13,10 42 | db '$' 43 | 44 | .code 45 | 46 | ;--- int 13h extension initialization 47 | ;--- assumes: CS=_TEXT, DS=0000 48 | 49 | int13ext proc 50 | 51 | push es 52 | pusha 53 | mov eax,ds:[13h*4] 54 | mov cs:[oldi13a],eax 55 | mov cs:[oldi13b],eax 56 | sub word ptr ds:[413h],1 ;decrease conv. memory by 1 kB 57 | mov ax,ds:[413h] 58 | shl ax,6 59 | mov es,ax 60 | shl eax,16 61 | xor di,di 62 | mov si,offset myint13 63 | mov cx,size_int13ext2 64 | cld 65 | rep movsb es:[di],cs:[si] 66 | mov ds:[13h*4],eax 67 | popa 68 | pop es 69 | retf 70 | 71 | ;--- the new int 13h code 72 | 73 | myint13: 74 | cmp dl,80h ;HD 0? 75 | jz is_hd0 76 | cmp dl,81h ;HD 1? 77 | jz is_hd1 78 | jmp_oldvec: 79 | db 0eah ;opcode jmp ssss:oooo 80 | oldi13a dd 0 81 | is_hd0: 82 | is_hd1: 83 | xor dl,1 ; swap disks 84 | cmp ah,8 ; ah=8 is special because DL returns # of HDs 85 | jz jmp_oldvec 86 | pushf 87 | db 09ah ;opcode call ssss:oooo 88 | oldi13b dd 0 89 | push bp 90 | mov bp,sp 91 | push ax 92 | pushf 93 | xor dl,1 ; restore DL 94 | pop ax 95 | mov byte ptr [bp+2].IRETS.wFL,al 96 | pop ax 97 | pop bp 98 | iret 99 | size_int13ext equ $ - int13ext 100 | size_int13ext2 equ $ - myint13 101 | int13ext endp 102 | 103 | main proc 104 | 105 | local dwFB:dword 106 | 107 | cld 108 | mov si,81h 109 | nextchr: 110 | lodsb es:[si] 111 | cmp al,13 112 | jz cmdl_done 113 | cmp al,20h 114 | jbe nextchr 115 | mov dx,offset helptxt 116 | mov ah,9 117 | int 21h 118 | ret 119 | cmdl_done: 120 | mov bx,4435h ;FASTBOOT/REBOOT device ID 121 | mov ax,1684h ;get API entry point 122 | int 2Fh 123 | cmp al,0 124 | jnz not_installed 125 | mov word ptr dwFB+0,di 126 | mov word ptr dwFB+2,es 127 | mov ah,0 ;get version 128 | call dwFB 129 | jc not_installed 130 | test ah,1 ;FASTBOOT variant? 131 | jz not_installed 132 | 133 | ;--- test that at least 2 HDs are present 134 | 135 | push ds 136 | mov ax,40h 137 | mov ds,ax 138 | mov al,ds:[75h] 139 | pop ds 140 | cmp al,2 141 | jb no_hds 142 | 143 | ;--- FASTBOOT API AH=4: DS:SI=start extension, ECX=size extension in bytes 144 | 145 | mov si,offset int13ext 146 | mov ecx, size_int13ext 147 | mov ah,4 148 | call dwFB 149 | jc no_int13ext 150 | mov dx,DStr("int 13h extension loaded") 151 | mov ah,9 152 | int 21h 153 | call lfout 154 | ret 155 | 156 | not_installed: 157 | mov dx,DStr("FASTBOOT not installed") 158 | mov ah,9 159 | int 21h 160 | call lfout 161 | ret 162 | no_hds: 163 | mov dx,DStr("at least 2 HDs are needed") 164 | mov ah,9 165 | int 21h 166 | call lfout 167 | ret 168 | no_int13ext: 169 | mov dx,DStr("int 13h extension not accepted") 170 | mov ah,9 171 | int 21h 172 | call lfout 173 | ret 174 | main endp 175 | 176 | lfout proc 177 | mov dx,DStr(13,10) 178 | mov ah,9 179 | int 21h 180 | ret 181 | lfout endp 182 | 183 | start: 184 | mov ax,cs 185 | mov ds,ax 186 | mov dx,ss 187 | sub dx,ax 188 | shl dx,4 189 | mov ss,ax 190 | add sp,dx 191 | mov bx,sp 192 | shr bx,4 193 | mov cx,es 194 | sub ax,cx 195 | add bx,ax 196 | mov ah,4Ah 197 | int 21h 198 | call main 199 | mov ah,4ch 200 | int 21h 201 | 202 | end start 203 | 204 | -------------------------------------------------------------------------------- /Include/PRINTF.INC: -------------------------------------------------------------------------------- 1 | 2 | ;--- simple printf 3 | 4 | ;--- i64toa(long long n, char * s, int base); 5 | ;--- convert 64-bit long long to string 6 | 7 | i64toa proc stdcall uses edi number:qword, outb:ptr, base:dword 8 | 9 | mov ch,0 10 | mov edi, base 11 | mov eax, dword ptr number+0 12 | mov esi, dword ptr number+4 13 | cmp edi,-10 14 | jne @F 15 | neg edi 16 | and esi,esi 17 | jns @F 18 | neg esi 19 | neg eax 20 | sbb esi,0 21 | mov ch,'-' 22 | @@: 23 | mov ebx,outb 24 | add ebx,22 25 | mov byte ptr [ebx],0 26 | @@nextdigit: 27 | dec ebx 28 | xor edx,edx 29 | xchg eax,esi 30 | div edi 31 | xchg eax,esi 32 | div edi 33 | add dl,'0' 34 | cmp dl,'9' 35 | jbe @F 36 | add dl,7+20h 37 | @@: 38 | mov [ebx],dl 39 | mov edx, eax 40 | or edx, esi 41 | jne @@nextdigit 42 | cmp ch,0 43 | je @F 44 | dec ebx 45 | mov [ebx],ch 46 | @@: 47 | mov eax,ebx 48 | ret 49 | 50 | i64toa endp 51 | 52 | printf proc c fmt:ptr, args:vararg 53 | 54 | local flag:byte 55 | local longarg:byte 56 | local size_:dword 57 | local fillchr:dword 58 | local szTmp[24]:byte 59 | local crs:Client_Reg_Struc 60 | 61 | pushad 62 | mov ebp, [ebp] 63 | lea edi, crs 64 | @VMMCall Save_Client_State 65 | @VMMCall Begin_Nest_Exec 66 | mov ebp, [esp+2*4] ;restore EBP 67 | cld 68 | lea edi,args 69 | @@L335: 70 | mov esi,fmt 71 | nextchar: 72 | lodsb 73 | or al,al 74 | je done 75 | cmp al,'%' 76 | je formatitem 77 | call handle_char 78 | jmp nextchar 79 | done: 80 | mov ebp, [ebp] 81 | @VMMCall End_Nest_Exec 82 | lea esi, crs 83 | @VMMCall Restore_Client_State 84 | popad 85 | ret 86 | 87 | formatitem: 88 | push offset @@L335 89 | xor edx,edx 90 | mov [longarg],dl 91 | mov bl,1 92 | mov cl,' ' 93 | cmp BYTE PTR [esi],'-' 94 | jne @F 95 | dec bl 96 | inc esi 97 | @@: 98 | mov [flag],bl 99 | cmp BYTE PTR [esi],'0' 100 | jne @F 101 | mov cl,'0' 102 | inc esi 103 | @@: 104 | mov [fillchr],ecx 105 | mov ebx,edx 106 | 107 | .while ( byte ptr [esi] >= '0' && byte ptr [esi] <= '9' ) 108 | lodsb 109 | sub al,'0' 110 | movzx eax,al 111 | imul ecx,ebx,10 ;ecx = ebx * 10 112 | add eax,ecx 113 | mov ebx,eax 114 | .endw 115 | 116 | mov [size_],ebx 117 | cmp BYTE PTR [esi],'l' 118 | jne @F 119 | mov [longarg],1 120 | inc esi 121 | @@: 122 | lodsb 123 | mov [fmt],esi 124 | cmp al,'x' 125 | je handle_x 126 | cmp al,'X' 127 | je handle_x 128 | cmp al,'d' 129 | je handle_d 130 | cmp al,'u' 131 | je handle_u 132 | cmp al,'s' 133 | je handle_s 134 | cmp al,'c' 135 | je handle_c 136 | and al,al 137 | jnz @F 138 | pop eax 139 | jmp done 140 | handle_c: 141 | mov eax,[edi] 142 | add edi, 4 143 | @@: 144 | call handle_char 145 | retn 146 | 147 | handle_s: 148 | mov esi,[edi] 149 | add edi,4 150 | jmp print_string 151 | handle_d: 152 | handle_i: 153 | mov ebx,-10 154 | jmp @F 155 | handle_u: 156 | mov ebx, 10 157 | jmp @F 158 | handle_x: 159 | mov ebx, 16 160 | @@: 161 | xor edx,edx 162 | mov eax,[edi] 163 | add edi,4 164 | cmp longarg,1 165 | jnz @F 166 | mov edx,[edi] 167 | add edi,4 168 | jmp printnum 169 | @@: 170 | and ebx,ebx 171 | jns @F 172 | cdq 173 | @@: 174 | printnum: 175 | lea esi, szTmp 176 | invoke i64toa, edx::eax, esi, ebx 177 | mov esi, eax 178 | 179 | print_string: ;print string ESI, size EAX 180 | mov eax, esi 181 | .while byte ptr [esi] 182 | inc esi 183 | .endw 184 | sub esi, eax 185 | xchg eax, esi 186 | mov ebx,size_ 187 | sub ebx,eax 188 | .if flag == 1 189 | .while sdword ptr ebx > 0 190 | mov eax, [fillchr] 191 | call handle_char ;print leading filler chars 192 | dec ebx 193 | .endw 194 | .endif 195 | 196 | .while byte ptr [esi] 197 | lodsb 198 | call handle_char ;print char of string 199 | .endw 200 | 201 | .while sdword ptr ebx > 0 202 | mov eax, [fillchr] 203 | call handle_char ;print trailing spaces 204 | dec ebx 205 | .endw 206 | retn 207 | 208 | 209 | handle_char: 210 | push ebp 211 | mov ebp, [ebp] 212 | mov ah, 0Eh 213 | mov [ebp].Client_Reg_Struc.Client_EAX, eax 214 | mov byte ptr [ebp].Client_Reg_Struc.Client_EBX+1, 0 215 | mov eax, 10h 216 | @VMMCall Exec_Int 217 | pop ebp 218 | retn 219 | 220 | printf endp 221 | -------------------------------------------------------------------------------- /Test/XMSTEST2.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;--- XMSTEST2: test max block allocation 3 | ;--- Public Domain. 4 | ;--- to be assembled with JWasm or Masm v6. 5 | 6 | .model small 7 | .386 8 | .dosseg 9 | .stack 2048 10 | 11 | cr equ 13 12 | lf equ 10 13 | 14 | BUFFSIZ equ 10000h 15 | 16 | ;--- define a string constant 17 | 18 | CStr macro string:vararg 19 | local xxx 20 | .const 21 | xxx db string 22 | db 0 23 | .code 24 | exitm 25 | endm 26 | 27 | xms_move struct 28 | len dd ? ; block length in bytes 29 | src_handle dw ? ; source handle 30 | src_offset dd ? ; offset into source 31 | dest_handle dw ? ; destination handle 32 | dest_offset dd ? ; offset into destination 33 | xms_move ends 34 | 35 | .data 36 | 37 | xmsadr dd 0 ;XMS host call address 38 | 39 | .code 40 | 41 | assume DS:DGROUP 42 | 43 | include printf.inc 44 | 45 | ;--- test xms move block function 46 | 47 | movetest proc 48 | 49 | local handle:word 50 | local maxmem:dword 51 | local buffer:word 52 | local emm:xms_move 53 | 54 | ;--- allocate DOS memory block 55 | mov ah,48h 56 | mov bx,BUFFSIZ / 16 57 | int 21h 58 | jnc @F 59 | invoke printf, CStr("not enough DOS memory",lf) 60 | jmp failed 61 | @@: 62 | mov buffer, ax 63 | 64 | ;--- allocate XMS block 65 | mov ah,88h ;query free xms mem 66 | mov bl,0 67 | call [xmsadr] 68 | mov maxmem, eax 69 | mov bh,0 70 | push bx 71 | invoke printf, CStr("xms function 88h returned bl=%X, eax=%lX",lf), bx, eax 72 | pop bx 73 | cmp bl,0 74 | jnz failed 75 | 76 | mov edx, maxmem 77 | mov ah,89h 78 | mov bl,0 79 | call [xmsadr] 80 | mov handle, dx 81 | mov bh,0 82 | push bx 83 | invoke printf, CStr("xms function 89h returned bl=%X, dx=%X",lf), bx, dx 84 | pop bx 85 | cmp bl,0 86 | jnz failed 87 | 88 | ;--- test 1 89 | 90 | cld 91 | mov es, buffer 92 | mov di, 0 93 | mov cx, BUFFSIZ / 4 94 | mov eax, 0deadbabeh 95 | rep stosd 96 | 97 | mov emm.len, BUFFSIZ 98 | mov emm.src_handle, 0 99 | mov word ptr emm.src_offset+0, 0 100 | mov word ptr emm.src_offset+2, es 101 | mov ax, handle 102 | mov emm.dest_handle, ax 103 | mov emm.dest_offset, 0 104 | mov edi, maxmem 105 | shl edi, 10 ;kB -> byte 106 | .while edi 107 | mov dx,handle 108 | lea si, emm ;ds:si->xms move struct 109 | mov ah,0bh 110 | mov bl,0 111 | call [xmsadr] 112 | push ax 113 | invoke printf, CStr("XMS block move, ax=%u, dest ofs=%lX",13), ax, emm.dest_offset 114 | pop ax 115 | .break .if ax == 0 116 | add emm.dest_offset, BUFFSIZ 117 | .if edi > BUFFSIZ 118 | sub edi, BUFFSIZ 119 | .else 120 | mov emm.len, edi 121 | xor edi, edi 122 | .endif 123 | .endw 124 | invoke printf, CStr(10) 125 | 126 | ;--- free xms handle 127 | mov dx,handle 128 | mov ah,0ah 129 | mov bl,0 130 | call [xmsadr] 131 | failed: 132 | ret 133 | movetest endp 134 | 135 | ;--- main 136 | 137 | main proc c 138 | 139 | mov ax,4300h 140 | int 2fh 141 | test al,80h ;xms host found? 142 | jnz main1 143 | invoke printf, CStr("no XMS host found",lf) 144 | jmp exit 145 | main1: 146 | mov ax,4310h ;get XMS call address 147 | int 2fh 148 | mov word ptr xmsadr+0,bx 149 | mov word ptr xmsadr+2,es 150 | invoke printf, CStr("XMS call address: %X:%X",lf), 151 | word ptr [xmsadr+2], word ptr [xmsadr+0] 152 | 153 | call movetest 154 | 155 | exit: 156 | ret 157 | main endp 158 | 159 | ;--- init 160 | 161 | start proc 162 | 163 | mov ax,@data 164 | mov ds,ax 165 | 166 | mov cx,ds 167 | mov ax,ss 168 | sub ax,cx 169 | shl ax,4 170 | add ax,sp 171 | push ds 172 | pop ss 173 | mov sp,ax 174 | 175 | ;--- free DOS mem 176 | mov ax, ds 177 | mov cx, es 178 | sub ax, cx 179 | mov bx, sp 180 | add bx, 15 181 | shr bx, 4 182 | add bx, ax 183 | mov ah, 4Ah 184 | int 21h 185 | 186 | pushf 187 | pushf 188 | pop ax 189 | or ah,70h ;a 80386 will have bit 15 cleared 190 | push ax ;if bits 12-14 are 0, it is a 80286 191 | popf ;or a bad emulation 192 | pushf 193 | pop ax 194 | popf 195 | and ah,0f0h 196 | js no386 ;bit 15 set? then its a 8086/80186 197 | jnz is386 198 | no386: 199 | invoke printf, CStr("a 80386 is needed",lf) 200 | jmp done 201 | is386: 202 | call main 203 | done: 204 | mov ah,4Ch 205 | int 21h 206 | start endp 207 | 208 | END start 209 | -------------------------------------------------------------------------------- /Test/EMS56.ASM: -------------------------------------------------------------------------------- 1 | 2 | ;*** test int 67h, ah=56h (alter map and call) 3 | 4 | .286 5 | .model small 6 | .stack 2048 7 | .dosseg 8 | option casemap:none 9 | .386 10 | 11 | lf equ 10 12 | ;extern __acrtused:abs 13 | 14 | CStr macro text:vararg 15 | local x 16 | .const 17 | x db text,0 18 | .code 19 | exitm 20 | endm 21 | 22 | EMS56 struct 23 | dwProc dd ? ;far proc to call 24 | bSizeNew db ? 25 | pMapNew dd ? ;new mapping 26 | bSizeOld db ? 27 | pMapOld dd ? ;old mapping 28 | EMS56 ends 29 | 30 | log_phys_map struct 31 | dwLogPage dw ? ;logical page 32 | dwPhysPage dw ? ;segment or phys page 33 | log_phys_map ends 34 | 35 | .data 36 | 37 | ems56 EMS56 <> 38 | 39 | MapNew log_phys_map <0,0> 40 | log_phys_map <1,1> 41 | 42 | MapOld log_phys_map <-1,0> 43 | log_phys_map <-1,1> 44 | 45 | .code 46 | 47 | include 48 | 49 | main proc c argc:word, argv:word 50 | 51 | local handle:word 52 | local wPages:word 53 | local frame:word 54 | 55 | mov handle,-1 56 | mov ax,3567h 57 | int 21h 58 | mov ax,bx 59 | mov cx,es 60 | or ax,cx 61 | jz noemm 62 | 63 | mov bx,2 64 | mov ah,43h ;alloc 2 pages 65 | int 67h 66 | and ah,ah 67 | jnz error2 68 | mov handle,dx 69 | invoke printf, CStr("Int 67h, ah=43h, bx=2: Handle %X allocated",lf), handle 70 | 71 | mov bx,0 72 | mov dx,handle 73 | mov ax,4400h ;map to phys page 0 74 | int 67h 75 | and ah,ah 76 | jnz error4 77 | invoke printf, CStr("Int 67h, ax=4400h, bx=0: log page 0 mapped to phys page 0",lf) 78 | 79 | mov bx,1 80 | mov dx,handle 81 | mov ax,4401h ;map to phys page 1 82 | int 67h 83 | and ah,ah 84 | jnz error4 85 | invoke printf, CStr("Int 67h, ax=4401h, bx=1: log page 1 mapped to phys page 1",lf) 86 | 87 | mov ah,41h ;get page frame 88 | int 67h 89 | and ah,ah 90 | jnz error3 91 | mov frame,bx 92 | invoke printf, CStr("Int 67h, ah=41h: Page Frame is %X",lf), frame 93 | 94 | ;--- now copy a small test routine into page 0 of page frame 95 | 96 | mov es,frame 97 | mov di,0 98 | mov si,offset testpr 99 | push ds 100 | push cs 101 | pop ds 102 | mov cx,sizeproc 103 | rep movsb 104 | pop ds 105 | 106 | ;--- unmap page 0 107 | 108 | mov bx,-1 109 | mov dx,handle 110 | mov ax,4400h ;unmap page 0 111 | int 67h 112 | and ah,ah 113 | jnz error4 114 | invoke printf, CStr("Int 67h, ax=4400, bx=-1: phys page 0 unmapped",lf) 115 | 116 | mov dx,handle 117 | mov ax,5602h 118 | int 67h 119 | mov ax, sp 120 | invoke printf, CStr("Int 67h, ax=5602h: additional stack space for call: %X, SP=%X",lf), bx, ax 121 | 122 | ;--- prepare ax=5600h, DS:SI->EMS56 123 | 124 | mov si,offset ems56 125 | mov ax, frame 126 | mov word ptr [si].EMS56.dwProc+0, 0 127 | mov word ptr [si].EMS56.dwProc+2, ax 128 | mov [si].EMS56.bSizeNew,2 129 | mov word ptr [si].EMS56.pMapNew+0, offset MapNew 130 | mov word ptr [si].EMS56.pMapNew+2, ds 131 | mov [si].EMS56.bSizeOld,2 132 | mov word ptr [si].EMS56.pMapOld+0, offset MapOld 133 | mov word ptr [si].EMS56.pMapOld+2, ds 134 | mov dx,handle 135 | mov ax,5600h 136 | int 67h 137 | and ah,ah 138 | jnz error5 139 | 140 | mov ax,sp 141 | invoke printf, CStr("Int 67h, ax=5600h ok, SP after call=%X",lf), ax 142 | 143 | exit2: 144 | invoke printf, CStr(lf) 145 | exit: 146 | mov dx,handle 147 | cmp dx,-1 148 | jz @F 149 | mov ah,45h 150 | int 67h 151 | @@: 152 | ret 153 | noemm: 154 | invoke printf, CStr("EMM not found",lf) 155 | jmp exit 156 | error2: 157 | mov al,ah 158 | mov ah,0 159 | invoke printf, CStr("int 67h, ah=43h, bx=%u failed, status=%02X",lf), bx, ax 160 | jmp exit 161 | error3: 162 | mov al,ah 163 | mov ah,0 164 | invoke printf, CStr("int 67h, ah=41h failed, status=%02X",lf), ax 165 | jmp exit 166 | error4: 167 | mov al,ah 168 | mov ah,0 169 | invoke printf, CStr("int 67h, ah=44h failed, status=%02X",lf), ax 170 | jmp exit 171 | error5: 172 | mov al,ah 173 | mov ah,0 174 | invoke printf, CStr("int 67h, ax=5600h failed, status=%02X",lf), ax 175 | jmp exit 176 | main endp 177 | 178 | ;--- this small routine is copied into page 0 of page frame 179 | 180 | testpr proc far 181 | mov ah,02 182 | mov dl,'*' 183 | int 21h 184 | ret 185 | testpr endp 186 | 187 | sizeproc equ $ - testpr 188 | 189 | start: 190 | mov ax,@data 191 | mov ds,ax 192 | mov bx,ss 193 | mov cx,ds 194 | sub bx,cx 195 | shl bx,4 196 | add bx,sp 197 | mov ss,ax 198 | mov sp,bx 199 | call main 200 | mov ah,4Ch 201 | int 21h 202 | 203 | END start 204 | --------------------------------------------------------------------------------