Assembler source code for the small model DPMI example
(Cut this out and name it TINY.ASM)
;--------------------------------------------
; TINY.ASM - A tiny model protected mode
; program using DPMI
;--------------------------------------------
; To run this program a DPMI "server" must
; be present. Windows 3.X, Windows 95/98,
; Windows NT, and OS/2 provide DPMI servers
; for DOS programs. Recent versions of some
; memory managers, like QEMM and 386Max also
; have the capability of providing a DPMI
; server.
;--------------------------------------------
; This program should build with just about
; any version of MASM or TASM you might have.
; It will also build with the Watcom WASM
; assembler.
;--------------------------------------------
.186
TinyDPMI segment para public 'code'
assume cs:TinyDPMI
org 100h
start label near
jmp TinyStart
even
;--------------------------------------------
; This set of variables define what will be
; passed to and from DOS when executing a
; "simulated" real mode interrupt from
; protected mode.
;--------------------------------------------
RealSimStruc label dword
rEDI dd 0
rESI dd 0
rEBP dd 0
dd 0
rEBX dd 0
rEDX dd 0
rECX dd 0
rEAX dd 0
rFLAGS dw 0
rES dw 0
rDS dw 0
rFS dw 0
rGS dw 0
rIP dw 0
rCS dw 0
rSP dw 0
rSS dw 0
;--------------------------------------------
; This DWORD is the mode switch entry point
; that gets called when switching into
; protected mode.
;--------------------------------------------
ModeSwitch dd ?
;--------------------------------------------
; Our protected mode DS
;--------------------------------------------
ProtDS dw ?
;--------------------------------------------
; Messages
;--------------------------------------------
NoDPMImsg label byte
db "No DPMI server present!"
db 13,10,'$'
HelloMsg label byte
db "Hello from DPMI protected mode!"
db 13,10,'$'
;--------------------------------------------
; RealSim calls DPMI protected mode services
; to simulate a real mode software interrupt.
;--------------------------------------------
RealSim proc near
pusha ;
push es ;
push ds ;
xor cx,cx ; Let DPMI server
mov ds:rSS,cx ; provide a small
mov ds:rSP,cx ; DOS stack
mov bh,00h ;
mov bl,al ; BL=interrupt
mov ax,0300h ; AX=SimRealModeInt
push ds ;
pop es ; ES:DI-->RealSimStruc
mov di,offset RealSimStruc
int 31h ; Call DPMI server
pop ds ;
pop es ;
popa ;
mov ds,cs:ProtDS ;
ret ;
RealSim endp
;--------------------------------------------
; The first instruction in the COM file is
; a JMP to this label.
;--------------------------------------------
TinyStart label near
assume ds:TinyDPMI
mov rCS,cs ; Default some
mov rSS,ss ; registers in
mov rDS,ds ; the real sim
mov rES,es ; structure
mov rSP,sp ; to COM defaults
;
; Check for DPMI present
;
mov ax,1687h ;
int 2Fh ;
xchg cx,ax ; CX=AX, AX=?
jcxz DPMIyes ;
;--------------------------------------------
; No DPMI server is present or we failed for
; some reason to make it into protected mode
; if we get here. Show message & terminate.
;--------------------------------------------
mov dx,offset NoDPMImsg
mov ah,9 ;
int 21h ;
NotProtectedMode:
mov ax,4CFFh ; rc=-1
int 21h ;
;--------------------------------------------
; We have a DPMI server present.
; Save the mode switch address.
;--------------------------------------------
DPMIyes label near
mov word ptr ModeSwitch+0,di
mov word ptr ModeSwitch+2,es
;--------------------------------------------
; Give DPMI private data area to work with.
;--------------------------------------------
mov dx,offset EndOfTestLabel
shr dx,4 ; Convert to
mov ax,cs ; para offset
add ax,dx ; from start
mov es,ax ; ES=DPMI private data
;--------------------------------------------
; Try to get into protected mode
;--------------------------------------------
xor ax,ax ; AX=0 -> 16 bit DPMI
call dword ptr [ModeSwitch]
jc NotProtectedMode
;--------------------------------------------
; We're in protected mode if we get here!
; Display the hello message using a simulated
; Int 21h function 9h
;--------------------------------------------
mov ds:ProtDS,ds
mov word ptr ds:rEAX,0900h
mov word ptr ds:rEDX,offset HelloMsg
mov al,21h
call RealSim
;--------------------------------------------
; Terminate this DPMI app. DPMI apps
; terminate by doing a normal Int 21 fn 4C
; while in protected mode.
;--------------------------------------------
mov ax,4C00h ; rc=0
int 21h ;
;--------------------------------------------
; The end of this COM file should be *plenty*
; of private data space for any DPMI server.
;--------------------------------------------
dw 16 dup (0) ; Pad up.
EndOfTestLabel label byte
TinyDPMI ends
end start
Copyright © 1995,1998, Tony Ingenoso