
             ******************************************************
             (S)VGA TRICKS - revision 1.1 - Mekka/Symposium 97 rel.
             ******************************************************

                    written by Type One / Pulpe, ex TFL-TDV

  --------------------------------------------------------------------------
  This little text was originally placed in the Imphobia MAG 12.  I've added
  some little things and I want it to be available for every programmers and
  not only sceners.  I hope  you'll like it  and I encourage  you to D/L the
  Imphobia MAGs (great MAG, Darky !!!) available on ftp.cdrom.com /pub/demos
  and ftp.arosnet.se to read other amazing programming tricks and more...

  The version released in the Imphobia mag and in september 96 has some bugz
  in the code description.  I hope that the  current version doesn't contain
  bugz anymore.  I've also reactualized the text and added some stuffs.
  --------------------------------------------------------------------------

  References:
  -----------

- "Programmer's Guide to the EGA and VGA Cards", Second Edition, Richard
  Ferraro, Addison-Wesley. (The Third Edition exists !!!)

- "VGADOC 4/WHATVGA 2.00", Finn Thoegersen. Available on nice FTPs like
  ftp://garbo.uwasa.fi/pc/doc-hard/vgadoc4b.zip

- Scitech products : sdd53a.exe (univbe 5.3a), svbase60.exe (svga kit 6.0)
                     mgl30.exe (Graphics Library)

  ftp://ftp.scitechsoft.com/dev

- VBE 2.00 official doc : vbe200.exe
  ftp://ftp.scitechsoft.com/dev

- alternative VBE 2.00 for S3 and Video RAM booster: s3vbe200.zip, s3spdup.zip
  ftp://ftp.uni-muenster.de/pub/meschede

- Cirrus Video RAM booster : cirb101.zip or cirboost.zip (written by me ;-) )
  ftp://ftp.cdrom.com/pub/demos/code/hardware

- FLamoot VGA setup : flamoot.zip (written by me ;-) )
  ftp://ftp.cdrom.com/pub/demos/code/vga

- VGATricks 4 by Trixter/Hornet - vgadoc4.zip
  ftp://ftp.cdrom.com/pub/demos/code/hardware

  Well, i just want to speak here about tricking the VGA/SVGA adapter ...

  95% of the VLB video cards are SVGA and support at least 15 bits mode (32k).
100% of the PCI video cards support 32k, 65k, and 16M  colors  (in  24  or  32
bits),  and support LFB mode (linear frame buffer).  I don't know  any VLB/PCI
video cards with less than 1M ram.  So  since  the scene  has moved on 486 VLB
more than 3 years ago (and now Pentium/PCI),  why didn't they use the features
of the VLB/PCI-videos in demos sooner ???


I'll speak here about 12 points:

(1) History                     (7)  No Mode-X with SVGA  (13) 160x100
(2) 320x200x256 > 1 page        (8)  Video RAMs speed up  (14) 320x600
(3) 320x200 Hicolor             (9)  50Hz/60Hz            (15) Quiz?
(4) S3 Trio/Vision limitations  (10) 320x256              (16) BitBLT
(5) S3 805 bug                  (11) 120Hz/Luminati       (17) misc
(6) UNIVBE "safe" modes         (12) 256x256

                                  ==========
                                  1. HISTORY
                                  ==========

  As far as i know,  the first full SVGA demo i've seen is  the demo presented
by Realtech at ASM 95.  But,  if i remember, the rulez of the ASM 95 party was
that the demo had to run on a 100% VGA display too. Some  times  before,  some
groups  like  Impact Studios and their "Project Angel" demo implemented stuffs
using the SVGA properties (i.e. 320x200x256 chained and banked).  Even Complex
have  used  some  tricks  in their famous demo "Dope" to reduce wait states on
Cirrus Logic video cards. The problem of custom SVGA routs  is  obviously  the
incompatibility  with  future  generations of video cards and that is probably
why only a few guyz have attempted to play with SVGA.

  But  since  february 1995,  a new weapon is born which is called UNIVBE 5.1.
This nice VBE driver developped by Scitech offers you a 100% VBE 2.0 interface
(giving  you an  access  to LFB addressing), and last but not least, plenty of
new video modes (the one they can manage with your video cards), in particular
320x200x65k  and 320x200x256 multipages. When i got the beta release in  early
february  95,  I was just developping my own way to handle the SVGA, but i had
some probs to get my code working on all video cards.

  With the release of UniVBE 5.1,  i  immediatly  thought that everyone should
use it in demos,  to get really high quality gfx, in particular in 3D effects.
But  since  most  parties were forcing people to use VGA, i think that no many
groups were ready to adopt it,  and  so we've  seen  many  fake-18 bits  modes
and other cheats to make the illusion, and blah blah ...

  The opportunity to launch UniVBE 5.1 in the demo scene was Wired 95, because
some  members  of my crew (not me) were in the organizing staff, and because i
really believed in Wired. I've done all my possible to influence my friends to
allow  SVGA support (specially Hicolor and even True Color) with UniVBE 5.1...
and they have done it. At Wired 95, i think that 2 demos used SVGA features:

1) Realtech's "Countdown" which supports VBE 2.0 LFB, video modes from 320x100
   up to 1600x1200 !!!! (but still in 256 colors),  and even S3 BitBLT support
   (however some probs on S3-805 ;-) ).

