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