home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c185 / 2.ddi / OWLSRC.EXE / CSCAPE / SOURCE / PCEVGA.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-11  |  12.3 KB  |  463 lines

  1. /*
  2.     pcevga.c
  3.  
  4.     % EGA and VGA support
  5.  
  6.     7/27/88  by Ted.
  7.  
  8.     OWL 1.1
  9.     Copyright (c) 1988, 1989 by Oakland Group, Inc.
  10.     ALL RIGHTS RESERVED.
  11.  
  12.     Revision History:
  13.     -----------------
  14.      8/31/88 Ted    Added actual ega graphics code.
  15.      4/14/89 ted    Added palette poking function.
  16.      4/20/89 ted    Fixed setcolmap loop counts from 16 to cmap->nentries.
  17.      5/06/89 ted    Added colormap initialization.
  18.      6/15/89 Ted    Added PlotText func.
  19.      6/28/89 ted    removed dispid and changed mmwidth/height to x/ypixperm.
  20.      7/10/89 ted    installed new text-plotting approach.
  21.      7/12/89 ted    Added OSTATIC's and '_func' macros.
  22.      8/22/89 ted    Added fontdesc_struct elements to def_font initialization.
  23.      9/06/89 ted    Added pragma to turn off MS -Oi optimization.
  24. */
  25.  
  26. #include "pcpriv.h"
  27.  
  28. #define XORBIT        0x80
  29.  
  30. OSTATIC pc_setinfo_func            (evga_setinfo);
  31. OSTATIC void                     DIGPRIV evga_setfuncs(_arg1(dig_struct *));
  32. OSTATIC dig_dControl_func        (evga_dControl);
  33. OSTATIC dig_pDrawCursor_func    (evga_DrawCursor);
  34. OSTATIC dig_pClear_func            (evga_Clear);
  35. OSTATIC dig_pDrawPixmap_func    (evga_DrawPixmap);
  36. OSTATIC dig_pReadPixmap_func    (evga_ReadPixmap);
  37. OSTATIC dig_pScrollBoxVt_func    (evga_ScrollBoxVt);
  38. OSTATIC dig_pScrollBoxHz_func    (evga_ScrollBoxHz);
  39. OSTATIC ramplanecopy_func         (evga_segtomem);
  40. OSTATIC ramplanecopy_func         (evga_memtoseg);
  41. OSTATIC void                    DIGPRIV ega_setcolmap(_arg1(ocolmap_type));
  42. OSTATIC void                    DIGPRIV vga_setcolmap(_arg1(ocolmap_type));
  43. /* -------------------------------------------------------------------------- */
  44.  
  45. boolean pc_ModeD(digp)
  46.     dig_struct *digp;
  47. {
  48.     return(pc_OpenEVGA(digp, 0x0D));
  49. }
  50.  
  51. boolean pc_ModeE(digp)
  52.     dig_struct *digp;
  53. {
  54.     return(pc_OpenEVGA(digp, 0x0E));
  55. }
  56.  
  57. boolean pc_ModeF(digp)
  58.     dig_struct *digp;
  59. {
  60.     return(pc_OpenEVGA(digp, 0x0F));
  61. }
  62.  
  63. boolean pc_Mode10(digp)
  64.     dig_struct *digp;
  65. {
  66.     return(pc_OpenEVGA(digp, 0x10));
  67. }
  68.  
  69. boolean pc_Mode11(digp)
  70.     dig_struct *digp;
  71. {
  72.     return(pc_OpenEVGA(digp, 0x11));
  73. }
  74.  
  75. boolean pc_Mode12(digp)
  76.     dig_struct *digp;
  77. {
  78.     return(pc_OpenEVGA(digp, 0x12));
  79. }
  80. /* -------------------------------------------------------------------------- */
  81.  
  82. boolean DIGPRIV pc_OpenEVGA(digp, mode)
  83.     dig_struct *digp;
  84.     int mode;
  85. {
  86.     if (!pc_OpenDIG(digp, mode, evga_setinfo)) {
  87.         return(FALSE);
  88.     }
  89.     evga_setfuncs(digp);
  90.     return(TRUE);
  91. }
  92. /* -------------------------------------------------------------------------- */
  93.  
  94. static void DIGPRIV evga_setfuncs(digp)
  95.     dig_struct *digp;
  96. {
  97.     pc_setgfuncs(digp);        /* Set the standard ptrs & vars for pc graphics */
  98.  
  99.     digp->dControl      = evga_dControl;
  100.  
  101.     digp->pDrawCursor    = evga_DrawCursor;
  102.     digp->pClear        = evga_Clear;
  103.     digp->pScrollBoxVt    = evga_ScrollBoxVt;
  104.     digp->pScrollBoxHz    = evga_ScrollBoxHz;
  105.  
  106.     digp->pDrawPixmap    = evga_DrawPixmap;
  107.     digp->pReadPixmap    = evga_ReadPixmap;
  108. }
  109. /* -------------------------------------------------------------------------- */
  110.  
  111. static dispinfo_struct evgainfo = {
  112.     {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0},    /* devname */
  113.     0x0E,            /* mode */
  114.     0, 0,            /* xpixperm, ypixperm */
  115.     &pcdatastruc.dmspace, /* dispmap */
  116.     VID_EVGAADDR,    /* dispaddr */
  117.     80,                /* bytewidth */
  118.     0,                /* ileave */
  119.     0,                /* ilsize */
  120.     4,                /* nplanes */
  121.     1,                /* pixbits */
  122.  
  123.     16L,            /* ncolors */
  124.     DTYPE_MAPCOLOR,    /* color type */
  125.     (ocolmap_type)&pcdefcmap,     /* defcolmap */
  126.  
  127.     FALSE,            /* hardcursor */
  128.     BO_LSBYTFIRST,    /* byteorder */
  129.     {                /* def_font */
  130.         0,                /* fontid */
  131.         { 8, 8, 0, 0,0,0, 0 },        /* real: width, height, style, etc. */
  132.         { 8, 8, 0, 0,0,0, 0 }        /* req:  width, height, style, etc. */
  133.     }
  134. };
  135. /* -------------------------------------------------------------------------- */
  136.  
  137. static boolean DIGPRIV evga_setinfo(mode)
  138.     int mode;
  139. {
  140. /* Set up the device info structure */
  141.     memmove(&pcdata->info, &evgainfo, sizeof(dispinfo_struct));
  142.     pc_initdispmap(640, 200);
  143.  
  144.     pcdata->info.mode = mode;
  145.  
  146. /* Pre-set default values */
  147.     pchdata->xmouscale = 1;
  148.  
  149.     /* Set up stuff for font plotter */
  150.     pcdata->attrcols = pc_attrcols;
  151.     pcdata->plotchar = pc_evgaplotchar;
  152.  
  153.     switch(mode) {
  154.     case 0x0D:
  155.         pchdata->xmouscale = 2;
  156.         pcdata->info.dispmap->width = 320;
  157.         pcdata->info.bytewidth = 40;
  158.         strncpy(pcdata->info.devname, "IBM PC EGA LORES", DEVNAMELEN-1);
  159.         break;
  160.     case 0x0E:
  161.         strncpy(pcdata->info.devname, "IBM PC EGA MEDRES", DEVNAMELEN-1);
  162.         break;
  163.     case 0x0F:
  164.         pcdata->info.dispmap->height = 350;
  165.         pcdata->info.nplanes = 2;
  166.         pcdata->info.ncolors = 4;
  167.         strncpy(pcdata->info.devname, "IBM PC EGA MONO", DEVNAMELEN-1);
  168.         pcdata->info.defcolmap = (ocolmap_type)&pcdefmcmap;
  169.         pcdata->info.def_font.real.height = 14;
  170.         break;
  171.     case 0x10:
  172.         pcdata->info.dispmap->height = 350;
  173.         strncpy(pcdata->info.devname, "IBM PC EGA HIRES", DEVNAMELEN-1);
  174.         pcdata->info.def_font.real.height = 14;
  175.         break;
  176.     case 0x11:
  177.         pcdata->info.dispmap->height = 480;
  178.         pcdata->info.nplanes = 1;
  179.         pcdata->info.ncolors = 2;
  180.         strncpy(pcdata->info.devname, "IBM PC VGA MONO", DEVNAMELEN-1);
  181.         pcdata->info.def_font.real.height = 16;
  182.         pcdata->info.defcolmap = (ocolmap_type)&pcdefmcmap;
  183.         pcdata->plotchar = pc_1bitplotchar;
  184.         break;
  185.     case 0x12:
  186.         pcdata->info.dispmap->height = 480;
  187.         strncpy(pcdata->info.devname, "IBM PC VGA HIRES", DEVNAMELEN-1);
  188.         pcdata->info.def_font.real.height = 16;
  189.         break;
  190.     }
  191.     pcdata->info.devname[DEVNAMELEN-1] = '\0';
  192.  
  193.     pchdata->ymouscale = 1;
  194.  
  195.     return(TRUE);
  196. }
  197. /* -------------------------------------------------------------------------- */
  198.  
  199. int evga_dControl(msg, indata, outdata)
  200.     dig_dcmsg msg;
  201.     VOID *indata;
  202.     VOID *outdata;
  203. {
  204.     switch (msg) {
  205.     case DC_SETCOLMAP:
  206.         if (pcdata->info.dispmap->height <= 350) {
  207.             ega_setcolmap((ocolmap_type) indata);
  208.         }
  209.         else vga_setcolmap((ocolmap_type) indata);
  210.         break;
  211.     case DC_GETCOLMAP:
  212.         ocolmap_set((ocolmap_type) outdata, pcdata->colmap);
  213.         break;
  214.     default:
  215.         return(pc_dControl(msg, indata, outdata));
  216.     }
  217.     return(TRUE);
  218. }
  219. /* -------------------------------------------------------------------------- */
  220.  
  221. static void evga_DrawCursor(ptd, ctype)
  222.     ptd_struct *ptd;
  223.     cursortype ctype;
  224. {
  225.     win_type win;
  226.     opbox cursbox;
  227.     opbox *opboxp;
  228.  
  229.     if (ctype != CURSOR_NONE) {
  230.         win = ptd->win;
  231.         dig_getcursbox(win, ctype, &cursbox);
  232.         cursbox.xmax += 1;
  233.         if (opbox_clipbox(ptd->relboxp, &cursbox)) {
  234.             opboxp = ptd->relboxp;
  235.             ptd->relboxp = &cursbox;
  236.             evga_Clear(ptd, win_GetFgColor(win));
  237.             ptd->relboxp = opboxp;
  238.         }
  239.     }
  240. }
  241. /* -------------------------------------------------------------------------- */
  242. /* EGA/VGA register control functions */
  243. /* -------------------------------------------------------------------------- */
  244. #define GCADDR        0x3CE
  245. #define GSADDR        0x3C4
  246. #define MODEREG        0x00
  247.  
  248. /* Disable Set/Reset / Disable Data Rotate / Unmask Writes */
  249. #define setup()                    \
  250.         (outp(GCADDR, 1), outp(GCADDR+1, 0x00),    \
  251.          outp(GCADDR, 3), outp(GCADDR+1, 0x00),    \
  252.          outp(GCADDR, 8), outp(GCADDR+1, 0xFF))
  253. #define planewrite()        (setup(), writemode(0))
  254. #define planeread()            writemode(1)
  255.  
  256. #define wplaneselect(plane)    (outp(GSADDR, 2), outp(GSADDR+1, 0x01 << (plane)))
  257. #define wallplanes()        (outp(GSADDR, 2), outp(GSADDR+1, 0x0F))
  258. #define rplaneselect(plane)    (outp(GCADDR, 4), outp(GCADDR+1, (byte)(plane)))
  259. #define writemode(mode)        (outp(GCADDR, 5), outp(GCADDR+1, MODEREG | (mode)))
  260.  
  261. /* Turn off Microsoft inline optimization for outp. It kills this code somehow. */
  262. #ifdef M5
  263. #    pragma function(outp)
  264. #endif
  265. /* -------------------------------------------------------------------------- */
  266.  
  267. static void evga_Clear(ptd, color)
  268.     ptd_struct *ptd;
  269.     opixval color;
  270. {
  271.     writemode(2);
  272.     ram_Clear(ptd, color);
  273.     writemode(0);
  274. }
  275. /* -------------------------------------------------------------------------- */
  276.  
  277. static void evga_ScrollBoxVt(ptd, nrows)
  278.     ptd_struct *ptd;
  279.     opcoord nrows;
  280. {
  281.     writemode(1);
  282.     ram_ScrollBoxVt(ptd, nrows);
  283.     writemode(0);
  284. }
  285. /* -------------------------------------------------------------------------- */
  286.  
  287. static void evga_ScrollBoxHz(ptd, ncols)
  288.     ptd_struct *ptd;
  289.     opcoord ncols;
  290. {
  291.     writemode(1);
  292.     ram_ScrollBoxHz(ptd, ncols);
  293.     writemode(0);
  294. }
  295. /* -------------------------------------------------------------------------- */
  296.  
  297. static void evga_DrawPixmap(ptd, pmap, pmboxp)
  298.     ptd_struct *ptd;
  299.     pmap_type pmap;
  300.     opbox *pmboxp;
  301. /*
  302.     Copy from the portion of pmap that is inside 'pmboxp' to the
  303.     display inside of 'ptd->relboxp'.
  304. */
  305. {
  306.     opbox scrbox;
  307.     opcoord pmx, pmy;
  308.  
  309.     if (copypm_clip(ptd, pmap, pmboxp, &scrbox, &pmx, &pmy)) {
  310.  
  311.         planewrite();
  312.  
  313.         if (pc_nplanes() == 1) {
  314.             ram_copypm(&scrbox, pmap, pmx, pmy, ram_memtoseg);
  315.         }
  316.         else {
  317.             ram_copypm(&scrbox, pmap, pmx, pmy, (ramcopy_fptr) evga_memtoseg);
  318.             wallplanes();
  319.         }
  320.     }
  321. }
  322. /* -------------------------------------------------------------------------- */
  323.  
  324. static void DIGPRIV evga_memtoseg(segm, segoffs, membuf, bwidth, memoffs)
  325.     unsigned segm;
  326.     unsigned segoffs;
  327.     byte *membuf;
  328.     unsigned bwidth;
  329.     unsigned memoffs;
  330. {
  331.     int iplane;
  332.  
  333.     for (iplane = 0; iplane < pc_nplanes(); iplane++) {
  334.         wplaneselect(iplane + (pc_nplanes()==2) ? iplane : 0);    /* Mode F: planes 0,2 */
  335.         ram_memtoseg(segm, segoffs, ((byte **)membuf)[iplane] + memoffs, bwidth);
  336.     }
  337.     writemode(0);
  338. }
  339. /* -------------------------------------------------------------------------- */
  340.  
  341. static void evga_ReadPixmap(ptd, pmap, pmboxp)
  342.     ptd_struct *ptd;
  343.     pmap_type pmap;
  344.     opbox *pmboxp;
  345. /*
  346.     Copy into the portion of pmap that is inside 'pmboxp' from the
  347.     display inside of 'ptd->relboxp'.
  348. */
  349. {
  350.     opbox scrbox;
  351.     opcoord pmx, pmy;
  352.  
  353.     if (copypm_clip(ptd, pmap, pmboxp, &scrbox, &pmx, &pmy)) {
  354.  
  355.         planeread();
  356.  
  357.         if (pc_nplanes() == 1) {
  358.             rplaneselect(0);
  359.             ram_copypm(&scrbox, pmap, pmx, pmy, ram_segtomem);
  360.         }
  361.         else {
  362.             ram_copypm(&scrbox, pmap, pmx, pmy, (ramcopy_fptr) evga_segtomem);
  363.             wallplanes();
  364.         }
  365.         writemode(0);
  366.     }
  367. }
  368. /* -------------------------------------------------------------------------- */
  369.  
  370. static void DIGPRIV evga_segtomem(segm, segoffs, membuf, bwidth, memoffs)
  371.     unsigned segm;
  372.     unsigned segoffs;
  373.     byte *membuf;
  374.     unsigned bwidth;
  375.     unsigned memoffs;
  376. {
  377.     int iplane;
  378.  
  379.     for (iplane = 0; iplane < pc_nplanes(); iplane++) {
  380.         rplaneselect(iplane + (pc_nplanes()==2) ? iplane : 0);    /* Mode F: planes 0,2 */
  381.         ram_segtomem(segm, segoffs, ((byte **)membuf)[iplane] + memoffs, bwidth);
  382.     }
  383. }
  384. /* -------------------------------------------------------------------------- */
  385.  
  386. static void DIGPRIV ega_setcolmap(cmap)
  387.     ocolmap_type cmap;
  388. {
  389.     OREGS regs;
  390.     byte r, g, b, palval;
  391.     int i, ipix;
  392.  
  393.     if (cmap == NULL) {
  394.         return;
  395.     }
  396.     /* From cmap, set the rgb vals for the appropriate regs */
  397.     /* as nearly as possible */
  398.     for (i = 0; i < cmap->nentries; i++) {
  399.         ipix = cmap->firstpix + i;
  400.         if (ipix > 16) break;
  401.  
  402.         /* construct the color (use only hi 2 bits of each rgb level) */
  403.         r = ocolmap_pixred(cmap, ipix) >> 1;
  404.         g = ocolmap_pixgreen(cmap, ipix) >> 2;
  405.         b = ocolmap_pixblue(cmap, ipix) >> 3;
  406.         palval = ((b >> 4) & 1) | ((g >> 4) & 2) | ((r >> 4) & 4) |
  407.                   (b & 8)        |  (g & 16)         |  (r & 32);
  408.  
  409.         /* set the palette entry */
  410.         regs.x.ax = 0x1000;
  411.  
  412.         regs.h.bl = (byte)i;
  413.         regs.h.bh = palval;
  414.  
  415.         oakint86(BIOS_VIDINT, ®s);
  416.  
  417.     /* Copy the info into our colmap copy */
  418.         ocolmap_setpixrgb(pcdata->colmap, ipix,
  419.                 (r << 1)& 0xC0 +63, (g << 2)& 0xC0 +63, (b << 3)& 0xC0 +63);
  420.     }
  421. }
  422. /* -------------------------------------------------------------------------- */
  423.  
  424. static void DIGPRIV vga_setcolmap(cmap)
  425.     ocolmap_type cmap;
  426. {
  427.     OREGS regs;
  428.     byte palregs[17];
  429.     int i, ipix;
  430.  
  431.     if (cmap == NULL) {
  432.         return;
  433.     }
  434.     /* set the register block selector mode and value to 0,0 */
  435.     /* assume mode 0, block 0 */
  436.  
  437.     /* read pal regs */
  438.     regs.x.ax = 0x1009;            /* int 10h, funtion 10.09: get palette regs */
  439.     regs.a.esdx = palregs;
  440.     oakint86es(BIOS_VIDINT, ®s, 17);
  441.  
  442.     /* from cmap, set the rgb vals for the appropriate regs */
  443.     for (i = 0; i < cmap->nentries; i++) {
  444.         ipix = cmap->firstpix + i;
  445.         if (ipix > 16) break;
  446.  
  447.         /* set the palette entry's rgb val */
  448.         regs.x.ax = 0x1010;
  449.         regs.x.bx = palregs[ipix];
  450.         regs.h.dh = ocolmap_pixred(cmap, ipix) >> 2;
  451.         regs.h.ch = ocolmap_pixgreen(cmap, ipix) >> 2;
  452.         regs.h.cl = ocolmap_pixblue(cmap, ipix) >> 2;
  453.  
  454.     /* Copy the info into our colmap copy */
  455.         ocolmap_setpixrgb(pcdata->colmap, ipix,
  456.                 (regs.h.dh << 2)+3, (regs.h.ch << 2)+3, (regs.h.cl << 2)+3);
  457.  
  458.         oakint86(BIOS_VIDINT, ®s);
  459.     }
  460. }
  461. /* -------------------------------------------------------------------------- */
  462.  
  463.