home *** CD-ROM | disk | FTP | other *** search
/ The 7th Guest [PC] / T7G_DISK2.BIN / vesa / candt / vesa452.asm < prev    next >
Assembly Source File  |  1991-04-11  |  24KB  |  908 lines

  1.     page 70, 132
  2.  
  3.  
  4.  
  5. ;----------------------------------------------------------------------
  6. ; Module Name    :VESA452.asm
  7. ; Program Name    :VESA452.com
  8. ; Description    :This program traps Video BIOS Fuction calls made from an
  9. ;        Application program. It is a TSR(Terminate & Stay Resident)
  10. ;        program.
  11. ; Date        :February 26, 1990
  12. ; Version    :1.0
  13. ; Programmer    :Rakesh K. Jain
  14. ; Copyright (C) Chips and Technologies, Inc. 1990
  15. ;----------------------------------------------------------------------
  16.  
  17.     include    vesa.inc        ; to include VESA structures & constants
  18.     include    vesa452.inc        ; 452 related stuff
  19.  
  20. ;
  21. ; Code Segment Starts
  22. ;
  23.     code    segment
  24.     assume    cs:code, ds:code, ss:code, es:code
  25.  
  26.     org    100h            ;for making the program .COM type
  27.  
  28. begin    :
  29.     jmp    main            ; jump to the initialization part
  30.  
  31.  
  32. ;------------------------------------------------------------------
  33. ;    This routine stores BIOS Video Function Number into a Buffer
  34. ;    and then calls BIOS fuction.
  35. ;------------------------------------------------------------------
  36. VideoHandler proc    near
  37. ; look for functions to be implemented here
  38.     cmp    ah, VESA_FUNCTIONS
  39.     jnz    VHNotVGACntlFun
  40.  
  41. ; Its a VESA function
  42.     call    VESAFunctions
  43.     iret
  44.  
  45. VHNotVGACntlFun:
  46.     pushf            ;Push Flags to compensate for IRET
  47.     callfar
  48. oldvect    dw    0
  49.     dw    0        ;Old Video Interrupt Vector
  50.     iret
  51. VideoHandler endp
  52.  
  53.  
  54.  
  55. VESAFunctions proc    near
  56.     cmp    al, MAX_FUNCTIONS
  57.     ja    VESAFNotAValidFunction
  58.     cmp    al,5                ; Window Control function
  59.     jnz    @F
  60.     push    cs
  61.     call    near ptr SuperVGASetCPUMemWin    ; This is far call
  62.     ret
  63. @@:
  64.     pushem    <es,ds,di,si,dx,cx,ax,bx>    ; dont change ax, bx order
  65.     xor    ah, ah
  66.     shl    ax, 1                ; ax = function index
  67.     xchg    ax, bx
  68.     mov    bx, cs:DispatchTable[bx]    ; function ptr in bx
  69.     xchg    ax, bx
  70.     call    ax
  71. DirectReturn:
  72.     popem    <bx,ax,cx,dx,si,di,ds,es>    ; dont change ax, bx order
  73.     mov    ax, cs:Status
  74.     ret
  75. VESAFNotAValidFunction:
  76.     cmp    al, 70h
  77.     jne    @f
  78.     call    SetChipsWindowSize
  79.     mov    ax, 704fh
  80.     ret
  81. @@:
  82.     cmp    al, 71h
  83.     jne    @f
  84.     call    GetChipsWindowSize
  85.     mov    ax, 714fh
  86.     ret
  87. @@:
  88.     xor    al, al        ; function not supported
  89.     ret
  90. VESAFunctions endp
  91.  
  92.  
  93.  
  94. SuperVGAInfo    proc    near
  95. ;
  96. ; copy our info structure
  97. ;
  98.     cld                ; play it safe, don't assume things
  99.     mov    ax, cs
  100.     mov    ds, ax            ; Set our data segment
  101.     mov    si, OFFSET VGAInfo
  102.     mov    cx, (SIZE VGAInfoBlock) / 2
  103.     rep movsw
  104. IF    (SIZE VGAInfoBlock) AND 1
  105.     movsb
  106. ENDIF
  107. if 0    ;** we assume that 82C452 presence is already been checked, when we installed this TSR
  108. ;
  109. ; Look for 82C452 (CHIPS Super VGA)
  110. ;
  111.     call    ReadChipsVGAId        ; Id is returned in ah
  112. ;
  113. ; if VGA is identified as Chips product then look for specific VGA
  114. ; look for Chips Id
  115. ;
  116.     cmp    ah, CHIPS_ID    ; is it chips Id?
  117.     jnz    VGACError00    ; non Chips VGA/EGA
  118. ;
  119. ; VGA is identified as Chips VGA
  120. ;
  121.     mov    ah, 80H        ; open extended registers at 3d6/3d7H
  122.     call    ExtRegs
  123.     call    ReadVGATypeNRev
  124.     mov    bl, ah        ; place this info to proper reg
  125.     and    ah, 0F0H    ; test VGA type
  126.     cmp    ah, CHIPSVGA_452
  127.     jnz    VGACFNot452
  128. ;
  129. ; 82C452 is found, return success
  130. ;
  131. endif    ;**0
  132.     mov    Status, SUCCESS SHL 8 + VESA_FUNCTIONS
  133.     ret
  134. if 0    ;** Presence of 82c452 is alraedy been checked
  135. VGACError00:
  136. VGACFNot452:
  137.     mov    Status, FAILURE SHL 8 + VESA_FUNCTIONS
  138.     ret
  139. endif    ;** 0
  140. SuperVGAInfo    endp
  141.  
  142.  
  143.  
  144. SuperVGAModeInfo proc    near
  145.     cld                ; play it safe
  146.     mov    ax, cs
  147.     mov    ds, ax            ; Set our data segment
  148.     mov    si, OFFSET ModeInfo
  149.     mov    ax, cx            ; VESA Mode No ****** to be changed to bx
  150.     mov    dx, di            ; save di in dx
  151.     mov    bx, es            ; save es in bx
  152.     call    VESAToInternalMode
  153.     call    InternalModeToIndex
  154.     mov    ax, di            ; al = Mode Index
  155.     mov    ah, SIZE ModeInfoBlock
  156.     mul    ah            ; ax = +(SIZE ModeInfoBlock)*Index
  157.     add    si, ax            ; si = ModeInfo+(SIZE ModeInfoBlock)*Index
  158.     mov    di, dx            ; restore di
  159.     mov    es, bx            ; restore es
  160.     mov    cx, OBLG_INFO_SIZE
  161.     test    [si].ModeAttributes, MA_EXT_INFO
  162.     jz    @F
  163.     add    cx, EXT_INFO_SIZE
  164. @@:
  165.     push    di            ; save start address
  166.     rep movsb
  167.     pop    di            ; restore start adress
  168.     mov    ax, word ptr ChipsNoOfWindows
  169.                     ; al = # of Windows, ah = Window Size
  170.     cmp    al, 1            ; Is there only 1 windows supported
  171.     jz    @F            ; By default we enable only one window
  172.     mov    es:[di].WinBAttributes,WIN_ATTR    ; Enable second window also
  173.     cmp    ah, 64            ; Is it Dual page 64K ?
  174.     jz    @F            ; Yes, we are all set
  175.     mov    es:[di].WinBSegment, WINB_NADDR    ; change selector to dual page 32K windows
  176. @@:
  177.     mov    byte ptr es:[di].WinSize, ah    ; copy size of the window
  178.     mov    cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS
  179.     ret
  180. SuperVGAModeInfo endp
  181.  
  182.  
  183.  
  184. SuperVGASetMode    proc    near
  185.     mov    ax, bx                ; ax = VESA Mode
  186.     call    VESAToInternalMode        ; ax = Internal Mode (BIOS Mode)
  187.     mov    bx, ax                ; save internal mode
  188.     and    ah, ah                ; see if ah = 0
  189.     jnz    SVSMError
  190.     int    10H                ; call BIOS to set mode
  191. ; did BIOS set the mode ?
  192.     mov    ax, 40h
  193.     mov    ds, ax
  194.     mov    di, 49h
  195.     and    bl, NOT 80H            ; Clear Not-clear-memory bit
  196.     cmp    [di], bl
  197.     jnz    SVSMError
  198. ;
  199. ; find out what value is to be programmed in the GR06 and XR0B to select
  200. ; proper CPU address window. We have table of these value so we have
  201. ; to compute index to the table first. There are 4 entries in the table.
  202. ;    NumberOfWin    SizeofWin    XR0B    GR06 (Low)
  203. ;    1        64 K        0    4
  204. ;    1        128K        0    0
  205. ;    2        32 K        2    4
  206. ;    2        64 K        2    0
  207. ; We assume that # of windows and windows size will always have these values
  208. ;
  209.     cmp    bl, 6ah            ; For all standard modes and 132 column modes
  210.     jb    StandardModes        ; don't bother about paging etc
  211.     mov    bx, word ptr cs:ChipsNoOfWindows
  212.                     ; bl = # of Windows, bh = Window Size
  213.     mov    cl, 6            ; # of bits to be shifted
  214.     shr    bl, 1            ; 'C' if bl = 1, bl = 0/1
  215.     adc    cl, 0            ; cl = 6/5
  216.     shr    bh, cl            ; bl = 0/1
  217.     shl    bl, 1
  218.     add    bl, bh
  219.     xor    bh, bh            ; bx = index into the table
  220.     shl    bx, 1            ; each entry is one word
  221.  
  222.     mov    dx, 3ceh        ; dx = Graphics Controller addr
  223.     mov    al, 6
  224.     out    dx, al
  225.     inc    dx
  226.     in    al, dx
  227.     and    al, 11110011b        ; clear memory size bits
  228.     or    al, cs:WinRegTable[bx]    ; GR06 value
  229.     out    dx, al
  230.  
  231.     mov    ah, 80h            ; Open extended registers
  232.     call    ExtRegs
  233.  
  234.     mov    dx, EGA_BASE + EXTR_ADDR
  235.     mov    al, 0bh
  236.     out    dx, al
  237.     inc    dx
  238.     in    al, dx            ; read current value
  239.     and    al, 11111101b        ; clear dual page bit
  240.     or    al, cs:WinRegTable[bx+1] ; XR0B value
  241.     out    dx, al
  242. StandardModes:
  243.  
  244.     mov    cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS
  245.     ret
  246. SVSMError:
  247.     mov    cs:Status, FAILURE SHL 8 + VESA_FUNCTIONS
  248.     ret
  249. SuperVGASetMode    endp
  250.  
  251.  
  252.  
  253. SuperVGAGetMode    proc    near
  254.     mov    ax, 0F00H
  255.     int    10H
  256.     xor    ah, ah            
  257.     mov    bx, ax            ; save this info in bx
  258.     call    InternalModeToVesa
  259.     jnc    @F
  260.     xchg    ax, bx
  261. @@:
  262.     pop    dx            ; get return addr
  263.     pop    ax            ; pop bx in ax *******
  264.     push    bx            ; push mode to be returned
  265.     push    dx            ; 
  266.     mov    cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS
  267.     ret
  268. SuperVGAGetMode    endp
  269.  
  270.  
  271.  
  272. SuperVGAVideoState    proc    near
  273.     mov    ah, 1cH                ; ah = BIOS function to save/restore VIDEO state
  274.     mov    al, dl                ; al = subfunction
  275.     push    ax                ; save function
  276.     push    cx
  277.     test    cx, VS_SUPERVGA_STATE
  278.     jz    SVVSNotSuperVGA0
  279. ;
  280. ; Super VGA state
  281. ;
  282.     cmp    al, VS_GET_BUFSIZE
  283.     jnz    SVVSNotBufSize
  284. ;
  285. ; get buf size function
  286. ;
  287.     cmp    cx, VS_SUPERVGA_STATE        ; if it is SUPERVGA_STATE only
  288.     jnz    @F                ; save cx, ax and call BIOS
  289. ; only SUPERVGA_STATE
  290.     mov    bx, SUPERVGA_SIZE
  291.     pop    cx
  292.     pop    ax                ; restore sunfunction
  293.     jmp    SVVSNotSuperVGA1        ; don't call BIOS
  294.  
  295. SVVSNotBufSize:
  296.     cmp    al, VS_SAVE_STATE
  297.     jnz    SVVSNotSaveState
  298. ;
  299. ; save state function
  300. ; es:bx --> pointer to buffer, bx will be updated by routine
  301. ;
  302.     call    SaveSuperVGAState
  303.     jmp    short @F
  304. SVVSNotSaveState:
  305.     cmp    al, VS_RESTORE_STATE
  306.     jnz    SVVSNotRestoreState
  307. ;
  308. ; restore state function
  309. ; es:bx --> pointer to buffer, bx will be updated by routine
  310. ;
  311.     call    RestoreSuperVGAState
  312. SVVSNotRestoreState:
  313. SVVSNotSuperVGA0:
  314. @@:
  315.     int    10H
  316.     pop    cx                ; restore requested state
  317.     pop    ax                ; restore subfunction function
  318.     test    cx, VS_SUPERVGA_STATE
  319.     jz    SVVSNotSuperVGA1
  320. ; super vga function
  321.     cmp    al, VS_GET_BUFSIZE        ; is it GET_BUFSIZE function ?
  322.     jnz    @F                ; no
  323.     add    bx, SUPERVGA_SIZE        ; add # of full block
  324. SVVSNotSuperVGA1:
  325.     pop    dx                ; pop return address
  326.     pop    ax                ; pop bx in ax *******
  327.     push    bx                ; put bx on stack
  328.     push    dx                ; push new address
  329. @@:
  330.     mov    cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS
  331.     ret
  332. SuperVGAVideoState    endp
  333.  
  334.  
  335.  
  336. SuperVGASetCPUMemWin    proc    far
  337.     cmp    bh,01
  338.     je    SuperVGAMapVideoMem
  339.     push    dx                ; save page
  340.     mov    ah, 80h
  341.     call    ExtRegs
  342.     pop    dx                ; restore page
  343.     mov    ah, dl                ; ah = page #
  344.     mov    al, PAGE_REG_A
  345.     and    bl, 01                ; consider only LSB
  346.     add    al, bl
  347. ;**    push    dx                ; Save dx
  348.     mov    dx, EGA_BASE+EXTR_ADDR
  349.     out    dx, ax
  350.     mov    cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS
  351. ;**    pop    dx                ; Restore dx
  352.     ret
  353. SuperVGASetCPUMemWin    endp
  354.  
  355.  
  356.  
  357. SuperVGAMapVideoMem    proc    near
  358.     mov    ah, 80h
  359.     call    ExtRegs
  360.     mov    al, PAGE_REG_A
  361.     and    bl, 01                ; consider only LSB
  362.     add    al, bl
  363.     mov    dx, EGA_BASE+EXTR_ADDR
  364.     out    dx,al
  365.     inc    dx
  366.     in    al,dx
  367.     xor    ah,ah
  368.     mov    dx,ax
  369.     mov    cs:Status, SUCCESS SHL 8 + VESA_FUNCTIONS
  370.     ret
  371. SuperVGAMapVideoMem    endp
  372.  
  373.  
  374.  
  375. SuperVGADACCntl    proc    near
  376.     ret
  377. SuperVGADACCntl    endp
  378.  
  379.  
  380.  
  381. ;----------------------------------------------------------------------
  382. ; This routine saves extended registers into a buffer.
  383. ; 2 bytes per register are saved. High byte contains reg value and low
  384. ; byte reg index.
  385. ;
  386. ; Entry:
  387. ;    es:bx --> pointer to buffer (2 bytes per extended reg)
  388. ; Destroyed:
  389. ;    ds, si, di, dx & flags
  390. ; Preseeved:
  391. ;    ax, cx, and bx updated, to be used by BIOS later
  392. ;-----------------------------------------------------------------------
  393. SaveSuperVGAState    proc    near
  394.     push    cx
  395.     push    ax                ; save important regs
  396.     mov    ah, 80H
  397.     call    ExtRegs                ; Open extended registers
  398.     mov    ax, cs
  399.     mov    ds, ax                ; ds = cs (our data seg)
  400.     mov    si, OFFSET ExtRegIndex        ; pointer to ext reg indices table
  401.     mov    di, bx                ; buffer pointer
  402.     mov    dx, EGA_BASE+EXTR_ADDR
  403.     mov    cx, NEXTREGS            ; # of ext regs to be saved
  404. SAVSLoop:
  405.     lodsb                    ; load ext reg index in al
  406.     mov    ah, al                ; ah = al = index
  407.     out    dx, al                ; index the port
  408.     inc    dx                ; dx = data port (3d7)
  409.     in    al, dx                ; read value
  410.     dec    dx                ; dx = address port
  411.     xchg    al, ah                ; ah = value, al = index
  412.     stosw                    ; store it
  413.     loop    SAVSLoop            ; do till all regs are over
  414.     add    bx, 2*NEXTREGS            ; increment pointer for BIOS fuction
  415.     pop    ax
  416.     pop    cx                ; restore important regs
  417.     ret
  418. SaveSuperVGAState    endp
  419.  
  420.  
  421.  
  422. ;----------------------------------------------------------------------
  423. ; This routine restores extended registers from user buffer
  424. ; Entry:
  425. ;    es:bx --> pointer to buffer (2 bytes per extended reg)
  426. ; Destroyed:
  427. ;    ds, si, dx & flags
  428. ; Preseeved:
  429. ;    ax, cx, and bx updated, to be used by BIOS later
  430. ;-----------------------------------------------------------------------
  431. RestoreSuperVGAState    proc    near
  432.     push    cx
  433.     push    ax                ; save important regs
  434.     mov    ah, 80H
  435.     call    ExtRegs                ; Open extended registers
  436.     mov    ax, es
  437.     mov    ds, ax
  438.     mov    si, bx                ; ds:si --> pointer to save regs
  439.     mov    dx, EGA_BASE+EXTR_ADDR
  440.     mov    cx, NEXTREGS
  441. RSVSLoop:
  442.     lodsw
  443.     out    dx, ax                ; output value to appropriate port
  444.     loop    RSVSLoop
  445.     add    bx, 2*NEXTREGS            ; increment pointer for BIOS fuction
  446.     pop    ax                ; restore important regs
  447.     pop    cx
  448.     ret
  449. RestoreSuperVGAState    endp
  450.  
  451.  
  452.  
  453. ;---------------------------------------------------------------------
  454. ; This routine converts user given mode into a 82C452 BIOS mode number
  455. ; Entry:
  456. ;    ax = VESA mode
  457. ; Exit:
  458. ;    if 'C' is clear, ax = internal mode (60H to 7BH)
  459. ;    else    Error... ax not changed
  460. ; Destroyed:
  461. ;    es, cx, di
  462. ;----------------------------------------------------------------------
  463. VESAToInternalMode    proc    near
  464.     mov    di, cs
  465.     mov    es, di
  466.     mov    di, OFFSET VESAModeTable
  467.     mov    cx, NMODES
  468.     push    ax
  469.     and    ah, NOT 80h        ; clear memory-not-clear bit
  470.     repnz scasw            ; scan til value matches
  471.     jnz    VESATIMInvalidMode
  472.     sub    di, OFFSET VESAModeTable
  473.     shr    di, 1            ; Offset to byte table
  474.     mov    al, cs:InternalModeTable[di-1]
  475.     xor    ah, ah
  476.     pop    cx            ; pop the original mode number
  477.     and    ch,80h            ; extract 15th bit
  478.     or    al,ch            ; and OR it to mode number
  479.     clc                ; cheer on success
  480.     ret
  481. VESATIMInvalidMode:
  482.     pop    cx            ; balance the stack
  483.     stc                ; weep on failuare
  484.     ret
  485. VESAToInternalMode    endp
  486.  
  487.  
  488. ;---------------------------------------------------------------------
  489. ; This routine converts internal mode into a VESA given mode number
  490. ; Entry:
  491. ;    ax = internal mode
  492. ; Exit:
  493. ;    if 'C' is clear, ax = internal mode (60H to 7BH)
  494. ;    else    Error...
  495. ; Destroyed:
  496. ;    es, cx, di
  497. ;----------------------------------------------------------------------
  498. InternalModeToVESA    proc    near
  499.     mov    di, cs
  500.     mov    es, di
  501.     mov    di, OFFSET InternalModeTable
  502.     mov    cx, NMODES
  503.     repnz scasb            ; scan til value matches
  504.     jnz    IMTVESAInvalidMode
  505.     sub    di, OFFSET InternalModeTable
  506.     shl    di, 1            ; Offset to word table
  507.     mov    al, cs:InternalModeTable[di-2]
  508.     clc                ; cheer on success
  509.     ret
  510. IMTVESAInvalidMode:
  511.     stc                ; weep on failuare
  512.     ret
  513. InternalModeToVESA    endp
  514.  
  515.  
  516.  
  517. ;---------------------------------------------------------------------
  518. ; This routine converts an Internal mode into an index (0 to NMODES-1)
  519. ; Entry:
  520. ;    ax = Internal mode
  521. ; Exit:
  522. ;    if 'C' is clear, di = index of internal mode table (0 to NMODES -1)
  523. ;    else    Error...
  524. ; Destroyed:
  525. ;    es, cx, di
  526. ;----------------------------------------------------------------------
  527. InternalModeToIndex    proc    near
  528.     mov    di, cs
  529.     mov    es, di
  530.     mov    di, OFFSET InternalModeTable
  531.     mov    cx, NMODES
  532.     repnz scasb            ; scan til value matches
  533.     jnz    IMTIInvalidMode
  534.     sub    di, OFFSET InternalModeTable+1
  535.     clc                ; cheer on success
  536.     ret
  537. IMTIInvalidMode:
  538.     stc                ; weep on failuare
  539.     ret
  540. InternalModeToIndex    endp
  541.  
  542.  
  543.  
  544. ExtRegs proc    near
  545. ;---------------------------------------------------------------------
  546. ; Opens extended register space at 3d6/3d7H
  547. ; Entry:
  548. ;    ah = 80/40H to open extended register space at 3d6/3b6H
  549. ;    ah = 0  to close extended register space
  550. ; Destroyed:
  551. ;    ax, dx
  552. ; Output:
  553. ;    None
  554. ;---------------------------------------------------------------------
  555.  
  556. ; place VGA in setup mode
  557.     mov    dx, cs:SetupAddr
  558.     mov    al, byte ptr cs:SetupData[0]    ; value to place vga in setup mode
  559.     cli                ; Disable interrupts
  560.     out    dx, al
  561.  
  562. ; enable/disable extended registers
  563.     push    dx            ; save setup address
  564.     mov    dx, 103h
  565.     mov    al, ah            ; open extended register at 3d6/3d7H
  566.     out    dx, al
  567.     pop    dx            ; restore setup address
  568.  
  569. ; take VGA out of setup mode
  570.     mov    al, byte ptr cs:SetupData[1]    ; value to take vga out of setup mode
  571.     out    dx, al
  572.     sti                ; Enable interrupt
  573.     ret
  574. ExtRegs endp
  575.  
  576.  
  577. ;------------------------------------------------------------------------
  578. SetChipsWindowSize proc near
  579.  
  580.     mov    word ptr cs:ChipsNoOfWindows, dx
  581. ;**    .ERRNZ    OFFSET ChipsWindowSize - OFFSET ChipsNoOfWindows -1
  582.     ret
  583.  
  584. SetChipsWindowSize endp
  585.  
  586.  
  587. ;------------------------------------------------------------------------
  588. GetChipsWindowSize proc near
  589.  
  590.     mov    dx, word ptr cs:ChipsNoOfWindows
  591. ;**    .ERRNZ    OFFSET ChipsWindowSize - OFFSET ChipsNoOfWindows -1
  592.     ret
  593.  
  594. GetChipsWindowSize endp
  595.  
  596.  
  597. ;---------------------------------------------------------------------
  598. ;        Resident Data Declaration
  599. ;---------------------------------------------------------------------
  600. marker    db    'VESA for 82C452'
  601. marklen    EQU    $ - marker
  602. msg1    db    'VESA Program already installed', NL, EOS
  603.  
  604. DispatchTable    dw    OFFSET SuperVGAInfo
  605.         dw    OFFSET SuperVGAModeInfo
  606.         dw    OFFSET SuperVGASetMode
  607.         dw    OFFSET SuperVGAGetMode
  608.         dw    OFFSET SuperVGAVideoState
  609.         dw    OFFSET SuperVGASetCPUMemWin
  610.         dw    OFFSET SuperVGAMapVideoMem
  611.         dw    OFFSET SuperVGADACCntl
  612. Status        dw    0            ; status of every call
  613.  
  614. SetupAddr    dw    46e8h            ; setup port for PC/AT
  615. SetupData    dw    0e1eh            ; setup data for PC/AT
  616.  
  617. ChipsNoOfWindows    db    1        ;** for two undocumented functions
  618. ChipsWindowSize        db    64        ;** for two undocumented functions
  619.     .ERRNZ    OFFSET ChipsWindowSize - ChipsNoOfWindows -1 ; don't break sequence
  620. WinRegTable    db    04, 00            ; values for GR06 bit 3,2 and XR0B bit 1
  621.         db    00, 00
  622.         db    04, 02
  623.         db    00, 02
  624.  
  625. ExtRegIndex    LABEL    BYTE
  626. defextregs <02H,05H,0AH,0BH,0CH,0DH,0EH,10H,11H,20H,21H,22H,23H,24H>
  627. defextregs <28H,2BH,30H,31H,32H,33H,34H,35H,36H,37H,38H,39H,3AH>
  628. ;;******    db    XR04,XR06,XR14,XR15,XR16,XR18,XR19,XR1A,XR1B,XR1C,XR1D,XR1E
  629. NEXTREGS    equ    $ - ExtRegIndex
  630.  
  631.  
  632. IF    (2*NEXTREGS) AND BLOCKSIZE -1
  633. PARTIAL_BLOCK    equ    1            ; if partial block add one more block
  634. ELSE
  635. PARTIAL_BLOCK    equ    0
  636. ENDIF
  637.  
  638. SUPERVGA_SIZE    equ    (((2*NEXTREGS)/BLOCKSIZE) + PARTIAL_BLOCK)
  639.  
  640.  
  641. VESAModeTable    dw    102h,71h,104h,100h,101h,7Ah,END_OF_MODES
  642.         ; This table hold VESA mode numbers.
  643.         ; This the one which is passed to the user in VGAInfo
  644. VESAModeTableLen    equ    ($ - VESAModeTable -2)/2
  645.  
  646. InternalModeTable db    70h,71h,72h,78h,79h,7Ah
  647.         ; This table holds internal modes corresponding to VESA modes.
  648.         ; Like VESA mode 100 is mapped to internal (BIOS) mode 70H
  649.         ; If any new VESA mode is added, the Internal Mode Table
  650.         ; should be reordered so that new VESA mode and Internal
  651.         ; Mode are in same position in the respective tables and
  652.         ; also parameter sequence in InitModeInfo macro should be
  653.         ; changed correspondingly
  654.  
  655. NMODES        equ    $ - InternalModeTable
  656.  
  657.     .ERRNZ    NMODES - VESAModeTableLen
  658.                 ; give error on size missmatch of two tables
  659.  
  660.  
  661. ModeInfo label    ModeInfoBlock
  662. InitModeInfo    <<Mode70>,<Mode71>,<Mode72>,<Mode78>,<Mode79>,<Mode7A>>
  663.  
  664. VGAInfo    VGAInfoBlock    <>        ; use default values
  665.  
  666. ChipsString    db    'CHIPS 82C452, the Super VGA', 0
  667.  
  668.  
  669.  
  670.  
  671. ProgSize label    word        ;Create Label to get Size of the Program
  672.  
  673. ;----------------------------------------------------------------------
  674. ; ************************ End of Resident Code *********************
  675. ;----------------------------------------------------------------------
  676.  
  677.  
  678.  
  679. main    proc    near
  680.     getvector    VideoInt
  681.     mov    ax, OFFSET marker - OFFSET VideoHandler
  682.     mov    cx, marklen
  683.     mov    di, bx
  684.     add    di, ax            ; es:[di] Pointer to Previous Marker String
  685.     mov    si, OFFSET marker
  686.     cld
  687.     repe cmpsb
  688.     jcxz    AlreadyLoaded
  689.     jmp    short start
  690. AlreadyLoaded    :
  691.     print    msg1
  692.     int    20h            ;Exit to DOS
  693.  
  694. start    :
  695. ;
  696. ; Look for 82C452 VGA
  697. ;
  698.     call    ReadChipsVGAId
  699.     cmp    ah, CHIPS_ID        ; is it chips Id?
  700.     jnz    error_exit        ; Chis VGA is not present
  701.     mov    ah, 80h            ; open extended reg at 3d6/3d7
  702.     call    ExtRegs
  703.     call    ReadVGATypeNRev
  704.     and    ah, 0f0h        ; extract upper nibble
  705.     cmp    ah, CHIPSVGA_452
  706.     jz    ChipsVGAPresent        ; Chips 82C452 is present
  707. error_exit:
  708.     print    msg4
  709.     int    20h            ;Exit to DOS
  710.  
  711. ChipsVGAPresent:            ; our VGA is present
  712.     print    msg0            ;Initial Message
  713. ;
  714. ; Look for command line parameter for monitor
  715. ; es, ds, and cs are same
  716. ;
  717.     mov    ax, cs
  718.     mov    es, ax            ; es = ds = cs
  719.     mov    di, 80H            ; offset of command trail area
  720.     mov    cl, [di]        ; al = # of chars in command trail
  721.     and    cl, cl
  722.     jz    MainDefaultMonitor
  723.     inc    di
  724.     mov    al, '+'            ; For MultiSync + monitor
  725.     xor    ch, ch            ; cx = n chars
  726.     repnz scasb            ; read first char
  727.     jnz    MainDefaultMonitor
  728. ;
  729. ; MultiSync Plus Monitor    
  730. ;
  731.     inc    monitor
  732.     print    msg3
  733.     .errnz    MULTISYNC_PLUS -1
  734. MainDefaultMonitor:            ; by default 'monitor' is 0 for MultiSync II
  735.  
  736. ;    
  737. ; Initialize VGAInfo structure
  738. ;
  739.     mov    si, OFFSET VGAInfo
  740.     mov    ax, OFFSET ChipsString
  741.     mov    WORD PTR [si].OEMString, ax
  742.     mov    WORD PTR [si].OEMString+2, ds
  743.     mov    ax, OFFSET VESAModeTable
  744.     mov    WORD PTR [si].VideoModePtr, ax
  745.     mov    WORD PTR [si].VideoModePtr+2, ds
  746.  
  747. ;
  748. ; Initialize ModeInfo structure tables
  749. ;
  750.     mov    cx, NMODES        ; # of modes table support
  751.     mov    si, OFFSET ModeInfo
  752.     xor    bx, bx            ; bx = index
  753.     mov    dl, monitor        ; monitor type
  754. MainModeInfoLoop:
  755.     mov    al, InternalModeTable[bx]    ; al = internal mode
  756.                     ; according to table
  757.     cmp    dl, MULTISYNC_PLUS
  758.     jz    MainMultiSyncPlus
  759. ;
  760. ; not a MultiSync Plus monitor. Disable Mode 71H, & 72H
  761. ;
  762.     cmp    al, 71H
  763.     jb    MainCommon        ; Not 960x720 1024x768 16 col mode
  764.     cmp    al, 72H
  765.     ja    MainCommon        ; if(mode > 72H)
  766. ;
  767. ; mode 71H & 72H can not be handled by MultiSyncII. Disable them.
  768. ;
  769.     and     [si].ModeAttributes, NOT MA_HW_SUPP
  770.     jmp    short MainCommon    ; done
  771.  
  772. ;**    jmp    short @F        ; do it down
  773.  
  774. MainMultiSyncPlus:            ; all modes are supported
  775. ;**    cmp    al, 70H
  776. ;**    jz    @F            ; MultiSyncPlus can not handle at 40MHz
  777. ;**    cmp    al, 79H
  778. ;**    jbe    MainCommon
  779. ;**;
  780. ;**; modes 70, 7a, 7b can not be handled by MultiSyncPlus. Diasable them.
  781. ;**;
  782. ;**@@:
  783. ;**    and     [si].ModeAttributes, NOT MA_BIOS_INIT
  784.  
  785. MainCommon:
  786.     mov    ax, OFFSET SuperVGASetCPUMemWin
  787.     mov    WORD PTR [si].WinFuncPtr, ax
  788.     mov    WORD PTR [si].WinFuncPtr+2, ds
  789.     inc    bx            ; increase index
  790.     add    si, SIZE ModeInfoBlock
  791.     loop    MainModeInfoLoop
  792.  
  793. ;
  794. ; Install interrupt handler
  795. ;
  796.     call    ChgVdoVector    ;Save Current Video Vector and
  797.                         ;Change it to New Handler
  798. ;
  799. ; Terminate But Stay Resident
  800. ;
  801.     mov    ah, TSR        ;TSR Function Number
  802.     mov    al, 0        ;Return code
  803.     mov    dx, OFFSET ProgSize    ;Size of the program in bytes
  804.     mov    cl, 4
  805.     shr    dx, cl        ;dx = ProgSize/16 (Size in Paragraphs)
  806.     inc    dx
  807.     int    21h
  808. main    endp
  809.  
  810.  
  811.  
  812. ;------------------------------------------------------------------
  813. ;    This routine saves current Video Vector
  814. ;    and initialize it with New Video Interrupt Handler
  815. ;------------------------------------------------------------------
  816. ChgVdoVector proc    near
  817.     getvector    VideoInt
  818.     mov    oldvect, bx
  819.     mov    oldvect+2, es    ;Save Old Vector
  820. ; Set Video Vector to New Handler
  821.     setvector    VideoInt, VideoHandler
  822.     ret
  823. ChgVdoVector endp
  824.  
  825.  
  826.  
  827. ReadChipsVGAId proc    near
  828. ;---------------------------------------------------------------------
  829. ; read chips global Id register
  830. ; Entry:
  831. ;    None
  832. ; Destroyed:
  833. ;    ax, dx
  834. ; Output:
  835. ;    ah = CHIPS Id (0A5H if successful)
  836. ;----------------------------------------------------------------------
  837. ; Find which machine Microchannel/AT
  838.     mov    ah,0c0h            ; Find out system configuration
  839.     int    15H            ; Microchannel or AT
  840.     mov    dx,46e8h        ; Assume VGA Setup Port for PC/AT
  841.     mov    ax,0e1eh        ; al = 1eH to put VGA in Setup Mode
  842.                     ; ah = 0eH to place VGA in normal mode
  843.     jc    @F            ; call not successful, assume PC/AT
  844.     test    byte ptr es:[bx+5],2    ; Is it Microchannel Machine ?
  845.     jz    @F            ; No, We already have proper values
  846.     mov    dx,094h            ; Yes, Microchannel values
  847.     mov    ax,0ffdfh        ; al = df, ah = ff for microchannel
  848. @@:
  849.     mov    cs:SetupAddr, dx    ; save it for use in GrOpenExtRegs
  850.     mov    cs:SetupData, ax    ; save it for use in GrOpenExtRegs
  851.     cli                ; Don't interrupt while doing serious business
  852.     out    dx,al
  853.     push    dx            ; save port
  854.     mov    dx,104h            ; CHIPS ID Port
  855.     in    al,dx
  856.     pop    dx            ; CHIPS VGA Setup Port
  857.     xchg    al,ah            ; Save ID in ah, al = value to get outof setup port
  858.     out    dx,al
  859.     sti                ; Serious business is over
  860.     ret
  861. ReadChipsVGAId endp
  862.  
  863.  
  864.  
  865. ReadVGATypeNRev proc    near
  866. ;----------------------------------------------------------------------
  867. ; read chip type and rev no
  868. ; Entry:
  869. ;    None
  870. ; Destroyed:
  871. ;    ax, dx
  872. ; Output:
  873. ;    ah = Chips type and revision no
  874. ;----------------------------------------------------------------------
  875.  
  876.     mov    dx, EGA_BASE+EXTR_ADDR
  877.     xor    al, al            ; al = XR00
  878.     out    dx, al
  879.     inc    dx
  880.     in    al, dx            ; al = chips type and rev no
  881.     mov    ah, al            ; return the info in ah
  882.     ret
  883. ReadVGATypeNRev endp
  884.  
  885.  
  886.  
  887. ;----------------------------------------------------------------------
  888. ;         Transient data declaration
  889. ;----------------------------------------------------------------------
  890.  
  891. msg0    db    'VESA452 - VESA BIOS Extension Version 1.0 for 82C452 Super VGA Controller', NL
  892.     db    'Release Version 0.2',NL,NL
  893.     db    'Copyright (C) Chips and Technologies, Inc. 1990. ',NL
  894.     db    NL
  895.     db    'A "+" on command line enables all the modes supported by the video BIOS.',NL
  896.     db    'Default is NEC MultiSync II or equivalent monitor supported modes.',NL
  897.     db    NL,EOS
  898.  
  899. msg3    db    'Monitor supported is MultiSync Plus',NL,EOS
  900.  
  901. msg4    db    'Chips and Technologies Super VGA 82C452 is not present.',NL
  902.     db    TAB, 'VESA driver is not installed.',NL,EOS
  903.  
  904. monitor    db    MULTISYNC_II        ; default for MultiSync II
  905.  
  906. code    ends
  907.     end    begin
  908.