2 Programming the VGA Registers
\r
3 by Boone (boone@ucsd.edu), March '94
\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
45 constant PALSIZE = 256*3;
\r
46 unsigned character buffer[PALSIZE];
\r
52 for i = 0 to PALSIZE-1
\r
54 buffer[i] = buffer[i] - 1;
\r
56 output 0 to port 3C8h;
\r
57 for i = 0 to PALSIZE-1
\r
58 output buffer[i] to port 3C9h;
\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
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
92 for i = 0 to PALSIZE-1
\r
94 buffer[i] = buffer[i] - 1;
\r
96 while bit 3 of port 3DAh is 0
\r
98 while bit 3 of port 3DAh is 1
\r
101 output 0 to port 3C8h;
\r
102 for i = 0 to PALSIZE-1
\r
103 output buffer[i] to port 3C9h;
\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
124 palbuf DB 768 DUP (?)
\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
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
139 mov dl,[si] ; put next pal reg in dx
\r
140 cmp al,dl ; is it 0?
\r
142 dec dl ; yes, so subtract one
\r
143 mov [si],dl ; put it back into palette buffer
\r
146 dec cx ; decrement counter
\r
147 inc si ; increment our buffer
\r
149 jne decloop ; not done yet, so loop around
\r
151 mov cx,768 ; reset for palette output
\r
152 sub si,768 ; reset palbuf pointer
\r
154 out dx,al ; inform VGA of palette change
\r
155 inc dx ; DX = 3C8h + 1 = 3C9h
\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
161 cli ; disable interrupts!
\r
164 mov cl,80h ; do inner loop 128 times
\r
166 in al,dx ; wait for current retrace to end
\r
170 in al,dx ; wait for current screen trace to end
\r
174 mov dx,bx ; load up the palette change register
\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
182 jne innerloop ; loop while not done
\r
184 dec ch ; decrement outer loop counter
\r
186 jne outloop ; loop while not done
\r
188 sti ; restore interrupts
\r
190 mov ax,fadecnt ; entire palette has been sent
\r
191 dec ax ; so check fade loop
\r
193 cmp ax,0 ; ready to quit?
\r
194 jne fadeloop ; nope, keep fading!
\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
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
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
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
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
303 Here's the list. Have fun...
\r
305 Documentation Over the I/O Registers for Standard VGA Cards
\r
307 Documentated by Shaggy of The Yellow One
\r
308 Email: D91-SJD@TEKN.HJ.SE
\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
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
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
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
344 Description: d7 uses IRQ2
\r
346 ------------------------------------------------------------
\r
347 Port-Index: - Port: 03bah,03dah ; read only
\r
348 usage: d3 Vertical retrace
\r
349 d0 Horizontal retrace
\r
351 ------------------------------------------------------------
\r
352 Port-Index: - Port: 03c3h,46e8h
\r
353 usage: d7-d1 Reserved
\r
354 d0 VGA enable/disable (03c3h only)
\r
356 Description: Disables access to display memmory and the other
\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
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
370 ------------------------------------------------------------
\r
371 Port-Index: 02h Port: 03d4h, 03b4h
\r
372 usage: Start horizontal blanking
\r
373 Description: Character at which blanking starts
\r
375 ------------------------------------------------------------
\r
376 Port-Index: 03h Port: 03d4h, 03b4h
\r
377 usage: End horizontal 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
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
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
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
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
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
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
447 ------------------------------------------------------------
\r
448 Port-Index: 0bh Port: 03d4h, 03b4h
\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
495 d6 Double word mode
\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
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
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
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
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
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
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
558 ------------------------------------------------------------
\r
559 Port-Index: 03h Port: 03c4h
\r
560 usage: Character generator select register
\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
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
578 d1 Extended memory (disable 64k modes)
\r
581 ------------------------------------------------------------
\r
582 Port-Index: 00h Port: 03ceh
\r
583 usage: Set / Reset register
\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
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
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
614 d4,d3 Function select
\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
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
634 d5 Shift register mode
\r
636 d3 Color compare mode enable (1 = enable)
\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
649 ------------------------------------------------------------
\r
650 Port-Index: 06h Port: 03ceh
\r
651 usage: Miscellaneous register
\r
654 00 = A000h for 128k
\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
662 ------------------------------------------------------------
\r
663 Port-Index: 07h Port: 03ceh
\r
664 usage: Color don't care register
\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
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
699 d5 Horizontal panning compatibility
\r
701 d3 Background intensify / enable blinking
\r
702 d2 Line graphics enable (text modes only)
\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
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
727 ------------------------------------------------------------
\r
728 Port-Index: 12h Port: 03c0h
\r
729 usage: Color plane enable register
\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
746 ------------------------------------------------------------
\r
747 Port-Index: 13h Port: 03c0h
\r
748 usage: Horizontal panning register
\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
754 d3-d0 Number of pixels shifted to the left
\r
755 0+,1+,2+ 13h Other modes
\r
766 ------------------------------------------------------------
\r
767 Port-Index: 14h Port: 03c0h
\r
768 usage: Color select register
\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
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
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
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