Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Parallel

Super VGA Programming


JUL90: SUPER VGA PROGRAMMING

SUPER VGA PROGRAMMING

Coping with a myriad of options

Christopher A. Howard

Chris is president of Genus Microprogramming, which provides a number of tools that support Super VGA (including the PCX Programmer's Toolkit, PCX Effects, and PCX Text). He can be reached at Genus Microprogramming, 11315 Meadow Lake, Houston, TX 77077, or on CompuServe: 75100,17.


Once upon a time users were presented a short and simple list of display adapter choices -- color or monochrome. Although, from a programmer's perspective those days are still enticing -- a myriad of standards has developed since then. The resolutions of the Hercules, CGA, EGA, and VGA adapters have all provided a common ground for users and developers alike. The next step (as defined by IBM) is the 8514/A, but it has been slow in its adoption. There is also Texas Instruments TIGA (pronounced TIE-GA), an interface for its 34010 and 34020 chips, but it, too, is in the first stages of support. Meanwhile, a number of video board manufacturers have released adapters with capabilities beyond the IBM VGA standard resolution of 320 x 200 x 256. These extended resolutions are collectively known as Super VGA.

In the simpler days of CGA and Hercules, the graphics screen was directly memory mapped. All a programmer had to do was point at it and write it. Aside from the minor headache of interleave addressing, graphics programming was relatively easy. To save the screen, just save that block of memory with a function such as BSAVE, and load it with BLOAD. Later came the EGA with its planar memory and hosts of registers, and things suddenly got more complicated and easier at the same time. Although functions such as BSAVE would no longer work, features like masking and logical operations became easier. The VGA followed this theme with higher resolutions and more colors, and finally we have Super VGA.

This article provides the ability to program the Super VGA modes for some of the major chipsets. A method of detecting each of the chipsets is presented, along with functions for addressing video memory and displaying a pixel at any location. Because any graphics function reduces down to plotting a pixel somewhere on the display, it is possible to extrapolate these functions to any other graphics operation, from the simple to the complex.

The Chipsets

Currently, there are many chipsets on the market that provide Super VGA capabilities. In order to provide an adequate sample, I'll cover three of the major chipsets -- Tseng Labs, Paradise, and Video Seven. Although board vendors may use the same chipset, it is still up to the vendor which features are incorporated into a particular adapter (see Table 1). Super VGA offers the advantages of higher resolution and color capabilities, with the disadvantage of no existing standard. In fact, each chipset must be programmed separately even though you may wish to support only one mode, such as 640 x 480 x 256. Even something as basic as mode numbers can vary wildly between board manufacturers.

Table 1: Video adapters and supported modes

  Chipset      Adapter                  800x  640x  640x  640x  800x
                                        600x  350x  400x  480x  600x
                                        16    256   256   256   256
  ------------------------------------------------------------------

  Tseng Labs   Orchid ProDesigner VGA   29H
               Orchid ProDesigner Plus  29H   2DH         2EH   3DH
               Genoa 5300               29H
               Genoa 5400               29H   2DH         2EH   30H
               STB Extra/EM             29H   2DH         2EH   30H
               Tseng                    29H   2DH         2EH   30H

  Paradise     Paradise Plus-16         58H
               Paradise Professional    58H         5EH   5F

  Video Seven  Video Seven Fastwrite    62H         66H
               Video Seven VRAM         62H         66H   67H   69H

Identification

Some manufacturers have made it easy to identify their chips. One of the easiest is Video Seven. Basically, they have provided an extended BIOS function call that returns valid information when the chipset is present, and garbage otherwise. This provides a consistent and reliable interface.

The other vendors, however, provide no method of identifying their chips. In these cases, a crude but effective BFAI (brute force and ignorance) approach can be used. All vendors include a copyright notice at the beginning of the video BIOS. You can search this area for strings -- such as "Tseng" or "PARADISE" -- in order to identify the chip. This method has worked rather well, but I would like to take this opportunity to suggest that these vendors provide a solution similar to Video Seven's.

This method is not a new one. Many software vendors used a similar technique in order to identify an IBM adapter, and they keyed in the letters "IBM" in the copyright string. This, of course, caused problems for clone vendors. How could they remain compatible with those software packages, and still use the letters IBM without copyright conflicts? Orchid Technology's solution is shown in Figure 1, but for fun you can use DEBUG to display your video board's BIOS by running DEBUG and using the command D C000:0, 100 to dump the first 256 bytes of your VGA's ROM BIOS.

Figure 1: Orchid ProDesigner VGA ROM-BIOS dump

  C000:0000  55AA30EB  5B546869  73206973  206E6F74         This is not
  C000:0010  20612070  726F6475  6374206F  66204942     a product of IB
  C000:0020  4D202028  49424D20  69732061  20747261     M (IBM is a tra
  C000:0030  64656D61  726B206F  6620496E  7465726E    demark of Intern
  C000:0040  6174696F  6E616C20  42757369  6E657373    ational Business
  C000:0050  204D6163  68696E65  7320436F  72702E29      Machines Corp.
  C000:0060  EB6F202A  20436F70  79726967  68742863       Copyright (c)
  C000:0070  29313938  38205473  656E6720  4C61626F     1988 Tseng Labo
  C000:0080  7261746F  72696573  2C20496E  632E2030    ratories, Inc. O
  C000:0090  382F3039  2F383820  56382E30  3058014F    8/09/88 V8.00X O
  C000:00A0  72636869  64205465  63686E6F  6C6F6779    rchid Technology
  C000:00B0  20496E63  2EAB4400  C0000000  00000000                Inc.

Initially, a function should be called that identifies the standard adapters (such as HGC, CGA, EGA, or VGA), but that would cover another article. An excellent reference is Richard Wilton's book, Programmer's Guide to PC and PS/2 Video Systems (Microsoft Press). Once a VGA adapter has been identified, the svQueryChipset function can be called to identify whether the VGA has a chipset that supports Super VGA resolutions. It tests for boards that have a BIOS function call first, and continues with ROM BIOS searches if that fails. In the event no match is found, it returns an error code. At that point your program must query the user, or assume that no supported Super VGA adapter exists.

Initializing the Mode

Initializing the Super VGA graphics mode is no different from setting any standard graphics mode. Each adapter has extended the ROM BIOS interrupt 10H function so that the Super VGA modes are included. However, each board vendor has assigned its own mode numbers to those extended modes -- which is one reason why they are harder to support. Because there is no standard mode number, a table of modes must be maintained for all supported chipsets.

The example code uses a two-step process for managing display modes, based on the method Genus Microprogramming uses for our graphics products. First, the display type is set with the function svSetDisplay, which selects the chipset and the mode. A defined constant is used so that other display types and modes can be easily added, thereby hiding the internal workings of the library. Note that this function does not actually set the mode -- it only performs initialization internal to the Super VGA library and does not affect the calling program's environment. The mode change is performed in the svSetMode function, which takes as its arguments either the svTEXT or svGRAPHICS constants. Listing One , page 82, and Listing Two, page 84, contain the defines macros for Super VGA graphics manipulation. Both are implemented in Microsoft ASM, Version 5.x. The file in Listing Three, page 84, contains procedures for identifying various Super VGA adapters and uses the procedures svQueryChipset. Listing Four, page 85, contains the internal routine procedures for calculating a pixel's address for any given display mode using the procedures svPixelAddr2D, svPixelAddr30, and svPixelAddr5F. Listing Five, page 86, contains procedures for putting (displaying) a pixel for any given display mode or virtual buffer using the procedure svPutPixel. Listing Six, page 90, lists the function declarations for the Super VGA library for C, while Listing Seven, page 90, is a Microsoft C 5.1 test program for testing the Super VGA QueryChipset and PutPixel functions. (Compile with CL /c /AS svTest.C and link svTest ,,, svLib;). Listings Eight (page 91) and Nine (page 92) are the make files for making the Super VGA Library and the Super VGA test program. For more detail on Super VGA used, Table 2 lists the ports, indexes, and functions. Figure 3 illustrates the bits required for Bank selection.

Table 2: Register explanations

Port       Index   Function                  Description
-----------------------------------------------------------------------

EGAgraph  (3CEH)                            EGA/VGA/SVGA graphics controller
                   parPROA    (09H)  (bank) Paradise PROA reg used for bank sel
                   parPR5     (0FH)
                   parLOCK    (0H)          Paradise PR5 reg used for locking
                                            and unlocking
                   parUNLOCK  (5H)
EGAseq    (3C4H)                            EGA/VGA/SVGA Sequencer register
                   v7pagesel  (F9H)
                   v7banksel  (F6H)
                   v7SR6      (06H)
                   v7enable   (EAH)         Video7 SR6 reg used for
                                            locking and unlocking
                   v7disable  (AEH)
VGAsegsel  (3CDH)            (bank)         VGA Segment select (Tseng)
VGAmisci   (3CCH)                           VGA Miscellaneous In
VGAmisco   (3C2H)                           VGA Miscellaneous Out

There are several reasons for splitting up the initialization and mode change functions. First, it allows the library to coexist with other graphics libraries, each of which requires an initialization routine of its own -- and its routine needs to set the mode. In that case, a call to svSetDisplay and then its init would set the mode and make both libraries usable. Second, most initialization is required only once, not every time the mode is set. By calling svSetDisplay once, later calls to svSetMode can be made to switch back and forth between graphics and text modes. Lastly, the program is easier to maintain because the initialization function is performed once at the top of the program, not every time the mode is changed.

What you may notice is that the mode numbers in the table for the Video Seven chipset do not match the published mode constants. Technically, the correct modes are the 66H, 67H, and 69H numbers, and Video Seven recommends that the mode be set through a modified BIOS SetMode function. We found that every time the mode was set to 66H, a BIOS GetMode function call would always return 1AH. This caused problems because the svSetMode function always reads back the mode to ensure it was successfully set -- and it would always appear that it did not. To get around this problem and provide a standard way of setting and getting the mode, all of our libraries just go ahead and set the mode to 1AH (or 1BH or 1DH), and everything works fine. If you wish to set the mode for the Video Seven in the recommended way, use the @V7Mode macro provided.

Extended 16-Color

There is one Super VGA mode that remains fairly constant across all boards, the 800 x 600 x 16 color mode. It is basically an extension of the 640 x 350 x 16 color EGA and 640 x 480 x 16 color VGA modes. It is programmed in exactly the same way, with the major changes being the mode number and pixel addressing. Because EGA programming has been well covered for several years now, we will not go into it here. To summarize, it is still planar, with each of the four planes fitting into one segment (64K bytes), for a total memory requirement of just under 256K bytes. To address a single pixel, use the formula b = ((y*800)+ x)/8, then mask out the pixel in that byte. The bit you want to affect is x mod 8. All logical operations and bit masking are performed as any normal EGA or VGA 16-color mode.

Extended 256-Color

The Super VGA 256-color modes are an entirely new format. The memory layout is different from any previous video mode. It is not interleaved such as the CGA or Hercules adapters, nor is it planar such as the EGA and VGA 16-color modes. It is closest to the 320 x 200 x 256 VGA 13H mode, complicated by the fact that the memory crosses 64K-byte segment boundaries.

Like the EGA and VGA, the Super VGA video memory is accessed through a 64K-byte area located at A0000 hex. To get around the memory requirements of the Super VGA modes (a mode like 640 x 480 x 256 requires over 300K of video RAM), all chipsets use a sliding window scheme. For the Tseng and Video Seven chipsets, this window can be thought of as a 64K bank of memory that can be located at any 64K boundary. Do not think of it as a purely rectangular window -- the 64K window can start and stop anywhere within video memory (see Figure 2). This also means that the window starts and stops in the middle of a scanline, limiting some optimizations (such as checking for a bank change at the end of a scanline instead of any pixel). For the Tseng chipset, bank selection is all handled within a single byte. However, the Video Seven chipset gets the award for the most complicated bank switch. It involves setting three different bits in three different registers. The bank selection code for the example library is performed through macros, called @TsengSeg and @V7Seg.

The Paradise chipset is a little different in that it does not restrict the window to 64K boundaries. It is closer to an actual sliding window because it can be placed at any 4K increment. Unlike the Tseng and Video Seven, the window can be kept purely rectangular by placing it every 32 lines. This is because 32 lines * 640 bytes = 20480 = 5 * 4K increment. For some functions this is an advantage, but in the case of svPutPixel it does not help. The macro @ParSeg emulates the other chipsets by forcing the window to a 64K increment (every sixteenth 4K position).

Note that both the Video Seven and the Paradise chipsets require that the extended Super VGA registers be unlocked/enabled before they can be written to, and they recommend that these registers be locked/disabled when the function has completed using them. This is done with an out to a port, and they are supposedly locked in order to prevent accidental writes to those port locations. The only extended registers used in these examples involve bank selection.

Addressing Memory

Address calculations are simpler in the 256-color modes because each pixel is represented by 1 byte, and the memory is linear (all in a row, with no planes, and no interleaving). Compared to the CGA and Hercules interleaving and the planes of the EGA and VGA, Super VGA is the easiest.

The address calculations are performed by the functions in the svPA.ASM module (see Listing Four). Only two functions are necessary: One for 640-wide modes, and one for 800-wide Tseng and Video Seven modes. The routines merely involve multiplying the y coordinate by the screen width, and then adding in the x coordinate. Because each pixel is a byte, no conversion is necessary. The 64K bank number is automatically determined by the multiplication, because the AX register holds a maximum of 64K before it overflows into DX. Thus, the bank is returned to DX and the offset into that bank is returned in AX -- easy.

Displaying a Pixel

Now that the pixel can be addressed, it is only a matter of writing it. The svPutPixel function contained in the svPP.ASM module (see Listing Five) simply uses the information returned from the svPixelAddr function to set the window bank and update the pixel. The function appears a little more convoluted due to the logical operations supported. To set the logical operation, use the function svSetOp before calling the svPutPixel function.

Optimization

These example functions were derived from Genus Microprogramming's current graphics tools that support multiple languages and compilers. Although the routines are fast, the derivation presented here is not necessarily optimized for speed. Optimizations may include streamlining the svPutPixel functions themselves so that the @Entry and @Exit macros are removed, or including separate pixel functions within other primitives such as line or circle functions. The examples are meant to illustrate the Super VGA programming process itself, and modular programming techniques. As my old physics professor used to eloquently understate, "The rest of the proof is trivial, and is left as an exercise for the student." In other words, why hand it to you when you can have fun trying?

Conclusion

The Super VGA modes are, in my opinion, easier to program than most other video modes for two main reasons:

    1. The memory is linear, not interleaved or planar, which simplifies buffer addressing.

    2. Pixels are addressed as single bytes, which simplifies pixel addressing, masking, and logical operations.

The only constraining factor is the lack of standardization, which has slowed the adoption of the extended modes. With new standards such as VESA on the horizon, this situation should change soon.

_SUPER VGA PROGRAMMING_ by Christopher A. Howard

[LISTING ONE]

<a name="0169_0011">

; svDefs.INC                                                                 ;
; Copyright (c) Genus Microprogramming, Inc. 1988-89  All Rights Reserved.   ;
;**************************************************************************;
; This file contains defines for Super VGA graphics manipulation.            ;
; Microsoft ASM 5.x version.              Programmer: Chris Howard           ;
;**************************************************************************;

;Display Segments
EGAseg    equ       0A000H                  ;EGA/VGA/SVGA graphics segment
BIOSseg   equ       0C000H                  ;Graphics BIOS segment

;EGA defines
EGAgraph  equ       03CEH                   ;EGA Graphics Register
EGAseq    equ       03C4H                   ;EGA Sequencer Register

;VGA defines
VGAsegsel equ       03CDH                   ;VGA Segment select
VGAmisci  equ       03CCH                   ;VGA Misc In
VGAmisco  equ       03C2H                   ;VGA Misc Out

;Paradise defines
parPROA   equ       09H                     ;proa index value
parPR5    equ       0FH                     ;pr5  index value
parLOCK   equ       0                       ;Lock   proa to pr4 (write to pr5)
parUNLOCK equ       5                       ;Unlock proa to pr4 (write to pr5)
parFUNC   equ       6FH                     ;Paradise Function

;Video 7 defines
v7SR6     equ       06H                     ;sr6 index value
v7banksel equ       0F6H                    ;Bank select
v7pagesel equ       0F9H                    ;Page select
v7enable  equ       0EAH                    ;Enable extensions
v7disable equ       0AEH                    ;Disable extensions
v7modenum equ       06F05H                  ;Number to use for mode sets

;Display mode numbers
TEXTMODE  equ       3                       ;Text mode number

;Display mode types
svTEXT    equ       0                       ;Text mode
svGRAPH   equ       1                       ;Graphics mode

;Display types
mindisp   equ       0                       ;Minimum display type
svDISP_2D equ       0                       ;Tseng    2DH  (640x350x256)
svDISP_2E equ       1                       ;Tseng    2EH  (640x480x256)
svDISP_30 equ       2                       ;Tseng    30H  (800x600x256)
svDISP_5E equ       3                       ;Paradise 5EH  (640x400x256)
svDISP_5F equ       4                       ;Paradise 5FH  (640x480x256)
svDISP_66 equ       5                       ;Video 7  66H  (640x400x256)
svDISP_67 equ       6                       ;Video 7  67H  (640x480x256)
svDISP_69 equ       7                       ;Video 7  69H  (800x600x256)
maxdisp   equ       7                       ;Maximum display type

;Logical Operations
RMWbits   equ       18H                     ;Read-Modify-Write bits
svOpREP   equ       00000000B               ;SET pixel value directly
svOpAND   equ       00000001B               ;AND pixel value with data
svOpOR    equ       00000010B               ;OR  pixel value with data
svOpXOR   equ       00000011B               ;XOR pixel value with data

;Chipsets
svUNKNOWN equ       0                       ;Unknown chip set
svTSENG   equ       1                       ;Tseng Labs chip set
svPARA    equ       2                       ;Paradise
svV7      equ       3                       ;Video 7

;Masks
capmask   equ       11011111B               ;To convert letters to caps

;Error codes
svSUCCESS equ       0                       ;Success
svBADMODE equ       -1                      ;Bad display mode

;Internal Constants
unknown   equ       -1                      ;A constant is unknown
bytesrow  equ       80                      ;CGA bytes per full row
bitsbyte  equ       8                       ;Bits per byte

;Display structure
svstruc   STRUC
svtype    db        ?                       ;Display type
svmode    db        ?                       ;Display mode
svfunc    dd        ?                       ;Display function
svstruc   ENDS



<a name="0169_0012"><a name="0169_0012">
<a name="0169_0013">
[LISTING TWO]
<a name="0169_0013">

; svMacs.INC                                                                 ;
; Copyright (c) Genus Microprogramming, Inc. 1988-89  All Rights Reserved.   ;
;**************************************************************************;
; This file contains macros for Super VGA graphics manipulation.             ;
; Microsoft ASM 5.x version.              Programmer: Chris Howard           ;
;**************************************************************************;

; Interrupts
INT_BIOS  equ       10H                     ;BIOS (video)
INT_DOS   equ       21H                     ;DOS Functions


; BIOS Functions (int 10H)
SETMODE   equ       00H                     ;Set the Display mode
GETMODE   equ       0FH                     ;Check the Display mode

; Macros
@DOS      MACRO     func                    ;;Macro to use DOS function calls
          mov       ah,func
          int       INT_DOS
          ENDM

@BIOS     MACRO     func                    ;;Macro to use BIOS function calls
          push      bp                      ;;Some functions destroy bp
          mov       ah,func
          int       INT_BIOS
          pop       bp
          ENDM

@@LoadSeg MACRO     seg,val                 ;;Macro to load a segment reg
          mov       ax,val
          mov       seg,ax
          ENDM

@@Data    MACRO     seg                     ;;Macro to load data seg in reg
          ASSUME    seg:@data
          mov       ax,@data
          mov       seg,ax
          ENDM

@SetMode  MACRO     mode                    ;;Macro to set display mode
          IFDIFI    <mode>,<al>
          mov       al,mode
          ENDIF
          @BIOS     SETMODE
          ENDM

@GetMode  MACRO                             ;;Macro to get display mode
          @BIOS     GETMODE
          ENDM

@Port     MACRO     portnum,portval         ;;Macro to set a port to a value
          IFDIFI    <portval>,<al>
          mov       al,portval
          ENDIF
          IFDIFI    <portnum>,<dx>
          mov       dx,portnum
          ENDIF
          out       dx,al
          ENDM

@EGAPort  MACRO     portnum,portreg,portval ;;Macro to set an EGA port
          IFDIFI    <portreg>,<al>
          mov       al,portreg
          ENDIF
          IFDIFI    <portnum>,<dx>
          mov       dx,portnum
          ENDIF
          out       dx,al
          inc       dx
          mov       al,portval
          out       dx,al
          ENDM

@TsengSeg MACRO     seg                     ;;Macro to set the Tseng VGA seg
          push      ax
          IFDIFI    <seg>,<al>
          mov       al,seg
          ENDIF
          mov       ah,al                   ;;Save a copy
          shl       ah,1                    ;;Rotate up (Bits 0-2 = write seg
          shl       ah,1                    ;;                3-5 = read  seg
          shl       ah,1                    ;;                6-7 = seg cnfg)
          or        al,ah                   ;;Combine read and write segs
          or        al,01000000B            ;; and set to configuration 2
          @Port     VGAsegsel,al            ;;Now set it
          pop       ax
          ENDM

@ParSeg   MACRO     seg                     ;;Macro to set Paradise VGA seg
          push      cx
          IFDIFI    <seg>,<ch>
          mov       ch,seg
          ENDIF
          mov       cl,4                    ;Turn 4K window into 64K window
          shl       ch,cl                   ; by multiplying by 16
          @EGAPort  EGAgraph,parPROA,ch     ; and set the new index
          pop       cx
          ENDM

@V7Seg    MACRO     seg                     ;;Macro to set the V7VGA segment
          push      ax
          push      bx
          IFDIFI    <seg>,<bh>
          mov       bh,seg
          ENDIF
          mov       bl,bh
          and       bl,00000001B            ;;Mask for bank bit 0
          @EGAPort  EGAseq,V7pagesel,bl     ;;Set the bit
          mov       bl,bh                   ;;Get a copy of seg again
          and       bl,000000010B           ;;Mask for bank bit 1
          shl       bl,1                    ;;Shift it up
          shl       bl,1
          shl       bl,1
          shl       bl,1
          mov       dx,VGAmisci             ;;Read the Misc In reg
          in        al,dx
          and       al,NOT 00100000B        ;;Make sure bit is clear
          or        bl,al
          @Port     VGAmisco,bl             ;;Write to Misc Out
          @Port     EGAseq,v7banksel
          inc       dx
          in        al,dx
          mov       bl,bh                   ;;Get a copy of seg again
          shr       bl,1                    ;;Dupe bit 2 to bit 0 (r/w equal)
          shr       bl,1
          add       bl,7
          not       bl
          and       bl,5
          and       al,11110000B            ;;Clear bank select bits
          or        al,bl
          out       dx,al
          pop       bx
          pop       ax
          ENDM

@V7Mode   MACRO     mode                    ;;Macro to set Video7 mode
          IFDIFI    <mode>,<bl>
          mov       bl,mode
          ENDIF
          mov       ax,v7modenum            ;;Indicate Video7 mode set
          int       INT_BIOS
          ENDM

@Entry    MACRO     splocal                 ;;Macro for entering routine
          push      bp                      ;; and setting up frame
          mov       bp,sp
          sub       sp,splocal              ;;Allocate local space
          push      ds
          push      es
          push      si
          push      di
          @@Data    ds
          ENDM

@Exit     MACRO     retcode,splocal         ;;Macro for setting return code
          mov       ax,retcode              ;; and restoring regs
          pop       di
          pop       si
          pop       es
          pop       ds
          mov       sp,bp                   ;;Remove local space
          pop       bp                      ;;Restore frame
          ret       splocal                 ;;Remove parms
          ENDM

@SetRet   MACRO     retcode,errcode
          mov       WORD PTR retcode,errcode
          ENDM



<a name="0169_0014"><a name="0169_0014">
<a name="0169_0015">
[LISTING THREE]
<a name="0169_0015">

; svQC.ASM                                                                   ;
; Copyright (c) Genus Microprogramming, Inc. 1988-89  All Rights Reserved.   ;
;**************************************************************************;
; This file contains procedures for identifying various Super VGA adapters.  ;
; Procedures: svQueryChipset                                                 ;
; Microsoft ASM 5.x version.              Programmer: Chris Howard           ;
;**************************************************************************;

; Include files
  INCLUDE svDefs.inc
  INCLUDE svMacs.inc

  .model  small
  .data
  .code
          PUBLIC    svQueryChipset

;**********
; This procedure attempts to determine the type of VGA chip set.
; Calling: retcode = pcxQueryChipset()
;

;Define variable locations on the stack  (pascal model)
qcparm    equ       0

;Define local variables
qcret     equ       <[bp- 2]>               ;return code
qclocal   equ       2                       ;Total local space needed

svQueryChipset      PROC FAR
          @Entry    qclocal                 ;Set up frame and save regs
          mov       al,0                    ;Look for a V7VGA
          @BIOS     parFUNC
          xor       al,al                   ;Clear al
          cmp       bx,'V7'                 ;Is this a Video7?
          jne       svQC_Para
          @SetRet   qcret,svV7              ;Indicate that this is a Video7
          jmp       svQC_exit

svQC_Para:
          @@LoadSeg es,BIOSseg              ;Point to the BIOS location
          mov       di,0
          mov       cx,500                  ;Search the first 500 bytes
          mov       al,'P'                  ;Look for 'PARADISE'

svQC_Parafind:
          repne     scasb                   ;Search
          jcxz      svQC_Tseng
          cmp       BYTE PTR es:[di  ],'A'  ;Next Letter?
          jne       svQC_Parafind           ; Compare one at a time, so
                                            ; we can avoid static data ...)
          cmp       BYTE PTR es:[di+1],'R'  ;
          jne       svQC_Parafind           ; If not a match, continue search
          cmp       BYTE PTR es:[di+2],'A'
          jne       svQC_Parafind
          cmp       BYTE PTR es:[di+3],'D'
          jne       svQC_Parafind
          cmp       BYTE PTR es:[di+4],'I'
          jne       svQC_Parafind
          cmp       BYTE PTR es:[di+5],'S'
          jne       svQC_Parafind
          cmp       BYTE PTR es:[di+6],'E'
          jne       svQC_Parafind

          @SetRet   qcret,svPARA            ;We found the Paradise name
          jmp       SHORT svQC_exit

svQC_Tseng:
          @@LoadSeg es,BIOSseg              ;Point to the BIOS location
          mov       di,0
          mov       cx,500                  ;Search the first 500 bytes
          mov       al,'T'                  ;Look for 'Tseng'

svQC_Tsfind:
          repne     scasb                   ;Search
          jcxz      svQC_unknown

          cmp       BYTE PTR es:[di  ],'s'  ;Next Letter?
          jne       svQC_Tsfind             ; Compare one at a time, so
                                            ; we can avoid static data ...)
          cmp       BYTE PTR es:[di+1],'e'  ;
          jne       svQC_Tsfind             ; If not a match, continue search
          cmp       BYTE PTR es:[di+2],'n'
          jne       svQC_Tsfind
          cmp       BYTE PTR es:[di+3],'g'
          jne       svQC_Tsfind

          @SetRet   qcret,svTSENG           ;We found the Tseng name
          jmp       SHORT svQC_exit

