home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- DTIFF2.C - DTIFF2, Display Tag Image File Format.
- Modified by Tom Cervenka for Late Night Software, (c) 1988
- All Rights Reserved.
-
- This code was modified from source mentioned in BYTE Vol 13, Num 11,
- "IBM Special Edition", "VGA VIDEO MODES", p. 187, by Richard Wilton
- and downloaded via BIX LISTINGS Conference.
-
- *****************************************************************************/
- /******************************************************************************
- * *
- * Name: gvmode.c *
- * *
- * Function: program VGA CRTC in graphics modes *
- * *
- * Syntax: GVMODE <horizontal pixels> <vertical pixels> [adjust] *
- * *
- ******************************************************************************/
-
- #include <stdio.h>
- #include <dos.h>
- #define outpw(portid,v) outport(portid,v)
-
- #define DOTRATE0 25.175E6
- #define DOTRATE1 28.322E6
- #define CHARHEIGHT 16 /* (should be 8, 14, or 16) */
-
- int far *ADDR_6845 = (int far *)0x00400063;
- union REGS regs; /* used by int86() */
-
- char *vgaxset( int HPixels, int VPixels, int HAdjust )
- {
- float DotRate;
- float LineRate;
- float FrameRate;
- float HSyncDuration = 3.813E-6; /* duration of HSync signal */
- int CharWidth = 8; /* size of displayed characters */
- int CharHeight = CHARHEIGHT;
-
- /* ROM BIOS data values */
- unsigned int far *CRT_COLS = (int far *)0x0040004A;
- unsigned int far *CRT_LEN = (int far *)0x0040004C;
-
- int Cols; /* number of displayed character columns */
- int HSyncTime; /* number of horiz sync clocks */
- int HOverscan = 8; /* number of overscan clocks */
- int HTotal; /* total clocks in one horiz scan */
- /* int HAdjust = 0; */ /* horizontal adjustment */
- /* int HPixels; */ /* number of horizontal pixels */
- int VOverscan = 16; /* number of overscan scan lines */
- int VSyncTime = 2; /* number of scan lines of vert sync signal */
- int VRetrTime = 30; /* number of scan lines of vertical retrace */
- /* int VPixels; */ /* number of vertical pixels (scan lines) */
-
- int CRTCval[0x19]; /* values for CRTC regs */
- int i;
-
- /* check args */
-
- if( HPixels % 16 )
- {
- return("Error: Horizontal pixel count must be a multiple of 16\n");
- }
-
- /* start with either 640x350 or 640x480 16-color graphics mode */
-
- regs.x.ax = ( (VPixels <= 350) ? 0x0010 : 0x0012 );
- int86( 0x10, ®s, ®s );
-
- /* call BIOS to select displayed character matrix */
-
- regs.x.ax = 0x1100;
- switch( CharHeight )
- {
- case 8:
- regs.x.ax += 0x23; /* use 8x8 character definitions */
- break;
-
- case 14:
- regs.x.ax += 0x22; /* use 8x14 character definitions */
- break;
-
- case 16:
- regs.x.ax += 0x24; /* use 8x14 character definitions */
- break;
- }
-
- regs.x.bx = 0;
- regs.x.dx = VPixels / CharHeight; /* number of character rows */
- int86( 0x10, ®s, ®s );
-
- /* select dot clock */
-
- i = inp( 0x3CC ); /* read Miscellaneous Output reg */
- i &= 0xF3; /* bits 2-3 = 00b (25.172 MHz) */
-
- if( (unsigned)((HPixels/CharWidth)*VPixels) > (unsigned)((640/8)*480) )
- i |= 4; /* bits 2-3 = 01b (28.322 MHz) */
-
- VRwait();
- SetSeqReg( 0, 1 ); /* synchronous Sequencer reset */
- outp( 0x3C2, i ); /* update Misc Output reg */
- SetSeqReg( 0, 3 ); /* clear Sequencer reset */
-
- /* compute CRTC horizontal and vertical timing parameters */
-
- DotRate = ( ((inp(0x3CC) & 0x0C) == 0) ? DOTRATE0 : DOTRATE1);
-
- HSyncTime = /* duration of Horiz Sync signal (rounded) */
- ( (DotRate * HSyncDuration) / (float)CharWidth ) + 0.5;
-
- Cols = HPixels / CharWidth;
-
- HTotal = Cols + HSyncTime + HOverscan;
-
- for( i=0; i<=0x18; i++ ) /* get current CRTC register values */
- CRTCval[i] = GetCRTCReg( i );
-
- CRTCval[0] = HTotal - 5; /* Reg 0: Horiz Total */
- CRTCval[1] = Cols - 1; /* Reg 1: Horiz Disp Enable End */
- CRTCval[2] = Cols; /* Reg 2: Start Horiz Blank */
- CRTCval[3] = ((HTotal-2) & 0x1F) | 0x80; /* Reg 3: End Horiz Blank */
- CRTCval[4] = Cols + HAdjust + 4; /* Reg 4: Start Hsync */
- CRTCval[5] = /* Reg 5: End Hsync */
- ((CRTCval[4] + HSyncTime) & 0x1F) | /* bits 0-4 */
- (((HTotal-2) & 0x20) << 2); /* bit 7 */
- CRTCval[0x13] = Cols / 2; /* Reg 0x13: Offset */
-
- CRTCval[6] = /* Reg 6: Vertical Total */
- VPixels + VOverscan + VSyncTime + VRetrTime - 2;
- CRTCval[0x10] = /* Reg 0x10: Vert Retrace Start */
- VPixels + (VOverscan+VRetrTime)/2;
- CRTCval[0x11] = /* Reg 0x11: Vert Retrace End */
- (CRTCval[0x11] & 0xF0) | /* bits 4-7 */
- ((CRTCval[0x10] + VSyncTime) & 0x0F); /* bits 0-3 */
- CRTCval[0x12] = VPixels - 1; /* Reg 0x12: Vert Display Enable End */
- CRTCval[0x15] = /* Reg 0x15: Start Vert Blank */
- VPixels + VOverscan/2;
- CRTCval[0x16] = /* Reg 0x16: End Vert Blank */
- CRTCval[6] - VOverscan/2 + 2;
- CRTCval[7] = /* Reg 7: Overflow */
- ((CRTCval[0x10] & 0x200) >> 2) | /* bit 7 */
- ((CRTCval[0x12] & 0x200) >> 3) | /* bit 6 */
- ((CRTCval[6] & 0x200) >> 4) | /* bit 5 */
- (CRTCval[7] & 0x10) | /* bit 4 */
- ((CRTCval[0x15] & 0x100) >> 5) | /* bit 3 */
- ((CRTCval[0x10] & 0x100) >> 6) | /* bit 2 */
- ((CRTCval[0x12] & 0x100) >> 7) | /* bit 1 */
- ((CRTCval[6] & 0x100) >> 8); /* bit 0 */
- CRTCval[9] = /* Reg 9: Max Scan Line */
- (CRTCval[9] & 0xDF) | ((CRTCval[0x15] & 0x200) >> 4); /* bit 5 */
-
- /* program the CRTC with new timing parameters */
-
- CRTCval[0x11] &= 0x7F; /* disable CRTC write-protect */
- SetCRTCReg( 0x11, CRTCval[0x11] );
-
- for( i=0; i<=0x18; i++ )
- SetCRTCReg( i, CRTCval[i] ); /* update CRTC regs */
-
- CRTCval[0x11] |= 0x80; /* enable CRTC write-protect */
- SetCRTCReg( 0x11, CRTCval[0x11] );
-
- SetATCReg( 0x11, 1 ); /* set a blue border (for screen alignment) */
-
- /* update BIOS data area */
-
- *CRT_COLS = Cols;
- *CRT_LEN = ((VPixels * Cols * 2) + 0xFFF) & 0xF000;
-
- /* display register values and timings */
- /*
- printf( "\nDisplayed resolution is %d by %d pixels",
- HPixels, VPixels );
- printf( "\nDisplayed character matrix is %d by %d pixels",
- CharWidth, CharHeight );
-
- printf( "\n\nCRTC registers:\n" ); /* show CRTC register values */
- for( i=0; i<=0x18; i++ )
- printf( " %2X", i );
-
- printf( "\n" );
- for( i=0; i<=0x18; i++ )
- printf( " %2X", GetCRTCReg( i ) );
-
- LineRate = /* scan lines per second */
- DotRate / (float)((CRTCval[0]+5)*CharWidth);
- i = ((GetCRTCReg(7) & 0x20) << 4) /* vertical total (scan lines) */
- + ((GetCRTCReg(7) & 0x1) << 8)
- + GetCRTCReg(6) + 2;
- FrameRate = LineRate / (float)i; /* frames per second */
-
- printf( "\n\nDot rate = %6.3f MHz, %d dots/char",
- DotRate/1E6, CharWidth );
- printf( "\nLine rate = %5.2f KHz", LineRate/1E3 );
- printf( "\nFrame rate = %4.1f Hz\n", FrameRate );
- */
- return(NULL);
- }
-
- SetCRTCReg( r, v ) /* update a CRTC register */
- int r; /* register number */
- int v; /* 8-bit value */
- {
- outpw( *ADDR_6845, (v<<8) | r );
- }
-
- GetCRTCReg( r ) /* read a CRTC register */
- int r; /* register number */
- {
- outp( *ADDR_6845, r );
- return inp( *ADDR_6845+1 );
- }
-
- SetSeqReg( r, v ) /* update a Sequencer register */
- int r;
- int v;
- {
- outpw( 0x3C4, (v<<8) | r );
- }
-
- SetATCReg( r, v ) /* set an Attribute Controller register */
- int r;
- int v;
- {
- regs.x.ax = 0x1000;
- regs.h.bh = v;
- regs.h.bl = r;
- int86( 0x10, ®s, ®s ); /* use video BIOS to set register */
- }
-
- VRwait() /* wait for vertical retrace */
- {
- register int CRTStatusPort = *ADDR_6845 + 6;
-
- while( (inp( CRTStatusPort ) & 8) != 0 );
- while( (inp( CRTStatusPort ) & 8) == 0 );
- }
-
- /* The following code was written by Tom Cervenka */
-
- extern int MaxX;
-
- void vgaxputpixel(int x, int y, int color)
- {
- unsigned offset;
- static unsigned char far *pixpos;
-
- offset=(x/8)+(y*((MaxX+1)/8));
- pixpos=MK_FP(0xa000,offset);
- *pixpos=(*pixpos)|(1<<(7-(x%8)));
- }
-
- void hercputpixel(int x, int y, int color)
- {
- unsigned offset;
- static unsigned char far *pixpos;
-
- offset=(0x2000*(y%4))+(90*(y/4))+(x/8);
- pixpos=MK_FP(0xB000,offset);
- *pixpos=(*pixpos)&(~(1<<(7-(x%8))));
- }
-
- void cgaputpixel(int x, int y, int color)
- {
- unsigned offset;
- static unsigned char far *pixpos;
-
- offset=(0x2000*(y%2))+(80*(y/2))+(x/8);
- pixpos=MK_FP(0xB800,offset);
- *pixpos=(*pixpos)&(~(1<<(7-(x%8))));
- }