]> 4ch.mooo.com Git - 16.git/blobdiff - doc/vgaregs.txt
refresh wwww
[16.git] / doc / vgaregs.txt
diff --git a/doc/vgaregs.txt b/doc/vgaregs.txt
new file mode 100755 (executable)
index 0000000..07f141d
--- /dev/null
@@ -0,0 +1,806 @@
+\r
+                         Programming the VGA Registers\r
+                      by Boone (boone@ucsd.edu), March '94\r
+\r
+   The IBM PC has long been slammed by owners of other computers which come \r
+with superior graphics capabilities built right into hardware.  The PC is a \r
+strange beast to program in general, and when it comes to graphics the \r
+programmer doesn't get much help from the video hardware.  However, there are \r
+quite a few neat tricks you can do using the VGA registers, as I'm sure you're \r
+aware.  The trick is knowing just which registers to use and how to use them to \r
+achieve the desired results.  In particular, precise timing is necessary to \r
+avoid screen flicker and/or "snow".  The registers on your video card are \r
+necessary for just about any communication with the VGA besides basic \r
+reading/writing of pixels.  Some of the registers are standard, which are the \r
+ones we will be discussing here.  Most SVGA chipsets have their own special \r
+functions associated with different registers for things such as bank \r
+switching, which is part of what makes trying to write SVGA programs so \r
+difficult.  The registers are also used to set the various attributes of each \r
+video mode: horizontal and vertical resolution, color depth, refresh rate, \r
+chain-4 mode, and so on.  Luckily, BIOS handles all this for us and since we \r
+only need to set the video mode once at program start-up and once at exit, you \r
+should need to mess with these particular functions too much, unless you are \r
+using a special mode, such as mode X.  (See the mode X section for more info on \r
+all this.)  If you want to experiment with the video mode registers, ftp \r
+yourself a file called TWEAK*.* (my version is TWEAK10.ZIP).  For now we'll \r
+just assume the video mode has already been set to whatever mode you wish.\r
+   One of the most common techniques used by game programmers is fade in/out.  \r
+A clean fade is simple but very effective.  Suprisingly, even big-budget games \r
+like Ultima VII often have a lot of screen noise during their fades.  With a \r
+little effort you can easily write your own noise-free fade routines.  There's \r
+nothing like giving a professional first impression on your intro screen, since \r
+the fade-in is likely to be the very first thing they see of your program.\r
+   BIOS is much to slow for this timing-critical opperation, so we'll have to \r
+get down and dirty with our VGA card.  Fading is a fairly simple process.  As \r
+you should know, the VGA palette consists of 256 colors with 3 attributes for \r
+each color: red, green and blue.  Every cycle of the fade, we have to go \r
+through all 768 attributes and if it is larger than 0 subtract one.  We'll use \r
+regsiters 3C8h and 3C9h for palette opperations.  The operation for sending a \r
+palette to the card is straight-forward: send a 0 to port 3C8h and then your \r
+768 byte buffer to port 3C9h.  This is good enough for setting the palette at \r
+the start of your program, but of course it has to go in a loop for the fade, \r
+since you'll have to do this 256 times, subtracting one from each non-zero \r
+member of the buffer.  The pseudo-code looks something like this:\r
+\r
+   constant PALSIZE = 256*3;\r
+   unsigned character buffer[PALSIZE];\r
+   boolean done;\r
+   counter i,j;\r
+\r
+      for j = 255 to 0\r
+       {\r
+         for i = 0 to PALSIZE-1\r
+            if buffer[i] > 0\r
+               buffer[i] = buffer[i] - 1;\r
+\r
+         output 0 to port 3C8h;\r
+         for i = 0 to PALSIZE-1\r
+            output buffer[i] to port 3C9h;\r
+       }\r
+\r
+   Easy enough, right?  If you convert this to the language of your choice it \r
+should run fine.  (Make sure you have the buffer pre-loaded with the correct \r
+palette, however, or you will get very strange results...)  But you'll notice \r
+the "snow" mentioned earlier.  Depending on your video card, this could mean \r
+that you see no noise at all to fuzz covering your entire screen.  Even if it \r
+look fine on your system, however, we want to make sure it will be smooth on \r
+*all* setups it could potentially be run on.  For that we're going to have to \r
+ask the video card when it's safe to send the palette buffer to the card, and \r
+for that we'll need the retrace register.\r
+   Putting aside palette concerns for a moment, I'll briefly cover the retrace \r
+on your video card.  (See the next section of this article for a more in-depth \r
+discussion of this.)  Bascially the vertical retrace is a short time in which \r
+the screen is not being updated (from video memory to your monitor) and you can \r
+safely do writes to your video memory or palette without worrying about getting \r
+snow, flicker, tearing, or other unwanted side-effects.  This is a pretty quick \r
+period (retrace occurs 60 to 70 times a second) so you can't do too much at \r
+once.\r
+   Returning to our fade: we want to update the palette during the vertical \r
+retrace.  The value we want is bit 3 of register 3DAh.  While that bit is zero \r
+we're safe to write.  The best practice in this case is to wait for the bit to \r
+change to one (screen is being traced) and then the instant it changes to 0, \r
+blast all our new video info to the card.  It won't be necessary in this case \r
+since all we are doing is fading the palette and then waiting for the next \r
+retrace, but if you're doing animation or playing music at the same time \r
+you'll want to include this extra bit of code as a safety net.  Otherwise you \r
+might detect the 0 in the refresh bit at the very last instant of the retrace \r
+and end up writing while the screen is being traced.  The pseudo-code now goes \r
+like this:\r
+\r
+      for j = 255 to 0\r
+       {\r
+         for i = 0 to PALSIZE-1\r
+            if buffer[i] > 0\r
+               buffer[i] = buffer[i] - 1;\r
+\r
+         while bit 3 of port 3DAh is 0\r
+            no opperation;\r
+         while bit 3 of port 3DAh is 1\r
+            no opperation;\r
+\r
+         output 0 to port 3C8h;\r
+         for i = 0 to PALSIZE-1\r
+            output buffer[i] to port 3C9h;\r
+       }\r
+\r
+   That's it!  All that's left is for you to implement it in your favorite \r
+language.  However, I can hear the cries right now: "Code!  Give us some real \r
+assembly code we can use!"  I'm reluctant to provided it as this is the exact \r
+sort of thing that is easy to cut and paste into your program without knowing \r
+how it works.  However, I'll give you the unoptimized main loop in 80x86 \r
+assembly as this may be clearer to you that my explanation or pseudo-code.  Two \r
+things to remember about this code: it is optimized enough to be smooth on any \r
+video card (or any that I've seen, anyway) assuming that the fade is the _only_ \r
+thing going on.  There's some other things you may want to change if you plan \r
+to say, play music during this process.  Secondly, you'll need to have the \r
+current palette loaded into the buffer beforehand.  You could read it from the \r
+VGA card using either registers or BIOS, but this is both slow and (in my \r
+oppinion) sloppy coding.  You should *never* ask the video card about anything \r
+(excluding retrace) that you could keep track of yourself.  In the case of the \r
+palette, you probably already loaded it from disk anyway, or if you are using \r
+the default palette <cough, gag, choke> just read the values once and store \r
+them in your executable or in a resource file.\r
+\r
+     palbuf   DB                  768 DUP (?)\r
+     fadecnt  DW                  040h\r
+\r
+; At this point, you should:\r
+;  1) have the video mode set\r
+;  2) have palbuf loaded with the current palette\r
+;  3) have something on the screen to fade!\r
+\r
+fadeloop:\r
+\r
+     xor      al,al               ; used for comparisons and port 3D8h\r
+     mov      cx,768              ; loop counter\r
+     mov      si,offset palbuf    ; save palette buffer in si\r
+\r
+decloop:\r
+     mov      dl,[si]              ; put next pal reg in dx\r
+     cmp      al,dl                ; is it 0?\r
+     je       next                 ; nope...\r
+     dec      dl                   ; yes, so subtract one\r
+     mov      [si],dl              ; put it back into palette buffer\r
+\r
+next:\r
+     dec      cx                   ; decrement counter\r
+     inc      si                   ; increment our buffer\r
+     cmp      cx,0\r
+     jne      decloop              ; not done yet, so loop around\r
+\r
+     mov      cx,768              ; reset for palette output\r
+     sub      si,768              ; reset palbuf pointer\r
+     mov      dx,03c8h\r
+     out      dx,al               ; inform VGA of palette change\r
+     inc      dx                  ; DX = 3C8h + 1 = 3C9h\r
+\r
+     mov      ch,02h              ; do outter loop 2 times\r
+     mov      dx,03dah            ; prepare refresh register\r
+     mov      bx,03c9h            ; prepare palette reg (for quick loading)\r
+\r
+     cli                          ; disable interrupts!\r
+\r
+outloop:\r
+     mov      cl,80h              ; do inner loop 128 times\r
+\r
+     in       al,dx               ; wait for current retrace to end\r
+     test     al,08h\r
+     jnz      $-5\r
+\r
+     in       al,dx               ; wait for current screen trace to end\r
+     test     al,08h\r
+     jz       $-5\r
+\r
+     mov      dx,bx               ; load up the palette change register\r
+\r
+innerloop:\r
+     mov      al,[si]             ; load next byte of palbuf\r
+     out      dx,al               ; send it to the VGA card\r
+     dec      cl                  ; decrement counter\r
+     inc      si                  ; increment palbuf pointer\r
+     cmp      cl,0\r
+     jne      innerloop           ; loop while not done\r
+\r
+     dec      ch                  ; decrement outer loop counter\r
+     cmp      ch,0\r
+     jne      outloop             ; loop while not done\r
+\r
+     sti                          ; restore interrupts\r
+\r
+     mov      ax,fadecnt          ; entire palette has been sent\r
+     dec      ax                  ; so check fade loop \r
+     mov      fadecnt,ax\r
+     cmp      ax,0                ; ready to quit?\r
+     jne      fadeloop            ; nope, keep fading!\r
+\r
+\r
+   I should add a few comments about this code segment.  First of all, it \r
+assumes you want to fade every color all the way down.  You may only want to \r
+fade certain sections of the palette (if your screen was only using a certain \r
+number of colors) or maybe your palette is low-intensity so you don't need to \r
+go the full 256 loops to get every color down to 0.  It also goes by ones, so \r
+if you want a faster fade you can have it subtract two from each attribute.  \r
+If you want to fade to a certain color other than black (for instance, fade to \r
+red such as the "getting hit" effect in Doom), you'll need to check if each \r
+attribute is above or below your target color and increment or decrement \r
+accordingly.  Also, you may have noticed something in the code absent from the \r
+pseudo-code: it only sends 128 colors to the card each retrace!  This is \r
+because if you use all 256 the next retrace may start before you get all colors \r
+sent to the video card, thanks to the unoptimized code.  Some recommend as \r
+little as 64 colors per retrace, however I've found 128 to be okay and \r
+certainly much faster.  The above code works for any VGA-equiped machine, \r
+regardless of processor, but you'll probably want to compress all the IN and \r
+OUT loops into REP INSB/OUTSB, REP INSW/OUTSW, or REP INSD/OUTSD instructions \r
+depending upon the minimum processor requirement for your game/demo.\r
+   I won't describe fading in since it's the same sort of thing, and I'm sure \r
+you can figure it out once you know how to use the registers themselves.  It's \r
+a little more complicated since you need a second buffer of target values for \r
+your attributes, but otherwise quite similar.\r
+\r
+   Next up is vertical retrace.  This is simply one of many read registers on \r
+your VGA, but it happens to be one of the most useful for animation and palette \r
+fades (as shown above).  Here's a quick rundown of what exactly the vertical \r
+retrace is, and why it's useful.\r
+   There's an electron gun in the back of your monitor that keeps the pixels \r
+"refreshed" with their correct values every 1/60th of a second or so.  It fires \r
+electrons at each pixel, row by row.  The horizontal retrace is the time it \r
+takes it to return from the right side of the screen after it has traced a row.  \r
+This is a very short time and I wouldn't worry about that too much right now, \r
+as it is only useful for very specialized (and quite tricky) hardware effects.\r
+More useful, however, is the vertical retrace which occurs when the electron \r
+gun reaches the bottom of the screen (one entire screen traced) and it returns \r
+diagonally to the upper-right hand corner of the screen.  During this time you \r
+are free to update anything you like having to do with video with no noise or \r
+interference (since nothing on the screen is being updated).  This is a fairly \r
+short amount of time, though, so whatever you want to do you better do it \r
+_quickly_.  For animation, you'll usually want to keep a second buffer in main \r
+memory (remember that video RAM is quite slow compared to main RAM) which you \r
+can use to write your animations to.  When the vertical retrace occurs, you'll \r
+want to blast the entire thing to the VGA as quickly as possible, using a \r
+memory copy instruction.  You can find more on this in articles which cover \r
+animation.\r
+\r
+   Lastly I'll briefly describe the VGA mode-set registers.  There are quite a \r
+number of them and for the most part they're pretty boring.  By sending \r
+different values to these registers you can achieve the various video modes \r
+that your card is capable of.  These registers set values such as horizontal \r
+and vertical resolution, retrace timing, addressing modes, color depth, timing, \r
+and other fun stuff.  The truth is that it's easier and just as effective to\r
+let the BIOS (gasp!) handle setting the screen mode for you, particularly since \r
+most games use standard modes such as 320x200 anyway.  At the very least you \r
+can let BIOS set the mode to begin with and then just modify the registers to \r
+"tweak" the mode the way you want it.  Any of these non-BIOS modes are \r
+generally refered to as mode X.  I don't want to go deep into detail on the \r
+setting and usage of mode X because there is already so much info availible on \r
+the topic.  Check out the Mode X Faq (regularly posted in comp.sys.ibm.pc.demos \r
+and rec.games.programmer), Micheal Abrash's collumn in Dr. Dobb's and his \r
+X-sharp library, or the section on mode X in the PC-GPE.\r
+   One mode register I'll cover quickly is the chain-4 enable/disable.  A lot \r
+of programmers seem to have trouble visualizing what this thing does exactly. \r
+Bit 3 of port 3C4h (index 4) controls chain-4 mode.  Normally it is on.  This \r
+allows fast linear addressing of the bytes in video memory, which is the way \r
+you are probably used to addressing them.  For example, to change the second \r
+pixel on the screen to a certain color, you simply write the value to address \r
+A000:0001.  With chain-4 disabled (the main feature of mode X besides better \r
+resolution) A000:0000 refers to the first pixel in the upper-left corner of \r
+your screen, A000:0001 refers to the fourth pixel, A000:0002 to the eight pixel \r
+and so on.  The odd pixels are accessed by changing the write plane.  Since \r
+there are four planes, you effectively get an extra two bits of addressing \r
+space, boosting the total bit width for your pixel addressing from 16 to 18.  \r
+Standard chain-4 four only allows access to 64K of memory (2^16) while \r
+disabling this feature gives you the full 256K (2^18) of memory to work with.  \r
+The disadvantage, of course, is that pixel writes are slower due to the port \r
+writes required to access odd pixels.  How can this be an advantage?  For one \r
+thing, you can write four pixels at a time as long as they are all the same \r
+color - handy for single-color polygons, as in flight simulators.  Secondly, \r
+you get four times as much memory.  This allows you to have higher resolutions \r
+without bank switching, or scroll the screen using hardware scrolling, or do \r
+page flipping for smooth animation.  And since you can change the resolution, \r
+you can give yourself a sqaure aspect ration (320x240) which is better for \r
+bitmap rotations and the like.  But remember that it can be slower for \r
+bitmapped graphics because you have to do at least four writes to the card (to \r
+change planes) in order to copy bitmaps from main RAM to video memory.  Don't \r
+use mode X just because you think it's "cool"; make sure you have a good reason \r
+for wanting to use it in your program, or otherwise you're wasting a lot of \r
+effort for no reason.\r
+\r
+   Now, I'm sure you want me to continue until I divulge all the secrets of the \r
+VGA register to you - but, I only have some much time and space.  Besides, I \r
+still haven't uncovered all of their mysteries and capabilities myself.  \r
+However, below is a list of the registers which you may want to play with for \r
+various effects.  The following list was posted on rec.games.programmer by \r
+Andrew Bromage (bromage@mundil.cs.mu.OZ.AU), so thanks to him for posting in to \r
+begin with.\r
+   That's it for this article and I hope it helped you understand your VGA card \r
+a little better.  If not, re-read it, and try writing your own programs which \r
+use the registers.  The only way to really understand it (as with most things) \r
+is to get some hands-on experience.\r
+   If you've got any questions, comments, flames, or corrections related to \r
+this document or game programming/design in general, feel free to post an \r
+article in rec.games.programmer (in case you haven't noticed by now, I hang out \r
+there regularly) or send mail to boone@ucsd.edu.\r
+\r
+Here's the list.  Have fun...\r
+\r
+          Documentation Over the I/O Registers for Standard VGA Cards\r
+\r
+                    Documentated by Shaggy of The Yellow One\r
+                           Email: D91-SJD@TEKN.HJ.SE\r
+\r
+Feel free to spread this to whoever wants it.....\r
+------------------------------------------------------------\r
+Port-Index:  -               Port: Write/03c2h Read/03cch\r
+usage:       d7   Vertical sync polarity\r
+             d6   Horizontal sunc polarity\r
+             d5   Odd /even page\r
+             d4   Disable video\r
+             d3   Clock select 1\r
+             d2   Clock select 0\r
+             d1   Enable/Disable display RAM\r
+             d0   I/O address select\r
+Description: Sync polarity: Bits are set as below for VGA displays\r
+             that use sync polarity to determine screen resolution.\r
+             Many newer multiple frequency displays are insensitive\r
+             to sync polarity\r
+\r
+             d7 d6      Resolution\r
+             0  0       Invalid\r
+             0  1       400 lines\r
+             1  0       350 lines\r
+             1  1       480 lines\r
+\r
+             I/O address select: When set to zero, selects the\r
+             monochrome I/O address space (3bx). When set to one,\r
+             it selects the color I/O address space (3dx)\r
+\r
+------------------------------------------------------------\r
+Port-Index: -                Port: 03c2h ; read only\r
+usage:      d7    Vertical Retrace Interrupt pendling\r
+            d6    Feature connector bit 1\r
+            d5    Feature connector bit 0\r
+            d4    Switch sense\r
+            d0-d3 Unused\r
+\r
+Description: d7 uses IRQ2\r
+\r
+------------------------------------------------------------\r
+Port-Index: -                Port: 03bah,03dah ; read only\r
+usage:      d3  Vertical retrace\r
+            d0  Horizontal retrace\r
+\r
+------------------------------------------------------------\r
+Port-Index: -                Port: 03c3h,46e8h\r
+usage:      d7-d1  Reserved\r
+            d0     VGA enable/disable (03c3h only)\r
+\r
+Description: Disables access to display memmory and the other\r
+             VGA's ports\r
+\r
+------------------------------------------------------------\r
+Port-Index: 00h              Port: 03d4h, 03b4h\r
+usage:      Horizontal total\r
+Description: Total number of characters in horizontal scan minus\r
+             five ( including blanked and border characters)\r
+\r
+------------------------------------------------------------\r
+Port-Index: 01h              Port: 03d4h, 03b4h\r
+usage:      Horizontal display enable\r
+Description: Total number of characters displayed in horizontal\r
+             scan minus one.\r
+------------------------------------------------------------\r
+Port-Index: 02h              Port: 03d4h, 03b4h\r
+usage:      Start horizontal blanking\r
+Description: Character at which blanking starts\r
+\r
+------------------------------------------------------------\r
+Port-Index: 03h              Port: 03d4h, 03b4h\r
+usage:      End horizontal blanking\r
+            d7    Test\r
+            d6    Skew control\r
+            d5    Skew control\r
+            d0-d4 End blanking\r
+Description: End blanking: is five LSB bits of six-bit value,\r
+             which define the character at which blanking stops.\r
+             The MSB bit of this value is in register index 5.\r
+\r
+------------------------------------------------------------\r
+Port-Index: 04h              Port: 03d4h, 03b4h\r
+usage:      Start horizontal retrace\r
+Description: Character at which horizontal retrace starts\r
+\r
+------------------------------------------------------------\r
+Port-Index: 05h              Port: 03d4h, 03b4h\r
+usage:      End horizontal retrace\r
+            d7    End horizontal blanking bit 5\r
+            d6    Horizontal retrace delay\r
+            d5    Horizontal retrace delay\r
+            d0-d4 End horizontal retrace\r
+Description: End horizontal retrace: defines the character at\r
+             which horizontal retrace ends\r
+\r
+------------------------------------------------------------\r
+Port-Index: 06h              Port: 03d4h, 03b4h\r
+usage:      Vertical total\r
+Description: Total number of horizontal scan lines minus two\r
+             (including blanked and border characters). MSB bits\r
+             of this value are in register index 7\r
+\r
+------------------------------------------------------------\r
+Port-Index: 07h              Port: 03d4h, 03b4h\r
+usage:      Overflow register\r
+            d7  Vertical retrace start (bit 9)\r
+            d6  Vertical display enable end (bit 9)\r
+            d5  Vertical total (bit 9)\r
+            d4  Line compare (bit 8)\r
+            d3  Start vertical blank (bit 8)\r
+            d2  Vertical retrace start (bit 8)\r
+            d1  Vertical display enable end (bit 8)\r
+            d0  Vertical total (bit 8)\r
+------------------------------------------------------------\r
+Port-Index: 08h              Port: 03d4h, 03b4h\r
+usage:      Preset row scan\r
+            d7    Unused\r
+            d6    Byte panning control\r
+            d5    Byte panning control\r
+            d0-d4 Preset row scan\r
+Description: Byte panning control: is used to control byte\r
+             panning. This register together with attribute\r
+             controller register 13h allows for up to 31 pixels of\r
+             panning in double word modes\r
+             Preset row scan: Which character scan line is the\r
+             first to be displayed\r
+------------------------------------------------------------\r
+Port-Index: 09h              Port: 03d4h, 03b4h\r
+usage:      Maximum scan line/Character height\r
+            d7    double scan\r
+            d6    bit d9 of line compare register\r
+            d5    bit d9 of start vertical blank register\r
+            d0-d4 Maximum scan line\r
+Description: d0-d5=Character height-1,  only in textmodes\r
+------------------------------------------------------------\r
+Port-Index: 0ah              Port: 03d4h, 03b4h\r
+usage:      Cursor start\r
+            d7,d6 Reserved (0)\r
+            d5    Cursor off\r
+            d4-d0 Cursor start\r
+Description:\r
+------------------------------------------------------------\r
+Port-Index: 0bh              Port: 03d4h, 03b4h\r
+usage:      Cursor end\r
+            d7    reserved\r
+            d6,d5 Cursor skew\r
+            d4-d0 Cursor end\r
+Description:\r
+------------------------------------------------------------\r
+Port-Index: 0ch              Port: 03d4h, 03b4h\r
+usage:      Start address high\r
+------------------------------------------------------------\r
+Port-Index: 0dh              Port: 03d4h, 03b4h\r
+usage:      Start address low\r
+Description: Determine the offset in display memory to be\r
+             displayed on the upper-left corner on the screen\r
+------------------------------------------------------------\r
+Port-Index: 0eh              Port: 03d4h, 03b4h\r
+usage:      Cursor location (high byte)\r
+------------------------------------------------------------\r
+Port-Index: 0fh              Port: 03d4h, 03b4h\r
+usage:      Cursor location (low byte)\r
+Description: Where the cursor is displayed on screen\r
+------------------------------------------------------------\r
+Port-Index: 10h              Port: 03d4h, 03b4h\r
+usage:      Vertical retrace start\r
+Description: 8 bits out of 10\r
+------------------------------------------------------------\r
+Port-Index: 11h              Port: 03d4h, 03b4h\r
+usage:      Vertical retrace end\r
+            d7    Write protect CRTC register 0 to 7\r
+            d6    refresh cycle select\r
+            d5    enable vertical interrupt (when 0)\r
+            d4    Clear vertical interrupt (when 0)\r
+            d0-d3 Vertical retrace end\r
+------------------------------------------------------------\r
+Port-Index: 12h              Port: 03d4h, 03b4h\r
+usage:      Vertical display enable end\r
+Description: eight LSB bits out of ten-bit value which define\r
+             scan line minus one at which the display ends.\r
+             The other two are in CRTC register index 7\r
+------------------------------------------------------------\r
+Port-Index: 13h              Port: 03d4h, 03b4h\r
+usage:      Offset / Logical screen width\r
+Description: Logical screen width between successive scan lines\r
+------------------------------------------------------------\r
+Port-Index: 14h              Port: 03d4h, 03b4h\r
+usage:      Underline location register\r
+            d7    Reserved\r
+            d6    Double word mode\r
+            d5    count by 4\r
+            d0-d4 Underline location\r
+Description: Underline location: Monochrome textmode only\r
+------------------------------------------------------------\r
+Port-Index: 15h              Port: 03d4h, 03b4h\r
+usage:      Start vertical blanking\r
+Description: eight LSB bits of ten-bit value minus one which\r
+             define at which scan line the vertical blanking\r
+             starts. The other two bits are in CRTC registers\r
+             index 7 and 9\r
+------------------------------------------------------------\r
+Port-Index: 16h              Port: 03d4h, 03b4h\r
+usage:      End vertical blanking\r
+Description: eight LSB bits of a value which determine the scan\r
+             line after which vertical blanking ends.\r
+------------------------------------------------------------\r
+Port-Index: 17h              Port: 03d4h, 03b4h\r
+usage:      Mode control register\r
+            d7  Enable vertical and hoizontal retrace\r
+            d6  Byte mode (1), word mode (0)\r
+            d5  Address wrap\r
+            d4  Reserved\r
+            d3  count by 2\r
+            d2  multiple vertical by 2 (use half in\r
+                CRTC (8,10,12,14,18)\r
+            d1  Select row scan counter (not used)\r
+            d0  compatibilty mode support (enable interleave)\r
+------------------------------------------------------------\r
+Port-Index: 18h              Port: 03d4h, 03b4h\r
+usage:      Line compare register\r
+Description: Split screen,  8 bit value out of a ten-bit value\r
+------------------------------------------------------------\r
+Port-Index: 00h              Port: 03c4h\r
+usage:      Reset register\r
+            d7-d2 Reserved\r
+            d1    Synchronous reset\r
+            d0    Asynchronous reset\r
+Description: Synchr. when set to zero, will halt and reset\r
+             the sequencer at the end of its current cycle\r
+             Asyncht. when set to zero, will immediatly halt\r
+             and reset the sequencer. Data can be loss.\r
+------------------------------------------------------------\r
+Port-Index: 01h              Port: 03c4h\r
+usage:      Clock mode register\r
+            d7,d6 Reserved\r
+            d5    display off\r
+            d4    Allow 32-bit Fetch (not used in standard modes)\r
+            d3    Divide dot clock by 2 (used in some 320*200 modes)\r
+            d2    Allow 16-bit fetch (used in mon graphics modes)\r
+            d1    Reserved\r
+            d0    Enable (0) 9 dot characters (mono text and 400-line)\r
+Description: Display off: Will blank screen and give the cpu\r
+             uninterrupted access the display memory.\r
+------------------------------------------------------------\r
+Port-Index: 02h              Port: 03c4h\r
+usage:      Color plane write enable register\r
+            d7,d6 Reserved\r
+            d3    Plane 3 Write enable\r
+            d2    Plane 2 Write enable\r
+            d1    Plane 1 Write enable\r
+            d0    Plane 0 Write enable\r
+Description:\r
+------------------------------------------------------------\r
+Port-Index: 03h              Port: 03c4h\r
+usage:      Character generator select register\r
+            d7,d6 Reserved\r
+            d5    Character generator table select A (MSB)\r
+            d4    Character generator table select B (MSB)\r
+            d3,d2 Character generator table select A\r
+            d1,d0 Character generator table select B\r
+Description: This register is only of interest if your software\r
+             will be using multiple character sets. Either one\r
+             or two character sets can be active. Table A selects\r
+             the charcater with attribute d3 set to zero and\r
+             Table B is the one with d3 set to one.\r
+------------------------------------------------------------\r
+Port-Index: 04h              Port: 03c4h\r
+usage:      Memory mode register\r
+            d4-d7 Reserved\r
+            d3    Chain 4 (address bits 0&1 to select plan, mode 13h)\r
+            d2    Odd/even (address bit 0 to select plane 0&2 or   \r
+                  1&3 text modes)\r
+            d1    Extended memory (disable 64k modes)\r
+            d0    Reserved\r
+Description:\r
+------------------------------------------------------------\r
+Port-Index: 00h              Port: 03ceh\r
+usage:      Set / Reset register\r
+            d7-d4 Reserved (0)\r
+            d3    Fill data for plane 3\r
+            d2    Fill data for plane 2\r
+            d1    Fill data for plane 1\r
+            d0    Fill data for plane 0\r
+------------------------------------------------------------\r
+Port-Index: 01h              Port: 03ceh\r
+usage:      Set / Reset enable register\r
+            d7-d4 Reserved (0)\r
+            d3    enable set/reset for plane 3 (1 = enable)\r
+            d2    enable set/reset for plane 2 (1 = enable)\r
+            d1    enable set/reset for plane 1 (1 = enable)\r
+            d0    enable set/reset for plane 0 (1 = enable)\r
+Description: Set/Reset enable defines which memory planes will\r
+             receive fill data from set/reset register. Any plane\r
+             that is disable for set/reset will be written with\r
+             normal processor output data\r
+------------------------------------------------------------\r
+Port-Index: 02h              Port: 03ceh\r
+usage:      Color compare register\r
+            d7-d4 Reserved\r
+            d3    Color compare value for plane 3\r
+            d2    Color compare value for plane 2\r
+            d1    Color compare value for plane 1\r
+            d0    Color compare value for plane 0\r
+Description: one indicate that color is the same\r
+------------------------------------------------------------\r
+Port-Index: 03h              Port: 03ceh\r
+usage:      Data rotate / Function select register\r
+            d7-d5 Resrved (0)\r
+            d4,d3 Function select\r
+            d2-d0 Rotate count\r
+\r
+            d4 d3  Function\r
+            0  0   Write data unmodified\r
+            0  1   Write data ANDed with processor latches\r
+            1  0   Write data ORed with processor latches\r
+            1  1   Write data XORed with processor latches\r
+Description: Rotation is made before writing data\r
+------------------------------------------------------------\r
+Port-Index: 04h              Port: 03ceh\r
+usage:      Read plane select register\r
+            d7-d2 Reserved (0)\r
+            d1,d0 Defines color plane for reading (0-3)\r
+Description: Doesnt matter in color compare mode\r
+------------------------------------------------------------\r
+Port-Index: 05h              Port: 03ceh\r
+usage:      Mode register\r
+            d7    Reserved (0)\r
+            d6    256-colour mode\r
+            d5    Shift register mode\r
+            d4    Odd / Even mode\r
+            d3    Color compare mode enable (1 = enable)\r
+            d2    Reserved (0)\r
+            d1,d0 Write mode\r
+\r
+            d1 d0 Write mode\r
+            0  0  Direct write (data rotate, set/reset may apply)\r
+            0  1  Use processor latches as write data\r
+            1  0  Color plane n (0-3) is filled with the value of\r
+                  bit n in the write data\r
+            1  1  Use (rotated) write data ANDed with Bit mask as\r
+                  bit mask. Use set/reset as if set/reset was\r
+                  enable for all planes\r
+Description:\r
+------------------------------------------------------------\r
+Port-Index: 06h              Port: 03ceh\r
+usage:      Miscellaneous register\r
+            d7-d4 Reserved\r
+            d3-d2 Memory map\r
+                  00 = A000h for 128k\r
+                  01 = A000h for 64k\r
+                  10 = B000h for 32k\r
+                  11 = B800h for 32k\r
+            d1    Odd/even enable (used in text modes)\r
+            d0    Graphics mode enable\r
+Description: Memory map defines the location and size of the\r
+             host window\r
+------------------------------------------------------------\r
+Port-Index: 07h              Port: 03ceh\r
+usage:      Color don't care register\r
+            d7-d4 Reserved (0)\r
+            d3    Plane 3 don't care\r
+            d2    Plane 2 don't care\r
+            d1    Plane 1 don't care\r
+            d0    Plane 0 don't care\r
+Description: Color don't care is used in conjunction with color\r
+             compare mode. This register masks particular planes\r
+             from being tested during color compare cycles.\r
+------------------------------------------------------------\r
+Port-Index: 08h              Port: 03ceh\r
+usage:      Bitmask register\r
+Description: The bitmask register is used to mask certain bit\r
+             positons from being modified.\r
+------------------------------------------------------------\r
+Port-Index: -                 Port: 03c0h both index and data\r
+usage:      d7,d6 Reserved\r
+            d5    Palette address source\r
+                  0 = palette can be modified, screen is blanked\r
+                  1 = screen is enable, palette cannot be modified\r
+            d4-d0 Palette register address\r
+Description: Palette register address selects which register of\r
+             the attributes controller will be addres,sed by the\r
+             next I/O write cycle\r
+------------------------------------------------------------\r
+Port-Index: 00h-0fh          Port: 03c0h\r
+usage:      Color palette register\r
+            d6,d7 Reserved\r
+            d5-d0 Color value\r
+Description: not used in 256 color modes\r
+------------------------------------------------------------\r
+Port-Index: 10h              Port: 03c0h\r
+usage:      Mode control register\r
+            d7  p4,p5 source select\r
+            d6  pixel width\r
+            d5  Horizontal panning compatibility\r
+            d4  Reserved\r
+            d3  Background intensify / enable blinking\r
+            d2  Line graphics enable (text modes only)\r
+            d1  display type\r
+            d0  graphics / text mode\r
+Description: p4,p5 source select: selects the source for video\r
+              outputs p4 and p5 to the DACs. If set to zero, p4\r
+              and p5 are driven from the palette registers (normal\r
+              operation). If set to one, p4 and p5 video outputs\r
+              come from bits 0 and 1 of the color select register.\r
+             pixel width: is set to one in mode 13h (256-color mode)\r
+             horizontal panning compatibility: enhances the\r
+              operation of the line compare register of the CRT\r
+              controller, which allows one section of the screen\r
+              to be scrolled while another section remains stationary.\r
+              When this bit is set to one, the stationary\r
+              section of the screen will also be immune to horizontal\r
+              panning.\r
+------------------------------------------------------------\r
+Port-Index: 11h              Port: 03c0h\r
+usage:      Screen border color\r
+Description: In text modes, the screen border color register\r
+             selects the color of the border that sorrounds the\r
+             text display area on the screen. This is also referred\r
+             to by IBM as overscan. Unfortunately, this feature\r
+             does not work properly on EGA displays in 350-line\r
+             modes.\r
+------------------------------------------------------------\r
+Port-Index: 12h              Port: 03c0h\r
+usage:      Color plane enable register\r
+            d7,d6 Reserved\r
+            d5,d4 Video status mux\r
+            d3    Enable color plane 3\r
+            d2    Enable color plane 2\r
+            d1    Enable color plane 1\r
+            d0    Enable color plane 0\r
+Description:  The video status mux bits can be used in conjunction\r
+             with the diagnostic bits of input status register 1\r
+             to read palette registers. For the EGA, this is the\r
+             only means available for reading the palette registers.\r
+              Enable color planes can be used to enable or disable\r
+             color planes at the input to the color lockup table.\r
+             A zero in any of these bit positions will mask the\r
+             data from that color plane. The effect on the display\r
+             will be the same as if that color plane were cleared\r
+             to all zeros.\r
+------------------------------------------------------------\r
+Port-Index: 13h              Port: 03c0h\r
+usage:      Horizontal panning register\r
+            d7-d4 reserved\r
+            d3-d0 Horizontal pan\r
+Description: Horizontal pan allows the display to be shifted\r
+             horizontally one pixel at a time.\r
+\r
+             d3-d0      Number of pixels shifted to the left\r
+                        0+,1+,2+     13h     Other modes\r
+                        3+,7,7+\r
+             0          1            0       0\r
+             1          2            1       -\r
+             2          3            2       1\r
+             3          4            3       -\r
+             4          5            4       2\r
+             5          6            5       -\r
+             6          7            6       3\r
+             7          8            7       -\r
+             8          9            -       -\r
+------------------------------------------------------------\r
+Port-Index: 14h              Port: 03c0h\r
+usage:      Color select register\r
+            d7-d4 Reserved\r
+            d3    color 7\r
+            d2    color 6\r
+            d1    color 5\r
+            d0    color 4\r
+Description:  Color 7 and color 6: are normally used as the high\r
+             order bits of the eight-bit video color data from the\r
+             attribute controller to the DACs. The only exceptions\r
+             are 256-color modes\r
+              Color 5 and color 4: can be used in place of the p5\r
+             and p6 outputs from the palette registers (see mode\r
+             control register - index 10h). In 16-color modes, the\r
+             color select register can be used to rapidly cycle\r
+             between sets of colors in the video DAC.\r
+------------------------------------------------------------\r
+Port-Index: -                Port: 03c6h\r
+usage:      Pixel mask register\r
+Description: ???\r
+------------------------------------------------------------\r
+Port-Index: -                Port: 03c7h\r
+usage:      DAC state register (read-only)\r
+Description: if d0 and d1 is set to zero it indicates that\r
+             the lookup table is in a write mode\r
+------------------------------------------------------------\r
+Port-Index: -                Port: 03c7h\r
+usage:      Lookup table read index register (Write only)\r
+Description: Used when you want to read the palette (set color\r
+             number)\r
+------------------------------------------------------------\r
+Port-Index: -                Port: 03c8h\r
+usage:      Lookup table write index register\r
+Description: Used when you want to change palette (set color\r
+             number)\r
+------------------------------------------------------------\r
+Port-Index: -                Port: 03c9h\r
+usage:      Lookup table data register\r
+Description: Read color value (Red-Green-Blue) or write same data.\r
+------------------------------------------------------------\r