;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
;/*****************************************************************************
;*
;* SOURCE FILE NAME = EGASTATE.ASM
;*
;* DESCRIPTIVE NAME = Pointer shape support routines
;*
;*
;* VERSION      V2.0
;*
;* DATE         01/06/87
;*
;* DESCRIPTION  SAVE_HW_REGS is called by the pointer shape routine to save
;*              the state of those EGA's registers which must be used to
;*              draw the pointer shape.  RES_HW_REGS is called by the
;*              pointer shape routine to restore the state of those EGA
;*              registers saved by SAVE_HW_REGS, and to prepare for the next
;*              call to SAVE_HW_REGS.  INIT_HW_REGS is called immediately
;*              after the EGA is placed into graphics mode to initialize
;*              locations in EGA memory that are required by, but not
;*              altered by, SAVE_HW_REGS.
;*
;*              Restrictions:
;*
;*              These routines are intended to be executed while protected
;*              with some form of a semephore.  The contents of both the
;*              Graphics Controller Address Register and the Sequencer Address
;*              Register are assumed to belong to these pieces of code while
;*              executing, and assumed not to change unless done so by these
;*              routines.  INIT_HW_REGS must be called before any call to
;*              either SAVE_HW_REGS or RES_HW_REGS.  RES_HW_REGS must be
;*              called prior to the next call to SAVE_HW_REGS or the detection
;*              code will fail.
;*
;* FUNCTIONS    init_hw_regs
;*              set_misc_regs
;*              set_test_locs
;*              DeviceSeamlessInit
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   01/06/87                     Written by Walt Moore [waltm]
;*   ??/??/92                     Paul King
;*
;*****************************************************************************/


.386
.MODEL FLAT
ASSUME  SS:FLAT, DS:FLAT, CS:FLAT, ES:FLAT

        .xlist
INCL_GRE_BITMAPS                equ     1
INCL_GPIBITMAPS                 equ     1
        include pmgre.inc
        DINCL_BITMAP            equ     1
        DINCL_EGAMEM            equ     1
        DINCL_ENABLE            equ     1
        include driver.inc
        include egafam.inc
        include extern.inc
ifdef EGAMEM_IS_STRUCT
        include egamem.inc
endif

ifdef SEAMLESS
        include seamless.inc
        INCLUDE pointer.inc
        include curstrc.inc
        include palette.inc
endif

        .list


set_test_locs PROTO SYSCALL
set_misc_regs PROTO SYSCALL
far_exclude16 PROTO FAR16 SYSCALL
far_unexclude16 PROTO FAR16 SYSCALL
init_hw_regs16 PROTO FAR16 SYSCALL


;/*
;**       Data register I/O addresses must follow the Address register
;**       I/O addresses.
;*/


        .ERRNZ  GRAF_DATA-GRAF_ADDR-1
        .ERRNZ  SEQ_DATA-SEQ_ADDR-1

;/*
;**       Don't want to explicitly define a read mode on every output to
;**       the Graphics Controller's Mode Register.  The default should be
;**       Data Read if not specified.
;*/


        .ERRNZ  M_DATA_READ

;/*
;**       The ordering of the planes and their index values are assumed
;**       to be the following.  It is unlikely that these will ever
;**       change.
;*/


        .ERRNZ  MM_C3-00001000b                  ;Map mask values
        .ERRNZ  MM_C2-00000100b
        .ERRNZ  MM_C1-00000010b
        .ERRNZ  MM_C0-00000001b

        .ERRNZ  RM_C0                             ;Read map values (sequential)
        .ERRNZ  RM_C1-RM_C0-1
        .ERRNZ  RM_C2-RM_C1-1
        .ERRNZ  RM_C3-RM_C2-1


;/*
;**       The following locations are used to save and restore
;**       the indicated EGA registers.
;*/



.DATA
                db      GRAF_ENAB_SR             ;Enable Set/Reset register address
saved_enab_sr   db      ?                         ;Computed Enable Set/Reset

                db      GRAF_DATA_ROT            ;Data Rotate register address
saved_data_rot  db      ?               ;Computed Data Rotate function

                db      GRAF_READ_MAP   ;Read Map register address
saved_read_map  db      ?               ;Computed Read Map Select

                db      GRAF_BIT_MASK   ;Bit Mask register address
saved_bit_mask  db      ?               ;Computed Bit Mask

saved_map_mask  db      ?               ;Computed Map Mask

;/*
;**       The func_select table is used to translate the results of step
;**       5C into the actual value for the Data Rotate register. The
;**       algorithm which scans the planes to determine the boolean
;**       operation of the Data Rotate register returns 0 wherever a
;**       changed occured in the table listed for step 5C.
;**
;**       Since C0 is never involved in the result, it is masked off
;**       via a SHR instruction.
;*/


func_select     label   byte
        db      DR_SET                  ;000 - illegal
        db      DR_SET                  ;001 - illegal
        db      DR_XOR                  ;010 - XOR
        db      DR_SET                  ;011 - illegal
        db      DR_SET                  ;100 - SET
        db      DR_AND                  ;101 - AND
        db      DR_OR                   ;110 - OR
        db      DR_SET                  ;111 - illegal

ifdef SEAMLESS

EXTERNDEF       HWPalette:RGB2

_SEAMLESSDATA SEGMENT 'DATA'

PUBLIC SeamDataStart
SeamDataStart   LABEL DWORD

else ;NOT SEAMLESS

_DATA SEGMENT 'DATA'

PUBLIC DataStart
DataStart   LABEL DWORD
endif  ;SEAMLESS

        ALIGN   4
drqVideo           vvdrq_s <0A0000h,\
                            0ffffffffh,\
                            reserved_latches,\
                            OFFSET fbShadowFlags,\
                            OFFSET fControllerOwned,\
                            OFFSET fControllerNotify,\
                            shadow_size,\
                            OFFSET shadow_data>

;/*
;**   The following shadow data is updated by the Video VDD whenever it
;**   is sharing VRAM with the display driver.  Note that when the VDD
;**   doesn't own the controller, this data simply contains the default
;**   settings required by display driver for normal task-time operation.
;**
;**   In other words, the pointer code always restores unreadable registers
;**   directly from these tables.  It does not care who (PM thread, or
;**   windowed graphics VDM thread) it interrupts.
;*/


        public  shadow_data                       ;shadow_data must be the address
        public  shadow_size                       ;of the first "shadowed_xxx" entry

        public  shadowed_seq_indx
        public  shadowed_seq_mode
        public  shadowed_graf_indx
        public  shadowed_graf_rot
        public  shadowed_graf_mode
        public  shadowed_graf_misc

        shadow_data label byte
shadowed_seq_indx   vvreg_s                      <EGA_BASE+SEQ_ADDR,  -1, SEQ_MAP_MASK>
shadowed_seq_mode   vvreg_s                      <EGA_BASE+SEQ_ADDR,  SEQ_MODE, SM_ODD_PLANE OR SM_EXTENDED>
shadowed_graf_indx  vvreg_s                      <EGA_BASE+GRAF_ADDR, -1, GRAF_BIT_MASK>
shadowed_graf_rot   vvreg_s                      <EGA_BASE+GRAF_ADDR, GRAF_DATA_ROT, DR_SET>
shadowed_graf_mode  vvreg_s                      <EGA_BASE+GRAF_ADDR, GRAF_MODE, M_PROC_WRITE OR M_DATA_READ>
shadowed_graf_misc  vvreg_s                      <EGA_BASE+GRAF_ADDR, GRAF_MISC, MS_NON_ALPHA OR MS_A0000_64K>
        shadow_size = ($-shadow_data)/size vvreg_s

;/*
;** The following is data added to support sharing of off-screen memory and
;** the video controller between the PM display driver and the video driver
;** for MVDM.
;**
;** fControllerOwned and fControllerNotify are flags managed jointly by
;** display driver and video driver;  fControllerMine, on the other hand, is
;** set only when fControllerOwned has been set by the display driver.
;**
;** fbOffScreen contains bits describing availability and use of off-screen
;** memory.  If the video driver is loaded, we rely on it for allocation/
;** deallocation of off-screen memory;  otherwise, we are on our own (just
;** like in the good ol' days of 1.1 and 1.2).
;**
;** pOffScreenUsed holds the address of off-screen memory currently in use,
;** and nbOffScreenUsed is the size of that memory (in number of contiguous
;** bytes).  If the display driver ever supports multiple clients of
;** off-screen memory, then it can link blocks of off-screen memory together
;** either with a separate linked list, or by storing links and owner IDs in
;** the blocks themselves.
;**
;** The address kept in pOffScreenUsed is actually an offset from the top of
;** physical VRAM, and must be combined with an appropriate physical VRAM
;** selector/alias before it can be dereferenced.
;**
;** lnbTotalScreenSize is a dword count of the total number of bytes of memory
;** installed on the adapter, divided by the maximum number of planes, to
;** yield the total amount of multi-plane memory available.  For a 256k EGA or
;** VGA, this would be 64k (65536D aka 10000h).
;*/

        public  fVDMControllerMine

fControllerOwned        BYTE    0
fControllerNotify       BYTE    0
fbShadowFlags           BYTE    0
fControllerMine         BYTE    0
fbOffScreen             BYTE    0
fVDMControllerMine      BYTE    0

far_exclude16 PROTO FAR16 SYSCALL
far_unexcelude16 PROTO FAR16 SYSCALL
init_hw_regs16 PROTO FAR16 SYSCALL
InnerCheckCursor PROTO SYSCALL

