home *** CD-ROM | disk | FTP | other *** search
- ; This little program just prints a string to DOS using function 0300h.
- ; Then it allocates a real mode callback, calls the real mode callback from
- ; protected mode, and prints a string out of the protected mode callback
- ; routine. Not the standard usage of callbacks, but just to demonstrate.
-
- .386p
- locals
-
- STACKLEN = 400h ; size of stack in bytes
-
- PMODE_TEXT segment para public use16 'CODE'
- PMODE_TEXT ends
- _TEXT segment para public use16 'CODE'
- _TEXT ends
- EXE_STACK segment para stack use16 'STACK'
- EXE_STACK ends
-
- extrn _pm_info:far, _pm_init:far
-
- _TEXT segment para public use16 'CODE'
- assume cs:_TEXT, ds:_TEXT
- org 0
-
- ;═════════════════════════════════════════════════════════════════════════════
- errmsgtbl dw errmsg0,errmsg1,errmsg2,errmsg3
- dw errmsg4,errmsg5,errmsg6
-
- errmsg0 db 'Not enough low memory!',13,10,36
- errmsg1 db '80386 or better not detected!',13,10,36
- errmsg2 db 'System already in protected mode and no VCPI or DPMI found!',13,10,36
- errmsg3 db 'DPMI host is not 32bit!',13,10,36
- errmsg4 db 'Could not enable A20 gate!',13,10,36
- errmsg5 db 'Could not enter DPMI 32bit protected mode!',13,10,36
- errmsg6 db 'Could not allocate needed DPMI selectors!',13,10,36
-
- msg0 db 'Hello World from Protected Mode...',13,10
- db 'Press any key to continue...',13,10,36
- msg1 db 'Hello World from a Real Mode Callback...',13,10
- db 'Press any key to exit...',13,10,36
-
- align 4
- regstruc_edi label dword
- regstruc_di dw ?,?
- regstruc_esi label dword
- regstruc_si dw ?,?
- regstruc_ebp label dword
- regstruc_bp dw ?,?
- dd ?
- regstruc_ebx label dword
- regstruc_bx label word
- regstruc_bl db ?
- regstruc_bh db ?,?,?
- regstruc_edx label dword
- regstruc_dx label word
- regstruc_dl db ?
- regstruc_dh db ?,?,?
- regstruc_ecx label dword
- regstruc_cx label word
- regstruc_cl db ?
- regstruc_ch db ?,?,?
- regstruc_eax label dword
- regstruc_ax label word
- regstruc_al db ?
- regstruc_ah db ?,?,?
- regstruc_flags dw ?
- regstruc_es dw ?
- regstruc_ds dw ?
- regstruc_fs dw ?
- regstruc_gs dw ?
- regstruc_ip dw ?
- regstruc_cs dw ?
- regstruc_sp dw ?
- regstruc_ss dw ?
-
- dataselector dw ?
-
- ;═════════════════════════════════════════════════════════════════════════════
- start:
- push cs ; DS = CS
- pop ds
-
- call _pm_info ; get information
- jnc short @@startf0 ; if no error, go on
-
- @@startf1:
- mov si,ax ; print error message for code AX
- add si,ax
- mov dx,errmsgtbl[si]
- mov ah,9
- int 21h
- mov ax,4cffh
- int 21h
-
- @@startf0:
- xor ax,ax ; check low memory and allocate low
- mov cx,ss ; buffer needed for protected mode
- add cx,STACKLEN
- mov dx,es:[2]
- sub dx,cx
- cmp dx,bx
- jb @@startf1
- mov es,cx
-
- call _pm_init ; enter protected mode
- jc @@startf1 ; if error, go to error message
-
- mov dataselector,ds ; preserve data selector
-
-
- push ds ; ES = DS for register structure
- pop es
-
- mov edi,offset regstruc_edi ; offset of register structure
- xor cx,cx ; no parameters on stack
- mov bx,21h ; call interrupt 21h
- mov ax,300h ; INT 31h function 0300h
-
- mov regstruc_ah,9 ; function code 9, put string
- mov regstruc_ds,_TEXT ; set DS:DX for DOS string put
- mov regstruc_dx,offset msg0
- mov regstruc_ss,0 ; SS:SP = 0, PMODE will provide stack
- mov regstruc_sp,0
-
- int 31h ; do the call to real mode
-
-
- xor ah,ah ; wait for keypress
- int 16h
-
-
- push ss ; ES = SS for register structure
- pop es
-
- sub esp,32 ; stack space for register structure
- mov edi,esp ; EDI = offset of register structure
-
- push cs ; DS:ESI = callback routine
- pop ds
- mov esi,offset callback
-
- mov ax,303h ; INT 31h function 0303h
- int 31h ; allocate real mode callback
-
-
- sub esp,32 ; stack space for register structure
- mov edi,esp ; EDI = offset of register structure
-
- mov dword ptr [esp+2eh],0 ; SS:SP = 0 in register structure
- mov [esp+2ah],dx ; IP is offset of real mode callback
- mov [esp+2ch],cx ; CS is segment of real mode callback
- mov word ptr [esp+20h],0 ; zero FLAGS in register structure
-
- xor cx,cx ; no parameters on stack
- xor bh,bh ; BH must be 0
- mov ax,301h ; INT 31h function 0301h
-
- int 31h ; call real mode callback
-
-
- add esp,64 ; free stack space
-
- mov ah,4ch ; exit to DOS
- int 21h
-
- ;─────────────────────────────────────────────────────────────────────────────
- callback:
- cld
- lods dword ptr ds:[esi] ; get return seg:off from real mode
- mov dword ptr es:[edi+2ah],eax ; stack, and update return address
- add word ptr es:[edi+2eh],4 ; adjust SP in register structure
-
- push es edi ; preserve register structure ES:EDI
-
-
- mov es,cs:dataselector ; ES = main stream data selector
-
- mov edi,offset regstruc_edi ; offset of register structure
- xor cx,cx ; no parameters on stack
- mov bx,21h ; call interrupt 21h
- mov ax,300h ; INT 31h function 0300h
-
- mov es:regstruc_dx,offset msg1 ; offset of new string, other fields
- ; were set previously
- int 31h ; do the call to real mode
-
-
- xor ah,ah ; wait for keypress
- int 16h
-
-
- pop edi es ; restore register structure ES:EDI
-
- iretd ; done with callback
-
- _TEXT ends
-
- EXE_STACK segment para stack use16 'STACK'
- db STACKLEN dup(?)
- EXE_STACK ends
-
- end start
-
-