2) Our demo "Hurtless", which also supports VBE 2.00 LFB (or 1.2 banked),  and
   640x200 & 320x200 32k colors,  320x200x256 16 pages (like "Project Angel"),
   with  UniVBE 5.1+  if  present,  or with  custom  routines  if not present,
   Hardware BitBLT for Cirrus Logic, Advanced Logic, S3, Primus, ... ;    DRAM
   speed up for S3 and Cirrus Logic.

  Then, during november 95, the demo A-Colors came, which supports 32k and 16M
(!!) colors.  At  The  Party 95,  Realtech  used  65K  colors  in  their  demo
"6th sense", really nice, (if you can run it, because their VBE 2.00 interface
was really bugged !!!).

  During spring 96, UNIVBE 5.2 was launched.  It supports the VBE 2.00 and the
VBE/AF standard.   With  VBE/AF,  you  have  a  clean way  to  access  the GFX
accelerators of your cards (Hardware BitBLT, lines, ...).   The  current  last
version of UNIVBE is the 5.3a.  It supports more cards than the 5.2, automatic
video centering and 32 bits palet functions.

  More and more demos/games have supported LFB and/or True/HiColor during 1996:
Quake,  Duke,  Supermax  (Complex/TG96),  Molejo  (Valhalla/Wired96),  Washing
Machine  (Coma/ASM96),  Balance  (Pulse/GRAVITY96), Vivatacidhouse (Zden Moshe
/Wired96),  First (Black Rainbow/Cache96),  Onyx (Shock/Cache96), Rotaliator (
Dubius/Skenery96), ...

  However UniVBE 5.1+ is a wonderfull tool,  it  has some limitations  that we
must consider if we want to run our code on every Video cards.  In newsgroups,
i've yet read some mails speaking about problems to run such demos (like  "Why
doesn't Supermax run on my S3 Trio", ...). In fact some video modes are "safe"
and  some others "not",  and even  new releases of  UniVBE 5.x will not change
that... but i'll speak about that in the next lines ...



     =====================================================================
     2. HOW TO DO 320x200x256 WITH MORE THAN 1 PAGE, WITHOUT UNIVBE 5.1+ ?
     =====================================================================

  The following tricks may be used if UniVBE isn't present.

  There are 3 ways:

a) Init mode 13h and enable access to bank registers

   You  have  to do a specific code to enable the bank registers, and then use
   a specific  code  to  switch  the  banks.  If you want a nice collection of
   specific codes,  I suggest you to D/L vgadoc4b.zip  (see in the beginning).
   This is the only way to get multipage on a S3, for example, because  method
   'b' doesn't work on such card.

b) Set 640x??? mode en then half the horizontal values

   I think this is the best method,  because  you start from a SVGA mode where
   all the bank registers are enabled. So you don't have to do a specific code
   to enable the banks and you can even use VESA calls to switch the banks !!!
   Moreover,  this  is the only solution if you want to get 320x200 multipages
   on Cirrus Logic video cards.  I think this works on 70% of the VGAs.   With
   this method you can even get a 320x200 LFB mode if you use a VESA 2.00 call.

h320 LABEL WORD
        DW 2D00h      ; 3d4/00  horizontal total
        DW 2701h      ; 3d4/01  horizontal display enable end
        DW 2802h      ; 3d4/02  horizontal blank start
        DW 9003h      ; 3d4/03  horizontal blank end
        DW 2B04h      ; 3d4/04  horizontal retrace start
        DW 8005h      ; 3d4/05  horizontal retrace end
        DW 2813h      ; 3d4/13  logical width
        DW 0901h      ; 3c4/01  clock mode register

        mov   ax,4f02h
        mov   bx,101h  ; 640x480x256 (60Hz)
        int   10h

        ; remove tho following lines
        ; if you want a LFB mode (need a VESA 2.00)
        ;
        ; mov   ax,4f02h
        ; mov   bx,4101h  ; 640x480x256 (60Hz)
        ; int   10h
        ;
        ; but now, your video page is somewhere above the first megabyte.
        ; Use the adequate VBE 2.00 system call to get the PHYSICAL address of
        ; the video page (function 4F01h : get mode infos). Then convert this
        ; physical address into a logical address using function 0800h of DPMI
        ; (int 31h) (see (14) misc). VBE 2.00 documentation is available on
        ; ftp.scitechsoft.com (see references at the beginning)

        mov   dx,3d4h  ; remove protection
        mov   al,11h
        out   dx,al
        inc   dl
        in    al,dx
        and   al,7fh
        out   dx,al
        dec   dl

        ; horizontal parameters
        mov   esi,OFFSET h320
        REPT  6+1
        outsb
        inc   dl
        outsb
        dec   dl
        ENDM
        mov   dl,0c4h
        outsb         ; clock
        inc   dl
        outsb

        ;----------------------------------
        ; we are in 320x480x256 (60Hz) !!!!
        ;----------------------------------

        mov   dx,3d4h  ; double the lines
        mov   al,9
        out   dx,al
        inc   dl
        in    al,dx
        and   al, NOT(31)
        or    al, 1
        out   dx,al

        ;------------------------------------
        ; Now we have 320x240x256 (60Hz) !!!!
        ;------------------------------------

        ; hey these values are dumped from Mode 13h ;-)
        ;
        ; misc output
         mov   dx,3cch   ; clock reg read
         in    al,dx     ; get current Vertical/Horizontal clock
         and   al,0Fh    ; keep horizontal clock
         or    al,60h    ; 400 scanlines V-clock
         mov   dl,0c2h   ; clock reg write
         out   dx,al

         mov   dl,0d4h   ; CRTC port
         mov   ax,0bf06h ; vertical total
         out   dx,ax
         mov   ax,01f07h ; overflow reg
         out   dx,ax
         mov   ax,09c10h ; vertical retrace start
         out   dx,ax
         mov   ax,08e11h ; vertical retrace end
         out   dx,ax
         mov   ax,08f12h ; vertical display enable end
         out   dx,ax
         mov   ax,09615h ; vertical blank start
         out   dx,ax
         mov   ax,0b916h ; vertical blank end
         out   dx,ax

         ;---------------------------------------------
         ; Now we have 320x200x256 but in 60Hz :-( !!!!
         ;---------------------------------------------


c) enable a 128k page in a0000-bffff to get 2 pages

   This doesn't work on every cards. It works on the Cirrus Logic and possibly
   on some Tsengs (?), and ...  I suggest you to do a test. Make sure that you
   don't  have  EMM  or  QEMM using the space between b0000 and bffff (you can
   test it by checking if there is RAM in this zone before enabling the 128k).
   On Cirrus Logic, it only works in SVGA modes :-(.

         mov    dx,3ceh          ; active 128k adressing
         mov    al,06
         out    dx,al
         inc    dl
         in     al,dx            ; rem: dx=3cf/3ce=6
         and    al,NOT(1100y)    ; Video RAM should be mapped on a0000-b7fff
         out    dx,al


  But  even  with  these 3 methods, there are still video cards on which it is
impossible to get a full working multipage mode (ie. S3 805)



             ====================================================
             3. HOW TO DO 320x200 HICOLOR WITHOUT UniVBE 5.1+ ???
             ====================================================

  The following trick may be used if UniVBE is not present.

  On  most  SVGA  HiColor  cards,  you  can  obtain  320x200  HiColor  from  a
640x480x256 or 640x400x256  mode  (VESA 101h and 100h respectively).  This  is
because most HiColor DACs are inspired from early Sierra DAC  (which  combines
2 consecutive bytes to form a color),  but  they  don't  use the same value to
enter in HiColor.  So we also need 640x480 Hicolor, just to dump the DAC value
in this mode.  640x480 Hicolor  should be supported by every BIOS because it's
a Windows mode ;-).


  For  example,  if your video card has a Sierra like DAC,  you can do 320x200
