home *** CD-ROM | disk | FTP | other *** search
- /* I don't have Turbo Pascal, but I wanted to see what these looked like,
- and whether or not they worked on my VGA. I've got a clone VGA with a
- "Trident" bios. I've got 512 K. Does anyone know how to do a similar
- trick that gets me 640x480x256? Or even 640x400x256 for those of us
- without 512K VGAs?
- -- russ (nelson@clutx [.bitnet | .clarkson.edu])
- Live up to the light thou hast, and more will be granted thee.
-
- */
-
- #include <dos.h>
-
- /*
- >From Hoke@cup.portal.com Mon Oct 30 09:52:08 1989
- From: Hoke@cup.portal.com (Hoke S Johnson)
- Newsgroups: comp.graphics
- Subject: VGA 360x480x256 mode usage code examples
- Date: 30 Oct 89 06:48:05 GMT
- Organization: The Portal System (TM)
-
- Since I received a large number of requests for code examples on how
- to set and use the 360x480x256 color mode on the VGA card I am posting
- some Turbo Pascal Code routines and code fragments that demonstrate
- the use of this mode. I have also included a 320x400x256 color mode
- set as well which is very similar to the 360x480x256 color mode. This
- code has been tried on the Compaq VGA card and on the Orchid Designer
- VGA card and it works on both. I cannot guarantee the suitability of
- this code for any particular VGA card but believe that it will work
- fine for all register level compatible VGA cards. Have fun and enjoy.
-
-
- The following VGA 360x480x256 mode set procedure was converted from assembly
- language code which appeared in the Sept/Oct 1989 Programmer's Journal
- Volume 7.5 in an article by Michael Abrash, who received the 360x480x256
- mode set code from John Bridges who has placed them in the public domain.
- The conversion from assembly language to Turbo Pascal Version 5.0 was
- done by Hoke Johnson.
- */
-
-
- #define VGAPage 0xA000 /* VGA video RAM segment address */
-
-
- /* Procedure to set standard VGA card into 360x480x256 color mode */
- void VGA360x480()
- {
- char Inbyte;
-
- _AX = 0x0013;
- geninterrupt(0x10); /* Let the bios set up into 320x200x256 mode first */
-
- outportb(0x3c4, 0x04);
- outportb(0x3c5, 0x06); /* Disable chain 4 */
-
-
- /* Clear out the display memory, this did not appear in the Journal article */
-
- outportb(0x3c4, 0x02);
- outportb(0x3c5, 0x0F);
-
- memset(MK_FP(VGAPage,0), 0, 65535);
-
- /* The following Sync reset was included in the Programmer's Journal
- article, but I had to disable it since it causes all of my PCs to hang
- when I include it */
-
- #if 0
- outportb($3c4, $00);
- outportb($3c5, $01);
- #endif
- /* Sync reset */
- outportb(0x3c2, 0xE7); /* Use the 28mHz clock */
-
- outportb(0x3d4, 0x11);
- Inbyte = inportb(0x3d5) & 0x7f;
- outportb(0x3d4, 0x11);
- outportb(0x3d5, Inbyte); /* Enable the writing of CRTC Registers */
-
- /* Write the CRTC Registers */
-
- outportb(0x3d4, 0x00);
- outportb(0x3d5, 0x6b);
-
- outportb(0x3d4, 0x01);
- outportb(0x3d5, 0x59);
-
- outportb(0x3d4, 0x02);
- outportb(0x3d5, 0x5a);
-
- outportb(0x3d4, 0x03);
- outportb(0x3d5, 0x8e);
-
- outportb(0x3d4, 0x04);
- outportb(0x3d5, 0x5e);
-
- outportb(0x3d4, 0x05);
- outportb(0x3d5, 0x8a);
-
- outportb(0x3d4, 0x06);
- outportb(0x3d5, 0x0d);
-
- outportb(0x3d4, 0x07);
- outportb(0x3d5, 0x3e);
-
- outportb(0x3d4, 0x09);
- outportb(0x3d5, 0x40);
-
- outportb(0x3d4, 0x10);
- outportb(0x3d5, 0xea);
-
- outportb(0x3d4, 0x12);
- outportb(0x3d5, 0xdf);
-
- outportb(0x3d4, 0x13);
- outportb(0x3d5, 0x2d);
-
- outportb(0x3d4, 0x14);
- outportb(0x3d5, 0x00);
-
- outportb(0x3d4, 0x15);
- outportb(0x3d5, 0xe7);
-
- outportb(0x3d4, 0x16);
- outportb(0x3d5, 0x06);
-
- outportb(0x3d4, 0x17);
- outportb(0x3d5, 0xe3);
-
- outportb(0x3d4, 0x11);
- outportb(0x3d5, 0xac);
- }
-
- /*
-
- The following code fragment shows how to write an arbitrary scanline
- of pixels on the screen in 360x480x256 VGA mode. The Linenumbers are
- numbered from 0 to 479 starting from the upper left. A byte array
- (Scanline) contains the pixels to be displayed.
-
- I,J,K,L are Words or Integers
- BT is a Byte
-
- I := Linenumber * 90; {The start of each graphic scan line is 360/4 or 90
- memory addresses after the previous scan line.
- Each scan line occupies 90 bytes of address space
- and since there are four memory planes there are
- 90 X 4 bytes of memory (360) for each scan line.
-
- If the upper left pixel is pixel number 0, and
- the lower right pixel is pixel number
- 360x480-1, an arbitrary pixel is accessed by
- finding the VGA memory address which is the
- pixel number shifted right 2 places relative
- to the start of VGA memory and the memory
- plane number is the 2 LSBs of the pixel
- number}
-
-
- For J := 0 to DispWidth - 1 do
- Begin
- L := I + j div 4; {Calculate VGA memory address offset}
- k := j mod 4; {Set K = 2 LSBs of pixel number}
- BT := $01 shl k; {Set BT = memory plane mask code}
- Port[$3c4] := $02; {Index Timing Sequencer register 2}
- Port[$3c5] := BT; {Write memory plane select mask}
- Mem[VGAPage:L] := ScanLine[j]; {Write pixel}
- End;
-
- The following routine sets the standard VGA into 320x400x256 mode, which
- is very similar to the 360x480x256 mode. Writing to the screen in
- 320x400x256 is the same as 360x480x256 mode, the only difference is
- the address span of each scan line which is 80 rather than 90.
-
- */
-
-
- void VGA320x400()
- {
- char Inbyte;
-
- _AX = 0x0013;
- geninterrupt(0x10);
-
- outportb(0x3c4, 0x04);
- outportb(0x3c5, 0x06); /* Disable chain 4 */
-
- outportb(0x3c4, 0x02);
- outportb(0x3c5, 0x0F);
-
- memset(MK_FP(VGAPage,0), 0, 65535);
-
- outportb(0x3c2, 0xE3); /* Set the 25mHz clock */
-
- outportb(0x3d4, 0x11);
- Inbyte = inportb(0x3d5) & 0x7f;
- outportb(0x3d4, 0x11);
- outportb(0x3d5, Inbyte); /* Enable the writing of CRTC Registers */
-
- outportb(0x3d4, 0x09);
- outportb(0x3d5, 0x40);
-
- outportb(0x3d4, 0x14);
- outportb(0x3d5, 0x00);
-
- outportb(0x3d4, 0x17);
- outportb(0x3d5, 0xe3);
- }
-
- void
- testpat(int x,int y)
- {
- int i,j;
- int k;
- char far *cp;
-
- outportb(0x3c4, 2);
- for (j = 0; j < y; j++) {
- k = j * (x >> 2);
- for (i = 0; i < x; i++) {
- outportb(0x3c5, 1 << (i & 3));
- cp = MK_FP(VGAPage,k + (i >> 2));
- *cp = (i + j);
- }
- }
- }
-
-
- main()
- {
- VGA320x400();
- testpat(320,400);
- getch();
- VGA360x480();
- testpat(360,480);
- getch();
- _AX = 0x0003;
- geninterrupt(0x10);
- }