svQC_unknown:
          @SetRet   qcret,svUNKNOWN         ;We did not find anything

svQC_exit:
          @Exit     qcret,qcparm            ;Return

svQueryChipset      ENDP
          END




<a name="0169_0016"><a name="0169_0016">
<a name="0169_0017">
[LISTING FOUR]
<a name="0169_0017">

; svPA.ASM                                                                   ;
; Copyright (c) Genus Microprogramming, Inc. 1988-89  All Rights Reserved.   ;
;**************************************************************************;
; This file contains procedures for calculating a pixel's address for any    ;
; given display mode. These are INTERNAL routines.                           ;
; Procedures: svPixelAddr2D  svPixelAddr30  svPixelAddr5F                    ;
; Microsoft ASM 5.x version.              Programmer: Chris Howard           ;
;**************************************************************************;

; Include files
  INCLUDE svDefs.inc
  INCLUDE svMacs.inc

  .model  small
  .data
  .code
          PUBLIC    svPixelAddr2D
          PUBLIC    svPixelAddr30

;**********

; This function determines the address of a pixel in SVGA 256 color
; modes:
;          2DH     640x350x256 Tseng
;          2EH     640x480x256 Tseng
;          66H     640x400x256 Video7
;          67H     640x480x256 Video7
;          5EH     640x400x256 Paradise
;          5FH     640x480x256 Paradise
; Calling: AX    = y-coordinate
;          BX    = x-coordinate
; Returns: ES:BX = pixel pointer
;          DX    = video segment
;