hicolor using the following method:


         ;  SIERRA DAC like method (works on 75% of the cards) !!!

         mov   ax,4f02h
         mov   bx,110h  ; set VESA 640x480x32K colors (works on VESA 1.2+)
         int   10h      ; (60 Hz)

        ; remove tho following lines
        ; if you want a LFB mode (need a VESA 2.00)
        ;
        ; mov   ax,4f02h
        ; mov   bx,4110h ; 640x480x32K (60Hz)
        ; int   10h
        ;
        ; but now, your video page is somewhere above the first megabyte.
        ; Use the adequate VBE 2.00 system call to get the PHYSICAL address of
        ; the video page (function 4F01h : get mode infos). Then convert this
        ; physical address into a logical address using function 0800h of DPMI
        ; (int 31h) (see (14) misc). VBE 2.00 documentation is available on
        ; ftp.scitechsoft.com (see references at the beginning)

         mov   dx,3d4h  ; remove protection
         mov   al,11h
         out   dx,al
         inc   dl
         in    al,dx
         and   al,7fh
         out   dx,al

         mov   dx,3c8h
         in    al,dx    ; reset to normal mode
         mov   dx,3c6h
         in    al,dx    ; FLIP-FLOP (see Ferraro's book for more precisions)
         in    al,dx
         in    al,dx
         in    al,dx    ; enable RS1

         in    al,dx    ; dump the DAC value in HiColor
         mov   HDAC,al  ; save it !!!

         mov   dx,3c8h
         in    al,dx    ; reset to normal mode

         mov   ax,4f02h
         mov   bx,101h  ; set VESA 640x480x256 colors (works on VESA 1.2+)
         int   10h      ; (60 Hz)

         mov   dx,3c8h
         in    al,dx    ; reset to normal mode
         mov   dx,3c6h
         in    al,dx
         in    al,dx
         in    al,dx
         in    al,dx    ; enable RS1

         mov   al,HDAC  ; get HiColor DAC value
         out   dx,al    ; set IT !!!!

         mov   dx,3c8h
         in    al,dx    ; reset to normal mode

         ;----------------------------------------
         ; You are now in 320x480x32K (60 Hz) !!!!
         ;----------------------------------------

         mov   dx,3d4h  ; double the lines
         mov   al,9
         out   dx,al
         inc   dl
         in    al,dx
         and   al, NOT(31)
         or    al, 1
         out   dx,al

         ;------------------------------------
         ; Now we have 320x240x32K (60Hz) !!!!
         ;------------------------------------

 ***     ; hey these values are dumped from Mode 13h ;-)
         ;
         ; misc output
         mov   dx,3cch   ; clock reg read
         in    al,dx     ; get current Vertical/Horizontal clock
         and   al,0Fh    ; keep horizontal clock
         or    al,60h    ; 400 scanlines V-clock
         mov   dl,0c2h   ; clock reg write
         out   dx,al

         mov   dl,0d4h   ; CRTC port
         mov   ax,0bf06h ; vertical total
         out   dx,ax
         mov   ax,01f07h ; overflow reg
         out   dx,ax
         mov   ax,09c10h ; vertical retrace start
         out   dx,ax
         mov   ax,08e11h ; vertical retrace end
         out   dx,ax
         mov   ax,08f12h ; vertical display enable end
         out   dx,ax
         mov   ax,09615h ; vertical blank start
         out   dx,ax
         mov   ax,0b916h ; vertical blank end
         out   dx,ax

         ;---------------------------------------------
         ; Now we have 320x200x32K but in 60Hz :-( !!!!
         ;---------------------------------------------


  Notes:

- If you start from 640x400, you'll get a 320x200x32K 70Hz,  but  the  problem
  is  that  640x400x256 is not present on every video cards (ie. Cirrus Logic,
  ...). However 640x400x256 is done on every video cards by UniVBE 5.1, but in
  this case,  if 320x200x32K is possible, UniVBE will provide it to you and it
  is not necessary to do it by hand !!!

- You can switch in a 65K mode in  a similar manner  (use mode 111h instead of
  110h at the beginning to dump the registers).

- You  can  get 320x350 or multiples if instead of the values dumped from Mode
  13h in ***, you use the values of the EGA mode 640x350... (the 350 scanlines
  V-clock is A0h, vertical total = BF06h, overflow = 1F07h,  v-retrace start =
  8310h, v-retrace end = 8511h, v-display enable end = 5D12h,  v-blank start =
  6315h, v-blank end = BA16h)

- You can call the "setdac15_" (or setdact16_) procedure of VGADOC4 to switch
  the DAC  and  to   avoid  the  Sierra  FLIP-FLOP.  setdac15_, (or setdac16_,
  setdac24_) is more general, it supports BrookTree DAC, ...  and even S3 Trio
  (but in this case, the screen becomes totally crasy ;-) ). This works on 85%
  of the cards.


  If your application is designed to run on 486s,  I  suggest you to use a 32K
