home *** CD-ROM | disk | FTP | other *** search
- /*
- pcevga.c
-
- % EGA and VGA support
-
- 7/27/88 by Ted.
-
- OWL 1.1
- Copyright (c) 1988, 1989 by Oakland Group, Inc.
- ALL RIGHTS RESERVED.
-
- Revision History:
- -----------------
- 8/31/88 Ted Added actual ega graphics code.
- 4/14/89 ted Added palette poking function.
- 4/20/89 ted Fixed setcolmap loop counts from 16 to cmap->nentries.
- 5/06/89 ted Added colormap initialization.
- 6/15/89 Ted Added PlotText func.
- 6/28/89 ted removed dispid and changed mmwidth/height to x/ypixperm.
- 7/10/89 ted installed new text-plotting approach.
- 7/12/89 ted Added OSTATIC's and '_func' macros.
- 8/22/89 ted Added fontdesc_struct elements to def_font initialization.
- 9/06/89 ted Added pragma to turn off MS -Oi optimization.
- */
-
- #include "pcpriv.h"
-
- #define XORBIT 0x80
-
- OSTATIC pc_setinfo_func (evga_setinfo);
- OSTATIC void DIGPRIV evga_setfuncs(_arg1(dig_struct *));
- OSTATIC dig_dControl_func (evga_dControl);
- OSTATIC dig_pDrawCursor_func (evga_DrawCursor);
- OSTATIC dig_pClear_func (evga_Clear);
- OSTATIC dig_pDrawPixmap_func (evga_DrawPixmap);
- OSTATIC dig_pReadPixmap_func (evga_ReadPixmap);
- OSTATIC dig_pScrollBoxVt_func (evga_ScrollBoxVt);
- OSTATIC dig_pScrollBoxHz_func (evga_ScrollBoxHz);
- OSTATIC ramplanecopy_func (evga_segtomem);
- OSTATIC ramplanecopy_func (evga_memtoseg);
- OSTATIC void DIGPRIV ega_setcolmap(_arg1(ocolmap_type));
- OSTATIC void DIGPRIV vga_setcolmap(_arg1(ocolmap_type));
- /* -------------------------------------------------------------------------- */
-
- boolean pc_ModeD(digp)
- dig_struct *digp;
- {
- return(pc_OpenEVGA(digp, 0x0D));
- }
-
- boolean pc_ModeE(digp)
- dig_struct *digp;
- {
- return(pc_OpenEVGA(digp, 0x0E));
- }
-
- boolean pc_ModeF(digp)
- dig_struct *digp;
- {
- return(pc_OpenEVGA(digp, 0x0F));
- }
-
- boolean pc_Mode10(digp)
- dig_struct *digp;
- {
- return(pc_OpenEVGA(digp, 0x10));
- }
-
- boolean pc_Mode11(digp)
- dig_struct *digp;
- {
- return(pc_OpenEVGA(digp, 0x11));
- }
-
- boolean pc_Mode12(digp)
- dig_struct *digp;
- {
- return(pc_OpenEVGA(digp, 0x12));
- }
- /* -------------------------------------------------------------------------- */
-
- boolean DIGPRIV pc_OpenEVGA(digp, mode)
- dig_struct *digp;
- int mode;
- {
- if (!pc_OpenDIG(digp, mode, evga_setinfo)) {
- return(FALSE);
- }
- evga_setfuncs(digp);
- return(TRUE);
- }
- /* -------------------------------------------------------------------------- */
-
- static void DIGPRIV evga_setfuncs(digp)
- dig_struct *digp;
- {
- pc_setgfuncs(digp); /* Set the standard ptrs & vars for pc graphics */
-
- digp->dControl = evga_dControl;
-
- digp->pDrawCursor = evga_DrawCursor;
- digp->pClear = evga_Clear;
- digp->pScrollBoxVt = evga_ScrollBoxVt;
- digp->pScrollBoxHz = evga_ScrollBoxHz;
-
- digp->pDrawPixmap = evga_DrawPixmap;
- digp->pReadPixmap = evga_ReadPixmap;
- }
- /* -------------------------------------------------------------------------- */
-
- static dispinfo_struct evgainfo = {
- {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0}, /* devname */
- 0x0E, /* mode */
- 0, 0, /* xpixperm, ypixperm */
- &pcdatastruc.dmspace, /* dispmap */
- VID_EVGAADDR, /* dispaddr */
- 80, /* bytewidth */
- 0, /* ileave */
- 0, /* ilsize */
- 4, /* nplanes */
- 1, /* pixbits */
-
- 16L, /* ncolors */
- DTYPE_MAPCOLOR, /* color type */
- (ocolmap_type)&pcdefcmap, /* defcolmap */
-
- FALSE, /* hardcursor */
- BO_LSBYTFIRST, /* byteorder */
- { /* def_font */
- 0, /* fontid */
- { 8, 8, 0, 0,0,0, 0 }, /* real: width, height, style, etc. */
- { 8, 8, 0, 0,0,0, 0 } /* req: width, height, style, etc. */
- }
- };
- /* -------------------------------------------------------------------------- */
-
- static boolean DIGPRIV evga_setinfo(mode)
- int mode;
- {
- /* Set up the device info structure */
- memmove(&pcdata->info, &evgainfo, sizeof(dispinfo_struct));
- pc_initdispmap(640, 200);
-
- pcdata->info.mode = mode;
-
- /* Pre-set default values */
- pchdata->xmouscale = 1;
-
- /* Set up stuff for font plotter */
- pcdata->attrcols = pc_attrcols;
- pcdata->plotchar = pc_evgaplotchar;
-
- switch(mode) {
- case 0x0D:
- pchdata->xmouscale = 2;
- pcdata->info.dispmap->width = 320;
- pcdata->info.bytewidth = 40;
- strncpy(pcdata->info.devname, "IBM PC EGA LORES", DEVNAMELEN-1);
- break;
- case 0x0E:
- strncpy(pcdata->info.devname, "IBM PC EGA MEDRES", DEVNAMELEN-1);
- break;
- case 0x0F:
- pcdata->info.dispmap->height = 350;
- pcdata->info.nplanes = 2;
- pcdata->info.ncolors = 4;
- strncpy(pcdata->info.devname, "IBM PC EGA MONO", DEVNAMELEN-1);
- pcdata->info.defcolmap = (ocolmap_type)&pcdefmcmap;
- pcdata->info.def_font.real.height = 14;
- break;
- case 0x10:
- pcdata->info.dispmap->height = 350;
- strncpy(pcdata->info.devname, "IBM PC EGA HIRES", DEVNAMELEN-1);
- pcdata->info.def_font.real.height = 14;
- break;
- case 0x11:
- pcdata->info.dispmap->height = 480;
- pcdata->info.nplanes = 1;
- pcdata->info.ncolors = 2;
- strncpy(pcdata->info.devname, "IBM PC VGA MONO", DEVNAMELEN-1);
- pcdata->info.def_font.real.height = 16;
- pcdata->info.defcolmap = (ocolmap_type)&pcdefmcmap;
- pcdata->plotchar = pc_1bitplotchar;
- break;
- case 0x12:
- pcdata->info.dispmap->height = 480;
- strncpy(pcdata->info.devname, "IBM PC VGA HIRES", DEVNAMELEN-1);
- pcdata->info.def_font.real.height = 16;
- break;
- }
- pcdata->info.devname[DEVNAMELEN-1] = '\0';
-
- pchdata->ymouscale = 1;
-
- return(TRUE);
- }
- /* -------------------------------------------------------------------------- */
-
- int evga_dControl(msg, indata, outdata)
- dig_dcmsg msg;
- VOID *indata;
- VOID *outdata;
- {
- switch (msg) {
- case DC_SETCOLMAP:
- if (pcdata->info.dispmap->height <= 350) {
- ega_setcolmap((ocolmap_type) indata);
- }
- else vga_setcolmap((ocolmap_type) indata);
- break;
- case DC_GETCOLMAP:
- ocolmap_set((ocolmap_type) outdata, pcdata->colmap);
- break;
- default:
- return(pc_dControl(msg, indata, outdata));
- }
- return(TRUE);
- }
- /* -------------------------------------------------------------------------- */
-
- static void evga_DrawCursor(ptd, ctype)
- ptd_struct *ptd;
- cursortype ctype;
- {
- win_type win;
- opbox cursbox;
- opbox *opboxp;
-
- if (ctype != CURSOR_NONE) {
- win = ptd->win;
- dig_getcursbox(win, ctype, &cursbox);
- cursbox.xmax += 1;
- if (opbox_clipbox(ptd->relboxp, &cursbox)) {
- opboxp = ptd->relboxp;
- ptd->relboxp = &cursbox;
- evga_Clear(ptd, win_GetFgColor(win));
- ptd->relboxp = opboxp;
- }
- }
- }
- /* -------------------------------------------------------------------------- */
- /* EGA/VGA register control functions */
- /* -------------------------------------------------------------------------- */
- #define GCADDR 0x3CE
- #define GSADDR 0x3C4
- #define MODEREG 0x00
-
- /* Disable Set/Reset / Disable Data Rotate / Unmask Writes */
- #define setup() \
- (outp(GCADDR, 1), outp(GCADDR+1, 0x00), \
- outp(GCADDR, 3), outp(GCADDR+1, 0x00), \
- outp(GCADDR, 8), outp(GCADDR+1, 0xFF))
- #define planewrite() (setup(), writemode(0))
- #define planeread() writemode(1)
-
- #define wplaneselect(plane) (outp(GSADDR, 2), outp(GSADDR+1, 0x01 << (plane)))
- #define wallplanes() (outp(GSADDR, 2), outp(GSADDR+1, 0x0F))
- #define rplaneselect(plane) (outp(GCADDR, 4), outp(GCADDR+1, (byte)(plane)))
- #define writemode(mode) (outp(GCADDR, 5), outp(GCADDR+1, MODEREG | (mode)))
-
- /* Turn off Microsoft inline optimization for outp. It kills this code somehow. */
- #ifdef M5
- # pragma function(outp)
- #endif
- /* -------------------------------------------------------------------------- */
-
- static void evga_Clear(ptd, color)
- ptd_struct *ptd;
- opixval color;
- {
- writemode(2);
- ram_Clear(ptd, color);
- writemode(0);
- }
- /* -------------------------------------------------------------------------- */
-
- static void evga_ScrollBoxVt(ptd, nrows)
- ptd_struct *ptd;
- opcoord nrows;
- {
- writemode(1);
- ram_ScrollBoxVt(ptd, nrows);
- writemode(0);
- }
- /* -------------------------------------------------------------------------- */
-
- static void evga_ScrollBoxHz(ptd, ncols)
- ptd_struct *ptd;
- opcoord ncols;
- {
- writemode(1);
- ram_ScrollBoxHz(ptd, ncols);
- writemode(0);
- }
- /* -------------------------------------------------------------------------- */
-
- static void evga_DrawPixmap(ptd, pmap, pmboxp)
- ptd_struct *ptd;
- pmap_type pmap;
- opbox *pmboxp;
- /*
- Copy from the portion of pmap that is inside 'pmboxp' to the
- display inside of 'ptd->relboxp'.
- */
- {
- opbox scrbox;
- opcoord pmx, pmy;
-
- if (copypm_clip(ptd, pmap, pmboxp, &scrbox, &pmx, &pmy)) {
-
- planewrite();
-
- if (pc_nplanes() == 1) {
- ram_copypm(&scrbox, pmap, pmx, pmy, ram_memtoseg);
- }
- else {
- ram_copypm(&scrbox, pmap, pmx, pmy, (ramcopy_fptr) evga_memtoseg);
- wallplanes();
- }
- }
- }
- /* -------------------------------------------------------------------------- */
-
- static void DIGPRIV evga_memtoseg(segm, segoffs, membuf, bwidth, memoffs)
- unsigned segm;
- unsigned segoffs;
- byte *membuf;
- unsigned bwidth;
- unsigned memoffs;
- {
- int iplane;
-
- for (iplane = 0; iplane < pc_nplanes(); iplane++) {
- wplaneselect(iplane + (pc_nplanes()==2) ? iplane : 0); /* Mode F: planes 0,2 */
- ram_memtoseg(segm, segoffs, ((byte **)membuf)[iplane] + memoffs, bwidth);
- }
- writemode(0);
- }
- /* -------------------------------------------------------------------------- */
-
- static void evga_ReadPixmap(ptd, pmap, pmboxp)
- ptd_struct *ptd;
- pmap_type pmap;
- opbox *pmboxp;
- /*
- Copy into the portion of pmap that is inside 'pmboxp' from the
- display inside of 'ptd->relboxp'.
- */
- {
- opbox scrbox;
- opcoord pmx, pmy;
-
- if (copypm_clip(ptd, pmap, pmboxp, &scrbox, &pmx, &pmy)) {
-
- planeread();
-
- if (pc_nplanes() == 1) {
- rplaneselect(0);
- ram_copypm(&scrbox, pmap, pmx, pmy, ram_segtomem);
- }
- else {
- ram_copypm(&scrbox, pmap, pmx, pmy, (ramcopy_fptr) evga_segtomem);
- wallplanes();
- }
- writemode(0);
- }
- }
- /* -------------------------------------------------------------------------- */
-
- static void DIGPRIV evga_segtomem(segm, segoffs, membuf, bwidth, memoffs)
- unsigned segm;
- unsigned segoffs;
- byte *membuf;
- unsigned bwidth;
- unsigned memoffs;
- {
- int iplane;
-
- for (iplane = 0; iplane < pc_nplanes(); iplane++) {
- rplaneselect(iplane + (pc_nplanes()==2) ? iplane : 0); /* Mode F: planes 0,2 */
- ram_segtomem(segm, segoffs, ((byte **)membuf)[iplane] + memoffs, bwidth);
- }
- }
- /* -------------------------------------------------------------------------- */
-
- static void DIGPRIV ega_setcolmap(cmap)
- ocolmap_type cmap;
- {
- OREGS regs;
- byte r, g, b, palval;
- int i, ipix;
-
- if (cmap == NULL) {
- return;
- }
- /* From cmap, set the rgb vals for the appropriate regs */
- /* as nearly as possible */
- for (i = 0; i < cmap->nentries; i++) {
- ipix = cmap->firstpix + i;
- if (ipix > 16) break;
-
- /* construct the color (use only hi 2 bits of each rgb level) */
- r = ocolmap_pixred(cmap, ipix) >> 1;
- g = ocolmap_pixgreen(cmap, ipix) >> 2;
- b = ocolmap_pixblue(cmap, ipix) >> 3;
- palval = ((b >> 4) & 1) | ((g >> 4) & 2) | ((r >> 4) & 4) |
- (b & 8) | (g & 16) | (r & 32);
-
- /* set the palette entry */
- regs.x.ax = 0x1000;
-
- regs.h.bl = (byte)i;
- regs.h.bh = palval;
-
- oakint86(BIOS_VIDINT, ®s);
-
- /* Copy the info into our colmap copy */
- ocolmap_setpixrgb(pcdata->colmap, ipix,
- (r << 1)& 0xC0 +63, (g << 2)& 0xC0 +63, (b << 3)& 0xC0 +63);
- }
- }
- /* -------------------------------------------------------------------------- */
-
- static void DIGPRIV vga_setcolmap(cmap)
- ocolmap_type cmap;
- {
- OREGS regs;
- byte palregs[17];
- int i, ipix;
-
- if (cmap == NULL) {
- return;
- }
- /* set the register block selector mode and value to 0,0 */
- /* assume mode 0, block 0 */
-
- /* read pal regs */
- regs.x.ax = 0x1009; /* int 10h, funtion 10.09: get palette regs */
- regs.a.esdx = palregs;
- oakint86es(BIOS_VIDINT, ®s, 17);
-
- /* from cmap, set the rgb vals for the appropriate regs */
- for (i = 0; i < cmap->nentries; i++) {
- ipix = cmap->firstpix + i;
- if (ipix > 16) break;
-
- /* set the palette entry's rgb val */
- regs.x.ax = 0x1010;
- regs.x.bx = palregs[ipix];
- regs.h.dh = ocolmap_pixred(cmap, ipix) >> 2;
- regs.h.ch = ocolmap_pixgreen(cmap, ipix) >> 2;
- regs.h.cl = ocolmap_pixblue(cmap, ipix) >> 2;
-
- /* Copy the info into our colmap copy */
- ocolmap_setpixrgb(pcdata->colmap, ipix,
- (regs.h.dh << 2)+3, (regs.h.ch << 2)+3, (regs.h.cl << 2)+3);
-
- oakint86(BIOS_VIDINT, ®s);
- }
- }
- /* -------------------------------------------------------------------------- */
-