
                                        ͸
                                                              
                      -=  OUTLAW  TRIAD  =-        

                                  Presents 


                    TWEAKING THE VIDEOMODE 13h INTO MODEX 
                                                              
                                                              
                Copyright Outlaw Triad (C) 1995  ;



  Written By : Vulture/OT                 Total Files  : 2
  File Type  : Textfile                   Release Date : 17th of December '95
  Difficulty : Hard level                 Filename     : TWEAKDOC.ARJ


Hello there! Vulture here typing another document on vga-programming.

Some time ago I wrote and released a textfile (CHAINDOC.ARJ) on the unchained
vgamode 13h. In this document I (tried to) explain it is possible to use the
256kB on the standard vga-card in mode 13h. To do this, one must unchain the
videomode. This gives us a resolution of 320*200*256 and 4 pages in display
memory. I also stated that it is possible to tweak the unchained videomode
into other resolutions. The way you handle a tweaked mode is the same as in
a standard unchained mode but you can get different resolutions to work with.

This document shows how to get into the ModeX, the mode which was 'invented'
by Michael Abrash in his columns printed in Dr Dobbs Journal. This mode has
a resolution of 320*240*256 which gives us 3 pages to work with and besides
that, it gives us a perfect square pixel. This eliminates the rectangular
pixels in standard mode 13h or standard unchained videomode. It is also
possible to get in even higher resolutions like 320*400*256. I will explain
that too. Full assembler source is included in this document. Enjoy!



The topics handled in this document will be:

 A. How to get into modex.
 B. Assembler code for modex.
 C. Other modes.
 D. Closing words.



- A. HOW TO GET INTO MODEX -

It is possible to tweak the vga-mode 13h into other resolutions. In order
to do this, one must first unchain the vgamode. This gives us the normal
unchained vga-mode with 4 pages of display memory. We then alter some vga
registers to get into a higher (or lower) resolution. For plasma you could
use a low resolution so you have to process less pixels. This gives more
speed to your demo. When displaying a picture, you could use a higher mode.
To get a different resolution to work with, you must reprogram the CtrC
Register. A total of 10 CrtC indexes must be updated. This can be done using
the OUT statement in assembler. First you select the CrtC Adress Register.
This is port 03d4h. Then select an index and give it the appropiate data.
The index and data values both are bytes. Two bytes are a word so you can
store the values into 1 register. In our case we'll use AX. Store the index
value into AL, the data into AH, out AX to the CrtC Register and you're done!
E.g 00d06h would mean index 06h (loaded in AL) and data 00dh (loaded in AH).
Do this for all 10 registers which must be updated. Piece of cake, eh?
Once you know what you're doing...

In the following diagram you can see which indexes must be altered and what
data should be transfered to these indexes. To fully understand what is done
when altering these registers, read a good book on vga-programming. If I go
and explain all of it in here, you would get a book anyway... ;-)

(Note: To get a better overview I have converted the hexdecimal value to
normal decimal values and their bitrepresentation. So one can see which bits
in the index are set and unset. I did this primarily for myself coz I had a
very hard time understanding the hex-code with both the index AND data in
them. Hopefully this will prefend you from having the same troubles I had.
Btw, there might be some errors in the convertion coz it's the first time
I did these things. And my math really stinks... ;-) )

- Diagram 1 -

       Index    Data in hex    decimal      binair
     
         6h        00dh      =    13d     =  00001101b
         7h        03eh      =    62d     =  00111110b
         9h        041h      =    65d     =  01000001b
         10h       0eah      =   234d     =  11101010b
         11h       0ach      =   172d     =  10101100b
         12h       0dfh      =   223d     =  11011111b
         14h       000h      =     0d     =  00000000b
         15h       0e7h      =   231d     =  11100111b
         16h       006h      =     6d     =  00000110b
         17h       0e3h      =   227d     =  11100011b