display  (becoz there are VLB and ISA boards supporting only 15bits/pix)  with
both LFB and BANKED adressing support.   If  it's  designed for  Pentium,  65K
LFB is preferable   ( I don't think  there exists  a PCI card without 65K  and
LFB adressing support. Oops, yes i've seen a Trident PCI 1Mo with only 256 col
DAC at my office ;-)....).



                     =====================================
                     4. S3 TRIO/VISION 864/964 LIMITATIONS
                     =====================================

  The new S3 family uses a new integrated RAMDAC wich is not  compatible  with
the old "Sierra"-like DAC wich was on S3-805, ...

  This new RAMDAC seems not to be able to handle 320x200 in  Hicolor/Truecolor
mode,  so  you  have  to  make  a version of your application runing in a mode
derivated from 640x480 Hicolor to be certain.

  S3 Trios are only able to display  16.7M colors  with  32 bits/pix  and  not
24 bits/pix !!!  This require a 2M adapter,  so  maybe  65K  is  preferable to
16.7M.

  We can't ignore S3 Trios because they are one of the best-selled videocards.



                 =============================================
                 5. S3 805 PROBLEMS WITH 320x200x256 MULTIPAGE
                 =============================================

  In particular the mode offered by UniVBE 5.1+.. This  mode  is  obtained  by
