Category : Printer + Display Graphics
Archive   : $$$PCX.ZIP
Filename : CGA.C

 
Output of file : CGA.C contained in archive : $$$PCX.ZIP

/* CGA.c - Low level drivers for the CGA board
*/


#include "lib.h"
#include "vgr.h"

int cga_init();
int cga_write_row();
int cga_clear();
int cga_clr_point();
int cga_xor_point();
int cga_get_point();
int cga_set_point();
int cga_mode();
int cga_null();
int cga_palette(); /* not tested! */
int cga_movmem();
int cga_peekb();
int cga_pokeb();

static int mode;
static int (*cga_func[])() = {
cga_init, cga_clear, cga_set_point, cga_clr_point,
cga_xor_point, cga_get_point, cga_write_row, cga_null,
cga_null, cga_mode, cga_movmem, cga_peekb, cga_pokeb,
cga_null, cga_palette };


static unsigned char far * far *cga_column;


static int cga_null()
{
return ERROR;
}


int cga_peekb( p )
unsigned char far *p;
{
#asm
les bx, dword ptr 4[bp]
mov dx, 03dah
x1: in al, dx
test al, 1
jnz x1
x2: in al, dx
test al, 1
jz x2
mov al, es:byte ptr [bx]
sub ah,ah
#endasm
}


int cga_pokeb( p, b )
unsigned char far *p;
unsigned char b;
{
#asm
mov ah,byte ptr 8[bp]
les bx,dword ptr 4[bp]
mov dx, 03dah
y1: in al, dx
test al, 1
jnz y1
y2: in al, dx
test al, 1
jz y2
mov es:byte ptr [bx],ah
#endasm
}


/* WARNING: cga_movmem() doesn't check for overlapping blocks!!!!
*/

int cga_movmem( s, d, n )
unsigned char far *s, *d;
int n;
{
for ( ; n--; s++, d++ )
{
#asm
les bx, dword ptr 4[bp]
mov ah, es:byte ptr [bx]
les bx, dword ptr 8[bp]
mov dx, 03dah
z1: in al, dx
test al, 1
jnz z1
z2: in al, dx
test al, 1
jz z2
mov es:byte ptr [bx],ah
#endasm
};
}

int cga_init()
{
void *malloc();
int row;

if ( !cga_column )
cga_column = CASTUCFPP malloc( sizeof CASTUCFP * 200 );

if ( !cga_column )
return ERROR;

for ( row = 0; row < 200; row++ )
cga_column[row] = CASTUCFP BASE_CGA + ((uint)row >> 1)*80l + (row & 1)*0x2000;

VGR_NBPL = VGR_NCOLORS =
VGR_HRES = VGR_VRES = 0; /* must set mode first! */

movmem( cga_func, vgr_func, sizeof(vgr_func) );
return OK;
}


/* Warning: NOT TESTED
*/
int cga_palette( bg, fg )
int fg, bg;
{
if ( !mode )
return OK; /* no meaning if not in 320x200x4 mode */

outportb( 0x3d9, ((uint)(fg & 0x07)<<5) | (bg & 0x0f) );
return OK;
}


int cga_write_row( row, prow, nbytes )
register unsigned int nbytes;
unsigned char far *prow;
int row;
{
cga_movmem( prow, cga_column[row], nbytes );
}


int cga_clear()
{
int i;

for ( i=0; i < 0x4000; i++ )
cga_pokeb( CASTUCFP (BASE_CGA + (long)i), 0 );
}


int cga_clr_point( x, y )
unsigned int x, y;
{
unsigned char far *p;

if ( mode )
{ p = cga_column[y] + (x>>2);
cga_pokeb( p, cga_peekb(p) & ~(0xc0 >> ((x & 0x03) << 1)) );
} else
{ p = cga_column[y] + (x>>3);
cga_pokeb( p, cga_peekb(p) & ~(0x80 >> (x & 0x07)) );
};
}


int cga_xor_point( x, y, color )
unsigned int x, y, color;
{
cga_set_point( x, y, cga_get_point( x, y ) ^ color );
}


int cga_get_point( x, y )
unsigned int x, y;
{
uint i;

if ( mode )
{ i = (unsigned int)(x & 0x03) << 1;
return (uint)(cga_peekb(cga_column[y]+(x>>2))&(0xc0>>i)) >> (6-i);
} else
return !!( cga_peekb( cga_column[y] + (x>>3) )
& (0x80 >> (x & 0x07)));
}


int cga_set_point( x, y, color )
unsigned int x, y, color;
{
unsigned char far *p;
unsigned char i;

if ( !mode )
{ p = cga_column[y] + (x>>3);
return cga_pokeb( p, cga_peekb(p) | (0x80 >> (x & 0x07)) );
};

p = cga_column[y] + (x>>2);
i = (x & 3) << 1;
cga_pokeb( p, cga_peekb(p) & ~(0xc0 >> i) );
cga_pokeb( p, cga_peekb(p) | ((color & 0x03) << (6-i)) );
}


int cga_mode( m )
int m;
{
if ( m == MODE_TEXT0 )
return vgr_mode(3);

if ( m == MODE_APA3 ) /* 320x200x4 */
{ VGR_HRES = 320;
VGR_VRES = 200;
VGR_NCOLORS = 4;
VGR_NBPL = 80;
mode = 1;
return vgr_mode(4);
};

if ( m == MODE_APA2 ) /* 640x200x2 */
{ VGR_HRES = 640;

VGR_VRES = 200;
VGR_NCOLORS = 2;
VGR_NBPL = 80;
mode = 0;
return vgr_mode(6);
};

return ERROR; /* mode not currently supported */
}