svPixelAddr2D       PROC FAR
          mov       dx,640                  ;Multiply y*BytesPerLine
          mul       dx
          add       bx,ax                   ;Add in x coordinate
          adc       dx,0                    ; and any carry
          @@LoadSeg es,EGAseg               ;ES:BX = byte address of pixel
          ret
svPixelAddr2D       ENDP

;**********

; This function determines address of pixel in SVGA 800x600x256 color modes:
;          30H     800x600x256 Tseng
;          69H     800x600x256 Video7
; Calling: AX    = y-coordinate (0-599)
;          BX    = x-coordinate (0-799)
; Returns: ES:BX = pixel pointer
;          DX    = video segment
;

svPixelAddr30       PROC FAR
          mov       dx,800                  ;Multiply y*bytesrow
          mul       dx
          add       bx,ax                   ;Add in x coordinate
          adc       dx,0                    ; and any carry
          @@LoadSeg es,EGAseg               ;ES:BX = byte address of pixel
          ret
svPixelAddr30       ENDP

          END




<a name="0169_0018"><a name="0169_0018">
<a name="0169_0019">
[LISTING FIVE]
<a name="0169_0019">


; svPP.ASM                                                                   ;
; Copyright (c) Genus Microprogramming, Inc. 1988-89  All Rights Reserved.   ;
;***************************************************************************;
; This file contains procedures for putting (displaying) a pixel for any     ;
; given display mode or virtual buffer.                                      ;
; Procedures: svPutPixel                                                     ;
; Microsoft ASM 5.x version.              Programmer: Chris Howard           ;
;***************************************************************************;

; Include files
  INCLUDE svDefs.inc
  INCLUDE svMacs.inc

  .model  small
  .data

svDisplay svstruc   <svDISP_2D,2DH,svPutPixel2D>      ;Tseng Labs
svlen     EQU       $-svDisplay
          svstruc   <svDISP_2E,2EH,svPutPixel2D>
          svstruc   <svDISP_30,30H,svPutPixel30>

          svstruc   <svDISP_5E,5EH,svPutPixel5F>      ;Paradise
          svstruc   <svDISP_5F,5FH,svPutPixel5F>

          svstruc   <svDISP_66,1AH,svPutPixel67>      ;Video7
          svstruc   <svDISP_67,1BH,svPutPixel67>
          svstruc   <svDISP_69,1DH,svPutPixel69>

          PUBLIC    svCurDisp,svLogOp

svCurDisp dw        svDISP_2D               ;Current display type
svPixFunc dd        ?                       ;Current pixel function
svBank    db        -1                      ;Current window bank
svLogOp   db        svOpREP                 ;Logical operation
          EXTRN     svPixelAddr2D           : FAR
          EXTRN     svPixelAddr30           : FAR
  .code
          PUBLIC    svSetDisplay
          PUBLIC    svSetMode
          PUBLIC    svSetOp
          PUBLIC    svPutPixel
