]> 4ch.mooo.com Git - 16.git/blob - 16/tweak16/XINTRO/XINTRO.TXT
[16_ca needs huge amounts of work and I should remember what needs to be done soon...
[16.git] / 16 / tweak16 / XINTRO / XINTRO.TXT
1 Title:          INTRODUCTION TO MODE X (XINTRO.TXT)\r
2 \r
3 Version:        1.8\r
4 \r
5 Author:         Robert Schmidt <robert@stud.unit.no>\r
6 \r
7 Copyright:      (C) 1993 of Ztiff Zox Softwear - refer to Status below.\r
8 \r
9 Last revision:  25-Nov-93\r
10 \r
11 Figures:        1. M13ORG - memory organization in mode 13h\r
12                 2. MXORG - memory organization in unchained modes\r
13 \r
14                 The figures are available both as 640x480x16 bitmaps\r
15                 (in GIF format), and as 7-bit ASCII text (ASC) files.\r
16 \r
17 C sources:      1. LIB.C v1.2 - simple graphics library for planar,\r
18                    256-color modes - optionally self-testing.\r
19 \r
20                 Excerpts from the source(s) appear in this article.\r
21                 Whenever there are conflicts, the external source file(s)\r
22                 are correct (or, at least, newest), _not_ the excerpts\r
23                 provided here.\r
24 \r
25 Status:         This article, its associated figures and source listings\r
26                 named above, are all donated to the public domain.\r
27                 Do with it whatever you like, but give credit where\r
28                 credit is due.  I would prefer it if this archive was\r
29                 distributed in its entirety, including the files\r
30                 mentioned above.\r
31 \r
32                 The standard disclaimer applies.\r
33 \r
34 Index:          0. ABSTRACT\r
35                 1. INTRODUCTION TO THE VGA AND ITS 256-COLOR MODE\r
36                 2. GETTING MORE PAGES AND PUTTING YOUR FIRST PIXEL\r
37                 3. THE ROAD FROM HERE\r
38                 4. BOOKS ON THE SUBJECT\r
39                 5. BYE - FOR NOW\r
40 \r
41 \r
42 0. ABSTRACT\r
43 \r
44 This text gives a fairly basic, yet technical, explanation to what, why\r
45 and how Mode X is.  It first tries to explain the layout of the VGA\r
46 memory and the shortcomings of the standard 320x200 256-color mode,\r
47 then gives instructions on how one can progress from mode 13h to a\r
48 multipage, planar 320x200 256-color mode, and from there to the\r
49 quasi-standard 320x240 mode, known as Mode X.\r
50 \r
51 A little experience in programming the standard VGA mode 13h\r
52 (320x200 in 256 colors) is assumed.  Likewise a good understanding of\r
53 hexadecimal notation and the concepts of segments and I/O ports is\r
54 assumed.  Keep a VGA reference handy, which at least should have\r
55 definitions of the VGA registers at bit level.\r
56 \r
57 Throughout the article, a simple graphics library for unchained (planar)\r
58 256-color modes is developed.  The library supports the 320x200 and\r
59 320x240 modes, active and visible pages, and writing and reading\r
60 individual pixels.\r
61 \r
62 \r
63 1. INTRODUCTION TO THE VGA AND ITS 256-COLOR MODE\r
64 \r
65 Since its first appearance on the motherboards of the IBM PS/2 50, 60\r
66 and 80 models in 1987, the Video Graphics Array has been the de facto\r
67 standard piece of graphics hardware for IBM and compatible personal\r
68 computers.  The abbreviation, VGA, was to most people synonymous with\r
69 acceptable resolution (640x480 pixels), and a stunning rainbow of colors\r
70 (256 from a palette of 262,144), at least compared to the rather gory\r
71 CGA and EGA cards.\r
72 \r
73 Sadly, to use 256 colors, the VGA BIOS limited the users to 320x200\r
74 pixels, i.e. the well-known mode 13h.  This mode has one good and one\r
75 bad asset.  The good one is that each one of the 64,000 pixels is easily\r
76 addressable in the 64 Kb video memory segment at 0A000h.  Simply calculate\r
77 the offset using this formula:\r
78 \r
79 offset = (y * 320) + x;\r
80 \r
81 Set the byte at this address (0A000h:offset) to the color you want, and\r
82 the pixel is there.  Reading a pixel is just as simple: just read the\r
83 corresponding byte.  This was heaven, compared to the havoc of planes and\r
84 masking registers needed in 16-color modes.  Suddenly, the distance from a\r
85 graphics algorithm on paper to an implemented graphics routine in assembly\r
86 was cut down to a fraction.  The results were impressively fast, too!\r
87 \r
88 The bad asset is that mode 13h is also limited to only one page, i.e.\r
89 the VGA can hold only one screenful at any one time (plus 1536 pixels, or\r
90 about four lines).  Most 16-color modes let the VGA hold more than one page,\r
91 and this enables you to show one of the pages to the user, while drawing on\r
92 another page in the meantime.  Page flipping is an important concept in making\r
93 flicker free animations.  Nice looking and smooth scrolling is also almost\r
94 impossible in mode 13h using plain VGA hardware.\r
95 \r
96 Now, the alert reader might say: "Hold on a minute!  If mode 13h enables\r
97 only one page, this means that there is memory for only one page.  But I\r
98 know for a fact that all VGAs have at least 256 Kb RAM, and one 320x200\r
99 256-color page should consume only 320*200=64000 bytes, which is less\r
100 than 64 Kb.  A standard VGA should room a little more than four 320x200\r
101 pages!"  Quite correct, and to see how the BIOS puts this limitation on\r
102 mode 13h, I'll elaborate a little on the memory organization of the VGA.\r
103 \r
104 The memory is separated into four bit planes.  The reason for this stems\r
105 from the EGA, where graphics modes were 16-color.  Using bit planes, the\r
106 designers chose to let each pixel on screen be addressable by a single\r
107 bit in a single byte in the video segment.  Assuming the palette has\r
108 not been modified from the default, each plane represent one of the EGA\r
109 primary colors: red, green, blue and intensity.  When modifying the bit\r
110 representing a pixel, the Write Plane Enable register is set to the\r
111 wanted color.  Reading is more complex and slower, since you can\r
112 only read from a single plane at a time, by setting the Read Plane\r
113 Select register.  Now, since each address in the video segment can\r
114 access 8 pixels, and there are 64 Kb addresses, 8 * 65,536 = 524,288\r
115 16-color pixels can be accessed.  In a 320x200 16-color mode, this makes\r
116 for about 8 (524,288/(320*200)) pages, in 640x480 you get nearly 2\r
117 (524,288/(640*480)) pages.\r
118 \r
119 In a 256-color mode, the picture changes subtly.  The designers decided\r
120 to fix the number of bit planes to 4, so extending the logic above to 8\r
121 planes and 256 colors does not work.  Instead, one of their goals was to\r
122 make the 256-color mode as easily accessible as possible.  Comparing the\r
123 8 pixels/address in 16-color modes to the 1-to-1 correspondence of\r
124 pixels and addresses of mode 13h, one can say that they have\r
125 succeeded, but at a certain cost.  For reasons I am not aware of, the\r
126 designers came up with the following effective, but memory-wasting\r
127 scheme:\r
128 \r
129 The address space of mode 13h is divided evenly across the four bit\r
130 planes.  When an 8-bit color value is written to a 16-bit address in the\r
131 VGA segment, a bit plane is automatically selected by the 2 least\r
132 significant bits of the address.  Then all 8 bits of the data is written\r
133 to the byte at the 16-bit address in the selected bitplane (have a look at\r
134 figure 1).  Reading works exactly the same way.  Since the bit planes are so\r
135 closely tied to the address, only every fourth byte in the video memory is\r
136 accessible, and 192 Kb of a 256 Kb VGA go to waste.  Eliminating the\r
137 need to bother about planes sure is convenient and beneficial, but to\r
138 most people the loss of 3/4 of the total VGA memory sounds just hilarious.\r
139 \r
140 To accomodate this new method of accessing video memory, the VGA\r
141 designers introduced a new configuration bit called Chain-4, which\r
142 resides as bit number 3 in index 4 of the Sequencer.  In 16-color modes,\r
143 the default state for this bit is off (zero), and the VGA operates as\r
144 described earlier.  In the VGA's standard 256-color mode, mode 13h, this\r
145 bit is turned on (set to one), and this turns the tieing of bit\r
146 planes and memory address on.\r
147 \r
148 In this state, the bit planes are said to be chained together, thus mode\r
149 13h is often called a _chained mode_.\r
150 \r
151 Note that Chain-4 in itself is not enough to set a 256-color mode -\r
152 there are other registers which deals with the other subtle changes in\r
153 nature from 16 to 256 colors.  But, as we now will base our work with\r
154 mode X on mode 13h, which already is 256-color, we won't bother about\r
155 these for now.\r
156 \r
157 \r
158 \r
159 2. GETTING MORE PAGES AND PUTTING YOUR FIRST PIXEL\r
160 \r
161 The observant reader might at this time suggest that clearing the\r
162 Chain-4 bit after setting mode 13h will give us access to all 256 Kb of\r
163 video memory, as the two least significant bits of the byte address\r
164 won't be `wasted' on selecting a bit plane.  This is correct.  You might\r
165 also start feeling a little uneasy, because something tells you that\r
166 you'll instantly loose the simple addressing scheme of mode 13h.  Sadly,\r
167 that is also correct.\r
168 \r
169 At the moment Chain-4 is cleared, each byte offset addresses *four*\r
170 sequential pixels, corresponding to the four planes addressed in 16-color\r
171 modes.  Every fourth pixel belong in the same plane.  Before writing to a byte\r
172 offset in the video segment, you should make sure that the 4-bit mask in the\r
173 Write Plane Enable register is set correctly, according to which of the four\r
174 addressable pixels you want to modify.  In essence, it works like a 16-color\r
175 mode with a twist.  See figure 2.\r
176 \r
177 So, is this mode X?  Not quite.  We need to elaborate to the VGA how to\r
178 fetch data for refreshing the monitor image.  Explaining the logic\r
179 behind this is beyond the scope of this getting-you-started text, and it\r
180 wouldn't be very interesting anyway.  Also, mode 13h has only 200 lines,\r
181 while I promised 240 lines.  I'll fix that later below.  Here is the minimum\r
182 snippet of code to initiate the 4 page variant of mode 13h (320x200), written\r
183 in plain C, using some DOS specific features (see header for a note about the\r
184 sources included):\r
185 \r
186 ----8<-------cut begin------\r
187 \r
188 /* width and height should specify the mode dimensions.  widthBytes\r
189    specify the width of a line in addressable bytes. */\r
190 \r
191 int width, height, widthBytes;\r
192 \r
193 /* actStart specifies the start of the page being accessed by\r
194    drawing operations.  visStart specifies the contents of the Screen\r
195    Start register, i.e. the start of the visible page */\r
196 \r
197 unsigned actStart, visStart;\r
198 \r
199 /*\r
200  * set320x200x256_X()\r
201  *      sets mode 13h, then turns it into an unchained (planar), 4-page\r
202  *      320x200x256 mode.\r
203  */\r
204 \r
205 set320x200x256_X()\r
206         {\r
207 \r
208         union REGS r;\r
209 \r
210         /* Set VGA BIOS mode 13h: */\r
211 \r
212         r.x.ax = 0x0013;\r
213         int86(0x10, &r, &r);\r
214 \r
215         /* Turn off the Chain-4 bit (bit 3 at index 4, port 0x3c4): */\r
216 \r
217         outport(SEQU_ADDR, 0x0604);\r
218 \r
219         /* Turn off word mode, by setting the Mode Control register\r
220            of the CRT Controller (index 0x17, port 0x3d4): */\r
221 \r
222         outport(CRTC_ADDR, 0xE317);\r
223 \r
224         /* Turn off doubleword mode, by setting the Underline Location\r
225            register (index 0x14, port 0x3d4): */\r
226 \r
227         outport(CRTC_ADDR, 0x0014);\r
228 \r
229         /* Clear entire video memory, by selecting all four planes, then\r
230            writing 0 to the entire segment. */\r
231 \r
232         outport(SEQU_ADDR, 0x0F02);\r
233         memset(vga+1, 0, 0xffff); /* stupid size_t exactly 1 too small */\r
234         vga[0] = 0;\r
235 \r
236         /* Update the global variables to reflect the dimensions of this\r
237            mode.  This is needed by most future drawing operations. */\r
238 \r
239         width   = 320;\r
240         height  = 200;\r
241 \r
242         /* Each byte addresses four pixels, so the width of a scan line\r
243            in *bytes* is one fourth of the number of pixels on a line. */\r
244 \r
245         widthBytes = width / 4;\r
246 \r
247         /* By default we want screen refreshing and drawing operations\r
248            to be based at offset 0 in the video segment. */\r
249 \r
250         actStart = visStart = 0;\r
251 \r
252         }\r
253 \r
254 ----8<-------cut end------\r
255 \r
256 As you can see, I've already provided some of the mechanics needed to\r
257 support multiple pages, by providing the actStart and visStart variables.\r
258 Selecting pages can be done in one of two contexts:\r
259 \r
260         1) selecting the visible page, i.e. which page is visible on\r
261            screen, and\r
262 \r
263         2) selecting the active page, i.e. which page is accessed by\r
264            drawing operations\r
265 \r
266 Selecting the active page is just a matter of offsetting our graphics\r
267 operations by the address of the start of the page, as demonstrated in\r
268 the put pixel routine below.  Selecting the visual page must be passed\r
269 in to the VGA, by setting the Screen Start register.  Sadly enough, the\r
270 resolution of this register is limited to one addressable byte, which\r
271 means four pixels in unchained 256-color modes.  Some further trickery is \r
272 needed for 1-pixel smooth, horizontal scrolling, but I'll make that a subject \r
273 for later.  The setXXXStart() functions provided here accept byte\r
274 offsets as parameters, so they'll work in any mode.  If widthBytes and\r
275 height are set correctly, so will the setXXXPage() functions.\r
276 \r
277 ----8<-------cut begin------\r
278 \r
279 /*\r
280  * setActiveStart() tells our graphics operations which address in video\r
281  * memory should be considered the top left corner.\r
282  */\r
283 \r
284 setActiveStart(unsigned offset)\r
285         {\r
286         actStart = offset;\r
287         }\r
288 \r
289 /*\r
290  * setVisibleStart() tells the VGA from which byte to fetch the first\r
291  * pixel when starting refresh at the top of the screen.  This version\r
292  * won't look very well in time critical situations (games for\r
293  * instance) as the register outputs are not synchronized with the\r
294  * screen refresh.  This refresh might start when the high byte is\r
295  * set, but before the low byte is set, which produces a bad flicker.\r
296  * I won't bother with this now.\r
297  */\r
298 \r
299 setVisibleStart(unsigned offset)\r
300         {\r
301         visStart = offset;\r
302         outport(CRTC_ADDR, 0x0C);               /* set high byte */\r
303         outport(CRTC_ADDR+1, visStart >> 8);\r
304         outport(CRTC_ADDR, 0x0D);               /* set low byte */\r
305         outport(CRTC_ADDR+1, visStart & 0xff);\r
306         }\r
307 \r
308 /*\r
309  * setXXXPage() sets the specified page by multiplying the page number\r
310  * with the size of one page at the current resolution, then handing the\r
311  * resulting offset value over to the corresponding setXXXStart()\r
312  * function.  The first page number is 0.\r
313  */\r
314 \r
315 setActivePage(int page)\r
316         {\r
317         setActiveStart(page * widthBytes * height);\r
318         }\r
319 \r
320 setVisiblePage(int page)\r
321         {\r
322         setVisibleStart(page * widthBytes * height);\r
323         }\r
324 \r
325 ----8<-------cut end------\r
326 \r
327 Due to the use of bit planes, the graphics routines tend to get more\r
328 complex than in mode 13h, and your first versions will generally tend to\r
329 be a little slower than mode 13h algorithms.  Here's a put pixel routine\r
330 for any unchained 256-color mode (it assumes that the 'width' variable\r
331 from the above code is set correctly).  Optimizing is left as an exercise\r
332 to you, the reader.  This will be the only drawing operation I'll cover\r
333 in this article, but all general primitives like lines and circles can be \r
334 based on this routine.  (You'll probably not want to do that though, due\r
335 to the inefficiency.)\r
336 \r
337 ----8<-------cut begin------\r
338 \r
339 putPixel_X(int x, int y, char color)\r
340         {\r
341 \r
342         /* Each address accesses four neighboring pixels, so set\r
343            Write Plane Enable according to which pixel we want\r
344            to modify.  The plane is determined by the two least\r
345            significant bits of the x-coordinate: */\r
346 \r
347         outportb(0x3c4, 0x02);\r
348         outportb(0x3c5, 0x01 << (x & 3));\r
349 \r
350         /* The offset of the pixel into the video segment is\r
351            offset = (width * y + x) / 4, and write the given\r
352            color to the plane we selected above.  Heed the active\r
353            page start selection. */\r
354 \r
355         vga[(unsigned)(widthBytes * y) + (x / 4) + actStart] = color;\r
356 \r
357         }\r
358 \r
359 char getPixel_X(int x, int y)\r
360         {\r
361 \r
362         /* Select the plane from which we must read the pixel color: */\r
363 \r
364         outport(GRAC_ADDR, 0x04);\r
365         outport(GRAC_ADDR+1, x & 3);\r
366 \r
367         return vga[(unsigned)(widthBytes * y) + (x / 4) + actStart];\r
368 \r
369         }\r
370 \r
371 ----8<-------cut end------\r
372 \r
373 \r
374 However, by now you should be aware of that the Write Plane Enable\r
375 register isn't limited to selecting just one bit plane, like the\r
376 Read Plane Select register is.  You can enable any combination of all\r
377 four to be written.  This ability to access 4 pixels with one\r
378 instruction helps quadrupling the speed in certain respects, especially when \r
379 drawing horizontal lines and filling polygons of a constant color.  Also, most \r
380 block algorithms can be optimized in various ways so that they need only\r
381 a constant number of OUTs (typically four) to the Write Plane Enable\r
382 register.  OUT is a relatively slow instruction.\r
383 \r
384 The gained ability to access the full 256 Kb of memory on a standard\r
385 VGA enables you to do paging and all the goodies following from that:\r
386 smooth scrolling over large maps, page flipping for flicker free\r
387 animation... and I'll leave something for your own imagination.\r
388 \r
389 In short, the stuff gained from unchaining mode 13h more than \r
390 upweighs the additional complexity of using a planar mode.  \r
391 \r
392 Now, the resolution of the mode is of little interest in this\r
393 context.  Nearly any 256-color resolution from (about) 80x8 to 400x300\r
394 is available for most VGAs.  I'll dwell particularly by 320x240, as this\r
395 is the mode that Michael Abrash introduced as 'Mode X' in his DDJ\r
396 articles.  It is also the resolution that most people refer to when\r
397 using that phrase.\r
398 \r
399 The good thing about the 320x240 mode is that the aspect ratio is\r
400 1:1, which means that each pixel is 'perfectly' square, i.e. not\r
401 rectangular like in 320x200.  An ellipse drawn with the same number of\r
402 pixels along both main axes will look like a perfect circle in 320x240,\r
403 but like a subtly tall ellipse in 320x200.\r
404 \r
405 Here's a function which sets the 320x240 mode.  You'll notice that\r
406 it depends on the first piece of code above:\r
407 \r
408 ----8<-------cut begin------\r
409 \r
410 set320x240x256_X()\r
411         {\r
412 \r
413         /* Set the unchained version of mode 13h: */\r
414 \r
415         set320x200x256_X();\r
416 \r
417         /* Modify the vertical sync polarity bits in the Misc. Output\r
418            Register to achieve square aspect ratio: */\r
419 \r
420         outportb(0x3C2, 0xE3);\r
421 \r
422         /* Modify the vertical timing registers to reflect the increased\r
423            vertical resolution, and to center the image as good as\r
424            possible: */\r
425 \r
426         outport(0x3D4, 0x2C11);         /* turn off write protect */\r
427         outport(0x3D4, 0x0D06);         /* vertical total */\r
428         outport(0x3D4, 0x3E07);         /* overflow register */\r
429         outport(0x3D4, 0xEA10);         /* vertical retrace start */\r
430         outport(0x3D4, 0xAC11);         /* vertical retrace end AND wr.prot */\r
431         outport(0x3D4, 0xDF12);         /* vertical display enable end */\r
432         outport(0x3D4, 0xE715);         /* start vertical blanking */\r
433         outport(0x3D4, 0x0616);         /* end vertical blanking */\r
434 \r
435         /* Update mode info, so future operations are aware of the\r
436            resolution: */\r
437 \r
438         height = 240;\r
439 \r
440         }\r
441 \r
442 ----8<-------cut end------\r
443 \r
444 \r
445 As you've figured out, this mode will be completely compatible with the\r
446 utility functions presented earlier, thanks to the global variable\r
447 'height'.  Boy, am I foreseeing or what!\r
448 \r
449 Other resolutions are achieved through giving other values to the sync\r
450 timing registers of the VGA, but this is quite a large and complex\r
451 subject, so I'll postpone this to later, if ever.\r
452 \r
453 Anyway, I hope I've helped getting you started using mode X.  As far as\r
454 I know, the two modes I've used above should work on *any* VGA and Super\r
455 VGA available, so this is pretty stable stuff.  Let me know of any \r
456 trouble, and - \r
457                         good luck!\r
458 \r
459 \r
460 \r
461 3. THE ROAD FROM HERE\r
462 \r
463 I'm providing information on various libraries and archives which relate\r
464 to what this article deals with.  If you want me to add anything to this\r
465 list (for future articles), let me know, although I can't promise anything.\r
466 I am assuming you have ftp access.\r
467 \r
468 \r
469 wuarchive.wustl.edu:/pub/MSDOS_UPLOADS/programming/xlib06.zip\r
470 \r
471 This is the current de facto C/assembler library for programming\r
472 unchained modes (do not confuse with a X Windows library).  All sources\r
473 are included, and the library is totally free.  It has functions for\r
474 pixels, lines, circles, bezier curves, mouse handling, sprites (bitmaps),\r
475 compiled bitmaps, and supports a number of resolutions.  The version number\r
476 ('06') is current as of November 1993.\r
477 \r
478 \r
479 graphprg.zip\r
480 \r
481 Michael Abrash' articles in Doctor Dobbs Journal is always mentioned\r
482 with awe.  In this 350 Kb archive, most of his interesting stuff has\r
483 been gathered.  Read about Mode X development and techniques from month\r
484 to month.  Included is also all the individual source code snippets from\r
485 each article, and also the full XSHARP library providing linedrawing,\r
486 polygons, bitmaps, solid 3D projection and speedy rendering, and even an\r
487 implementation of 2D texture mapping (can be used for quasi-3D texture\r
488 mapping), plus an article on assembly optimization on the i86 processor\r
489 family.  Definitely recommended.\r
490 \r
491 \r
492 oak.oakland.edu:/pub/msdos/vga/vgadoc2.zip\r
493 \r
494 This is a bare bones VGA register reference.  It also contains register\r
495 references for the CGA, EGA and Hercules cards, in addition to dozens of\r
496 SuperVGAs.  Check out the BOOKS section for some decent VGA references\r
497 though - you don't want to start tweaking without a real one.\r
498 \r
499 \r
500 wuarchive.wustl.edu:/pub/MSDOS_UPLOADS/programming/tweak15b.zip\r
501 \r
502 TWEAK might be of interest to the more adventurous reader.  TWEAK lets you\r
503 play around with the registers of the VGA in an interactive manner.\r
504 Various testing screens for viewing your newmade modes are applied at\r
505 the press of a key.  Version 1.5 adds a test screen which autodetects your \r
506 graphics mode and displays various information about resolutions etc.\r
507 Keep a VGA reference handy.  Don't try it if this is the first time you've \r
508 heard of 'registers' or 'mode X' or 'tweaking'.  I was planning a version\r
509 based on the Turbo Vision interface, but time has been short.  Maybe later!\r
510 \r
511 \r
512 \r
513 \r
514 4. BOOKS ON THE SUBJECT\r
515 \r
516 Extremely little has been published in written form about using\r
517 'Mode X'-style modes.  Below are some books which cover VGA programming\r
518 at varying degrees of technical level, but the only one to mention\r
519 unchained modes and Mode X, is Michael Abrash'.  I'd get one of the VGA\r
520 references first, though.\r
521 \r
522   o  George Sutty & Steve Blair : "Advanced Pogrammer's Guide to the\r
523      EGA/VGA" from Brady.  A bit old perhaps, but covers all *standard*\r
524      EGA/VGA registers, and discusses most BIOS functions and other\r
525      operations.  Contains disk with C/Pascal/assembler source code.\r
526      There's a sequel out for SuperVGAs, which I haven't seen.\r
527 \r
528   o  Michael Abrash : "Power Graphics Programming" from QUE/Programmer's\r
529      Journal.  Collections of (old) articles from Programmer's Journal on\r
530      EGA/VGA, read modes and write modes, animation, tweaking (320x400\r
531      and 360x480).  His newer ravings in DDJ covers fast 256-color\r
532      bitmaps, compiled bitmaps, polygons, 3D graphics, texture mapping\r
533      among other stuff.\r
534 \r
535   o  Richard F. Ferraro : "Programmer's Guide to the EGA and VGA video\r
536      cards including Super VGA".  I don't have this one, but heard it's\r
537      nice.  Detailed coverage of all EGA/VGA registers.  The Super VGA\r
538      reference makes it attractive.\r
539 \r
540   o  Richard Wilton : "Programmer's Guide to PC & PS/2 Video Systems"\r
541      Less technical, more application/algorithm oriented.  Nice enough,\r
542      even though it is a bit outdated, in that he discusses CGA and\r
543      Hercules cards just as much as EGA/VGA.\r
544 \r
545 \r
546 \r
547 \r
548 5. BYE - FOR NOW\r
549 \r
550 I am considering writing a text describing in more detail the process of\r
551 using TWEAK to achieve the VGA resolution you want or need.  However, I\r
552 thought I'd let this document go first, and see if I get any reactions.\r
553 If I don't, I'll stop.  Feel free to forward any suggestions,\r
554 criticisms, bombs and beers.\r
555 \r
556 I can be reached via:\r
557 \r
558   o  e-mail: robert@stud.unit.no\r
559 \r
560   o  land mail:\r
561 \r
562      Robert Schmidt\r
563      Stud.post 170\r
564      NTH\r
565      N-7034 Trondheim\r
566      NORWAY\r
567 \r
568 Nothing would encourage or please me more than a postcard from where you\r
569 live!\r