⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 videoid.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;
; Name:         VideoID
;
; Function:     Detects the presence of various video subsystems and
;                associated monitors.
;
; Caller:       Microsoft C:
;
;                       void VideoID(VIDstruct);
;
;                       struct
;                       {
;                         char VideoSubsystem;
;                         char Display;
;                       }
;                               *VIDstruct[2];
;
;               Subsystem ID values:
;                                0  = (none)
;                                1  = MDA
;                                2  = CGA
;                                3  = EGA
;                                4  = MCGA
;                                5  = VGA
;                                6  = 8514/A
;                                7  = XGA
;                               80h = HGC
;                               81h = HGC+
;                               82h = Hercules InColor
;
;               Display types:   0  = (none)
;                                1  = MDA-compatible monochrome
;                                2  = CGA-compatible color
;                                3  = EGA-compatible color
;                                4  = PS/2-compatible monochrome
;                                5  = PS/2-compatible color
;                                6  = 8514/A Monitor
;
;
;       The values returned in VIDstruct[0].VideoSubsystem and
;       VIDstruct[0].Display indicate the currently active subsystem.
;
;----------------------------------------------------------------------------


cssize equ 2    ;Used for small memory model

ARGpVID         EQU     [bp+4+cssize]   ; Pointer to structure

VIDstruct       STRUC                   ; corresponds to C data structure

Video0Type      DB      ?               ; first subsystem type
Display0Type    DB      ?               ; display attached to first
                                        ;  subsystem
Mode0           DB      ?               ; Mode of first subsystem
NumCols0        DB      ?               ; Number of columns on first
iMemory0        DW      ?               ; Memory in first system
Video1Type      DB      ?               ; second subsystem type
Display1Type    DB      ?               ; display attached to second
                                        ;  subsystem
Mode1           DB      ?               ; Mode of second subsystem
NumCols1        DB      ?               ; Number of columns on second
iMemory1        DW      ?               ; Memory in second system

VIDstruct       ENDS


Device0          EQU     word ptr Video0Type[di]
Device1          EQU     word ptr Video1Type[di]


MDA              EQU     1               ; subsystem types
CGA              EQU     2
EGA              EQU     3
MCGA             EQU     4
VGA              EQU     5
Eighty514        EQU     6
XGA              EQU     7
HGC              EQU     80h
HGCPlus          EQU     81h
InColor          EQU     82h

MDADisplay       EQU     1               ; display types
CGADisplay       EQU     2
EGAColorDisplay  EQU     3
VGAMonoDisplay   EQU     4
VGAColorDisplay  EQU     5
Eighty514Display EQU     6

TRUE             EQU     1
FALSE            EQU     0


DGROUP          GROUP   _DATA

_TEXT           SEGMENT byte public 'CODE'
                ASSUME  cs:_TEXT,ds:DGROUP

                PUBLIC  _VideoID
                EXTRN   C ArcnetCardPresent:FAR

_VideoID        PROC    far

                push    bp              ; preserve caller registers
                mov     bp,sp
                push    es              ; Save caller's ES
                push    si
                push    di

; initialize the data structure that will contain the results

                les     di,ARGpVID  ; ES:DI -> start of data structure

                mov     es:Device0,0       ; zero these variables
                mov     es:Device1,0

; look for the various subsystems using the subroutines whose addresses are
;  tabulated in TestSequence; each subroutine sets flags in TestSequence
;  to indicate whether subsequent subroutines need to be called

                mov     byte ptr TestSequence,TRUE
                mov     byte ptr XGAflag,FALSE
                mov     byte ptr Eighty514flag,FALSE
                mov     byte ptr EGAflag,TRUE
                mov     byte ptr CGAflag,TRUE
                mov     byte ptr Monoflag,TRUE

                mov     cx,NumberOfTests
                mov     si,offset DGROUP:TestSequence

L01:            lodsb                   ; AL := flag
                test    al,al
                lodsw                   ; AX := subroutine address
                jz      L02             ; skip subroutine if flag is false

                push    si
                push    cx
                call    ax              ; call subroutine to detect
                                        ;  subsystem
                pop     cx
                pop     si

L02:            loop    L01

; determine which subsystem is active

                call    FindActive

                pop     di              ; restore caller registers and
                                        ;  return
                pop     si
                pop     es
                mov     sp,bp
                pop     bp
                ret

_VideoID        ENDP


; FindXGA
;
; Note:  XGA adapters MAY be able to be detected by checking port
; 2110H.  Read the port, toggle bit 0, write to the port, wait,
; read the port and see if the port's value is the changed.  If it
; did, it is an XGA.  Don't forget to toggle the bit back again,
; and it might not hurt to disable interrupts (CLI) during the check.
;
; Bit 0 toggles the XGA's coprocessor between Intel and Motorola
; modes (backwards storage for 16 and 32 bit values).  Also, the XGA
; standard allows for up to six XGA adapters to exist in a system
; at one time, each port address is 16 (10H) higher than the other.
; Checking 2120H, 2130H, 2140H, 2150H, and 2160H may be well advised.
;
; In the short time we had to hand over our code, I was not able to
; determine how to detect the monitor type attached to the XGA.
; Sorry about that.  Also, I was not able to test this XGA detection
; theory out (except to see that VGAs did NOT retain the toggling of
; bit zero).
;


FindXGA         PROC    near

         mov  bx, OFFSET DGROUP:rgXgaPorts ; Store the XGA port address array location