enabling  banking  in  mode  13h.  This works on all S3, but on the 805 series
(many S3 VLBs) and may be on the 911 (i haven't tested), the pair  and  impair
rows are inverted !  Which is far to be aesthetic !!!  So regular mode 13h has
still a reason to exist !!!   So  demo/game  coders,  if you use a 320x200x256
display, do always a version runnable in 13h !!!  This  is also  true  for the
other low-res 256 colors modes :  320x???  &  360x??? (Quake is really ugly on
S3 805 with UniVBE low-res 256 colors modes :-( ).



                   =======================================
                   6: THE UniVBE MODES THAT ARE "SAFE" !!!
                   =======================================

  The UNIVBE  modes  that you  will get on  every 1M True  colors VLB/PCI SVGA
cards are (I don't consider modes above 640x480) :

          ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          640x480x256 (60Hz)  640x480x32k (60Hz)  640x480x65k (60Hz)
          640x400x256 (70Hz)  640x400x32k (70Hz)  640x480x65k (70Hz)
          640x350x256 (70Hz)  640x350x32k (70Hz)  640x480x65k (70Hz)
          ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  These are the high-res modes of UniVBE.   The so-called low-res modes are to
be  used very  carefully  (320x???,  360x???,  512x???)  because they can't be
handled on every cards (because of hardware limitations or because these cards
are too new  to be  supported  by UniVBE). Ex :  I wasn't able to show Molejo/
Valhalla to a friend because it works only in  Hicolor low-res and UniVBE 5.3a
can't handle these modes on his S3 Vision 968.

  Remember that  when a video  card is VBE 2.00  compatible, that doesn't mean
that there's a UniVBE integrated in the card.  VBE 2.00 is a specification for
constructors  (they don't impose any video modes)  and UniVBE  is a product of
Scitech!  For example,  i don't think  that  the integrated BIOS of the Matrox
Millenium (or newer models) have support for low-res modes.

  For my part, to be totally safe, i'm using routines that simulate 320x240 on
640x480 65k/32k when the low-res mode 320x240 isn't available.  So my code can
work on every new cards and  use  the benefits of UniVBE when it's present and
can handle low-res.

  However,  if you take the restriction  that  your code will only work on VGA
compatible cards (remember that VBE 2.00 is also available on Tiga, ...  there
is a flag in the modeinfo block returned by the function 4F01h  that indicates
if the mode is VGA compatible or not),you can alter the vertical ratio without
problem,  simply  by  ajusting  the  character  height  (using the regular VGA
registers):

            mov dx,3d4h
            mov al,9
            out dx,al
            inc dl
            in  al,dx
            and al, NOT(31)
            or  al, height
            out dx,al

            with 0 <= height <= 31


Example: if you set 640x480x256, you have

         with height = 0 : 640x480x256   -> /1
                     = 1 : 640x240x256   -> /2
                     = 2 : 640x160x256   -> /3
                     = ...

Note:  However the 800x600 and 1024x768 modes are safe, they can have problems
       with a video projector, so use them as a bonus.



                             ====================
                             7: NO X-MODE IN SVGA
                             ====================

  I've read some articles on the Net and in the PCGPE, I think,  talking about
using Mode X with a 640x400x256 or 640x240x256 display.  The idea is not bad ,
because with conventionnal Mode X,  you can address 256k of Video RAM  without
banking. So Mode X should offer a way to use such videos modes without banking
on every video cards (even old ISA).

  But... this is true if you suppose that your SVGA card works like a VGA card
in such modes ...  and that is NOT true !!!  New  generations  of cards are no
more Mode X compatible in Hi-Res !!!  If you try such code on S3, for example,
you will get some surprises.



                        ================================
                        8: Video RAMs SPEED UP / BOOSTER
                        ================================

a)  You  can  obtain  better  performance with a Cirrus Logic 542x, if you add
    these lines in your code (even with Mode X !) :
    --------------------------------------------------------------------------

        mov  dx,3c4h
        mov  al,0fh
        out  dx,al
        inc  dl
        in   al,dx
        and  al,NOT(8+16+32)
        or   al,(6 SHL 3)           ; 32 bit mode + CRT FIFO depth control
        out  dx,al

        dec  dl
        mov  al,16h
        out  dx,al
        inc  dl
        in   al,dx
        and  al,15
        or   al,(0 SHL 4)+(2 SHL 6) ; delay for mem Write I/O
        out  dx,al

  It  basically  reduces  the  Video RAMs  wait states.  I  think that Complex
used a similar trick in "Dope".  Normally there are no probs,  but it's always
a good idea to allow the user to disable the booster.


b) S3 cards can be accelerated by the following code :
   ---------------------------------------------------

; code hacked from S3SPEEDUP / meschede
; available on ftp.uni-muenster.de /pub/meschede/...

; read(port, index, value)         ; write(port, index, value)
; dx = port                        ; dx = port
; al = index                       ; al = index
; value -> ah                      ; ah = value
Read3D4  PROC NEAR                 Write3D4 PROC NEAR
         mov  dx,3d4h                       mov  dx,3d4h
         out  dx,al                         out  dx,al
         mov  ah,al                         xchg ah,al
         inc  dx                            inc  dx
         in   al,dx                         out  dx,al
         xchg ah,al                         xchg ah,al
         dec  dx                            dec  dx
         ret                                ret
Read3D4  ENDP                     Write3D4  ENDP


; enable extensions
ExtON    PROC NEAR
         mov  ax,4838h ; extensions enable (enable extended registers)
         call Write3D4 ; write(3d4h, 38h, 48h)
         mov  ax,0A039h; extensions enable2
         call Write3D4 ; write(3d4h, 39h, a0h)
         ret
ExtON    ENDP

; disable extensions
ExtOFF   PROC NEAR
         mov  ax,0038h ; disable extended registers
         call Write3D4 ; write(3d4h, 38h, 00h)
         mov  ax,0039h ; disable2
         call Write3D4 ; write(3d4h, 39h, 00h)
         ret
ExtOFF   ENDP

; enable linear and set vidmem to 0a0000h !!!!!!
MAP_A000H PROC NEAR
         pusha
         mov  bl,0ECh
         mov  bh,10h
         mov  cx,000Ah
         call ExtON   ; enable extensions
         mov  al,058h ; linear aperture options / bit 2
         call Read3D4 ; ah = read(3d4h, 58h)
         and  ah,0ECh ; clear bit 0,1 and 4
         call Write3D4; write(3d4h, 58h, new AH)
         mov  al,059h ; bit 0-1: linear memory address bit 8-9
         mov  ah,ch
         call Write3D4; write(3d4h, 59h, 00h)
         inc  al      ; 05Ah : bit 0-7 = linear mem address bit 0-7
         mov  ah,cl   ; in 64k units ???
         call Write3D4; write(3d4h, 5Ah, 0Ah)
         mov  al,058h ; linear aperture options
         call Read3D4 ; ah = read(3d4h, 58h)
         and  ah,bl   ; and ah,ECh -> clear bit 0,1 and 4
         or   ah,bh   ; or ah,10h (OR or ah,00h) -> set bit 4
         call Write3D4; write(3d4h, 58h, new AH)
         call ExtOFF  ; disable extensions
         popa
         ret
MAP_A000H ENDP

FAST_WRITE_BUFFER_ON PROC NEAR
         pusha
         call  ExtON   ; enable extensions
         mov   al,40h  ; bit 0: if set enables 8514/A mode
         call  Read3D4 ;   * 3: (801,805,928) Fast Write Buffer ON *
         or    ah,08h  ;     6: (801,805,928) Zero Wait State OFF (EISA)
         call  Write3D4; set bit 3 to ON
         call  ExtOFF  ; disable extensions
         popa
         ret
FAST_WRITE_BUFFER_ON ENDP

If you want to boost an SVGA mode banked, just type:

         call  MAP_A000h
         call  FAST_WRITE_BUFFER_ON

If you want to boost an SVGA LFB mode, just type:

         call  FAST_WRITE_BUFFER_ON



                      ====================================
                      9: 320x200x256 50Hz AND 60Hz CHAINED
                      ====================================

  If  you  want 50Hz chained mode (why ???), as in the demo "Xtal" by Complex,
just type this code:

        mov ax,13h
        int 10h       ; regular mode 13h chained

        mov dx,3d4h   ; remove protection
        mov al,11h
        out dx,al
        inc dl
        in  al,dx
        and al,7fh
        out dx,al

        mov dx,3c2h   ; misc output
        mov al,0e3h   ; clock
        out dx,al

        mov dx,3d4h
        mov ax,07006h ; Vertical Total
        out dx,ax
        mov ax,03E07h ; Overflow
        out dx,ax
        mov ax,0F310h ; Vertical start retrace
        out dx,ax
        mov ax,08C11h ; Vertical end retrace
        out dx,ax
        mov ax,08F12h ; Vertical display enable end
        out dx,ax
        mov ax,0E715h ; Vertical blank start
        out dx,ax
        mov ax,00416h ; Vertical blank end
        out dx,ax


  It  works  on  every  VGA !!!  Maybe some probs with VGA-2-RGB converters or
projectors... and it flicks a bit :-(

  The 320x200x256 60Hz version is normally more adapted for RGB projector  and
doesn't flick (and it is console compatible ;-), nice for games developpers) :

        mov ax,13h
        int 10h       ; regular mode 13h chained

        mov dx,3d4h   ; remove protection
        mov al,11h
        out dx,al
        inc dl
        in  al,dx
        and al,7fh
        out dx,al

        mov dx,3c2h   ; misc output
        mov al,0e3h   ; clock
        out dx,al

        mov dx,3d4h
        mov ax,0B006h ; Vertical Total
        out dx,ax
        mov ax,03E07h ; Overflow
        out dx,ax
        mov ax,0C310h ; Vertical start retrace
        out dx,ax
        mov ax,08C11h ; Vertical end retrace
        out dx,ax
        mov ax,08F12h ; Vertical display enable end
        out dx,ax
        mov ax,0E715h ; Vertical blank start
        out dx,ax
        mov ax,00416h ; Vertical blank end
        out dx,ax



                             ======================
                             10) 320x256x256 60Hz X
                             ======================

  Or the "Amiga PAL mode" ;-), like in "Ninja II" by Melon & Scoop,  just type
this code:

        mov ax,13h
        int 10h       ; regular mode 13h chained

        mov dx,3d4h   ; remove protection
        mov al,11h
        out dx,al
        inc dl
        in  al,dx
        and al,7fh
        out dx,al

        mov dx,3c4h
        mov ax,0604h
        out dx,ax     ; unchain

        mov dx,3c2h   ; misc output
        mov al,0e3h   ; clock
        out dx,al

        mov dx,3d4h
        mov ax,00B06h ; Vertical Total
        out dx,ax
        mov ax,0B207h ; Overflow
        out dx,ax
        mov ax,00A10h ; Vertical start retrace
        out dx,ax
        mov ax,0AC11h ; Vertical end retrace
        out dx,ax
        mov ax,0FF12h ; Vertical display enable end
        out dx,ax
        mov ax,00014h ; for mode X
        out dx,ax
        mov ax,00515h ; Vertical blank start
        out dx,ax
        mov ax,01016h ; Vertical blank end
        out dx,ax
        mov ax,0e317h ; for mode X
        out dx,ax


  This mode works like Mode-X and it works on every VGA !!!  Normally, it will
pass on every RGB converter/projector ...



                  ===========================================
                  11) 320x200x256 120Hz : The Luminati mode
                  (16 BITS MODE/TRANSPARENCY ON STANDARD VGA)
                  ===========================================

  A mode like the one used by Tran in his famous demos "Ambiance" and
  "Luminati" :

        mov ax,13h
        int 10h       ; regular mode 13h chained

        mov dx,3d4h   ; remove protection
        mov al,11h
        out dx,al
        inc dl
        in  al,dx
        and al,7fh
        out dx,al

        mov dx,3c4h
        mov ax,0604h
        out dx,ax     ; unchain

        mov dx,3d4h
        mov ax,00506h ; Vertical Total
        out dx,ax
        mov ax,01107h ; Overflow
        out dx,ax
        mov ax,0E710h ; Vertical start retrace
        out dx,ax
        mov ax,00011h ; Vertical end retrace
        out dx,ax
        mov ax,0C712h ; Vertical display enable end
        out dx,ax
        mov ax,00014h ; for mode X
        out dx,ax
        mov ax,0EF15h ; Vertical blank start
        out dx,ax
        mov ax,00816h ; Vertical blank end
        out dx,ax
        mov ax,0e317h ; for mode X
        out dx,ax


  It works in mode X in order to get 4 pages.