One can easily make these values accesable by using a label. As stated before,
the lower 2 values of the word represent the index we want to access while the
upper 3 values are representing the data that is being shifted to the selected
index. This is demonstrated here:

Label 320x240x256 Word      ; Index/data pairs for modex
  DW 00d06h     ; Vertical Total (first 8 bits)
  DW 03e07h     ; Overflow (ninth/tenth bit Vertical Total)
  DW 04109h     ; Cellheight (2)
  DW 0ea10h     ; Vertical Retrace Start
  DW 0ac11h     ; Vertical Retrace End & (un)protect registers 0-7
  DW 0df12h     ; Vertical Display End
  DW 00014h     ; Underline Location (disable dword mode)
  DW 0e715h     ; Start Vertical Blank
  DW 00616h     ; End Vertical Blank
  DW 0e317h     ; Mode Control (enable byte mode)

Reprogram (tweak) the Crt Controller Register with these values like this:

    xor     ax,ax        ; Empty ax
    mov     dx,03d4h     ; CrtC Register
    mov     cx,10        ; Number of entries
    mov     si,offset 320x240x256    ; Set ds:si to offset data
ParamLoop:
    lodsw                ; Load pair of index/data values into ax
    out     dx,ax        ; Out them to CrtC Register
    loop    ParamLoop

But before one can out these values, one must remove the write protection
on CrtC registers 0-7. Also set the dot-clock which can be either 0e3h
(for low res) or 0e7h (for high res).
Once you've done all this, clear the display memory and set the logical
screenwidth. The total ModeX setting code now looks like this:



- B. ASSEMBLER CODE FOR MODEX -

This code sets the 'official' modeX 320x240x256 with 3 pages.
Some things can be speed up but I'll leave that up to you.

; === Sequencer Registers ===

Seq_Index   =  3C4h   ; Sequencer Registers Adress
CrtC_Index  =  3D4h   ; CRTC Adress Register
Graph_Index =  3CEh   ; Graphics Adress Register
Attr_Index  =  3C0h   ; Atribute Controller Write

SetModeX PROC NEAR           ; Sets the ModeX 320*240*256
; === Set normal Mode 13h ===
    mov     ax,0013h         ; Videomode 13h  320*200*256
    int     10h              ; Set the mode

; === Disable chain4 bit ===
    mov     dx,Seq_Index     ; Sequencer Address Register
    mov     al,04h           ; Index 4 - Memory mode
    out     dx,al
    inc     dx               ; 03c5h - Data register => set the mem mode here
    in      al,dx
    and     al,11110111b     ; Disable 3rd bit will give us unchained memory
    or      al,00000100b     ; Bit 2 enabled => no odd/even-scheme
    out     dx,al

; === Set dot clock & scanning rate ===
    mov     ax,0100h
    out     dx,ax            ; Stop sequencer while setting Misc Output

    mov     dx,Misc_Output
    mov     al,0e3h          ; 0e3h = 227d = 11100011b
    out     dx,al            ; Select 25 MHz dot clock & 60 Hz scanning rate

    mov     dx,Seq_Index
    mov     ax,0300h         ; Index 00h --- 03h = 3d = 00000011b
    out     dx,ax            ; Undo reset (restart sequencer)

; === Remove write protection ===
    mov     dx,CrtC_Index
    mov     al,11h           ; VSync End contains write protect bit (bit 7)
    out     dx,al
    inc     dx               ; Crt Controller Data register
    in      al,dx
    and     al,01111111b     ; Remove write protect on various CrtC registers
    out     dx,al            ; (bit 7 is 0)

; === Initialize ModeX ===
    cld                      ; Clear direction flag (si increased)
    xor     ax,ax            ; Empty ax
    mov     dx,CrtC_Index    ; Port 03d4h
    mov     cx,10            ; Number of entries
    mov     si,offset 320x240x256