ifdef SEAMLESS
        PUBLIC  SeamlessStack,SeamlessStackEnd
        ALIGN   4
SeamlessStackGuard      db      4   dup('seam')
SeamlessStack           db      250 dup('_SEAMLESS_STACK_')
SeamlessStackEnd        LABEL   DWORD

EXTERNDEF SM_WINDRV:_SM_WINDRV
EXTERNDEF CurData:CURSORSTRUCT

SM_RING2_16BIT_CODE_MAP    EQU  SM_RING2 OR SM_CODE_ADDRESS OR SM_ADDRESS_16BIT OR SM_MAPPING  OR SM_MATCH_LINEAR
SM_RING2_16BIT_DATA_MAP    EQU  SM_RING2 OR SM_DATA_ADDRESS OR SM_ADDRESS_16BIT OR SM_MAPPING  OR SM_MATCH_LINEAR
SM_RING3_16BIT_CODE_MAP    EQU  SM_RING3 OR SM_CODE_ADDRESS OR SM_ADDRESS_16BIT OR SM_MAPPING  OR SM_MATCH_LINEAR
SM_RING2_16BIT_DATA_PASS   EQU  SM_RING2 OR SM_DATA_ADDRESS OR SM_ADDRESS_16BIT OR SM_PASSTHRU OR SM_MATCH_LINEAR

SM_RING2_32BIT_CODE_MAP    EQU  SM_RING2 OR SM_CODE_ADDRESS OR SM_ADDRESS_32BIT OR SM_MAPPING  OR SM_MATCH_LINEAR
SM_RING2_32BIT_DATA_MAP    EQU  SM_RING2 OR SM_DATA_ADDRESS OR SM_ADDRESS_32BIT OR SM_MAPPING  OR SM_MATCH_LINEAR
SM_RING3_32BIT_CODE_MAP    EQU  SM_RING3 OR SM_CODE_ADDRESS OR SM_ADDRESS_32BIT OR SM_MAPPING  OR SM_MATCH_LINEAR
SM_RING2_32BIT_DATA_PASS   EQU  SM_RING2 OR SM_DATA_ADDRESS OR SM_ADDRESS_32BIT OR SM_PASSTHRU OR SM_MATCH_LINEAR



        public          SM_PMDISP_ADDRESSES
SM_PMDISP_ADDRESSES     _SM_PMDISP_ADDRESSES < SM_RING2_32BIT_CODE_MAP,  SEAM_THUNK_SIZE, OFFSET SeamThunkStart>
                        _SM_PMDISP_ADDRESSES < SM_RING2_32BIT_DATA_MAP,  SEAM_DATA_SIZE , OFFSET SeamDataStart>
smSem                   _SM_PMDISP_ADDRESSES < SM_RING2_32BIT_DATA_MAP,  0fffh          , 0>
smICC                   _SM_PMDISP_ADDRESSES < SM_RING2_32BIT_CODE_MAP,  0fffh          , OFFSET InnerCheckCursor>
smPass                  _SM_PMDISP_ADDRESSES < SM_RING2_32BIT_DATA_PASS, 0              , 0>
smVRAM                  _SM_PMDISP_ADDRESSES < SM_RING2_32BIT_DATA_MAP,  0fffh          , OFFSET pVRAMInstance>
smVRAMVal               _SM_PMDISP_ADDRESSES < SM_RING2_32BIT_DATA_MAP,  0              , 0>
smCurData               _SM_PMDISP_ADDRESSES < SM_RING2_32BIT_DATA_MAP,  0fffh          , OFFSET FLAT:CurData>
smText                  _SM_PMDISP_ADDRESSES < SM_RING2_32BIT_CODE_MAP,  0ffffh         , OFFSET FLAT:_TEXT>
smHWPalette             _SM_PMDISP_ADDRESSES < SM_RING2_32BIT_DATA_MAP,  HW_PAL_SIZE * (SIZE RGB2), OFFSET FLAT:HWPalette>

NUM_SM_ADDRESSES EQU ($-SM_PMDISP_ADDRESSES) / (sizeof _SM_PMDISP_ADDRESSES)
endif ;SEAMLESS

public  SM_SETSIZE

if SCAN_CNT eq 480
SM_SETSIZE              VMSSIZE <, -1, 640, 480, 1, 1, 28h, 14h, 8>
endif
if SCAN_CNT eq 600
SM_SETSIZE              VMSSIZE <, -1, 800, 600, 1, 1, 28h, 14h, 8>
endif
if SCAN_CNT eq 768
SM_SETSIZE              VMSSIZE <, -1, 1024, 768, 1, 1, 28h, 14h, 8>
endif