;**********

; This function sets the display type by selecting the correct pixel
; function for all svPutPixel calls.

;Define variable locations on the stack  (pascal model)
sddisp    equ       <[bp+ 6]>               ;Display type
sdparm    equ       2

;Define local variables
sdret     equ       <[bp- 2]>               ;return code
sdlocal   equ       2                       ;Total local space needed

svSetDisplay        PROC FAR
          @Entry    sdlocal                 ;Set up frame and save regs
          @@Data    es                      ;Point to table
          mov       ax,sddisp               ;Get the display type
          mov       svCurDisp,ax            ;Assume valid, and store
          mov       bx,svlen                ;Get offset into table
          mul       bx
          mov       di,OFFSET svDisplay     ;Add starting location of table
          add       di,ax
          mov       ax,WORD PTR es:[di].svfunc[2]  ;Store current function
          mov       WORD PTR svPixFunc[2],ax       ; for fast reference
          mov       ax,WORD PTR es:[di].svfunc[0]
          mov       WORD PTR svPixFunc[0],ax

          @SetRet   sdret,svSUCCESS

svSD_exit:
          @Exit     sdret,sdparm

svSetDisplay        ENDP

;**********

; This function sets graphics mode for the currently selected display type.

;Define variable locations on the stack  (pascal model)
smmode    equ       <[bp+ 6]>               ;Flag for TEXT or GRAPHICS mode
smparm    equ       2

