Metropoli BBS
VIEWER: example2.asm MODE: TEXT (CP437)
; This program demonstrates calling a protected mode procedure from real mode.

        .386p
code16  segment para public use16
        assume cs:code16, ds:code32

;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; DATA
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

r_message       db      'Now we are in real mode',0dh,0ah,36

;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; CODE
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

;─────────────────────────────────────────────────────────────────────────────
rm:
        mov ax,code32                   ; need to address variables in CODE32
        mov ds,ax                       ;  segment. All necessary variables
                                        ;  are in the first 64k of the CODE32
                                        ;  segment so they are accessible with
                                        ;  the 16bit addressing that is done
                                        ;  in real mode
        mov eax,offset r_message        ; offset is from beginning of CODE16
        add eax,ds:_code16a             ; adjust to absolute address
        sub eax,ds:_code32a             ; convert to protected mode realative
                                        ;  address
        mov ds:v86r_edx,eax             ; this will become the EDX register on
                                        ;  entry to the routine we are calling
        mov edx,offset pm_rout          ; the routine in protected mode we
                                        ;  want to call
        int 32h                         ; call protected mode routine
        retf

code16  ends

code32  segment para public use32
        assume cs:code32, ds:code32

include pmode.inc

public  _main

;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; DATA
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

p_message0      db      'We are in protected mode.',0dh,0ah,36
p_message1      db      'We are now back in protected mode.',0dh,0ah,36

p_message_key   db      'Press any key to go on.',0dh,0ah,36

;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; CODE
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

;═════════════════════════════════════════════════════════════════════════════
_main:
        sti

        mov edx,offset p_message0
        call pm_rout

        mov cx,code16           ; segment of real mode far call
        mov dx,offset rm        ; offset of real mode far call
        int 32h                 ; call real mode far routine

        mov edx,offset p_message1
        call pm_rout

        jmp _exit

;─────────────────────────────────────────────────────────────────────────────
pm_rout:                        ; put message at EDX and wait for keypress
        call pm_put_msg         ; put input message

        mov edx,offset p_message_key
        call pm_put_msg         ; put 'press ny key...' message

        mov v86r_ah,0           ; use real mode INT 16h AH=0 to wait for key
        mov al,16h
        int 33h

        ret

;─────────────────────────────────────────────────────────────────────────────
pm_put_msg:                     ; put DOS string just line in EX_PM0.ASM
        add edx,_code32a
        shld eax,edx,28
        and edx,0fh
        mov v86r_ds,ax
        mov v86r_dx,dx
        mov v86r_ah,9
        mov al,21h
        int 33h
        ret

code32  ends
        end

[ RETURN TO DIRECTORY ]