OSDN Git Service

no idea how to get joy buttons 2 and 3 to function.
[proj16/16.git] / doc / vgaregs.txt
1 \r
2                          Programming the VGA Registers\r
3                       by Boone (boone@ucsd.edu), March '94\r
4 \r
5    The IBM PC has long been slammed by owners of other computers which come \r
6 with superior graphics capabilities built right into hardware.  The PC is a \r
7 strange beast to program in general, and when it comes to graphics the \r
8 programmer doesn't get much help from the video hardware.  However, there are \r
9 quite a few neat tricks you can do using the VGA registers, as I'm sure you're \r
10 aware.  The trick is knowing just which registers to use and how to use them to \r
11 achieve the desired results.  In particular, precise timing is necessary to \r
12 avoid screen flicker and/or "snow".  The registers on your video card are \r
13 necessary for just about any communication with the VGA besides basic \r
14 reading/writing of pixels.  Some of the registers are standard, which are the \r
15 ones we will be discussing here.  Most SVGA chipsets have their own special \r
16 functions associated with different registers for things such as bank \r
17 switching, which is part of what makes trying to write SVGA programs so \r
18 difficult.  The registers are also used to set the various attributes of each \r
19 video mode: horizontal and vertical resolution, color depth, refresh rate, \r
20 chain-4 mode, and so on.  Luckily, BIOS handles all this for us and since we \r
21 only need to set the video mode once at program start-up and once at exit, you \r
22 should need to mess with these particular functions too much, unless you are \r
23 using a special mode, such as mode X.  (See the mode X section for more info on \r
24 all this.)  If you want to experiment with the video mode registers, ftp \r
25 yourself a file called TWEAK*.* (my version is TWEAK10.ZIP).  For now we'll \r
26 just assume the video mode has already been set to whatever mode you wish.\r
27    One of the most common techniques used by game programmers is fade in/out.  \r
28 A clean fade is simple but very effective.  Suprisingly, even big-budget games \r
29 like Ultima VII often have a lot of screen noise during their fades.  With a \r
30 little effort you can easily write your own noise-free fade routines.  There's \r
31 nothing like giving a professional first impression on your intro screen, since \r
32 the fade-in is likely to be the very first thing they see of your program.\r
33    BIOS is much to slow for this timing-critical opperation, so we'll have to \r
34 get down and dirty with our VGA card.  Fading is a fairly simple process.  As \r
35 you should know, the VGA palette consists of 256 colors with 3 attributes for \r
36 each color: red, green and blue.  Every cycle of the fade, we have to go \r
37 through all 768 attributes and if it is larger than 0 subtract one.  We'll use \r
38 regsiters 3C8h and 3C9h for palette opperations.  The operation for sending a \r
39 palette to the card is straight-forward: send a 0 to port 3C8h and then your \r
40 768 byte buffer to port 3C9h.  This is good enough for setting the palette at \r
41 the start of your program, but of course it has to go in a loop for the fade, \r
42 since you'll have to do this 256 times, subtracting one from each non-zero \r
43 member of the buffer.  The pseudo-code looks something like this:\r
44 \r
45    constant PALSIZE = 256*3;\r
46    unsigned character buffer[PALSIZE];\r
47    boolean done;\r
48    counter i,j;\r
49 \r
50       for j = 255 to 0\r
51        {\r
52          for i = 0 to PALSIZE-1\r
53             if buffer[i] > 0\r
54                buffer[i] = buffer[i] - 1;\r
55 \r
56          output 0 to port 3C8h;\r
57          for i = 0 to PALSIZE-1\r
58             output buffer[i] to port 3C9h;\r
59        }\r
60 \r
61    Easy enough, right?  If you convert this to the language of your choice it \r
62 should run fine.  (Make sure you have the buffer pre-loaded with the correct \r
63 palette, however, or you will get very strange results...)  But you'll notice \r
64 the "snow" mentioned earlier.  Depending on your video card, this could mean \r
65 that you see no noise at all to fuzz covering your entire screen.  Even if it \r
66 look fine on your system, however, we want to make sure it will be smooth on \r
67 *all* setups it could potentially be run on.  For that we're going to have to \r
68 ask the video card when it's safe to send the palette buffer to the card, and \r
69 for that we'll need the retrace register.\r
70    Putting aside palette concerns for a moment, I'll briefly cover the retrace \r
71 on your video card.  (See the next section of this article for a more in-depth \r
72 discussion of this.)  Bascially the vertical retrace is a short time in which \r
73 the screen is not being updated (from video memory to your monitor) and you can \r
74 safely do writes to your video memory or palette without worrying about getting \r
75 snow, flicker, tearing, or other unwanted side-effects.  This is a pretty quick \r
76 period (retrace occurs 60 to 70 times a second) so you can't do too much at \r
77 once.\r
78    Returning to our fade: we want to update the palette during the vertical \r
79 retrace.  The value we want is bit 3 of register 3DAh.  While that bit is zero \r
80 we're safe to write.  The best practice in this case is to wait for the bit to \r
81 change to one (screen is being traced) and then the instant it changes to 0, \r
82 blast all our new video info to the card.  It won't be necessary in this case \r
83 since all we are doing is fading the palette and then waiting for the next \r
84 retrace, but if you're doing animation or playing music at the same time \r
85 you'll want to include this extra bit of code as a safety net.  Otherwise you \r
86 might detect the 0 in the refresh bit at the very last instant of the retrace \r
87 and end up writing while the screen is being traced.  The pseudo-code now goes \r
88 like this:\r
89 \r
90       for j = 255 to 0\r
91        {\r
92          for i = 0 to PALSIZE-1\r
93             if buffer[i] > 0\r
94                buffer[i] = buffer[i] - 1;\r
95 \r
96          while bit 3 of port 3DAh is 0\r
97             no opperation;\r
98          while bit 3 of port 3DAh is 1\r
99             no opperation;\r
100 \r
101          output 0 to port 3C8h;\r
102          for i = 0 to PALSIZE-1\r
103             output buffer[i] to port 3C9h;\r
104        }\r
105 \r
106    That's it!  All that's left is for you to implement it in your favorite \r
107 language.  However, I can hear the cries right now: "Code!  Give us some real \r
108 assembly code we can use!"  I'm reluctant to provided it as this is the exact \r
109 sort of thing that is easy to cut and paste into your program without knowing \r
110 how it works.  However, I'll give you the unoptimized main loop in 80x86 \r
111 assembly as this may be clearer to you that my explanation or pseudo-code.  Two \r
112 things to remember about this code: it is optimized enough to be smooth on any \r
113 video card (or any that I've seen, anyway) assuming that the fade is the _only_ \r
114 thing going on.  There's some other things you may want to change if you plan \r
115 to say, play music during this process.  Secondly, you'll need to have the \r
116 current palette loaded into the buffer beforehand.  You could read it from the \r
117 VGA card using either registers or BIOS, but this is both slow and (in my \r
118 oppinion) sloppy coding.  You should *never* ask the video card about anything \r
119 (excluding retrace) that you could keep track of yourself.  In the case of the \r
120 palette, you probably already loaded it from disk anyway, or if you are using \r
121 the default palette <cough, gag, choke> just read the values once and store \r
122 them in your executable or in a resource file.\r
123 \r
124      palbuf   DB                  768 DUP (?)\r
125      fadecnt  DW                  040h\r
126 \r
127 ; At this point, you should:\r
128 ;  1) have the video mode set\r
129 ;  2) have palbuf loaded with the current palette\r
130 ;  3) have something on the screen to fade!\r
131 \r
132 fadeloop:\r
133 \r
134      xor      al,al               ; used for comparisons and port 3D8h\r
135      mov      cx,768              ; loop counter\r
136      mov      si,offset palbuf    ; save palette buffer in si\r
137 \r
138 decloop:\r
139      mov      dl,[si]              ; put next pal reg in dx\r
140      cmp      al,dl                ; is it 0?\r
141      je       next                 ; nope...\r
142      dec      dl                   ; yes, so subtract one\r
143      mov      [si],dl              ; put it back into palette buffer\r
144 \r
145 next:\r
146      dec      cx                   ; decrement counter\r
147      inc      si                   ; increment our buffer\r
148      cmp      cx,0\r
149      jne      decloop              ; not done yet, so loop around\r
150 \r
151      mov      cx,768              ; reset for palette output\r
152      sub      si,768              ; reset palbuf pointer\r
153      mov      dx,03c8h\r
154      out      dx,al               ; inform VGA of palette change\r
155      inc      dx                  ; DX = 3C8h + 1 = 3C9h\r
156 \r
157      mov      ch,02h              ; do outter loop 2 times\r
158      mov      dx,03dah            ; prepare refresh register\r
159      mov      bx,03c9h            ; prepare palette reg (for quick loading)\r
160 \r
161      cli                          ; disable interrupts!\r
162 \r
163 outloop:\r
164      mov      cl,80h              ; do inner loop 128 times\r
165 \r
166      in       al,dx               ; wait for current retrace to end\r
167      test     al,08h\r
168      jnz      $-5\r
169 \r
170      in       al,dx               ; wait for current screen trace to end\r
171      test     al,08h\r
172      jz       $-5\r
173 \r
174      mov      dx,bx               ; load up the palette change register\r
175 \r
176 innerloop:\r
177      mov      al,[si]             ; load next byte of palbuf\r
178      out      dx,al               ; send it to the VGA card\r
179      dec      cl                  ; decrement counter\r
180      inc      si                  ; increment palbuf pointer\r
181      cmp      cl,0\r
182      jne      innerloop           ; loop while not done\r
183 \r
184      dec      ch                  ; decrement outer loop counter\r
185      cmp      ch,0\r
186      jne      outloop             ; loop while not done\r
187 \r
188      sti                          ; restore interrupts\r
189 \r
190      mov      ax,fadecnt          ; entire palette has been sent\r
191      dec      ax                  ; so check fade loop \r
192      mov      fadecnt,ax\r
193      cmp      ax,0                ; ready to quit?\r
194      jne      fadeloop            ; nope, keep fading!\r
195 \r
196 \r
197    I should add a few comments about this code segment.  First of all, it \r
198 assumes you want to fade every color all the way down.  You may only want to \r
199 fade certain sections of the palette (if your screen was only using a certain \r
200 number of colors) or maybe your palette is low-intensity so you don't need to \r
201 go the full 256 loops to get every color down to 0.  It also goes by ones, so \r
202 if you want a faster fade you can have it subtract two from each attribute.  \r
203 If you want to fade to a certain color other than black (for instance, fade to \r
204 red such as the "getting hit" effect in Doom), you'll need to check if each \r
205 attribute is above or below your target color and increment or decrement \r
206 accordingly.  Also, you may have noticed something in the code absent from the \r
207 pseudo-code: it only sends 128 colors to the card each retrace!  This is \r
208 because if you use all 256 the next retrace may start before you get all colors \r
209 sent to the video card, thanks to the unoptimized code.  Some recommend as \r
210 little as 64 colors per retrace, however I've found 128 to be okay and \r
211 certainly much faster.  The above code works for any VGA-equiped machine, \r
212 regardless of processor, but you'll probably want to compress all the IN and \r
213 OUT loops into REP INSB/OUTSB, REP INSW/OUTSW, or REP INSD/OUTSD instructions \r
214 depending upon the minimum processor requirement for your game/demo.\r
215    I won't describe fading in since it's the same sort of thing, and I'm sure \r
216 you can figure it out once you know how to use the registers themselves.  It's \r
217 a little more complicated since you need a second buffer of target values for \r
218 your attributes, but otherwise quite similar.\r
219 \r
220    Next up is vertical retrace.  This is simply one of many read registers on \r
221 your VGA, but it happens to be one of the most useful for animation and palette \r
222 fades (as shown above).  Here's a quick rundown of what exactly the vertical \r
223 retrace is, and why it's useful.\r
224    There's an electron gun in the back of your monitor that keeps the pixels \r
225 "refreshed" with their correct values every 1/60th of a second or so.  It fires \r
226 electrons at each pixel, row by row.  The horizontal retrace is the time it \r
227 takes it to return from the right side of the screen after it has traced a row.  \r
228 This is a very short time and I wouldn't worry about that too much right now, \r
229 as it is only useful for very specialized (and quite tricky) hardware effects.\r
230 More useful, however, is the vertical retrace which occurs when the electron \r
231 gun reaches the bottom of the screen (one entire screen traced) and it returns \r
232 diagonally to the upper-right hand corner of the screen.  During this time you \r
233 are free to update anything you like having to do with video with no noise or \r
234 interference (since nothing on the screen is being updated).  This is a fairly \r
235 short amount of time, though, so whatever you want to do you better do it \r
236 _quickly_.  For animation, you'll usually want to keep a second buffer in main \r
237 memory (remember that video RAM is quite slow compared to main RAM) which you \r
238 can use to write your animations to.  When the vertical retrace occurs, you'll \r
239 want to blast the entire thing to the VGA as quickly as possible, using a \r
240 memory copy instruction.  You can find more on this in articles which cover \r
241 animation.\r
242 \r
243    Lastly I'll briefly describe the VGA mode-set registers.  There are quite a \r
244 number of them and for the most part they're pretty boring.  By sending \r
245 different values to these registers you can achieve the various video modes \r
246 that your card is capable of.  These registers set values such as horizontal \r
247 and vertical resolution, retrace timing, addressing modes, color depth, timing, \r
248 and other fun stuff.  The truth is that it's easier and just as effective to\r
249 let the BIOS (gasp!) handle setting the screen mode for you, particularly since \r
250 most games use standard modes such as 320x200 anyway.  At the very least you \r
251 can let BIOS set the mode to begin with and then just modify the registers to \r
252 "tweak" the mode the way you want it.  Any of these non-BIOS modes are \r
253 generally refered to as mode X.  I don't want to go deep into detail on the \r
254 setting and usage of mode X because there is already so much info availible on \r
255 the topic.  Check out the Mode X Faq (regularly posted in comp.sys.ibm.pc.demos \r
256 and rec.games.programmer), Micheal Abrash's collumn in Dr. Dobb's and his \r
257 X-sharp library, or the section on mode X in the PC-GPE.\r
258    One mode register I'll cover quickly is the chain-4 enable/disable.  A lot \r
259 of programmers seem to have trouble visualizing what this thing does exactly. \r
260 Bit 3 of port 3C4h (index 4) controls chain-4 mode.  Normally it is on.  This \r
261 allows fast linear addressing of the bytes in video memory, which is the way \r
262 you are probably used to addressing them.  For example, to change the second \r
263 pixel on the screen to a certain color, you simply write the value to address \r
264 A000:0001.  With chain-4 disabled (the main feature of mode X besides better \r
265 resolution) A000:0000 refers to the first pixel in the upper-left corner of \r
266 your screen, A000:0001 refers to the fourth pixel, A000:0002 to the eight pixel \r
267 and so on.  The odd pixels are accessed by changing the write plane.  Since \r
268 there are four planes, you effectively get an extra two bits of addressing \r
269 space, boosting the total bit width for your pixel addressing from 16 to 18.  \r
270 Standard chain-4 four only allows access to 64K of memory (2^16) while \r
271 disabling this feature gives you the full 256K (2^18) of memory to work with.  \r
272 The disadvantage, of course, is that pixel writes are slower due to the port \r
273 writes required to access odd pixels.  How can this be an advantage?  For one \r
274 thing, you can write four pixels at a time as long as they are all the same \r
275 color - handy for single-color polygons, as in flight simulators.  Secondly, \r
276 you get four times as much memory.  This allows you to have higher resolutions \r
277 without bank switching, or scroll the screen using hardware scrolling, or do \r
278 page flipping for smooth animation.  And since you can change the resolution, \r
279 you can give yourself a sqaure aspect ration (320x240) which is better for \r
280 bitmap rotations and the like.  But remember that it can be slower for \r
281 bitmapped graphics because you have to do at least four writes to the card (to \r
282 change planes) in order to copy bitmaps from main RAM to video memory.  Don't \r
283 use mode X just because you think it's "cool"; make sure you have a good reason \r
284 for wanting to use it in your program, or otherwise you're wasting a lot of \r
285 effort for no reason.\r
286 \r
287    Now, I'm sure you want me to continue until I divulge all the secrets of the \r
288 VGA register to you - but, I only have some much time and space.  Besides, I \r
289 still haven't uncovered all of their mysteries and capabilities myself.  \r
290 However, below is a list of the registers which you may want to play with for \r
291 various effects.  The following list was posted on rec.games.programmer by \r
292 Andrew Bromage (bromage@mundil.cs.mu.OZ.AU), so thanks to him for posting in to \r
293 begin with.\r
294    That's it for this article and I hope it helped you understand your VGA card \r
295 a little better.  If not, re-read it, and try writing your own programs which \r
296 use the registers.  The only way to really understand it (as with most things) \r
297 is to get some hands-on experience.\r
298    If you've got any questions, comments, flames, or corrections related to \r
299 this document or game programming/design in general, feel free to post an \r
300 article in rec.games.programmer (in case you haven't noticed by now, I hang out \r
301 there regularly) or send mail to boone@ucsd.edu.\r
302 \r
303 Here's the list.  Have fun...\r
304 \r
305           Documentation Over the I/O Registers for Standard VGA Cards\r
306 \r
307                     Documentated by Shaggy of The Yellow One\r
308                            Email: D91-SJD@TEKN.HJ.SE\r
309 \r
310 Feel free to spread this to whoever wants it.....\r
311 ------------------------------------------------------------\r
312 Port-Index:  -               Port: Write/03c2h Read/03cch\r
313 usage:       d7   Vertical sync polarity\r
314              d6   Horizontal sunc polarity\r
315              d5   Odd /even page\r
316              d4   Disable video\r
317              d3   Clock select 1\r
318              d2   Clock select 0\r
319              d1   Enable/Disable display RAM\r
320              d0   I/O address select\r
321 Description: Sync polarity: Bits are set as below for VGA displays\r
322              that use sync polarity to determine screen resolution.\r
323              Many newer multiple frequency displays are insensitive\r
324              to sync polarity\r
325 \r
326              d7 d6      Resolution\r
327              0  0       Invalid\r
328              0  1       400 lines\r
329              1  0       350 lines\r
330              1  1       480 lines\r
331 \r
332              I/O address select: When set to zero, selects the\r
333              monochrome I/O address space (3bx). When set to one,\r
334              it selects the color I/O address space (3dx)\r
335 \r
336 ------------------------------------------------------------\r
337 Port-Index: -                Port: 03c2h ; read only\r
338 usage:      d7    Vertical Retrace Interrupt pendling\r
339             d6    Feature connector bit 1\r
340             d5    Feature connector bit 0\r
341             d4    Switch sense\r
342             d0-d3 Unused\r
343 \r
344 Description: d7 uses IRQ2\r
345 \r
346 ------------------------------------------------------------\r
347 Port-Index: -                Port: 03bah,03dah ; read only\r
348 usage:      d3  Vertical retrace\r
349             d0  Horizontal retrace\r
350 \r
351 ------------------------------------------------------------\r
352 Port-Index: -                Port: 03c3h,46e8h\r
353 usage:      d7-d1  Reserved\r
354             d0     VGA enable/disable (03c3h only)\r
355 \r
356 Description: Disables access to display memmory and the other\r
357              VGA's ports\r
358 \r
359 ------------------------------------------------------------\r
360 Port-Index: 00h              Port: 03d4h, 03b4h\r
361 usage:      Horizontal total\r
362 Description: Total number of characters in horizontal scan minus\r
363              five ( including blanked and border characters)\r
364 \r
365 ------------------------------------------------------------\r
366 Port-Index: 01h              Port: 03d4h, 03b4h\r
367 usage:      Horizontal display enable\r
368 Description: Total number of characters displayed in horizontal\r
369              scan minus one.\r
370 ------------------------------------------------------------\r
371 Port-Index: 02h              Port: 03d4h, 03b4h\r
372 usage:      Start horizontal blanking\r
373 Description: Character at which blanking starts\r
374 \r
375 ------------------------------------------------------------\r
376 Port-Index: 03h              Port: 03d4h, 03b4h\r
377 usage:      End horizontal blanking\r
378             d7    Test\r
379             d6    Skew control\r
380             d5    Skew control\r
381             d0-d4 End blanking\r
382 Description: End blanking: is five LSB bits of six-bit value,\r
383              which define the character at which blanking stops.\r
384              The MSB bit of this value is in register index 5.\r
385 \r
386 ------------------------------------------------------------\r
387 Port-Index: 04h              Port: 03d4h, 03b4h\r
388 usage:      Start horizontal retrace\r
389 Description: Character at which horizontal retrace starts\r
390 \r
391 ------------------------------------------------------------\r
392 Port-Index: 05h              Port: 03d4h, 03b4h\r
393 usage:      End horizontal retrace\r
394             d7    End horizontal blanking bit 5\r
395             d6    Horizontal retrace delay\r
396             d5    Horizontal retrace delay\r
397             d0-d4 End horizontal retrace\r
398 Description: End horizontal retrace: defines the character at\r
399              which horizontal retrace ends\r
400 \r
401 ------------------------------------------------------------\r
402 Port-Index: 06h              Port: 03d4h, 03b4h\r
403 usage:      Vertical total\r
404 Description: Total number of horizontal scan lines minus two\r
405              (including blanked and border characters). MSB bits\r
406              of this value are in register index 7\r
407 \r
408 ------------------------------------------------------------\r
409 Port-Index: 07h              Port: 03d4h, 03b4h\r
410 usage:      Overflow register\r
411             d7  Vertical retrace start (bit 9)\r
412             d6  Vertical display enable end (bit 9)\r
413             d5  Vertical total (bit 9)\r
414             d4  Line compare (bit 8)\r
415             d3  Start vertical blank (bit 8)\r
416             d2  Vertical retrace start (bit 8)\r
417             d1  Vertical display enable end (bit 8)\r
418             d0  Vertical total (bit 8)\r
419 ------------------------------------------------------------\r
420 Port-Index: 08h              Port: 03d4h, 03b4h\r
421 usage:      Preset row scan\r
422             d7    Unused\r
423             d6    Byte panning control\r
424             d5    Byte panning control\r
425             d0-d4 Preset row scan\r
426 Description: Byte panning control: is used to control byte\r
427              panning. This register together with attribute\r
428              controller register 13h allows for up to 31 pixels of\r
429              panning in double word modes\r
430              Preset row scan: Which character scan line is the\r
431              first to be displayed\r
432 ------------------------------------------------------------\r
433 Port-Index: 09h              Port: 03d4h, 03b4h\r
434 usage:      Maximum scan line/Character height\r
435             d7    double scan\r
436             d6    bit d9 of line compare register\r
437             d5    bit d9 of start vertical blank register\r
438             d0-d4 Maximum scan line\r
439 Description: d0-d5=Character height-1,  only in textmodes\r
440 ------------------------------------------------------------\r
441 Port-Index: 0ah              Port: 03d4h, 03b4h\r
442 usage:      Cursor start\r
443             d7,d6 Reserved (0)\r
444             d5    Cursor off\r
445             d4-d0 Cursor start\r
446 Description:\r
447 ------------------------------------------------------------\r
448 Port-Index: 0bh              Port: 03d4h, 03b4h\r
449 usage:      Cursor end\r
450             d7    reserved\r
451             d6,d5 Cursor skew\r
452             d4-d0 Cursor end\r
453 Description:\r
454 ------------------------------------------------------------\r
455 Port-Index: 0ch              Port: 03d4h, 03b4h\r
456 usage:      Start address high\r
457 ------------------------------------------------------------\r
458 Port-Index: 0dh              Port: 03d4h, 03b4h\r
459 usage:      Start address low\r
460 Description: Determine the offset in display memory to be\r
461              displayed on the upper-left corner on the screen\r
462 ------------------------------------------------------------\r
463 Port-Index: 0eh              Port: 03d4h, 03b4h\r
464 usage:      Cursor location (high byte)\r
465 ------------------------------------------------------------\r
466 Port-Index: 0fh              Port: 03d4h, 03b4h\r
467 usage:      Cursor location (low byte)\r
468 Description: Where the cursor is displayed on screen\r
469 ------------------------------------------------------------\r
470 Port-Index: 10h              Port: 03d4h, 03b4h\r
471 usage:      Vertical retrace start\r
472 Description: 8 bits out of 10\r
473 ------------------------------------------------------------\r
474 Port-Index: 11h              Port: 03d4h, 03b4h\r
475 usage:      Vertical retrace end\r
476             d7    Write protect CRTC register 0 to 7\r
477             d6    refresh cycle select\r
478             d5    enable vertical interrupt (when 0)\r
479             d4    Clear vertical interrupt (when 0)\r
480             d0-d3 Vertical retrace end\r
481 ------------------------------------------------------------\r
482 Port-Index: 12h              Port: 03d4h, 03b4h\r
483 usage:      Vertical display enable end\r
484 Description: eight LSB bits out of ten-bit value which define\r
485              scan line minus one at which the display ends.\r
486              The other two are in CRTC register index 7\r
487 ------------------------------------------------------------\r
488 Port-Index: 13h              Port: 03d4h, 03b4h\r
489 usage:      Offset / Logical screen width\r
490 Description: Logical screen width between successive scan lines\r
491 ------------------------------------------------------------\r
492 Port-Index: 14h              Port: 03d4h, 03b4h\r
493 usage:      Underline location register\r
494             d7    Reserved\r
495             d6    Double word mode\r
496             d5    count by 4\r
497             d0-d4 Underline location\r
498 Description: Underline location: Monochrome textmode only\r
499 ------------------------------------------------------------\r
500 Port-Index: 15h              Port: 03d4h, 03b4h\r
501 usage:      Start vertical blanking\r
502 Description: eight LSB bits of ten-bit value minus one which\r
503              define at which scan line the vertical blanking\r
504              starts. The other two bits are in CRTC registers\r
505              index 7 and 9\r
506 ------------------------------------------------------------\r
507 Port-Index: 16h              Port: 03d4h, 03b4h\r
508 usage:      End vertical blanking\r
509 Description: eight LSB bits of a value which determine the scan\r
510              line after which vertical blanking ends.\r
511 ------------------------------------------------------------\r
512 Port-Index: 17h              Port: 03d4h, 03b4h\r
513 usage:      Mode control register\r
514             d7  Enable vertical and hoizontal retrace\r
515             d6  Byte mode (1), word mode (0)\r
516             d5  Address wrap\r
517             d4  Reserved\r
518             d3  count by 2\r
519             d2  multiple vertical by 2 (use half in\r
520                 CRTC (8,10,12,14,18)\r
521             d1  Select row scan counter (not used)\r
522             d0  compatibilty mode support (enable interleave)\r
523 ------------------------------------------------------------\r
524 Port-Index: 18h              Port: 03d4h, 03b4h\r
525 usage:      Line compare register\r
526 Description: Split screen,  8 bit value out of a ten-bit value\r
527 ------------------------------------------------------------\r
528 Port-Index: 00h              Port: 03c4h\r
529 usage:      Reset register\r
530             d7-d2 Reserved\r
531             d1    Synchronous reset\r
532             d0    Asynchronous reset\r
533 Description: Synchr. when set to zero, will halt and reset\r
534              the sequencer at the end of its current cycle\r
535              Asyncht. when set to zero, will immediatly halt\r
536              and reset the sequencer. Data can be loss.\r
537 ------------------------------------------------------------\r
538 Port-Index: 01h              Port: 03c4h\r
539 usage:      Clock mode register\r
540             d7,d6 Reserved\r
541             d5    display off\r
542             d4    Allow 32-bit Fetch (not used in standard modes)\r
543             d3    Divide dot clock by 2 (used in some 320*200 modes)\r
544             d2    Allow 16-bit fetch (used in mon graphics modes)\r
545             d1    Reserved\r
546             d0    Enable (0) 9 dot characters (mono text and 400-line)\r
547 Description: Display off: Will blank screen and give the cpu\r
548              uninterrupted access the display memory.\r
549 ------------------------------------------------------------\r
550 Port-Index: 02h              Port: 03c4h\r
551 usage:      Color plane write enable register\r
552             d7,d6 Reserved\r
553             d3    Plane 3 Write enable\r
554             d2    Plane 2 Write enable\r
555             d1    Plane 1 Write enable\r
556             d0    Plane 0 Write enable\r
557 Description:\r
558 ------------------------------------------------------------\r
559 Port-Index: 03h              Port: 03c4h\r
560 usage:      Character generator select register\r
561             d7,d6 Reserved\r
562             d5    Character generator table select A (MSB)\r
563             d4    Character generator table select B (MSB)\r
564             d3,d2 Character generator table select A\r
565             d1,d0 Character generator table select B\r
566 Description: This register is only of interest if your software\r
567              will be using multiple character sets. Either one\r
568              or two character sets can be active. Table A selects\r
569              the charcater with attribute d3 set to zero and\r
570              Table B is the one with d3 set to one.\r
571 ------------------------------------------------------------\r
572 Port-Index: 04h              Port: 03c4h\r
573 usage:      Memory mode register\r
574             d4-d7 Reserved\r
575             d3    Chain 4 (address bits 0&1 to select plan, mode 13h)\r
576             d2    Odd/even (address bit 0 to select plane 0&2 or   \r
577                   1&3 text modes)\r
578             d1    Extended memory (disable 64k modes)\r
579             d0    Reserved\r
580 Description:\r
581 ------------------------------------------------------------\r
582 Port-Index: 00h              Port: 03ceh\r
583 usage:      Set / Reset register\r
584             d7-d4 Reserved (0)\r
585             d3    Fill data for plane 3\r
586             d2    Fill data for plane 2\r
587             d1    Fill data for plane 1\r
588             d0    Fill data for plane 0\r
589 ------------------------------------------------------------\r
590 Port-Index: 01h              Port: 03ceh\r
591 usage:      Set / Reset enable register\r
592             d7-d4 Reserved (0)\r
593             d3    enable set/reset for plane 3 (1 = enable)\r
594             d2    enable set/reset for plane 2 (1 = enable)\r
595             d1    enable set/reset for plane 1 (1 = enable)\r
596             d0    enable set/reset for plane 0 (1 = enable)\r
597 Description: Set/Reset enable defines which memory planes will\r
598              receive fill data from set/reset register. Any plane\r
599              that is disable for set/reset will be written with\r
600              normal processor output data\r
601 ------------------------------------------------------------\r
602 Port-Index: 02h              Port: 03ceh\r
603 usage:      Color compare register\r
604             d7-d4 Reserved\r
605             d3    Color compare value for plane 3\r
606             d2    Color compare value for plane 2\r
607             d1    Color compare value for plane 1\r
608             d0    Color compare value for plane 0\r
609 Description: one indicate that color is the same\r
610 ------------------------------------------------------------\r
611 Port-Index: 03h              Port: 03ceh\r
612 usage:      Data rotate / Function select register\r
613             d7-d5 Resrved (0)\r
614             d4,d3 Function select\r
615             d2-d0 Rotate count\r
616 \r
617             d4 d3  Function\r
618             0  0   Write data unmodified\r
619             0  1   Write data ANDed with processor latches\r
620             1  0   Write data ORed with processor latches\r
621             1  1   Write data XORed with processor latches\r
622 Description: Rotation is made before writing data\r
623 ------------------------------------------------------------\r
624 Port-Index: 04h              Port: 03ceh\r
625 usage:      Read plane select register\r
626             d7-d2 Reserved (0)\r
627             d1,d0 Defines color plane for reading (0-3)\r
628 Description: Doesnt matter in color compare mode\r
629 ------------------------------------------------------------\r
630 Port-Index: 05h              Port: 03ceh\r
631 usage:      Mode register\r
632             d7    Reserved (0)\r
633             d6    256-colour mode\r
634             d5    Shift register mode\r
635             d4    Odd / Even mode\r
636             d3    Color compare mode enable (1 = enable)\r
637             d2    Reserved (0)\r
638             d1,d0 Write mode\r
639 \r
640             d1 d0 Write mode\r
641             0  0  Direct write (data rotate, set/reset may apply)\r
642             0  1  Use processor latches as write data\r
643             1  0  Color plane n (0-3) is filled with the value of\r
644                   bit n in the write data\r
645             1  1  Use (rotated) write data ANDed with Bit mask as\r
646                   bit mask. Use set/reset as if set/reset was\r
647                   enable for all planes\r
648 Description:\r
649 ------------------------------------------------------------\r
650 Port-Index: 06h              Port: 03ceh\r
651 usage:      Miscellaneous register\r
652             d7-d4 Reserved\r
653             d3-d2 Memory map\r
654                   00 = A000h for 128k\r
655                   01 = A000h for 64k\r
656                   10 = B000h for 32k\r
657                   11 = B800h for 32k\r
658             d1    Odd/even enable (used in text modes)\r
659             d0    Graphics mode enable\r
660 Description: Memory map defines the location and size of the\r
661              host window\r
662 ------------------------------------------------------------\r
663 Port-Index: 07h              Port: 03ceh\r
664 usage:      Color don't care register\r
665             d7-d4 Reserved (0)\r
666             d3    Plane 3 don't care\r
667             d2    Plane 2 don't care\r
668             d1    Plane 1 don't care\r
669             d0    Plane 0 don't care\r
670 Description: Color don't care is used in conjunction with color\r
671              compare mode. This register masks particular planes\r
672              from being tested during color compare cycles.\r
673 ------------------------------------------------------------\r
674 Port-Index: 08h              Port: 03ceh\r
675 usage:      Bitmask register\r
676 Description: The bitmask register is used to mask certain bit\r
677              positons from being modified.\r
678 ------------------------------------------------------------\r
679 Port-Index: -                 Port: 03c0h both index and data\r
680 usage:      d7,d6 Reserved\r
681             d5    Palette address source\r
682                   0 = palette can be modified, screen is blanked\r
683                   1 = screen is enable, palette cannot be modified\r
684             d4-d0 Palette register address\r
685 Description: Palette register address selects which register of\r
686              the attributes controller will be addres,sed by the\r
687              next I/O write cycle\r
688 ------------------------------------------------------------\r
689 Port-Index: 00h-0fh          Port: 03c0h\r
690 usage:      Color palette register\r
691             d6,d7 Reserved\r
692             d5-d0 Color value\r
693 Description: not used in 256 color modes\r
694 ------------------------------------------------------------\r
695 Port-Index: 10h              Port: 03c0h\r
696 usage:      Mode control register\r
697             d7  p4,p5 source select\r
698             d6  pixel width\r
699             d5  Horizontal panning compatibility\r
700             d4  Reserved\r
701             d3  Background intensify / enable blinking\r
702             d2  Line graphics enable (text modes only)\r
703             d1  display type\r
704             d0  graphics / text mode\r
705 Description: p4,p5 source select: selects the source for video\r
706               outputs p4 and p5 to the DACs. If set to zero, p4\r
707               and p5 are driven from the palette registers (normal\r
708               operation). If set to one, p4 and p5 video outputs\r
709               come from bits 0 and 1 of the color select register.\r
710              pixel width: is set to one in mode 13h (256-color mode)\r
711              horizontal panning compatibility: enhances the\r
712               operation of the line compare register of the CRT\r
713               controller, which allows one section of the screen\r
714               to be scrolled while another section remains stationary.\r
715               When this bit is set to one, the stationary\r
716               section of the screen will also be immune to horizontal\r
717               panning.\r
718 ------------------------------------------------------------\r
719 Port-Index: 11h              Port: 03c0h\r
720 usage:      Screen border color\r
721 Description: In text modes, the screen border color register\r
722              selects the color of the border that sorrounds the\r
723              text display area on the screen. This is also referred\r
724              to by IBM as overscan. Unfortunately, this feature\r
725              does not work properly on EGA displays in 350-line\r
726              modes.\r
727 ------------------------------------------------------------\r
728 Port-Index: 12h              Port: 03c0h\r
729 usage:      Color plane enable register\r
730             d7,d6 Reserved\r
731             d5,d4 Video status mux\r
732             d3    Enable color plane 3\r
733             d2    Enable color plane 2\r
734             d1    Enable color plane 1\r
735             d0    Enable color plane 0\r
736 Description:  The video status mux bits can be used in conjunction\r
737              with the diagnostic bits of input status register 1\r
738              to read palette registers. For the EGA, this is the\r
739              only means available for reading the palette registers.\r
740               Enable color planes can be used to enable or disable\r
741              color planes at the input to the color lockup table.\r
742              A zero in any of these bit positions will mask the\r
743              data from that color plane. The effect on the display\r
744              will be the same as if that color plane were cleared\r
745              to all zeros.\r
746 ------------------------------------------------------------\r
747 Port-Index: 13h              Port: 03c0h\r
748 usage:      Horizontal panning register\r
749             d7-d4 reserved\r
750             d3-d0 Horizontal pan\r
751 Description: Horizontal pan allows the display to be shifted\r
752              horizontally one pixel at a time.\r
753 \r
754              d3-d0      Number of pixels shifted to the left\r
755                         0+,1+,2+     13h     Other modes\r
756                         3+,7,7+\r
757              0          1            0       0\r
758              1          2            1       -\r
759              2          3            2       1\r
760              3          4            3       -\r
761              4          5            4       2\r
762              5          6            5       -\r
763              6          7            6       3\r
764              7          8            7       -\r
765              8          9            -       -\r
766 ------------------------------------------------------------\r
767 Port-Index: 14h              Port: 03c0h\r
768 usage:      Color select register\r
769             d7-d4 Reserved\r
770             d3    color 7\r
771             d2    color 6\r
772             d1    color 5\r
773             d0    color 4\r
774 Description:  Color 7 and color 6: are normally used as the high\r
775              order bits of the eight-bit video color data from the\r
776              attribute controller to the DACs. The only exceptions\r
777              are 256-color modes\r
778               Color 5 and color 4: can be used in place of the p5\r
779              and p6 outputs from the palette registers (see mode\r
780              control register - index 10h). In 16-color modes, the\r
781              color select register can be used to rapidly cycle\r
782              between sets of colors in the video DAC.\r
783 ------------------------------------------------------------\r
784 Port-Index: -                Port: 03c6h\r
785 usage:      Pixel mask register\r
786 Description: ???\r
787 ------------------------------------------------------------\r
788 Port-Index: -                Port: 03c7h\r
789 usage:      DAC state register (read-only)\r
790 Description: if d0 and d1 is set to zero it indicates that\r
791              the lookup table is in a write mode\r
792 ------------------------------------------------------------\r
793 Port-Index: -                Port: 03c7h\r
794 usage:      Lookup table read index register (Write only)\r
795 Description: Used when you want to read the palette (set color\r
796              number)\r
797 ------------------------------------------------------------\r
798 Port-Index: -                Port: 03c8h\r
799 usage:      Lookup table write index register\r
800 Description: Used when you want to change palette (set color\r
801              number)\r
802 ------------------------------------------------------------\r
803 Port-Index: -                Port: 03c9h\r
804 usage:      Lookup table data register\r
805 Description: Read color value (Red-Green-Blue) or write same data.\r
806 ------------------------------------------------------------\r