home *** CD-ROM | disk | FTP | other *** search
- /* EGA - routines to drive the EGA board.
- */
-
- #include "lib.h"
- #include "vgr.h"
-
- /* proto's
- */
- int ega_init();
- int ega_select_plane();
- int ega_write_row();
- int ega_clear();
- int ega_set_palette();
- int ega_clr_point();
- int ega_xor_point();
- int ega_get_point();
- int ega_set_point();
- int ega_mode();
- int ega_null();
- int movmem();
- int peekb();
- int pokeb();
- int vgr_mode();
-
- static int (*ega_func[])() = {
- ega_init, ega_clear, ega_set_point, ega_clr_point,
- ega_xor_point, ega_get_point, ega_write_row, ega_select_plane,
- ega_set_palette,ega_mode, movmem, peekb, pokeb,
- ega_null, ega_null };
-
-
- /* EGA stuff
- */
-
- #define REG_ADDRESS 0x3c4
- #define REG_MAPMASK 0x3c5
- #define REG_IDX 0x3ce
- #define REG_VAL 0x3cf
- #define OUTIDX(i,v) {outportb(REG_IDX,i);outportb(REG_VAL,v);}
-
- static unsigned char far * far *ega_column;
-
-
- static int ega_null()
- {
- return ERROR;
- }
-
- int ega_init()
- {
- void *malloc();
- int row;
-
- if ( !ega_column )
- ega_column = CASTUCFPP malloc( sizeof CASTUCFP * 350 );
-
- if ( !ega_column )
- return ERROR;
-
- for ( row = 0; row < 350; row++ )
- ega_column[row] = CASTUCFP BASE_EGA + row*80l;
-
- VGR_HRES = 640;
- VGR_VRES = 350;
- VGR_NBPL = 80;
- VGR_NCOLORS = 16;
-
- movmem( ega_func, vgr_func, sizeof(vgr_func) );
- return OK;
- }
-
-
- int ega_select_plane( plane )
- int plane;
- {
- outportb( REG_ADDRESS, 2 );
- outportb( REG_MAPMASK, plane >= 0 ? 1 << (plane & 0x03) : -plane );
- }
-
-
- /* A version for the CGA card will have to check for retrace
- before copying each byte.
- */
- int ega_write_row( row, prow, nbytes )
- register unsigned int nbytes;
- unsigned char *prow;
- int row;
- {
- movmem( prow, ega_column[row], nbytes );
- }
-
-
- int ega_clear()
- {
- ega_select_plane( -0x0f );
- setmem( BASE_EGA, 0x8000, 0 );
- ega_select_plane( 0 );
- }
-
-
- int ega_set_palette( reg, red, green, blue )
- unsigned char reg, red, green, blue;
- {
- REGS r;
- unsigned char v;
-
- v = (blue & 0x01) | (blue & 0x02) * 4
- | (green & 0x01) * 2 | (green & 0x02) * 8
- | (red & 0x01) * 4 | (red & 0x02) * 16;
-
- r.ax = 0x1000;
- r.bx = ((unsigned int)v << 8) | reg;
- sysint( 0x10, &r, &r );
- }
-
-
- int ega_clr_point( x, y )
- unsigned int x, y;
- {
- ega_set_point( x, y, 0 );
- }
-
-
- int ega_xor_point( x, y, color )
- unsigned int x, y, color;
- {
- ega_set_point( x, y, ega_get_point( x, y ) ^ color );
- }
-
-
- int ega_get_point( x, y )
- unsigned int x, y;
- {
- #if 1
- REGS r;
-
- r.ax = 0x0d00;
- r.dx = y;
- r.cx = x;
-
- sysint( 0x10, &r, &r );
- return r.ax & 0xff;
- #endif
- #if 0
- unsigned char plane, mask, b, color;
- unsigned char far *p;
-
- p = ega_column[y] + (x>>3);
- b = 0x80 >> (x & 0x07);
-
- outportb( REG_ADDRESS, 2 );
-
- for ( color=plane=0; plane < 4; plane++ )
- { outportb( REG_MAPMASK, mask = (1 << plane) );
- color |= !!(*p & b) * mask;
- };
-
- return color;
- #endif
- }
-
-
- int ega_set_point( x, y, color )
- unsigned int x, y, color;
- {
- #if 1
- /* this works, but is painfully slow!! */
- REGS r;
-
- r.ax = 0x0c00 | color;
- r.dx = y;
- r.cx = x;
-
- sysint( 0x10, &r, &r );
- return OK;
- #endif
- #if 0
- /* This is my routine. It works if you stick to the color white!
- otherwise, it doesn't work because it's apparently not possible
- to directly read the EGA VRAM.
- */
- unsigned char plane, mask, b;
- unsigned char far *p;
-
- p = ega_column[y] + (x>>3);
- b = (unsigned int)0x80 >> (x & 0x07);
-
- outportb( REG_ADDRESS, 2 );
-
- for ( plane=0; plane < 4; plane++ )
- { outportb( REG_MAPMASK, mask = ((unsigned int)1 << plane) );
- if ( color & mask )
- *p |= b;
- else *p &= ~b;
- };
- #endif
- #if 0
- /* This is Gary Entsmingers routine,
- which works like an XOR function instead of
- a set function. I don't have the foggiest
- notion how it works. There's no reference in
- any of the (incomplete) doc that I've got
- to the registers used here.
- */
- unsigned char b;
- unsigned char far *p;
-
- p = ega_column[y] + (x>>3);
- b = (unsigned int)0x80 >> (x & 0x07);
-
- OUTIDX(0,color);
- OUTIDX(1, 0x0f);
- OUTIDX(8, b);
- OUTIDX(3, 0x18);
-
- /* It doesn't seem to matter what you do here as long as you
- don't assign -1 to *p. *p |= -1, *p &= -1, *p ^= *p and *p = *p
- all have the same effect - a hardware XOR function!
- */
- *p &= 0xff;
-
- OUTIDX(0,0);
- OUTIDX(1,0);
- OUTIDX(8,0xff);
- OUTIDX(3,0);
- #endif
- }
-
-
- int ega_mode( mode )
- int mode;
- {
- if ( mode == MODE_APA0 )
- return vgr_mode( 16 );
-
- if ( mode == MODE_TEXT0 )
- return vgr_mode( 3 );
-
- return ERROR; /* mode not currently supported */
- }
-
-