ifdef SEAMLESS
SEAM_DATA_SIZE EQU $ - SeamDataStart
_SEAMLESSDATA ENDS

else  ;NOT SEAMLESS
DATA_SIZE EQU $ - DataStart
_DATA ENDS

endif ;SEAMLESS

.CODE

page

;/*
;** The following three routines have no application in 256 color mode
;** and therefore were emptied out.
;*/

init_hw_regs PROC SYSCALL USES EDI
init_hw_exit:
        ret
init_hw_regs    ENDP

set_misc_regs PROC SYSCALL
        ret
set_misc_regs  ENDP

set_test_locs PROC SYSCALL
        ret
set_test_locs ENDP



ifdef SEAMLESS

EXTERN   DOS32FLATTOSEL:NEAR

;/***************************************************************************
;*
;* FUNCTION NAME = DeviceSeamlessInit
;*
;* DESCRIPTION   = Prepare for seamless operation
;*
;*
;* INPUT         = pAlias:DWORD
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DeviceSeamlessInit PROC SYSCALL,
        pAlias:DWORD

        LEA     EAX,fControllerOwned
        MOV     SM_WINDRV.fbControllerOwnedOff,AX
        LEA     EAX,fControllerNotify
        MOV     SM_WINDRV.fbControllerNotifyOff,AX
        LEA     EAX,fbShadowFlags
        MOV     SM_WINDRV.fbShadowFlagsOff,AX
        LEA     EAX,fControllerMine
        MOV     SM_WINDRV.fbControllerMineOff,AX
        LEA     EAX,shadowed_graf_mode
        MOV     SM_WINDRV.fbShadowedGrafModeOff,AX

        MOV     AX,CurData.bank_reg               ;this actually isn't initialized yet
        mov     SM_WINDRV.wBankReg,ax             ;because egainit hasn't been called

        MOV     SM_WINDRV.bfPaletteIsFixed,0     ;we are palette aware
        MOV     SM_WINDRV.ulLastPalUpdate,0      ;no updates yet
        MOV     EAX,OFFSET FLAT:HWPalette
        CALL    DOS32FLATTOSEL
        MOV     SM_WINDRV.pHWPalette,EAX

        LEA     EAX,SeamDataStart
        CALL    DOS32FLATTOSEL
        SHR     EAX,16
        MOV     SM_WINDRV.PtrDataSeg,AX

        LEA     EAX,SM_WINDRV
        CALL    DOS32FLATTOSEL
        MOV     smPass.pStart,EAX

        LEA     EAX,InnerCheckCursor
        MOV     smICC.pStart,EAX

        LEA     EAX,pVRAMInstance
        MOV     smVRAM.pStart,EAX

        MOV     EAX,pVRAMInstance       ;now get value
        MOV     smVRAMVal.pStart,EAX
        MOV     smVRAMVal.ulLength,0ffffh


        mov     eax,offset FLAT:CurData            ;          
        mov     smCurData.pStart,eax               ;          
        mov     smCurData.ulLength,0fffh           ;          
                                                   ;          
        mov     eax,offset FLAT:_TEXT              ;          
        mov     smText.pStart,eax                  ;          
        mov     smText.ulLength,0bfffh             ;          


        mov     eax,offset FLAT:HWPalette
        mov     smHWPalette.pStart,eax
        mov     smHWPalette.ulLength,HW_PAL_SIZE * (SIZE RGB2)

        mov     EDX,pAlias
        mov     [EDX].ALIASPARM.ulLen,SIZEOF ALIASPARM
        LEA     EAX,SeamDataStart
        CALL    DOS32FLATTOSEL
        shr     eax,16
        mov     [EDX].ALIASPARM.dsel,ax
        LEA     EDX,SM_WINDRV
        MOV     AX,SEG _SEAMCODE16
        mov     WORD PTR [EDX+06h],AX
        mov     WORD PTR [EDX+0Ah],AX
        mov     WORD PTR [EDX+0Eh],AX

        mov     ax,offset _SEAMCODE16:far_exclude16
        mov     WORD PTR [EDX+04h],AX
        mov     ax,offset _SEAMCODE16:far_unexclude16
        mov     WORD PTR [EDX+08h],AX
        mov     ax,offset _SEAMCODE16:init_hw_regs16
        mov     WORD PTR [EDX+0Ch],AX

        LEA     EAX,smSem
        mov     edx,NUM_SM_ADDRESSES
        ret
DeviceSeamlessInit ENDP
endif ;SEAMLESS

_SEAMCODE16 SEGMENT     PARA USE16 PUBLIC 'CODE'
PUBLIC SeamThunkStart
SeamThunkStart LABEL DWORD

SEAM_THUNK_SIZE EQU 0fffh

;SEAM_THUNK_SIZE EQU $ - OFFSET SeamThunkStart
_SEAMCODE16 ENDS
end