XgaTestLoop:
         mov  dx, [bx]            ; Get the XGA's port address
         and  dx, dx              ; Jump out if it's zero
         jz   fnXgaDone

         in   al, dx              ; Read the port
         mov  ch, al              ; Store the "original" port value

         xor  al, 1               ; change bit 0

         cli                      ; Clear all interrupts.  This is
                                  ;   important because this routine
                                  ;   changes the way the XGA functions.

         out  dx, al              ; Output the new value to the XGA port.

         jmp  short XgaWait01     ; Pause briefly, to allow the change
XgaWait01:                        ;   to take effect.
         jmp  short XgaWait02
XgaWait02:
         jmp  short XgaWait03
XgaWait03:

         in   al, dx              ; Get the "changed" value from the port.
         mov  cl, al              ; Store the "changed" value.

         mov  al, ch              ; Send the "original" back to the port.
         out  dx, al

         jmp  short XgaWait04     ; Pause briefly, to allow the change
XgaWait04:                        ;   to take effect.
         jmp  short XgaWait05
XgaWait05:
         jmp  short XgaWait06
XgaWait06:

         sti                      ; Restore all interrupts.

; I consider it a sucessful test if only bit zero changed.  More changes
;   might indicate that I am communicating with a different device.

         mov  ch, cl              ; Copy the "changed" port value to bh
         mov  ah, al              ; Copy the "original" port value to ah
         and  ch, 0FEh            ; Mask off bit 0 of "changed" value.
         and  ah, 0FEh            ; Mask off bit 0 of "original" value.

         cmp  ch, ah              ; Q: Do they match?
         jne  fnXgaNotFound       ; N: This is not an XGA port.

         cmp  cl, al              ; Q: Since bits 1-7 match, do all 8
                                  ;    bits match?
         jne  fnFoundXga          ; N: This is an XGA port.

; Keep looking
fnXgaNotFound:

         inc  bx                  ; Bump the port pointer.
         inc  bx
         jmp  short XgaTestLoop   ; Test the next port.


; This is an XGA.
fnFoundXga:

         mov  al, XGA             ; Say it is an XGA adapter.

; Currently, I do not have a test for the monitor.  I will assume it
;   is an 8514/A Monitor until I have an accurate test.

         mov  ah,Eighty514Display ; AH := Display type.

         call FoundDevice         ; Store the answer.

fnXgaDone:
         ret

FindXGA         ENDP


;
; Find8514
;
; This function detects the presence of an 8514 display card.
;
; The way we do this is to first write to the Error Term Register and then
; make sure we can read back the value we wrote. Then we check to see
; what kind of monitor is attached since the 8514 can function like a VGA.
;

Find8514        PROC    near

ERR_TERM        equ     92e8h     ; 8514 error term register.
SUBSYS_STAT     equ     42e8h     ; 8514 Subsystem status register.

         call ArcnetCardPresent
         or   ax,ax               ; if Arcnet Present do not do the 8514/a
         jnz  fn8514NotFound      ;   test as the Arcnet Card will be reset.

         mov  dx, ERR_TERM        ; load DX with port address (error term port
         in   ax, dx              ; Store original port value ...
         mov  ax, bx              ; ... in BX
         mov  ax, 5555h           ; load AX with value to write to port.
         out  dx, ax              ; Write the data.

         mov  cx, 10h             ; Wait for the port to respond
wait001: loop wait001

         in   ax, dx              ; Read the data back in.
         push ax                  ; Store the value on the stack for a moment
         mov  ax, bx              ; Restore the original value of the port
         out  dx, ax
         pop  ax                  ; Now restore the value we wish to check
         cmp  ax, 5555h           ; Q: is 8524 present ?
         jne  fn8514NotFound      ;   N: indicate 8514 not present.
                                  ;   Y: 8514 is present, now check monitor.
         ;
         ; Now we need to determine what type of monitor is attached to the
         ; 8514 card. To do this we check ID bits 0,1,2 in the subsystem
         ; status register. Depending on the Monitor attached we return:
         ;
         ; 8503 Display = VGAMonoDisplay
         ; 8512 Display = VGAColorDisplay
         ; 8513 Display = VGAColorDisplay
         ; 8514 Display = Eighty514Display
         ;
         mov  dx,SUBSYS_STAT      ; Now, we have the adapter. Check monitor.
         in   ax,dx               ; Get word from SUBSYS_STAT
         test ax,0040h            ; Check Bit 2.
         jz   Disp_8514           ; Bit 2 == 0 = 8514 Display = GAD_8514.
         test ax,0020h            ; Bit 1 == 0 = 8503 Display = VGA_MONO.
         jz   Disp_8503

         mov  ah,VGAColorDisplay  ; AH := Display type
         jmp  short fn8514Found

Disp_8503:
         mov  ah,VGAMonoDisplay   ; AH := Display type
         jmp  short fn8514Found

Disp_8514:
         mov  ah,Eighty514Display ; AH := Display type
         jmp  short fn8514Found

fn8514Found:
         mov  al,Eighty514        ; AL := subystem type
         call FoundDevice

; reset flags for subsystems that have been ruled out

         mov  byte ptr CGAflag,FALSE
         mov  byte ptr EGAflag,FALSE
         jmp  short fn8514Done

fn8514NotFound:

; Set the flag for subsystem yet to be checked

         mov  byte ptr XGAflag,TRUE

fn8514Done:
         ret

Find8514        ENDP

;
; FindVGA
;
;       This subroutine uses INT 10H function 1Ah to determine the video
;        BIOS Display Combination Code (DCC) for each video subsystem
;        present.
;

FindVGA         PROC    near

                mov     ax,1A00h
                int     10h             ; call video BIOS for info

                cmp     al,1Ah
                jne     L13             ; exit if function not supported
                                        ;  (i.e., no MCGA or VGA in system)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -