home *** CD-ROM | disk | FTP | other *** search
- /*
-
- VGA 320 * 400 * 256 * 2 frames routines.
-
- Written by: F van der Hulst, 20/2/91
-
- These routines display pixels in 320*400 mode by modifying the VGA
- registers, as outlined in Programmer's Journal V7.1 (Jan/Feb '89)
- article, pages 18-30, by Michael Abrash.
-
- The advantage of 320 * 400, is that it gives two separate video pages,
- which can be displayed on the screen independently. These can contain
- two views of a scene, taken from slightly different viewpoints. These
- are displayed alternately on the screen, in sync with a pair of
- "chopper glasses", to give a 3D effect.
- */
-
- #include <stdio.h>
- #include <dos.h>
- #include "mode_x.h"
-
-
- /* Setvgapalette sets the entire 256 color palette */
- /* PalBuf contains RGB values for all 256 colors */
- /* R,G,B values range from 0 to 63 */
- /* Taken from SVGA256.H, by Jordan Hargraphix Software */
-
- void setvgapalette(Palette *PalBuf)
- {
- struct REGPACK reg;
-
- reg.r_ax = 0x1012;
- reg.r_bx = 0;
- reg.r_cx = 256;
- reg.r_es = FP_SEG(PalBuf);
- reg.r_dx = FP_OFF(PalBuf);
- intr(0x10,®);
- }
-
-
- unsigned int act_page = 0; /* Current page being written to */
-
-
- void writepixel(int x, int y, unsigned char colour)
- {
- long addr;
-
- addr = ((x >> 2) + 320/4 * y + act_page);
- addr = ((addr & 0xffff0000l) << 4) + (addr & 0xffffL) + ((long) VGA_SEGMENT << 16);
- outport(SC_INDEX, (0x100 << (x & 3)) | MAP_MASK);
- *(char far*)addr = colour;
- }
-
- void set320x400mode(void)
- {
- struct REGPACK regs;
- unsigned char x;
-
- regs.r_ax = 0x13; /* Set 320*200*256 graphics mode via BIOS */
- intr(0x10, ®s);
-
- /*
- Change CPU addressing of video memory to linear (not odd/even, chain,
- or chain 4), to allow access to all 256K of display memory. Each byte
- will now control one pixel, with 4 adjacent pixels at any given
- address one pixel per plane.
- */
-
- outportb(SC_INDEX, MEMORY_MODE);
- x = inportb(SC_INDEX+1);
- x &= 0xf7; /* Turn off chain 4 */
- x |= 4; /* Turn off odd/even */
- outportb(SC_INDEX+1, x);
- outportb(GC_INDEX, GRAPHICS_MODE);
- x = inportb(GC_INDEX+1);
- x &= 0xef; /* Turn off odd/even */
- outportb(GC_INDEX+1, x);
- outportb(GC_INDEX, MISCELLANEOUS);
- x = inportb(GC_INDEX+1);
- x &= 0xfd; /* Turn off chain */
- outportb(GC_INDEX+1, x);
-
- /*
- Now clear the whole screen, since the mode 13h set only clears 64K. Do
- thisbefore switching CRTC out of mode 13h, so that we don't see grabage
- on the screen.
- */
-
- outport(SC_INDEX, 0x0f00 | MAP_MASK); /* Write to 4 planes at once */
- setmem(MK_FP(VGA_SEGMENT, 0), 0xffff, 0);
-
- /* Change mode to 320*400 by not scanning each line twice. */
-
- outportb(CRTC_INDEX, MAX_SCAN_LINE);
- x = inportb(CRTC_INDEX+1);
- x &= 0xe0; /* Set maximum scan line to 0 */
- outportb(CRTC_INDEX+1, x);
-
- /* Change CRTC scanning from doubleword to byte mode, allowing the CRTC to
- scan more than 64K
- */
- outportb(CRTC_INDEX, UNDERLINE);
- x = inportb(CRTC_INDEX+1);
- x &= 0xbf; /* Turn off doubleword */
- outportb(CRTC_INDEX+1, x);
- outportb(CRTC_INDEX, MODE_CONTROL);
- x = inportb(CRTC_INDEX+1);
- x |= 0x40; /* Turn on the byte mode bit, so memory is linear */
- outportb(CRTC_INDEX+1, x);
- }
-
- void end320x400mode(void)
- {
- struct REGPACK regs;
-
- regs.r_ax = 3; /* Return to text mode */
- intr(0x10, ®s);
- }
-
-
- /* Set visible page */
-
- void setvispage(int page)
- {
- outport(CRTC_INDEX, (page << 15) | START_ADDRESS_HIGH);
- }
-
-
- /* Set active page (page being written to) */
-
- void setactpage(int page)
- {
- act_page = page ? 0x8000 : 0;
- }
-
-
- void WaitForVerticalRetrace(void)
- {
- while (inportb(DISPIO) & VRT_bit); /* wait */
- while ((inportb(DISPIO) & VRT_bit) == 0); /* wait */
- }
-