3 ; Test program: Protected mode via DPMI (DOS Protected Mode Interface)
4 ; (C) 2010-2012 Jonathan Campbell.
5 ; Hackipedia DOS library.
7 ; This code is licensed under the LGPL.
8 ; <insert LGPL legal text here>
11 ; switching the CPU into 386 16-bit protected mode (and back) using DPMI
12 bits 16 ; 16-bit real mode
13 org 0x100 ; MS-DOS .COM style
15 ; assume ES == DS and SS == DS and DS == CS
23 ; we need to use DOS memory allocation, so we first need to resize our
24 ; memory ownership down to the actual size of the COM file.
25 ; Windows NT/XP/etc. seem to assume the COM takes 64KB, while Windows 95
26 ; follows the DOS way and has the COM assume all memory. So for this
27 ; code to work under Win9x much less DOS we need to do this step.
28 mov ah,0x4A ; INT 21h AH=4Ah resize memory block
30 mov es,bx ; ES=our PSP segment
32 shr bx,4 ; in paragraphs, the size of this program + data
39 mov [MY_PHYS_BASE+2],bx
40 mov [MY_PHYS_BASE+0],ax
46 mov dx,str_cpu_need_dpmi
47 jmp exit2dos_with_message
51 mov [dpmi_data_size],si
53 ; allocate private data for DPMI server, if needed
54 mov word [dpmi_data_seg],0
55 cmp word [dpmi_data_size],0
58 mov bx,[dpmi_data_size] ; in paragraphs
61 mov dx,str_cpu_dpmi_private_alloc_fail
62 jmp exit2dos_with_message
63 .allocd: mov [dpmi_data_seg],ax
65 ; at this point: either we allocated memory successfully, or the DPMI server does not need private data segment
67 mov es,[dpmi_data_seg]
69 call far word [dpmi_entry]
71 mov dx,str_dpmi_entry_fail
72 jmp exit2dos_with_message
74 ; save our protected mode side
80 ; we need a selector to draw on the screen with
91 ; now switch back to real mode
100 mov ax,[MY_SEGMENT] ; AX will become DS
101 mov cx,ax ; CX will become ES
102 mov dx,ax ; DX will become SS
103 movzx ebx,sp ; EBX will become (E)SP
104 mov si,ax ; SI will become CS
106 jmp far dword [raw_exit]
114 ; jump back to protected mode
115 mov ax,[MY_DATA_SEL] ; AX will become DS
116 mov cx,ax ; CX will become ES
117 mov dx,ax ; DX will become SS
118 movzx ebx,sp ; EBX will become (E)SP
119 mov si,[MY_CODE_SEL] ; SI will become CS
121 jmp far word [raw_entry]
132 ; ===== EXIT TO DOS WITH ERROR MESSAGE DS:DX
133 exit2dos_with_message:
137 exit2dos: mov ax,4C00h
141 ; DS:SI = what to put
142 ; DI = where to put it
163 ; DS:SI = what to put
164 ; DI = where to put it
185 str_cpu_need_dpmi:db "DPMI server required$"
186 str_cpu_dpmi_private_alloc_fail:db "Unable to allocate private data for DPMI$"
187 str_dpmi_entry_fail:db "Unable to enter DPMI protected mode$"
188 vdraw_msg: db "This message was drawn on screen from DPMI 16-bit protected mode!",0
189 vdraw3_msg: db "This message was drawn on screen back into DPMI 16-bit protected mode!",0
190 vdraw2_msg: db "This message was drawn on screen back from real mode!",0
198 dpmi_data_size: resw 1
199 dpmi_data_seg: resw 1