- You just have to flip between 2 screens, one containing the first 8 bits and
  the other containing the other 8 bits of the RGB colors.

            RRRRR GGGGGG BBBBB

               to split in
   RRRRRGGG                    GGGBBBBB
(pal and pic 1)    and     (pal and pic 2)
   1st page                    2nd page


- You can also flip between two traditionnal 256 colors screens to get some
  transparency !


  The only problem with this mode is that it is totally incompatible with  RGB
projectors  used  in  demos  parties.  So, this kind of modes is to be used in
BBStros, or if you want to use it in a party, you have to do a regular version
for RGB projector (using true HiColor, or using fake 18 bits -like Orange, for
example-, ...).  Comment:  fake 18 bits  is a mode like 320x480 or 640x480 256
colors where each scanline contains one primary color -> scan 0 = red,1=green,
2 = blue, 3 = red, 4 = green, 5 = blue, .... So you get a simulated  ??? x 160
18 bits mode (6 bits per primary color).

  It works on every VGA !!!!   Maybe not really good for some "modern" screens
which have automatic synchronisation (fine for windoze modes ;-) )


                            ===========================
                            12) 256x256 256 colors/60hz
                            ===========================

  This mode has the property to  have 256 bytes per scanline,  which is  quite
efficient for calculating the position of a dot.  The low byte  of  the  start
address is the X-coordinate and the high byte is the Y-coordinate.  This  mode
must be used carefully because  it's incompatible with  some screens and video
projectors... This mode is chained and you've got 1 page.


        mov ax,13h
        int 10h       ; regular mode 13h chained

        mov dx,3d4h   ; remove protection
        mov al,11h
        out dx,al
        inc dl
        in  al,dx
        and al,7fh
        out dx,al

        mov dx,3c2h   ; misc output
        mov al,0e3h   ; clock
        out dx,al

        mov dx,3d4h

        mov ax,05f00h ; Horizontal Total
        out dx,ax
        mov ax,03F01h ; Horizontal display enable end
        out dx,ax
        mov ax,04002h ; Horizontal blank start
        out dx,ax
        mov ax,08003h ; Horizontal blank end
        out dx,ax
        mov ax,05004h ; Horizontal retrace start
        out dx,ax
        mov ax,09A05h ; Horizontal retrace end
        out dx,ax
        mov ax,00B06h ; Vertical Total
        out dx,ax
        mov ax,0B207h ; Overflow
        out dx,ax
        mov ax,00A10h ; Vertical start retrace
        out dx,ax
        mov ax,0AC11h ; Vertical end retrace
        out dx,ax
        mov ax,0FF12h ; Vertical display enable end
        out dx,ax
        mov ax,02013h ; offset/logical scanline length
        out dx,ax
        mov ax,00515h ; Vertical blank start
        out dx,ax
        mov ax,01016h ; Vertical blank end
        out dx,ax


                ==============================================
                13) 160x100 256 colors - a technical curiosity
                ==============================================

  This  mode was  compatible  with every pure VGA cards,  but nowadays  it is