;Define local variables
smret     equ       <[bp- 2]>               ;return code
smlocal   equ       2                       ;Total local space needed

svSetMode           PROC FAR
          @Entry    smlocal                 ;Set up frame and save regs
          mov       svBank,-1               ;Initialize bank
          mov       ax,smmode               ;Get requested "mode"
          cmp       ax,svGRAPH              ;Setting to graphics?
          je        svSM_graph
          @SetMode  TEXTMODE                ;Set to text mode
          @SetRet   smret,svSUCCESS
          jmp       SHORT svSM_exit

svSM_graph:
          @@Data    es                      ;Point to table
          mov       ax,svCurDisp            ;Get the display type
          mov       bx,svlen                ;Get offset into table
          mul       bx
          mov       di,OFFSET svDisplay     ;Add starting location of table
          add       di,ax
          @SetMode  es:[di].svmode          ;Set to correct graphics mode
          @GetMode                          ;Make sure it stuck
          cmp       al,es:[di].svmode
          je        svSM_ok
          @SetRet   smret,svBADMODE         ;No, so return error
          jmp       SHORT svSM_exit

svSM_ok:
          @SetRet   smret,svSUCCESS
svSM_exit:
          @Exit     smret,smparm

svSetMode           ENDP

;**********

; This function sets the logical operation for all svPutPixel calls.

;Define variable locations on the stack  (pascal model)
soop      equ       <[bp+ 6]>               ;Logical Operation
soparm    equ       2

;Define local variables
soret     equ       <[bp- 2]>               ;return code
solocal   equ       2                       ;Total local space needed
svSetOp             PROC FAR
          @Entry    solocal                 ;Set up frame and save regs
          mov       ax,soop                 ;Get the logical operation
          cmp       ax,svOpXOR              ;Check range
          jbe       svSO_store
          @SetRet   soret,svBADMODE         ;Error
          jmp       SHORT svSO_exit

svSO_store:
          mov       svLogOp,al              ;Store it
          @SetRet   soret,svSUCCESS

svSO_exit:
          @Exit     soret,soparm

svSetOp             ENDP

;**********

; This function is the main entry point to all of the specific PutPixel
; routines. It sets up the appropriate parameters, then branches to the
; correct routine for the current display device.

;Define variable locations on the stack  (pascal model)
ppx       equ       <[bp+10]>               ;Pixel coordinate
ppy       equ       <[bp+ 8]>
ppcolor   equ       <[bp+ 6]>               ;Color
ppparm    equ       6

;Define local variables
ppret     equ       <[bp- 2]>               ;return code
pplocal   equ       2                       ;Total local space needed

svPutPixel          PROC FAR
          @Entry    pplocal                 ;Set up frame and save regs
          mov       ax,ppx                  ;Call pixel function
          push      ax
          mov       ax,ppy
          push      ax
          mov       ax,ppcolor
          push      ax
          call      DWORD PTR svPixFunc
          @SetRet   ppret,ax

svPP_exit:
          @Exit     ppret,ppparm

svPutPixel          ENDP

;**********

; NOTE: The stack frame is defined in svPutPixel

svPutPixel2D        PROC FAR

          @Entry    pplocal
          mov       ax,ppy                  ;Set up call to address routine
          mov       bx,ppx
          call      svPixelAddr2D           ;ES:BX -> buffer, DL -> seg
          cmp       dl,svBank               ;Is bank currently selected?
          je        svPP2D_op

          @TsengSeg dl

svPP2D_op:
          mov       al,ppcolor              ;Get color
          mov       dl,svLogOp              ;Get operation
          cmp       dl,svOpRep
          jz        svPP2D_rep              ; (fastest if replace)
          cmp       dl,svOpXOR              ;Is this XOR?
          je        svPP2D_xor
          cmp       dl,svOpAND              ;Is this AND?
          je        svPP2D_and

svPP2D_or:
          or        es:[bx],al              ;Or the pixel
          jmp       short svPP2D_ok

svPP2D_and:
          and       es:[bx],al              ;And the pixel
          jmp       short svPP2D_ok

svPP2D_xor:
          xor       es:[bx],al              ;Routine to XOR
          jmp       short svPP2D_ok

svPP2D_rep:
          mov       es:[bx],al              ;Set the pixel value

svPP2D_ok:
          @TsengSeg 0                       ;Reset
          @SetRet   ppret,svSUCCESS
          @Exit     ppret,ppparm

svPutPixel2D        ENDP

;**********

; NOTE: The stack frame is defined in svPutPixel

svPutPixel30        PROC FAR
          @Entry    pplocal
          mov       ax,ppy                  ;Set up call to address routine
          mov       bx,ppx
          call      svPixelAddr30           ;ES:BX -> buffer, DL -> seg
          cmp       dl,svBank               ;Is bank currently selected?
          je        svPP30_op
          @TsengSeg dl

svPP30_op:
          mov       al,ppcolor              ;Get color
          mov       dl,svLogOp              ;Get operation
          cmp       dl,svOpRep
          jz        svPP30_rep              ; (fastest if replace)
          cmp       dl,svOpXOR              ;Is this XOR?
          je        svPP30_xor
          cmp       dl,svOpAND              ;Is this AND?
          je        svPP30_and

svPP30_or:
          or        es:[bx],al              ;Or the pixel
          jmp       short svPP30_ok

svPP30_and:
          and       es:[bx],al              ;And the pixel
          jmp       short svPP30_ok

svPP30_xor:
          xor       es:[bx],al              ;Routine to XOR
          jmp       short svPP30_ok

svPP30_rep:
          mov       es:[bx],al              ;Set the pixel value

svPP30_ok:
          @TsengSeg 0                       ;Reset
          @SetRet   ppret,svSUCCESS
          @Exit     ppret,ppparm

svPutPixel30        ENDP

;**********

; NOTE: The stack frame is defined in svPutPixel

