; Copyright (C) 1996 CW Sandmann (sandmann@clio.rice.edu) 1206 Braelinn, Sugarland, TX 77479 ; ; This file is distributed WITHOUT ANY WARRANTY; without even the implied ; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. title cws_tsr_pmode SW_FLAGS = 0003h ; detect VCPI first, reprogram pic p386 SEGMENT _TEXT PUBLIC USE16 'CODE' group DGROUP _DATA, _BSS assume cs:_TEXT, ds:DGROUP, es:nothing, ss:nothing EXTRN pm_info:near, pm_init:near _dpmiint2f: cmp ax,1687h jne short not_us ct: mov cl,3 xor ax,ax ;Yes, we are here mov bx,1 ;32 bit programs supported mov dx,5ah ;0.90 version pn: mov si,1 ;paragraphs needed push cs pop es mov di,offset dpmientry iret not_us: db 0eah oldint2f label word dw 2 dup (?) dpmientry: ;far return point cs:ip on stack test al,1 jnz short ok_32 stc retf ok_32: pushad push ds push ss ; so we can compare later ; restore old int 2f vector since pmode is not reentrable and looks at int 2f xor ax,ax mov ds,ax mov eax, dword ptr cs:oldint2f mov ds:[2fh*4], eax ; atomic, cli not needed push DGROUP pop ds mov ax,SW_FLAGS ; switch flags call pm_init ; attempt to switch jnc short in_pm pop ax pop ds popad retf in_pm: pop ax ; original ss pop dx ; original ds cmp ax,dx mov bx,ss ; bx is just ss if same originally je short no_new_ds call seg_to_sel no_new_ds: mov ds,bx ; just in case mov dx,[esp+34] ; 8 dwords for pushad and 2 bytes for IP call seg_to_sel mov [esp+34],bx mov ax,0009h ; set selector type and access rights mov dx,cs ; get DPL from current CPL, and access lar cx,dx ; rights and type from current CS shr cx,8 ; type is already 16bit code segment int 31h jc short immed_exit popad retf ; Enter with segment in dx, exit with selector in bx seg_to_sel: mov bx,dx mov ax,002h ; DPMI says not use it for private int 31h ; selectors, but it's only PMODE/DJ |-) jc short immed_exit mov bx,ax ret immed_exit: mov ax,4cffh int 21h ; Called by pmode right before exit to free this memory exit_hook: mov ax,cs sub ax,10h ; psp base mov es,ax mov ah,49h int 21h ret start: ; execution starts here ; Deallocate Environment mov es,es:[2ch] mov ah,49h int 21h ; Call PMODE's info routine push _DATA pop ds mov ax, SW_FLAGS call pm_info jc short no_pmode cmp ch,3 jne short ok1 ; Fail - can't get to PM no_pmode: mov dx, offset msg_no_PM mov ah,9 int 21h mov ax,4c01h int 21h ; store PMODE returned values in our code space ok1: mov byte ptr ct+1,cl mov word ptr pn+1,bx ; Close all the handles (stdin, stdout, stderr, AUX, PRN) mov cx,4 closem: mov ah,3eh mov bx,cx int 21h loop closem ; Chain int 2f mov ax,352fh ;Get int 2f int 21h mov oldint2f+2,es mov oldint2f,bx push cs pop ds mov dx,offset _dpmiint2f mov ax,252fh int 21h ; Terminate and stay resident push _DATA pop ds mov pm_exit,offset exit_hook mov ax,3100h mov dx,ss ;temp SS is at end mov bx,cs ;CS is above PSP sub dx,bx add dx,10h ;add for psp int 21h ends SEGMENT _DATA PUBLIC USE16 'DATA' EXTRN pm_exit:word msg_no_PM db "Can't load PMODE.",13,10,"$" ends SEGMENT _BSS PUBLIC USE16 'BSS' ends SEGMENT _STACK STACK 'STACK' db 256 dup (?) ENDS end start