unstable with modern SVGA cards.  I only put it as a curiosity.

The principle is the same as 320x200 Hicolor,  but here  instead of switching
from 8 bits to 16 bits, you switch from 4 bits to 8 bits.

        mov    ax,0Dh
        int    10h        ; VGA 320x200x16 colors planar

        mov    dx,3d4h    ; double the lines
        mov    al,9
        out    dx,al
        inc    dl
        in     al,dx
        and    al, NOT(31)
        or     al, 1
        out    dx,al

        ; we are in 320x100x16 colors planar

        mov    dx,3c4h
        mov    ax,0E04h
        out    dx,ax      ; chain

        mov    dx,3d4h
        mov    ax,04014h  ; for chained mode
        out    dx,ax
        mov    ax,0A317h  ; for chained mode
        out    dx,ax

        ; we are in 320x100x16 colors chained (2 pixels of 4 bits/byte)

        mov    dx,3ceh    ; turn on DAC in 256 colors
        mov    al,05h
        out    dx,al
        inc    dl
        in     al,dx
        or     al,40h
        out    dx,al

        mov    dx,3c0h
        mov    al,030h
        out    dx,al
        inc    dl
        in     al,dx
        or     al,61h
        dec    dl
        out    dx,al

        ; we are in 160x100x256 colors chained (we have 4 pages)


I've used this mode in the first TFL-TDV demo called "Contrast" (not the one
by OXG ;-)) which won 2nd place at Wired 94 (yep, 3 years ago).


         ============================================================
         14) 320x600 - a nice way to do 18 bits on VGA 8 bits display
         ============================================================

  This nice mode was mentionned by Trixter/Hornet in his good VGA tricks docs.
This mode was first used by Adam BegStrom (as Trixter said)  and it's used in
the NAID (95?) report.  We've just used it in our X97 demo (Zone512 by Pulpe).

  The principle is always the same... You take your favourite 13h mode and you
modify the vertical parameters by taking those from 800x600x16 colors  (a mode
which is  between VGA and SVGA :  it's VESA but it  has curiously the standard
number 6Ah (VESA numbers are normally >= 100h and initialized with an extended
call to int 10h).


        mov    ax,13h
        int    10h        ; VGA 320x200x256 colors chained

        mov    dx,3d4h    ; remove protection
        mov    al,11h
        out    dx,al
        inc    dl
        in     al,dx
        and    al,7fh
        out    dx,al

        mov    dx,3c4h
        mov    ax,0604h
        out    dx,ax     ; unchain

        ; substitute standard parameters by those grabbed from 800x600x16

        mov    dx,3c2h   ; misc output
        mov    al,0e7h   ; change the clock
        out    dx,al

        mov    dx,3d4h
        mov    ax,06F06h ; Vertical Total
        out    dx,ax
        mov    ax,0F007h ; Overflow
        out    dx,ax
        mov    ax,06009h ; height to 0, don't double lines ...
        out    dx,ax
        mov    ax,05810h ; Vertical start retrace
        out    dx,ax
        mov    ax,08A11h ; Vertical end retrace
        out    dx,ax
        mov    ax,05712h ; Vertical display enable end
        out    dx,ax
        mov    ax,00014h ; for mode X
        out    dx,ax
        mov    ax,05815h ; Vertical blank start
        out    dx,ax
        mov    ax,06F16h ; Vertical blank end
        out    dx,ax
        mov    ax,0e317h ; for mode X
        out    dx,ax

  This mode gives you the same refresh as standard  800x600x16 which is 56 Hz
(in non-interlaced mode). The main interest of it is that the number of scan-
lines = 3x200  which is a triple 320x200x256 colors.   This can help to do an
elegant fake mode alternating RED/GREEN/BLUE lines. You can use it if you are
doing 24-bits colors effects. The effects can be designed for 24 bits and con-
verted to match the current VGA adapter (VESA True Color or fake mode 320x600
if not available). Rem: the addressing scheme is Mode-X.

  This mode should work with every monitors/projectors able to handle 800x600
non interlaced (which is normally always the case nowadays).


                                  ==========
                                  15) Quiz ?
                                  ==========

        ; Low-Hires ??????

        mov    ax,0Dh
        int    10h

        mov    dx,3d4h
        mov    al,11h
        out    dx,al
        inc    dl
        in     al,dx
        and    al,7fh
        out    dx,al

        mov    dx,3ceh
        mov    al,05h
        out    dx,al
        inc    dl
        in     al,dx
        or     al,40h
        out    dx,al

        mov    dx,3c0h
        mov    al,030h
        out    dx,al
        inc    dl
        in     al,dx
        or     al,61h
        dec    dl
        out    dx,al

        mov    dx,3c2h
        mov    al,0e7h
        out    dx,al

        mov    dx,3d4h
        mov    ax,06F06h
        out    dx,ax
        mov    ax,0F007h
        out    dx,ax
        mov    ax,06009h
        out    dx,ax
        mov    ax,05810h
        out    dx,ax
        mov    ax,08A11h
        out    dx,ax
        mov    ax,05712h
        out    dx,ax
        mov    ax,05815h
        out    dx,ax
        mov    ax,06F16h
        out    dx,ax


