home *** CD-ROM | disk | FTP | other *** search
- ; 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 = 0002h ; 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 cx,1
- mov ax,0
- int 31h
- mov bx,ax
-
- movzx edx,dx
- shl edx,4
- mov ecx,edx
- shr ecx,16
- mov ax,007h
- int 31h
-
- mov cx,0
- mov dx,-1
- mov ax,008h
- int 31h
-
- mov cx,4092h
- mov ax,009h
- int 31h
- 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
-