windows-nt/Source/XPSP1/NT/base/mvdm/dpmi/dxhpbios.asm

479 lines
11 KiB
NASM
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
PAGE ,132
TITLE DXHPBIOS.ASM -- Dos Extender HP Extended BIOS Mapping
; Copyright (c) Microsoft Corporation 1988-1991. All Rights Reserved.
;***********************************************************************
;
; DXHPBIOS.ASM -- Dos Extender HP Extended BIOS Mapping
;
;-----------------------------------------------------------------------
;
; This module provides the 286 DOS extender's protected-to-real mode
; mapping of selected HP Vectra Extended BIOS services.
;
;-----------------------------------------------------------------------
;
; 08/25/89 jimmat Original version
; 18-Dec-1992 sudeepb Changed cli/sti to faster FCLI/FSTI
;
;***********************************************************************
.286p
; -------------------------------------------------------
; INCLUDE FILE DEFINITIONS
; -------------------------------------------------------
.xlist
.sall
include segdefs.inc
include gendefs.inc
include pmdefs.inc
include interupt.inc
IFDEF ROM
include dxrom.inc
ENDIF
include intmac.inc
include stackchk.inc
include bop.inc
.list
; -------------------------------------------------------
; GENERAL SYMBOL DEFINITIONS
; -------------------------------------------------------
F_INS_XCHGFIX equ 06h
; -------------------------------------------------------
; EXTERNAL SYMBOL DEFINITIONS
; -------------------------------------------------------
extrn EnterIntHandler:NEAR
extrn LeaveIntHandler:NEAR
extrn EnterRealMode:NEAR
extrn EnterProtectedMode:NEAR
extrn ParaToLDTSelector:NEAR
extrn PMIntrEntryVector:NEAR
; -------------------------------------------------------
; DATA SEGMENT DEFINITIONS
; -------------------------------------------------------
DXDATA segment
extrn regUserSS:WORD
extrn regUserSP:WORD
extrn pbReflStack:WORD
extrn bReflStack:WORD
extrn fHardwareIntMoved:BYTE
public HPxBiosVectorRM
HPxBiosVectorRM dd ? ;offset to RM HP Int handler
PMCallBack dd 0 ;protected mode call back CS:IP
HPDriverHeader dw ? ;segment of HP driver header block
HPDriverSegSel dw 0,0 ;segment/selector pairs
dw 0,0
dw 0,0
dw -1
DXDATA ends
; -------------------------------------------------------
; CODE SEGMENT VARIABLES
; -------------------------------------------------------
DXCODE segment
IFNDEF ROM
extrn segDXData:WORD
extrn selDgroup:WORD
extrn PrevInt69Handler:DWORD
ENDIF
DXCODE ends
; -------------------------------------------------------
subttl HP Extended BIOS Mapping Interface
page
; -------------------------------------------------------
; HP EXTENDED BIOS MAPPING INTERFACE
; -------------------------------------------------------
DXPMCODE segment
assume cs:DXPMCODE
; -------------------------------------------------------
; HPxBIOS -- Interrupt routine for the HP Vectra Extended
; BIOS service calls. Currently, on the F_INS_XCHGFIX
; service is supported, and this is not mapped transparently!
; This support was added for the Windows HP mouse driver.
;
; Input: Various registers
; Output: Various registers
; Errors:
; Uses: All registers preserved, other than return values
;
; The following services are supported:
;
; AH=06 - F_INS_XCHGFIX (non transparent pm->rm mapping)
;
assume ds:NOTHING,es:NOTHING,ss:NOTHING
public HPxBIOS
HPxBIOS proc near
cmp ah,F_INS_XCHGFIX ;is this F_INS_XCHGFIX?
jz @f
jmp PMIntrEntryVector + 3*6Fh ;if not, just pass it on
@@:
call EnterIntHandler ;build an interrupt stack frame
assume ds:DGROUP,es:DGROUP ; also sets up addressability
cld ;cya...
; Save the protected mode CS:IP. NOTE: we only support one call back
; address (the last one)! This works for the current mouse driver, but
; may not work for other drivers.
mov ax,[bp].pmUserDI
mov word ptr PMCallBack,ax
mov ax,[bp].pmUserES
mov word ptr [PMCallBack+2],ax
; Execute the real mode HP Extended BIOS service
SwitchToRealMode
assume ds:DGROUP,es:DGROUP
xor ax,ax
mov es,ax
assume es:NOTHING
mov ax,es:[6Fh*4]
mov word ptr [HPxBiosVectorRM],ax
mov ax,es:[6Fh*4+2]
mov word ptr [HPxBiosVectorRM+2],ax
test byte ptr [bp].pmUserFL+1,02h ;enable interrupts if
jz @f ; caller had them enabled
FSTI
@@:
pop es
pop ds
assume ds:NOTHING,es:NOTHING
popa
push ax ;set our own call back routine,
mov ax,cs ; which will invoke the PM one
mov es,ax
pop ax
mov di,offset RMCallBack
FCLI
call ss:[HPxBiosVectorRM]
pushf
FCLI
pusha
push ds
push es
mov bp,sp ;restore stack frame pointer
IFDEF ROM
push ss
pop ds
ELSE
mov ds,selDgroup ;HP BIOS seems to change DS on us
ENDIF
assume ds:DGROUP
SwitchToProtectedMode
assume ds:DGROUP,es:DGROUP
; Perform fixups on the return values.
mov ax,[bp].intUserES ;we return real mode ES in BP!
mov [bp].intUserBP,ax
call LeaveIntHandler ;restore caller's registers, stack
assume ds:NOTHING,es:NOTHING
iret
HPxBIOS endp
; -------------------------------------------------------
DXPMCODE ends
; -------------------------------------------------------
subttl HP Pointing Device Handler
page
; -------------------------------------------------------
; HP POINTING DEVICE HANDLER
; -------------------------------------------------------
DXCODE segment
assume cs:DXCODE
; -------------------------------------------------------
; RMCallBack -- This routine is the RM entry point for
; the HP Pointing Device Handler. It switches the
; processor to protected mode and transfers control to the
; user pointing device handler. When that completes,
; it switches back to real mode and returns control to
; the HP BIOS.
;
; Input: none
; Output: none
; Errors: none
assume ds:NOTHING,es:NOTHING,ss:NOTHING
public RMCallBack
RMCallBack proc near
cld
push es ;save BIOS ds/es on it's stack
push ds
IFDEF ROM
SetRMDataSeg
ELSE
mov ds,selDgroup ;setup addressability to DOSX DGROUP
ENDIF
assume ds:DGROUP
mov HPDriverHeader,es ;save ES driver header block segment
; Allocate a new stack frame, and then switch to the local stack
; frame.
FCLI ;protect global regUserXX vars
mov regUserSP,sp ;save entry stack pointer so we can restore it
mov regUSerSS,ss ;save segment too
IFDEF ROM
push ds
pop ss
ELSE
mov ss,selDgroup ;switch to our own stack frame
ENDIF
mov sp,pbReflStack
sub pbReflStack,CB_STKFRAME ;adjust pointer to next stack frame
FIX_STACK
push regUserSS ;save HP BIOS stack address
push regUserSP ; so we can restore it later
push SEL_DXDATA or STD_RING ;DOSX DS to be poped in PM
pusha ;save general registers
; We are now running on our own stack, so we can switch into protected mode.
SwitchToProtectedMode
assume ds:DGROUP,es:DGROUP
; See if we've already mapped a selector to the HPDriverHeader segment. We
; have a table of 3 segment/selector pairs because the current Windows
; mouse driver support up to 3 pointing devices (all with the same call
; back address).
mov ax,HPDriverHeader ;get segment to map
FSTI ;don't need ints disabled now
mov bx,offset DGROUP:HPDriverSegSel-4
rmcb_cmp_seg:
add bx,4
cmp word ptr [bx],ax ;same segment?
jne @f
mov es,word ptr [bx+2] ; yes, get selector to ES
jmp short rmcb_sel_set
@@:
cmp word ptr [bx],0 ;empty table slot?
je rmcb_new_seg
cmp word ptr [bx],-1 ;end of table?
jne rmcb_cmp_seg
; Haven't seen this segment before, map a selector for it
rmcb_new_seg:
mov cx,ax ;save segment in cx
mov dx,bx ;save table offset in dx
mov bx,STD_DATA ;want a data selector
call ParaToLDTSelector
jnc @f ;BIG TROUBLE if can't create selector!
popa ; don't even call users routine
jmp short rmcb50
@@:
mov es,ax
assume es:NOTHING
mov bx,dx ;save this seg/sel pair if not
cmp word ptr [bx],-1 ; at the end of the table
je rmcb_sel_set
mov word ptr [bx],cx
mov word ptr [bx+2],ax
rmcb_sel_set:
popa ;restore general registers
; Build an iret frame on the stack so that the user's
; routine will return to us when it is finished.
pushf
push cs
push offset rmcb50
; Build a far return frame on the stack to use to transfer control to the
; user's protected mode routine
push word ptr [PMCallBack+2]
push word ptr [PMCallBack]
; At this point the stack looks like this:
;
; [14] stack segment of original stack
; [12] stack pointer of original stack
; [10] protect mode dos extender data segment
; [8] flags
; [6] segment of return address back to here
; [4] offset of return address back here
; [2] segment of user routine
; [0] offset of user routine
; Execute the user's pointing device handler
retf
; The users handler will return here after it is finsished.
rmcb50:
cld
pop ds ;restore DOSX DS
assume ds:DGROUP,es:NOTHING
FCLI ;protect global regUserXX vars
pop regUserSP
pop regUserSS
; Switch back to real mode.
push ax ;preserve AX
SwitchToRealMode
assume ds:DGROUP,es:DGROUP
pop ax
; Switch back to the original stack.
CHECK_STACK
mov ss,regUserSS
mov sp,regUserSP
; Deallocate the stack frame that we are using.
add pbReflStack,CB_STKFRAME
; And return to the HP BIOS
pop ds
pop es
iret
RMCallBack endp
; -------------------------------------------------------
subttl Classic HP Vectra Keyboard Hook
page
; -------------------------------------------------------
; CLASSIC HP VECTRA KEYBOARD HOOK
; -------------------------------------------------------
IFNDEF ROM
public RMVectraKbdHook
assume ds:NOTHING,es:NOTHING,ss:NOTHING
; If the master PIC has been remapped, we process the interrupt ourselves,
; otherwise, we just pass it on to the previous Int 69h handler (which
; is most likely the HP Vectra BIOS).
RMVectraKbdHook proc near
push ds
mov ds,segDXData
assume ds:DGROUP
test fHardwareIntMoved,0FFh ;PIC been remapped?
pop ds
assume ds:NOTHING
jnz @f
jmp [PrevInt69Handler] ; no, get out of the way
@@:
push ax
mov al,61h ; yes, EOI the third slave PIC
out 7Ch,al
pop ax
int 51h ; and simulate an IRQ 1 interrupt
iret
RMVectraKbdHook endp
ENDIF
DXCODE ends
; -------------------------------------------------------
DXPMCODE segment
assume cs:DXPMCODE
; -------------------------------------------------------
IFNDEF ROM
public PMVectraKbdHook
assume ds:NOTHING,es:NOTHING,ss:NOTHING
PMVectraKbdHook proc near
push ax ;EOI the third slave PIC
mov al,61h
out 7Ch,al
pop ax
int 51h ;simulate an IRQ 1 interrupt
iret ;back we go
PMVectraKbdHook endp
ENDIF
; -------------------------------------------------------
DXPMCODE ends
;****************************************************************
end