svPutPixel5F        PROC FAR
          @Entry    pplocal
          @EGAPort  EGAgraph,parPR5,parUNLOCK  ;Unlock proa to pr4

          mov       ax,ppy                  ;Set up call to address routine
          mov       bx,ppx
          cmp       dl,svBank               ;Is bank currently selected?
          je        svPP5F_op
          call      svPixelAddr2D           ;ES:BX -> buffer, DL -> seg
          @ParSeg   dl

svPP5F_op:
          mov       al,ppcolor              ;Get color
          mov       dl,svLogOp              ;Get operation
          cmp       dl,svOpRep
          jz        svPP5F_rep              ; (fastest if replace)
          cmp       dl,svOpXOR              ;Is this XOR?
          je        svPP5F_xor
          cmp       dl,svOpAND              ;Is this AND?
          je        svPP5F_and

svPP5F_or:
          or        es:[bx],al              ;Or the pixel
          jmp       short svPP5F_ok

svPP5F_and:
          and       es:[bx],al              ;And the pixel
          jmp       short svPP5F_ok

svPP5F_xor:
          xor       es:[bx],al              ;Routine to XOR
          jmp       short svPP5F_ok

svPP5F_rep:
          mov       es:[bx],al              ;Set the pixel value

svPP5F_ok:
          @EGAPort  EGAgraph,parPROA,0      ;Zero out proa
          @EGAPort  EGAgraph,parPR5,parLOCK ;Lock proa to pr4
          @SetRet   ppret,svSUCCESS
          @Exit     ppret,ppparm

svPutPixel5F        ENDP

;**********

; NOTE: The stack frame is defined in svPutPixel

svPutPixel67        PROC FAR

          @Entry    pplocal
          @EGAPort  EGAseq,v7SR6,v7enable   ;Enable Video 7 extensions

          mov       ax,ppy                  ;AX = y
          mov       bx,ppx                  ;BX = x
          call      svPixelAddr2D           ;ES:BX -> buffer, DL -> seg
          cmp       dl,svBank               ;Is bank currently selected?
          je        svPP67_op
          mov       cl,dl
          @V7Seg    cl

svPP67_op:
          mov       al,ppcolor              ;Get color
          mov       dl,svLogOp              ;Get operation
          cmp       dl,svOpRep
          jz        svPP67_rep              ; (fastest if replace)
          cmp       dl,svOpXOR              ;Is this XOR?
          je        svPP67_xor
          cmp       dl,svOpAND              ;Is this AND?
          je        svPP67_and

svPP67_or:
          or        es:[bx],al              ;Or the pixel
          jmp       short svPP67_ok

svPP67_and:
          and       es:[bx],al              ;And the pixel
          jmp       short svPP67_ok

svPP67_xor:
          xor       es:[bx],al              ;Routine to XOR
          jmp       short svPP67_ok

svPP67_rep:
          mov       es:[bx],al              ;Set the pixel value

svPP67_ok:
          @V7Seg    0                       ;Reset
          @EGAPort  EGAseq,v7SR6,v7disable  ;Disable Video 7 extensions
          @SetRet   ppret,svSUCCESS
          @Exit     ppret,ppparm

svPutPixel67        ENDP

;**********

; NOTE: The stack frame is defined in svPutPixel

svPutPixel69        PROC FAR
          @Entry    pplocal
          @EGAPort  EGAseq,v7SR6,v7enable   ;Enable Video 7 extensions

          mov       ax,ppy                  ;Set up call to address routine
          mov       bx,ppx
          call      svPixelAddr30           ;ES:BX -> buffer, DL -> seg
          cmp       dl,svBank               ;Is bank currently selected?
          je        svPP69_op
          mov       cl,dl
          @V7Seg    cl

svPP69_op:
          mov       al,ppcolor              ;Get color
          mov       dl,svLogOp              ;Get operation
          cmp       dl,svOpRep
          jz        svPP69_rep              ; (fastest if replace)
          cmp       dl,svOpXOR              ;Is this XOR?
          je        svPP69_xor
          cmp       dl,svOpAND              ;Is this AND?
          je        svPP69_and

svPP69_or:
          or        es:[bx],al              ;Or the pixel
          jmp       short svPP69_ok

svPP69_and:
          and       es:[bx],al              ;And the pixel
          jmp       short svPP69_ok

svPP69_xor:
          xor       es:[bx],al              ;Routine to XOR
          jmp       short svPP69_ok

svPP69_rep:
          mov       es:[bx],al              ;Set the pixel value

svPP69_ok:
          @V7Seg    0                       ;Reset
          @EGAPort  EGAseq,v7SR6,v7disable  ;Disable Video 7 extensions
          @SetRet   ppret,svSUCCESS
          @Exit     ppret,ppparm

svPutPixel69        ENDP

          END



<a name="0169_001a"><a name="0169_001a">
<a name="0169_001b">
[LISTING SIX]
<a name="0169_001b">

/* svLib.H                                                                  */
/* Copyright (c) Genus Microprogramming, Inc. 1988-89  All Rights Reserved. */
/**************************************************************************
  Function declarations for the Super VGA Library, for C.
  Microsoft C version 5.1                 Programmer: Chris Howard
***************************************************************************/

/* Display modes */
#define svTEXT       0                      /* Text mode                   */
#define svGRAPHICS   1                      /* Graphics mode               */

/* Display types */
#define svMINDISP    0
#define svDISP_2D    0                      /* Tseng    2DH (640x350x256)  */
#define svDISP_2E    1                      /* Tseng    2EH (640x480x256)  */
#define svDISP_30    2                      /* Tseng    30H (800x600x256)  */
#define svDISP_5E    3                      /* Paradise 5EH (640x400x256)  */
#define svDISP_5F    4                      /* Paradise 5FH (640x480x256)  */
#define svDISP_66    5                      /* Video 7  66H (640x400x256)  */
#define svDISP_67    6                      /* Video 7  67H (640x480x256)  */
#define svDISP_69    7                      /* Video 7  69H (800x600x256)  */
#define svMAXDISP    7

/* Logical Operations */
#define svSET        0                      /* SET pixel value directly    */
#define svAND        1                      /* AND pixel value with data   */
#define svOR         2                      /* OR  pixel value with data   */
#define svXOR        3                      /* XOR pixel value with data   */

/* Chip sets */
#define svUNKNOWN    0                      /* Unknown chip set            */
#define svTSENG      1                      /* Tseng Labs                  */
#define svPARA       2                      /* Paradise                    */
#define svV7         3                      /* Video 7                     */

/* Error Codes */
#define svSUCCESS    0                      /* Successful                  */
#define svBADMODE    -1                     /* Bad display mode            */

/* Functions */
extern  int   far pascal  svSetDisplay         (int);
extern  int   far pascal  svSetMode            (int);
extern  int   far pascal  svSetOp              (int);
extern  int   far pascal  svPutPixel           (int,int,int);
extern  int   far pascal  svQueryChipset       (void);