ParamLoop:
    lodsw                    ; Load pair of index/data values
    out     dx,ax            ; Out them to CrtC Register
    loop    ParamLoop

; === Clear VGA memory ===
    mov     dx,Seq_Index     ; Select port 03c4h
    mov     ax,00f02h        ; Map Mask Register (select all planes)
    out     dx,ax
    mov     ax,0a000h        ; VGA segment
    mov     es,ax
    xor     di,di            ; Set es:di to point to screenmem  di=0
    xor     ax,ax            ; Color to store = usually black = 0
    mov     cx,32768         ; 32768 (words) * 2 = 65536 bytes = 1 plane
    cld                      ; Clear dirflag => di is increased
    rep     stosw            ; Clear all 4 planes using wordwrites

; === Set logical screenwidth ===
    mov     dx,CrtC_Index    ; CrtC registers
    mov     al,13h           ; Index Logical screenwidth
    mov     ah,40            ; 1 page width & 3 pages in height
    out     dx,ax

    ret
SetModeX ENDP

And that's it! As you can see, you have to do a lot before you are in gfx
mode. But it is well worth the effort.



- C. OTHER MODES -

It is possible to create a large scale of different resolutions. The following
combinations will set a resolution of 320*400*256. Nice for pictures and stuff!

Label 320x400x256
  DW 04009h     ; Cellheight (1)
  DW 00014h     ; Underline Location (disable dword mode)
  DW 0e317h     ; Mode Control (enable byte mode)

In this mode, all you have to do is set the cellheight to 1. The normal
cellheight is 2 which means that every single scanline (Yline) is written
to the screen twice. So if you make it 1, the monitor will only show 1 line
instead of 2. Thus we get a resolution of 320*400*256 with 2 pages available
in display memory.

I will not get into other resolutions at this time. Primarily coz I have to
study these modes first ;-) and secondly ... the normal modex and the highres
of 320*400 are enough to get started with, IMHO.



D. CLOSING WORDS.

This document was written by Vulture / Outlaw Triad.

Thanks must go to Michael Abrash for explaining things and Draeden of VLA for
example source-code. Also thanks to Denthor of Asphyxia for releasing code to
this subject (allthough I think Denthor needs to be a little more specific on
things).

One more thing... if you really want to get into this stuff, buy a good book
on the subject. I recomment "Programmers Guide to the EGA, VGA and SuperVGA
Cards" from Richard F. Ferraro. It provides detailed explanation of all the
vga-registers. A real "must have"! (Damn, I should get paid for this ;-) )

Legal crap: Outlaw Triad accepts no responsibility for damage occured when
using this piece of software. Yo, it's free stuff, dudez! We've used this
code (in a modified form) ourselves and didn't have any troubles with it.

If you want to contact Outlaw Triad for some reason, call our distro-sites
and leave a message to Vulture. Or leave e-mail at: comma400@tem.nhl.nl
Visit our internet homepage at: http://www.nhl.nl/~comma400/vulture.html
These internet adresses should be valid at least till June 1996.

Outlaw is looking for another graphic artist to do some graphics for the
intros we want to create. Leave mail to Vulture.

 Ok, this is it, bye...

         Vulture / Outlaw Triad


                                OUTLAW DISTROS

       The Force              Blue Nose Prod            FireHouse     
   +31 (0)36-5346967        +31 (0)345-619401       +31 (0)528-274176 

                                Open For More!

                                OUTLAW GREETZ (in no order)

  Personal:

  DemoLisher (he-ya dude), MadMan (you're mad), Xotic (you make real
  cool gfx, man), Utter Chaos (at full speed), ThunderHawk (goodluck
  coding gfx), Silencer (ya making gfx?), Crusher (too bad you quit),
  all contacts on internet (you know who U R), and all otha people
  we know ... Bye!

  Groups:

  Chiparus, Acme, Inertia and all other demo-groups around...



            Outlaw Triad quote: "Let's make things understandable" 