Hahahaha !!!!! Do ya like it, Trixter ;-) ???????



                                  ==========
                                  16) BitBLT
                                  ==========

  Well, I don't want to develop the way to do Hardware BitBLT in this article,
but maybe i'll do in a next one.  Just some words:

  In fact,  Hardware BitBLT is really (and only?) usefull to clear a screen or
to copy a background in SVGA modes (at least if you don't want to rebuild your
code for each BitBLT processor). You can really improve your code if you use a
really  high  definition like 640x480 or 800x600...  For my part, i used it in
320x200x32K to scroll a background (128k to restore),  and I really got 5 more
frames/sec on a 486 DX40, using BitBLT.

  BitBLTs are stable in SVGAs modes... Don't use it in VGA modes !!! Don't use
it in the 320x200x256 multipages provided by UniVBE 5.1+, and don't use it  in
24 bits modes ( 3 BYTES / colors )  (BitBLT gets a bit confused when it has to
work with 3 bytes/col, in particular on S3).

  BitBLT is now easier with UniVBE 5.2+ and his VBE/AF support or with DirectX.
VBE/AF doc/code is available on ftp.scitechsoft.com,  and  DirectX doc/code is
available on ftp.microsoft.com (http://www.microsoft.com).



                           ========================
                           17) miscellaneous things
                           ========================


I assume here that you work in 32 bits protected mode...  Descriptions grabbed
from PMODEW 1.33 doc written by Thomas Pytel (Tran).


Function 0800h / DPMI INT 31h - Physical Address Mapping:
---------------------------------------------------------

  Converts a physical address into a linear address. This functions allows the
client  to  access  devices  mapped  at a  specific  physical  memory  address.
Examples  of this are  the frame buffers  of certain  video  cards in extended
memory.

In:
  AX     = 0800h
  BX:CX  = physical address of memory
  SI:DI  = size of region to map in bytes

Out:
  if successful:
    carry flag clear
    BX:CX  = linear address that can be used to access the physical memory

  if failed:
    carry flag set

Notes:
) It is the caller's responsibility to allocate and initialize a descriptor
  for access to the memory.

) Clients should not use this function to access memory below the 1 MB
  boundary.


Function 0801h / DPMI INT 31h - Free Physical Address Mapping:
--------------------------------------------------------------

  Releases a mapping of  physical  to  linear addresses  that was  previously
obtained with function 0800h.

In:
  AX     = 0801h
  BX:CX  = linear address returned by physical address mapping call

Out:
  if successful:
    carry flag clear

  if failed:
    carry flag set

Notes:
) The client should call this function when it is finished using a device
previously mapped to linear addresses with function 0801h.



                             ====================


  Greets to all my friends, all ex-TFL-TDV members, all Pulpe members,all kewl
guyz of the scene  I got a  nice chat with, and all guyz who will greet me and
my group in the future ;-)

 I especially thanx Bismarck/ex-TFL-TDV and Access/Pulpe for accepting SVGA at
Wired 95, Wizard/Imphobia and Walken/Impact Studios for some inspirations.

  Contact me at the following addresses:

  - llardin@cubic.pctrading.be

    if it doesn't work, ask access@pctrading.be or jcardin@is1.ulb.ac.be
    my current email

  - Laurent Lardinois
    271 chausse de Saint Job
    1180 Bruxelles, Belgium

                                          (C) 1997 Type One / Pulpe, ex TFL-TDV

*******************************************************************************
  The demo "Hurtless" TFL-TDV  presented at Wired 95,  featured 320x200/640x200
Hi-Color,  320x200x256  chained  multipages,  Hardware BitBLT,  LFB,  Video RAM
booster support, WITH or WITHOUT UniVBE, and N-Buffering.  Have  a  look if you
want  to  see  the thing working (however the demo might be unstable because of
the intensive use of Mikmod 2.03  virtual  timers ...  but  maybe  we'll  do  a
special release with Midas instead of Mikmod. The SB support is really random).
It is available on ftp.cdrom.com, ftp.arosnet.se, and hagar.arts.kuleuven.ac.be
*******************************************************************************