<a name="0169_001c"><a name="0169_001c">
<a name="0169_001d">
[LISTING SEVEN]
<a name="0169_001d">

/* svTest.C                                                                 */
/* Copyright (c) Genus Microprogramming, Inc. 1988-89  All Rights Reserved. */
/**************************************************************************
  This is a simple test program, for testing the Super VGA QueryChipset
  and PutPixel functions.
  Compile: CL /c /AS svTest.C
           link svTest,,,svLib;
  Microsoft C version 5.1                 Programmer: Chris Howard
***************************************************************************/

#include <stdio.h>
#include <conio.h>
#include "svlib.h"

/* Global data */
static char *chip[]    = {"[Unknown]","Tseng Labs","Paradise","Video7"};

/**********/

/* This is a crude box drawing routine. Uses the svPutPixel function to draw */
void svPutSquare(x,y,w,c)
int  x,y,w,c;

{
  int  i;
  for (i=0; i<w; i++) {
    svPutPixel(x+i,y,  c);
    svPutPixel(x+i,y+w,c);
    svPutPixel(x,  y+i,c);
    svPutPixel(x+w,y+i,c);
  }

} /* end of svPutSquare */

/**********/
void main(void)
{
  int  i,j,k,chipset,svdisplay,retcode;

  /* Display a header */
  printf("\n\nSuper VGA Test Program\n\n");

  /* Query the chipset, and see what we have */
  chipset = svQueryChipset();

  printf("Your Super VGA chipset is: %s\n\n",chip[chipset]);
  printf("Press any key to continue ...\n\n");
  getch();

  /* If we have a chipset we recognize, keep going */
  if (chipset != svUNKNOWN) {

    /* Based on the chipset, select a display type for 256 colors */
    switch (chipset) {
      case svTSENG:
        /* 640x480x256 */
        svdisplay = svDISP_2E;
        break;
      case svPARA:
        /* 640x400x256 */
        svdisplay = svDISP_5E;
        break;
      case svV7:
        /* 640x480x256 */
        svdisplay = svDISP_67;
        break;
    }

    /* Set the display and mode */
    retcode = svSetDisplay(svdisplay);
    retcode = svSetMode(svGRAPHICS);

    /* If the mode was set successfully, try displaying some pixels */
    if (retcode == svSUCCESS) {

      /* Display a rainbow bar, a few lines thick */
      for (j=0; j<10; j++) {
        for (i=0; i<256; i++)
          svPutPixel(200+i,200+j,i);
      }

      /* Demonstrate logical operations by XORing a 'square' across rainbow */
      retcode = svSetOp(svXOR);
      for (i=0; i<256; i++) {
        svPutSquare(200+i,200,10,15);
        /* Dummy delay */
        for (j=0; j<5000; j++)
          k = j;
        svPutSquare(200+i,200,10,15);
      }

      /* Wait for a key */
      getch();

      /* Return to text mode, and display completion message */
      svSetMode(svTEXT);

      printf("svTest completed\n\n");
    }
  }
  else {
    /* We could not recognize the chip, so suggest something */
    printf("No test can be run ...\n\n");
    printf("If you are sure of your chipset, try changing the program so\n");
    printf("the chip type is forced.\n\n");
  }
} /* end of main */





<a name="0169_001e"><a name="0169_001e">
<a name="0169_001f">
[LISTING EIGHT]
<a name="0169_001f">

# svLIB Make File                                                             #
# Copyright (c) Genus Microprogramming, Inc. 1988-89  All Rights Reserved.    #

############################################################################
# This make file is for making the Super VGA Library.                         #
# Usage: Make svLib /I                                                        #
# Microsoft ASM 5.1                       Programmer: Chris Howard            #
############################################################################

# Compiler and linker flags
AFLAGS   = /DLINT_ARGS /W2 /B63 /ZI
#          /D  = Define        /W2 = Max ASM warnings  /B  = Buffer size
CFLAGS   = /G0 /AS /Os /c /Zi
#          /G0 = 8088 code     /AS = Small model       /Os = Optimize Size
#          /c  = Compile only
DFLAGS   = /DLINT_ARGS /W3
#          /D  = Define        /W3 = Max C warnings
LFLAGS   =

# Compiler Programs
CC       = cl   $(CFLAGS)  $(DFLAGS)
ASM      = masm $(AFLAGS)
LINK     = link $(LFLAGS)
LIB      = lib

# ASM Include files
SVDEFS   = svDefs.inc
SVMACS   = svMacs.inc

# Libraries
SVLIB    = svLib

# Remember:
#
#   $*   = Base name of the outfile (without extension)
#   $@   = Complete outfile name
#   $**  = Complete list of infiles
#

############

# Query Chipset
svQC.obj: $*.asm $(SVDEFS) $(SVMACS)
         $(ASM) $*,$@;
         $(LIB) $(SVLIB) -$* +$@;

# Pixel Addressing
svPA.obj: $*.asm $(SVDEFS) $(SVMACS)
         $(ASM) $*,$@;
         $(LIB) $(SVLIB) -$* +$@;

# Put Pixel
svPP.obj: $*.asm $(SVDEFS) $(SVMACS)
         $(ASM) $*,$@;
         $(LIB) $(SVLIB) -$* +$@;

# End.




<a name="0169_0030"><a name="0169_0020"><a name="0169_0020">
<a name="0169_0021">
[LISTING NINE]
<a name="0169_0021">

# svTest Make File                                                            #

# Copyright (c) Genus Microprogramming, Inc. 1988-89  All Rights Reserved.    #
############################################################################
# This make file is for making the Super VGA Test program.                    #
# Microsoft C 5.1                         Programmer: Chris Howard            #
############################################################################

# Compiler and linker flags
CFLAGS   = /G0 /AS /Os /c
#          /G0 = 8088 code     /AS = Small model       /Os = Optimize Size
#          /c  = Compile only
DFLAGS   = /DLINT_ARGS /W3 /Zi
#          /D  = Define        /W3 = Max C warnings    /Zi = Codeview
LFLAGS   = /CO
#          /CO = Codeview

# Compiler Programs
CC       = cl   $(CFLAGS) $(DFLAGS)
ASM      = masm
LINK     = link $(LFLAGS)

# Include files
SV       = svlib.h

# Libraries
SVLIB    = svlib.lib

############

# The Test program
svtest.obj: $*.c  $(SV)
        $(CC) $*.c

# Now link it all together
svtest.exe: $*.obj $(SVLIB)
        $(LINK) $*,,,$(SVLIB);











Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.