;SCCSID = @(#)bvfdinit.asm      6.3 91/05/03
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************
        PAGE    58,132
        TITLE   BvsDInit.Asm -- Base Video Subsystem DynLink Iniitialization

;/*********************** START OF SPECIFICATIONS ***********************/
;/*                                                                     */
;/* SOURCE FILE NAME:    BvsDInit.Asm                                   */
;/*                                                                     */
;/* DESCRIPTIVE NAME:    BVS Dynamic Link Initialization                */
;/*                                                                     */
;/* COPYRIGHT:   na                                                     */
;/*                                                                     */
;/* STATUS:      na                                                     */
;/*                                                                     */
;/* NOTES:       Executes on level 3                                    */
;/*                                                                     */
;/*    DEPENDENCIES:     none                                           */
;/*                                                                     */
;/*    RESTRICTIONS:     none                                           */
;/*                                                                     */
;/*    PATCH LABEL:      na                                             */
;/*                                                                     */
;/* ENTRY POINT: BVSDINIT                                               */
;/*                                                                     */
;/* EXTERNAL REFERENCES: None                                           */
;/************************ END OF SPECIFICATIONS ************************/

        .xlist
        INCLUDE bvfcb.inc               ;BVS Data Structures
        INCLUDE error2.inc              ;Error codes
        INCLUDE struc.inc               ;Structured Macros
        .list

        EXTRN   CharFontBegin:FAR       ;Access character font buffer
        EXTRN   CharFontEnd2:FAR        ;Release character font buffer
        EXTRN   InAlDx:FAR              ;Read one status byte
        EXTRN   InAxDx:FAR              ;Read one status word
        EXTRN   PVBSelector:NEAR        ;Allocate PVB selector
        EXTRN   ReadEGASwitches:FAR     ;Read the EGA switches


XGASYSSEG SEGMENT PARA PUBLIC 'DATA'    ; XGASYS data segment                  ;@V2.1JLO01
        XGASYSDD     DB    "$$$XGA20"   ; Name of XGASYS device driver         ;@V2.1JLO01
        XGASYSHandle DW     ?           ; XGASYS File Handle                   ;@V2.1JLO01
        DMQSArray    DMQSDataS 8 dup (<>) ; 8 DMQS data structures             ;@V2.1JLO01
        pDMQSArray   DD     DMQSArray   ; DMQS data structure Pointer          ;@V2.1JLO01
        DMQSSvc      DW     1Ch         ; Service to get to DMQS data          ;@V2.1JLO01
XGASYSSEG ENDS                                                                 ;@V2.1JLO01

BVSDSEG SEGMENT PARA PUBLIC 'DATA'      ;Global data segment
PS2FnSt dw      32 dup (0)              ;PS2 Functionality/State Info Buf ;@@Z
BVSDSEG ENDS


BVSNSEG SEGMENT PARA PUBLIC 'DATA'      ;Instance data segment
BVSNSEG ENDS

BVS3SEG SEGMENT BYTE PUBLIC 'CODE'
        ASSUME  CS:BVS3SEG

;/*********************** START OF SPECIFICATIONS ***********************/
;/*                                                                     */
;/* SUBROUTINE NAME:     BVSDINIT                                       */
;/*                                                                     */
;/* DESCRIPTIVE NAME:    Initialize BVS                                 */
;/*                                                                     */
;/* FUNCTION:   Perform all global BVS initialization.                  */
;/*                                                                     */
;/* NOTES:      Executes on level 3.                                    */
;/*                                                                     */
;/* ENTRY POINT:  BVSDINIT                                              */
;/*   LINKAGE:  Call BVSDINIT from BVSDINIT                             */
;/*                                                                     */
;/* INPUT:  None                                                        */
;/*                                                                     */
;/* EXIT-NORMAL:  AX = -1                                               */
;/*                                                                     */
;/* EXIT-ERROR:  None                                                   */
;/*                                                                     */
;/* EFFECTS:    None                                                    */
;/*                                                                     */
;/* INTERNAL REFERENCES: None                                           */
;/*   ROUTINES:  GetScrHandle, BvsGetHW, CPInit                         */
;/*                                                                     */
;/* EXTERNAL REFERENCES: CDIB                                           */
;/*   ROUTINES:  DOSOPEN, DOSCLOSE, DOSGETSHRSEG                        */
;/************************ END OF SPECIFICATIONS ************************/
;
;Bgnsub BVSDINIT
;: Call GetScrHandle to open the Screen DD
;: Call BvsGetHW to get the video hardware configuration
;: Check for CodePage support
;: If CodePage support in system
;: : Call CPInit to initialize BVS CodePage support
;: Endif
;: Record the presence or absence of the Mouse
;Endsub

BVSDINIT PROC   NEAR
        PUBLIC  BVSDINIT

        sub     bx,bx                   ;Ensure BX = 0

        mov     ax,bvsnseg
        mov     es,ax                   ;ES = PPBVSCB
        Call    BvsGetHW                ;Get the video configuration

        push    es
        pop     ds                      ;DS = PPBVSCB
        mov     ax,bvsdseg
        mov     es,ax                   ;Get selector of common segment
        mov     es:[bx].cmn_devtypes,di ;Save the device types

        test    di,NOT (aioflag+mouflag) ;@@Z
        .if     nz near                 ;Some displays found
            mov     es:[bx].cmn_bvscbsize,0FFFEh and (1+size bvscb)
        .endif                          ;Some displays found
        RET
BVSDINIT ENDP

;/*********************** START OF SPECIFICATIONS ***********************/
;/*                                                                     */
;/* SUBROUTINE NAME:  BvsGetHW                                          */
;/*                                                                     */
;/* DESCRIPTIVE NAME:  Get Video Hardware Configuration                 */
;/*                                                                     */
;/* FUNCTION:  Places the current video configuration in DI             */
;/*                                                                     */
;/* NOTES:  Executes on Level 3                                         */
;/*                                                                     */
;/* ENTRY POINT:  BvsGetHW                                              */
;/*   LINKAGE:  Call BvsGetHW from BVSDINIT                             */
;/*                                                                     */
;/* INPUT:  DS = Common data selector                                   */
;/*                                                                     */
;/* EXIT-NORMAL:  AX = 0                                                */
;/*                                                                     */
;/* EXIT-ERROR:  None                                                   */
;/*                                                                     */
;/* EFFECTS:  None                                                      */
;/*                                                                     */
;/* INTERNAL REFERENCES:  PPBVSCB, BVSCBsg, LVBsg                       */
;/*   ROUTINES:  None                                                   */
;/*                                                                     */
;/* EXTERNAL REFERENCES:  None                                          */
;/*   ROUTINES:  None                                                   */
;/*                                                                     */
;/************************ END OF SPECIFICATIONS ************************/

;Bgnsub BvsGetHW
;: Call PVBSelector to get access to B0000 (MPA/CGA buffers)
;: Fill the buffer with 0/0
;: If Memory present at B0000
;: : Mark presence of MPA
;: Endif
;: If Memory present at B8000
;: : Mark presence of CGA
;: Endif
;: Call PVBSelector to get access to A0000 (Font buffer)
;: Call CharFontBegin to move the EGA buffer to A0000
;: If Memory present at A0000 (EGA+ present)
;: : Compute buffer size by checking presence of 16K memory blocks
;: : Call PVBSelector to get access to C0000 (EGA ROM)
;: : Scan ROM for locations of 8x8, 8x14, 8x16, 9x14, and 9x16 fonts
;: : Call ReadEGASwitches to get the EGA switches
;: : If Less fonts found than on an EGA (VGA)
;: : : Change flags to record VGA
;: : : Call DOSDEVIOCTL to read ROM font information
;: : : If no error
;: : : : Set alternate I/O flag
;: : : : Move ROM font information to common area
;: : : Endif
;: : Elseif 9-byte card id at CA000 (BRECON)
;: : : Change flags to record BRECON card
;: : : Call InAlDx to check the BRECON queue status
;: : : If successful
;: : : : Set Advanced Function flag
;: : : Endif
;: : Else
;: : : Change flags to record EGA configuration
;: : Endif
;: : Call CharFontEnd to restore video mapping
;: Endif
;Endsub

BvsGetHW PROC   NEAR
        push    bp

        mov     es:[bx].ppbvs_physaddrl,bx     ; @tb25
        mov     es:[bx].ppbvs_physaddrh,0000Ah ; @tb25  EGA/VGA test
        mov     es:[bx].ppbvs_length,bx        ; @tb25
        mov     es:[bx].ppbvs_lenhigh,bx       ; @tb25
        Call    PVBSelector             ; @tb25 Get access to A000:0

        sub     cx,cx                   ; @tb25 Use cx for buf cnt
        sub     di,di                   ; @tb25 Clear the flag word
        sub     si,si                   ; @tb25 Clear the buffer offset
        mov     ds,es:[bx].ppbvs_pvbsel ; @tb25 Get selector of PVB
        Call    ChangeBuffer            ; @tb25
        .if     z and                   ; @tb25 match
        Call    ChangeBuffer
        .if     z                       ; @tb25 Bytes still match
            inc     cx                  ; @tb25 Increment buf count
        .endif


        mov     es:[bx].ppbvs_physaddrl,bx
        mov     es:[bx].ppbvs_physaddrh,0000Bh ;Prepare for CGA/MONO test
        mov     es:[bx].ppbvs_length,bx
        mov     es:[bx].ppbvs_lenhigh,bx

        push    cx

        Call    PVBSelector             ;Get access to B000:0 to B000:FFFF

        pop     cx                      ;@tb25 Get buf count
        sub     di,di                   ;Clear the flag word
        sub     si,si                   ;Clear the buffer offset
        mov     ds,es:[bx].ppbvs_pvbsel ;Get selector of PVB
        Call    ChangeBuffer
        .if     z and                   ;Bytes match
        Call    ChangeBuffer
        .if     z                       ;Bytes still match
            or      di,mpaflag          ;Record presence of MPA
            inc     cx                  ;@tb25 Increment buf count
        .endif

        add     si,08000h               ;Point to CGA buffer
        Call    ChangeBuffer
        .if     z and                   ;Bytes match
        Call    ChangeBuffer
        .if     z                       ;Bytes still match
            or      di,cgaflag          ;Record presence of CGA card
            inc     cx                  ;@tb25 Increment buf count
        .endif

        push    es
        mov     ax,bvsdseg
        mov     ds,ax                   ;Get Common selector
        mov     ds:[bx].cmn_devtypes,cx ;@tb25 Save buffer count here
                                        ; temporarily since it gets
                                        ; written on return to bvsdinit...

        push    di
        mov     es,bx
        mov     di,bx                   ;ES:DI = 0:0
        mov     ah,0FEh
        int     10h                     ;Call Topview
        mov     ax,es
        or      ax,di                   ;Check for bits on
        pop     di
        .if     nz
            or      di,aioflag          ;Indicate TopView in system
        .endif

        mov     bh,3
        mov     si,cmn_font8x8
        Call    GetBiosFont
        .if     nz
            mov     [si+4],0800h
        .endif

        mov     bh,2
        mov     si,cmn_font8x14
        Call    GetBiosFont

        mov     bh,5
        mov     si,cmn_font9x14
        Call    GetBiosFont

        mov     bh,6
        mov     si,cmn_font8x16
        Call    GetBiosFont
        .if     nz
            mov     [si+4],1000h
        .endif

        mov     bh,7
        mov     si,cmn_font9x16
        Call    GetBiosFont

        mov     ah,12h
        mov     bl,10h
        int     10h                     ;Get EGA information

        .if     <bl b 10h> near         ;EGA Bios in system
            sub     si,si
            .if     <[si].cmn_font9x14+4 eq si> or ;Less fonts or
            .if     <[si].cmn_font9x16+4 ne si> ;More fonts than EGA
                push    ds              ;@S2
                push    di              ;save previous adapter types    ;@C35

                mov     ax,bvsdseg      ;@@Z
                mov     es,ax           ;@@Z
                mov     di,offset PS2FnSt ;Set info return addr ;@@Z
                sub     bx,bx           ;@@Z
                mov     ax,1B00h        ;Get video state info ;@@Z
                int     10h             ;Call PS2 Bios ;@@Z

                mov     bx,di           ;@@Z
                pop     di              ;previous adapter types found   ;@C35
;@C35***********mov     di,vgcflag      ;Preset analog color ;@@Z
                mov     al,es:[bx+25h]  ;Get Display Combination Code ;@@Z
                .if     <al eq 07h> or  ;@@Z
                .if     <al eq 0Bh>     ;@@Z
;@C35***************mov     di,vgmflag  ;Preset analog mono ;@@Z
                    test    byte ptr es:[bx+2Dh],40h ;@@Z
                    .if     nz          ;@@Z
                        mov     di,vgpflag ;Note PDP presence ;@@Z
                    .else                            ;set VGA mono      ;@C35
;@tb25******************xor     di,mpaflag OR vgmflag                   ;@C35
;@tb25 Check # of buffers (temporarily stored in cmn_devtypes...)       ;@tb25
;@tb25 If only one buffer, then it must be vga mono
;@tb25 Otherwise, check for the mpaflag set, and if so, set if off
                        .if   < [si].cmn_devtypes eq 1 >                ;@tb25
                            mov     di,vgmflag                          ;@tb25
                        .else                                           ;@tb25
                            or      di,vgmflag                          ;@tb25
                            test    di,mpaflag                          ;@tb25
                            .if    nz                                   ;@tb25
                                 xor    di,mpaflag                      ;@tb25
                            .endif                                      ;@tb25
                        .endif                                          ;@tb25
                    .endif              ;@@Z
                .else                                ;set VGA color     ;@C35
;@tb25************* xor     di,cgaflag OR vgcflag                       ;@C35
;@tb25 Check # of buffers (temporarily stored in cmn_devtypes...)       ;@tb25
;@tb25 If only one buffer, then it must be vga color
;@tb25 Otherwise, check for the cgaflag set, and if so, set if off
                    .if   < [si].cmn_devtypes eq 1 >                    ;@tb25
                         mov     di,vgcflag                             ;@tb25
                    .else                                               ;@tb25
                         or      di,vgcflag                             ;@tb25
                         test    di,cgaflag                             ;@tb25
                         .if    nz                                      ;@tb25
                               xor     di,cgaflag                       ;@tb25
                         .endif                                         ;@tb25
                    .endif                                              ;@tb25
                .endif                  ;@@Z

                mov     al,es:[bx+31h]  ;Get video memory ;@@Z
                inc     al              ;@@Z
                mov     byte ptr [si].cmn_devmemsz+2,al ;Set in common ;@@Z

                Call    ReadXGA         ;Get XGA  status ;XGA

                Call    Read8514        ;Get 8514 status ;@@Z

                pop     ds              ;@S2
            .else
                mov     al,cl           ;Get switches for testing
                xor     al,0Fh          ;Invert the bits
                .if     <al a 9>
                    sub     al,6        ;Ignore primary/secondary
                .endif
                .if     <al be 05h>
                    xor     di,mpaflag OR egmflag
                .else
                    .if     <al be 7>   ;EGA with ECD
                        xor     di,cgaflag OR egaflag
                    .else               ;EGA with CD
                        xor     di,cgaflag OR egcflag
                    .endif
                .endif
                inc     bl              ;Get high word of memsize ;@@Z
                mov     byte ptr [si].cmn_devmemsz+2,bl ;Save in common ;@@Z
            .endif
        .endif

        pop     es
        sub     bx,bx                   ;Restore base reg
        pop     bp
        RET
BvsGetHW ENDP

;B717847 ChangeBuffer PROC NEAR
;B717847        mov     ax,[si]
;B717847        xor     ax,-1
;B717847        mov     [si],ax                 ;Restore them again
;B717847        push    ds
;B717847        pop     ds                      ;Waste some time so memory can settle
;B717847        cmp     ax,[si]                 ;See if the change remains
;B717847        ret
;B717847 ChangeBuffer ENDP

ChangeBuffer PROC NEAR                                              ;B717847
        mov     ax,[si]                                             ;B717847
        xor     ax,055aah                                           ;B717847
        mov     [si],ax                 ;Restore them again         ;B717847
        xor     [si]+16,0aa55h                                      ;B717847
        cmp     ax,[si]                 ;See if the change remains  ;B717847
        ret                                                         ;B717847
ChangeBuffer ENDP                                                   ;B717847

GetBiosFont PROC NEAR                   ;Get font info from BIOS
        sub     bp,bp
        mov     ax,1130h
        int     10h                     ;Call Bios
        and     bp,bp
        .if     nz and                  ;Font found and
        .if     <<word ptr es:[bp+2]> eq 0> ;Probably good
            mov     [si],bp             ;Save Offset
            mov     ax,es
            mov     cl,12
            shr     ax,cl
            mov     [si+2],ax           ;Convert to 32-bit addr
            mov     [si+4],0E00h        ;Save default length
        .endif
        ret
GetBiosFont ENDP

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: ReadXGA                                           */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: ReadXGA configuration                            */
;/*                                                                     */
;/*  FUNCTION: Search until the 1st XGA adapter found beginning from    */
;/*            the planar and then slot 1 to 8.  Once an XGA adapter    */
;/*            is found, query which display is attached.               */
;/*                                                                     */
;/*  ENTRY POINT: ReadXGA                                               */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: None                                                        */
;/*                                                                     */
;/*  EXIT-NORMAL: AL = display type  ( Color8514, Color8512_8513, etc)  */
;/*               AH = memory size ( 0 - 512k, 1 - 1MB )                */
;/*                                                                     */
;/*  EXIT-ERROR:  AX = VDHERROR_NO_ADAPTER                              */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/

        PUBLIC  ReadXGA
ReadXGA PROC NEAR

        cli                             ; Disable interrupt                ;XGA
        in      al, 94h                 ; Read planar POS                  ;XGA
        mov     bl, al                  ; Save planar setting              ;XGA
        mov     al, 0DFh                ;                                  ;XGA
        out    94h, al                  ; Put planar into setup mode       ;XGA
                                                                           ;XGA
        mov     dx, 100h                ;                                  ;XGA
        in      ax, dx                  ; Get POS ID                       ;XGA
        .if     <ax eq 8FDBh>           ; XGA on planar?                   ;XGA
            call    GetMonID            ; On return: AX = Monitor ID value ;XGA
            mov     cx, ax              ;                                  ;XGA
            mov     al, bl              ;                                  ;XGA
            out    94h, al              ; Restore planar setting           ;XGA
        .else                           ;                                  ;XGA
            mov     al, bl              ;                                  ;XGA
            out    94h, al              ; Restore planar setting           ;XGA
            in      al, 96h             ; Read card slot setting           ;XGA
            mov     bl, al              ; Save current card slot setting   ;XGA
            mov     cx, 08h             ; Start with card slot 0 (bit 0-3) ;XGA
            .repeat                     ; Search up to 8 card slots for an ;XGA
                mov     al, cl          ;   XGA with a display attached    ;XGA
                out    96h, al          ; Put card slot into setup mode    ;XGA
                in      ax, dx          ; Get POS ID from slot             ;XGA
;JLO110293      cmp     ax, 8FDBh       ;                                  ;XGA
;JLO            .if     < z >           ; XGA found?                       ;XGA
                .if   <ax ge 8FD8h> and ; XGA found?                       ;XGA
                .if   <ax le 8FDBh>     ;                                  ;XGA
                    mov     ax, 0       ; Set up AX for repeat loop check  ;XGA
                    call    GetMonID    ; On return: AX = Monitor ID value ;XGA
                .else                   ;            AX = 0 means no disp  ;XGA
                    mov     ax, 0       ; Set up AX for repeat loop check  ;XGA
                .endif                  ;                                  ;XGA
            .until  <nonzero ax> or     ; XGA found                        ;XGA
            inc     cx                  ; Next slot                        ;XGA
            .until  <cx a 0Fh>          ; Search all 8 slots?              ;XGA
            mov     cx, ax              ;                                  ;XGA
            mov     al, bl              ;                                  ;XGA
            out    96h, al              ; Restore card slot setting        ;XGA
        .endif                          ;                                  ;XGA
        sti                                                                ;XGA
        mov     ax, cx                  ; Return VIO monitor ID value      ;XGA
        ret                                                                ;XGA
ReadXGA ENDP

Mon_Table   label   word
                public  Mon_Table

        db      00h                     ; 0000                             ;XGA
        db      00h                     ; 0001                             ;XGA
        db      00h                     ; 0010                             ;XGA
        db      00h                     ; 0011                             ;XGA
        db      00h                     ; 0100  5081                       ;XGA
        db      00h                     ; 0101  Buffalo                    ;XGA
        db      00h                     ; 0110                             ;XGA
        db      00h                     ; 0111  Boston                     ;XGA
        db      00h                     ; 1000                             ;XGA
        db      0Bh                     ; 1001  8604, 8507                 ;XGA
        db      09h                     ; 1010  8514                       ;XGA
        db      0Ch                     ; 1011  8515 (Dallas)              ;XGA
        db      00h                     ; 1100                             ;XGA
        db      03h                     ; 1101  8503                       ;XGA
        db      04h                     ; 1110  8513, 8512                 ;XGA
        db      00h                     ; 1111  No monitor attached        ;XGA

GetMonID PROC NEAR                                                         ;XGA

        mov     dx, 102h                ;                                  ;XGA
        in      al, dx                  ; Read POS 102                     ;XGA
        and     ax, 0Eh                 ; IODA is located in bit 1-3       ;XGA
                                                                           ;XGA
        mov     dx, cx                                                     ;XGA
        mov     cl, 3                                                      ;XGA
                                                                           ;XGA
        shl     ax, cl                  ; Use bit 1-3 to form IO address   ;XGA
                                                                           ;XGA
        mov     cx,dx                                                      ;XGA
                                                                           ;XGA
        mov     dx, 210Ah               ; Base IO address                  ;XGA
        or      dx, ax                  ; Form Device IO address (21xA)    ;XGA
        mov     al, 52h                 ;                                  ;XGA
        out     dx, al                  ; Index to Monitor ID address      ;XGA
        inc     dx                      ; Device Data address              ;XGA
        in      al, dx                  ; Get Monitor ID bits              ;XGA
        and     ax, 0Fh                 ; Clear the unwanted bits          ;XGA

        .if     <al  e  15>             ; 95xx monitor? or None attached?      ;@V2.1JLO01
                                        ; AL equals ff in both instances       ;@V2.1JLO01
          push      bx                  ; Preserve bx                          ;@V2.1JLO01
          push      dx                  ; Preserve dx                          ;@V2.1JLO01
          push      ds                  ; Preserve ds                          ;@V2.1JLO01
          push      si                  ; Preserve si                          ;@V2.1JLO01
          push      cx                  ; Preserve cx                          ;@V2.1JLO01
                                                                               ;@V2.1JLO01
          assume    ds:XGASYSSEG        ; Get Addressability to the data seg   ;@V2.1JLO01
          mov       ax, XGASYSSEG       ;                                      ;@V2.1JLO01
          mov       ds, ax              ;                                      ;@V2.1JLO01
                                                                               ;@V2.1JLO01
          mov       dx, OFFSET XGASYSDD ; XGASYS device driver                 ;@V2.1JLO01
                                                                               ;@V2.1JLO01
          mov       ah, 3Dh             ; Function - Open a File               ;@V2.1JLO01
          mov       al, 0C0h            ; OpenMode 11000000b = No Inherit,     ;@V2.1JLO01
                                        ; DenyNone, ReadOnly                   ;@V2.1JLO01
          int       21h                 ; Interrupt 21                         ;@V2.1JLO01
          jc        XGASYS_DMQS_ERR     ; CF Set on error                      ;@V2.1JLO01
                                                                               ;@V2.1JLO01
          mov       XGASYSHandle, ax    ; Save handle                          ;@V2.1JLO01
                                                                               ;@V2.1JLO01
          mov       ah, 44h             ; Function - IOCtl                     ;@V2.1JLO01
          mov       al, 0Ch             ; SubFunction - Generic Char Dev Req   ;@V2.1JLO01
          mov       bx, XGASYSHandle    ; handle                               ;@V2.1JLO01
          mov       ch, 81h             ; Category number of XGA.SYS IOCtl.    ;@V2.1JLO01
          mov       cl, 41h             ; General Function Service             ;@V2.1JLO01
          lds       dx, pDMQSArray      ; Set Data Packet to DMQS data struc   ;@V2.1JLO01
          mov       si, ds              ; Set Parm Packet Seg to same data seg ;@V2.1JLO01
          mov       di, OFFSET DMQSSvc  ; Service (1ch) to get to DMQS data    ;@V2.1JLO01
                                                                               ;@V2.1JLO01
          int       21h                 ; Interrupt 21                         ;@V2.1JLO01
          jc        XGASYS_DMQS_ERR     ; CF Set on error                      ;@V2.1JLO01
                                                                               ;@V2.1JLO01
          mov       ah, 3Eh             ; Function - Close a File              ;@V2.1JLO01
          mov       bx, XGASYSHandle    ; handle                               ;@V2.1JLO01
          int       21h                 ; Interrupt 21                         ;@V2.1JLO01
          jc        XGASYS_DMQS_ERR     ; CF Set on error                      ;@V2.1JLO01
                                                                               ;@V2.1JLO01
          pop       cx                  ; Contains Slot nbr (8H thru 0FH)      ;@V2.1JLO01
          push      cx                  ; Preserve cx                          ;@V2.1JLO01
          sub       cx, 7               ; Convert to DMQS Slot nbr (1 thru 8)  ;@V2.1JLO01
                                        ; data block - DMQS data               ;@V2.1JLO01
          mov       bx, OFFSET DMQSArray                                       ;@V2.1JLO01
          mov       dx, SIZEOFDMQSDataS ; DMQS structure size                  ;@V2.1JLO01
          xor       si, si                                                     ;@V2.1JLO01
          xor       ax, ax                                                     ;@V2.1JLO01
          .repeat                                                              ;@V2.1JLO01
                                                                               ;@V2.1JLO01
            mov     al, ds:[bx][si].slot_number                                ;@V2.1JLO01
            .if     <cx eq ax>          ; Match the Slots (8 vs 1, 9 vs 2,...) ;@V2.1JLO01
                                                                               ;@V2.1JLO01
              mov     ax, ds:[bx][si].monitor_id                               ;@V2.1JLO01
                                                                               ;@V2.1JLO01
              .if     <ax eq COMP_ID_9515> or                                  ;@V2.1JLO01
              .if     <ax eq COMP_ID_9517>                                     ;@V2.1JLO01
                                        ; Set the same as XGA with 8514...     ;@V2.1JLO01
                                        ; New flag/value was NOT created since ;@V2.1JLO01
                mov     di ,xgaflag3    ; all we want to do is set to 2000+nnn ;@V2.1JLO01
                                        ; where nnn is the monitor.  bvfcb.inc ;@V2.1JLO01
                                        ; current flag values were NOT expanded;@V2.1JLO01
                jmp     XGASYS_DMQS_EXIT                                       ;@V2.1JLO01
              .else                                                            ;@V2.1JLO01
                jmp     XGASYS_DMQS_ERR ; Monitor unknown                      ;@V2.1JLO01
              .endif                                                           ;@V2.1JLO01
            .endif                                                             ;@V2.1JLO01
                                                                               ;@V2.1JLO01
            add     si, dx              ; Point to the next DMQS struc, if any ;@V2.1JLO01
          .until  <[bx][si].next_DMQS_offset eq 0>                             ;@V2.1JLO01
                                                                               ;@V2.1JLO01
XGASYS_DMQS_ERR:                                                               ;@V2.1JLO01
          mov       ax, 0               ; No monitor information was found     ;@V2.1JLO01
                                                                               ;@V2.1JLO01
XGASYS_DMQS_EXIT:                                                              ;@V2.1JLO01
          assume    ds:NOTHING                                                 ;@V2.1JLO01
          pop       cx                  ; Restore cx                           ;@V2.1JLO01
          pop       si                  ; Restore si                           ;@V2.1JLO01
          pop       ds                  ; Restore ds                           ;@V2.1JLO01
          pop       dx                  ; Restore dx                           ;@V2.1JLO01
          pop       bx                  ; Restore bx                           ;@V2.1JLO01
          ret                           ; AX determines if READXGA looks at    ;@V2.1JLO01
        .endif                          ; any other Slots (0 = keep looking)   ;@V2.1JLO01

        mov     si, OFFSET Mon_Table    ; Setup offset to Mon ID table     ;XGA
        add     si, ax                  ; Form index into the Mon ID table ;XGA
        mov     al, BYTE PTR cs:[si]    ; Return VIO Monitor ID            ;XGA

        .if     <al e   9>                                                 ;XGA
            mov     di,xgaflag3 ;XGA with 8514                             ;XGA
        .endif                                                             ;XGA
        .if     <al e   3>                                                 ;XGA
            mov     di,xgaflag1 ;XGA with 8503                             ;XGA
        .endif                                                             ;XGA
        .if     <al e   4>                                                 ;XGA
            mov     di,xgaflag2 ;XGA with 8512/3                           ;XGA
        .endif                                                             ;XGA
        .if     <al e  11>                                                 ;XGA
            mov     di,xgaflag4 ;XGA with Type 11                          ;XGA
        .endif                                                             ;XGA
        .if     <al e  12>                                                 ;XGA
            mov     di,xgaflag0+xg2flag ;XGA with Type 12       ;B722413   ;XGA
         ;;;mov     di,xgaflag0 ;XGA with Type 12               ;B722413   ;XGA
        .endif                                                             ;XGA

        ret
GetMonID ENDP

Read8514 PROC   NEAR                    ;Get 8514 configuration in DI ;@@Z
        public  Read8514                ;@@Z

        mov     dx, 9AE9h               ;High byte of status reg ;D184
        in      al, dx                  ;Read 8514 Queue Status Reg ;D184
        test    al, 20h                 ;D184
        .if     <z>                     ;Not busy ;D184
            mov     dx,92E8h            ;@@Z
            mov     ax,5555h            ;@@Z
            out     dx,ax               ;@@Z
            in      ax,dx               ;@@Z
            .if     <ax eq 5555h>       ;8514 found ;@@Z
                mov     dx,42E8h        ;@@Z
                in      al,dx           ;Get display info ;@@Z

                mov     ah,al           ;@@Z
                and     al,70h          ;@@Z
                .if     <al ne 70h>     ;Display attached to 8514/A ;@@Z
                    .if     <al eq 10h> ;D184
                        mov     di,xg1flag ;8514/A with Type 11 ;D184
                    .endif              ;D184
                    .if     <al e 20h>  ;@@Z
                        mov     di,xgaflag ;8514/A with 8514 ;@@Z
                    .endif              ;@@Z
                    .if     <al eq 30h> ;D184
                        mov     di,xg2flag ;8514/A with Type 12 ;D184
                    .endif              ;D184
                    .if     <al e 50h>  ;@@Z
                        mov     di,xgmflag ;8514/A with 8503 ;@@Z
                    .endif              ;@@Z
                    .if     <al e 60h>  ;@@Z
                        mov     di,xgcflag ;8514/A with 8512/3 ;@@Z
                    .endif              ;@@Z

                    mov     byte ptr [si].cmn_devmemsz+2,8 ;Preset 512KB ;@@Z
                    test    ah,80h      ;@@Z
                    .if     nz          ;@@Z
                        mov     byte ptr [si].cmn_devmemsz+2,16 ;Set 1MB ;@@Z
                    .endif              ;@@Z
                .endif                  ;@@Z
            .endif                      ;@@Z
        .endif                          ;@@Z

        ret                             ;@@Z
Read8514 ENDP                           ;@@Z

BVS3SEG ENDS
        END                             ;BVSDINIT

;@@Z  = 07/17/88 STJ, Add flags for other VGA types
;D184 = 04/10/89 STJ, Identify other 8514 displays, B701002
;@C35 = 10/11/89 CJJ, Allow other adapters with VGA, B709049
;@tb25 = 11/03/89 TLB, Check # of bufs found and flags to determine cmn_devtypes
;         B709366
;@XGA = 08/21/90 WKB, Support XGA in 3xBox, B715181
;B717847 = 10/22/90 WKB, Identify video buffers on 486 machines, B717847
;B722413 = 05/03/91 WKB, Correct flags for XGA device type, B722413
;PJ09090 = 11/02/93 JLO, XGA POS ID now compared with 8FD8h - 8FDBh range to
;                        determine if it is as XGA-2 adapter (Defect 70631)
;@V2.1JLO01 01/19/94 76799 : Get DMQS Composite Monitor ID via XGA.SYS DevIoctl
