17dd7cddfSDavid du Colombier /* Copyright (C) 1990, 1991, 1993 Aladdin Enterprises. All rights reserved.
27dd7cddfSDavid du Colombier
3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier implied.
57dd7cddfSDavid du Colombier
6*593dc095SDavid du Colombier This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier
10*593dc095SDavid du Colombier For more information about licensing, please refer to
11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier
17*593dc095SDavid du Colombier /* $Id: gdevherc.c,v 1.5 2002/06/16 05:48:55 lpd Exp $*/
187dd7cddfSDavid du Colombier /* IBM PC-compatible Hercules Graphics display driver */
197dd7cddfSDavid du Colombier /* using direct access to frame buffer */
207dd7cddfSDavid du Colombier
217dd7cddfSDavid du Colombier #define FB_RASTER 90
227dd7cddfSDavid du Colombier #define SCREEN_HEIGHT 350
237dd7cddfSDavid du Colombier #define SCREEN_ASPECT_RATIO (54.0/35.0)
247dd7cddfSDavid du Colombier #define VIDEO_MODE 0x07
257dd7cddfSDavid du Colombier #define regen 0xb0000000L
267dd7cddfSDavid du Colombier
277dd7cddfSDavid du Colombier #define interrupt /* patch ANSI incompatibility */
287dd7cddfSDavid du Colombier #include "dos_.h"
297dd7cddfSDavid du Colombier typedef union REGS registers;
307dd7cddfSDavid du Colombier #include "gx.h"
317dd7cddfSDavid du Colombier #include "gsmatrix.h" /* for gxdevice.h */
327dd7cddfSDavid du Colombier #include "gxbitmap.h"
337dd7cddfSDavid du Colombier #include "gxdevice.h"
347dd7cddfSDavid du Colombier
357dd7cddfSDavid du Colombier /* outportb is defined in dos_.h */
367dd7cddfSDavid du Colombier #define outport2(port, index, data)\
377dd7cddfSDavid du Colombier (outportb(port, index), outportb((port)+1, data))
387dd7cddfSDavid du Colombier /* Define the nominal page height in inches. */
397dd7cddfSDavid du Colombier #ifdef A4
407dd7cddfSDavid du Colombier # define PAGE_HEIGHT_INCHES 11.69
417dd7cddfSDavid du Colombier #else
427dd7cddfSDavid du Colombier # define PAGE_HEIGHT_INCHES 11.0
437dd7cddfSDavid du Colombier #endif
447dd7cddfSDavid du Colombier
457dd7cddfSDavid du Colombier /* Dimensions of screen */
467dd7cddfSDavid du Colombier #define screen_size_x (FB_RASTER * 8)
477dd7cddfSDavid du Colombier #define screen_size_y SCREEN_HEIGHT
487dd7cddfSDavid du Colombier /* Other display parameters */
497dd7cddfSDavid du Colombier #define raster_x FB_RASTER
507dd7cddfSDavid du Colombier #define aspect_ratio SCREEN_ASPECT_RATIO
517dd7cddfSDavid du Colombier #define graphics_video_mode VIDEO_MODE
527dd7cddfSDavid du Colombier
537dd7cddfSDavid du Colombier /* Procedures */
547dd7cddfSDavid du Colombier
557dd7cddfSDavid du Colombier /* See gxdevice.h for the definitions of the procedures. */
567dd7cddfSDavid du Colombier
577dd7cddfSDavid du Colombier dev_proc_open_device(herc_open);
587dd7cddfSDavid du Colombier dev_proc_close_device(herc_close);
597dd7cddfSDavid du Colombier dev_proc_fill_rectangle(herc_fill_rectangle);
607dd7cddfSDavid du Colombier dev_proc_copy_mono(herc_copy_mono);
617dd7cddfSDavid du Colombier dev_proc_copy_color(herc_copy_color);
627dd7cddfSDavid du Colombier
637dd7cddfSDavid du Colombier /* The device descriptor */
647dd7cddfSDavid du Colombier private gx_device_procs herc_procs = {
657dd7cddfSDavid du Colombier herc_open,
667dd7cddfSDavid du Colombier gx_default_get_initial_matrix,
677dd7cddfSDavid du Colombier gx_default_sync_output,
687dd7cddfSDavid du Colombier gx_default_output_page,
697dd7cddfSDavid du Colombier herc_close,
707dd7cddfSDavid du Colombier gx_default_map_rgb_color,
717dd7cddfSDavid du Colombier gx_default_map_color_rgb,
727dd7cddfSDavid du Colombier herc_fill_rectangle,
737dd7cddfSDavid du Colombier gx_default_tile_rectangle,
747dd7cddfSDavid du Colombier herc_copy_mono,
757dd7cddfSDavid du Colombier herc_copy_color
767dd7cddfSDavid du Colombier };
777dd7cddfSDavid du Colombier
787dd7cddfSDavid du Colombier gx_device far_data gs_herc_device = {
797dd7cddfSDavid du Colombier std_device_std_body(gx_device, &herc_procs, "herc",
807dd7cddfSDavid du Colombier screen_size_x, screen_size_y,
817dd7cddfSDavid du Colombier /* The following parameters map an appropriate fraction of */
827dd7cddfSDavid du Colombier /* the screen to a full-page coordinate space. */
837dd7cddfSDavid du Colombier /* This may or may not be what is desired! */
847dd7cddfSDavid du Colombier (screen_size_y * aspect_ratio) / PAGE_HEIGHT_INCHES, /* x dpi */
857dd7cddfSDavid du Colombier screen_size_y / PAGE_HEIGHT_INCHES /* y dpi */
867dd7cddfSDavid du Colombier )
877dd7cddfSDavid du Colombier };
887dd7cddfSDavid du Colombier
897dd7cddfSDavid du Colombier
907dd7cddfSDavid du Colombier /* Forward declarations */
91*593dc095SDavid du Colombier private int herc_get_mode(void);
92*593dc095SDavid du Colombier private void herc_set_mode(int);
937dd7cddfSDavid du Colombier
947dd7cddfSDavid du Colombier /* Save the HERC mode */
957dd7cddfSDavid du Colombier private int herc_save_mode = -1;
967dd7cddfSDavid du Colombier
977dd7cddfSDavid du Colombier /* Reinitialize the herc for text mode */
987dd7cddfSDavid du Colombier int
herc_close(gx_device * dev)997dd7cddfSDavid du Colombier herc_close(gx_device *dev)
1007dd7cddfSDavid du Colombier { if ( herc_save_mode >= 0 ) herc_set_mode(herc_save_mode);
1017dd7cddfSDavid du Colombier return 0;
1027dd7cddfSDavid du Colombier }
1037dd7cddfSDavid du Colombier
1047dd7cddfSDavid du Colombier /* ------ Internal routines ------ */
1057dd7cddfSDavid du Colombier
1067dd7cddfSDavid du Colombier /* Read the device mode */
1077dd7cddfSDavid du Colombier private int
herc_get_mode(void)1087dd7cddfSDavid du Colombier herc_get_mode(void)
1097dd7cddfSDavid du Colombier { registers regs;
1107dd7cddfSDavid du Colombier regs.h.ah = 0xf;
1117dd7cddfSDavid du Colombier int86(0x10, ®s, ®s);
1127dd7cddfSDavid du Colombier return regs.h.al;
1137dd7cddfSDavid du Colombier }
1147dd7cddfSDavid du Colombier
1157dd7cddfSDavid du Colombier /* Set the device mode */
1167dd7cddfSDavid du Colombier private void
herc_set_mode(int mode)1177dd7cddfSDavid du Colombier herc_set_mode(int mode)
1187dd7cddfSDavid du Colombier { registers regs;
1197dd7cddfSDavid du Colombier regs.h.ah = 0;
1207dd7cddfSDavid du Colombier regs.h.al = mode;
1217dd7cddfSDavid du Colombier int86(0x10, ®s, ®s);
1227dd7cddfSDavid du Colombier }
1237dd7cddfSDavid du Colombier
1247dd7cddfSDavid du Colombier
1257dd7cddfSDavid du Colombier /****************************************************************/
1267dd7cddfSDavid du Colombier /* Hercules graphics card functions */
1277dd7cddfSDavid du Colombier /* */
1287dd7cddfSDavid du Colombier /* -- Taken from Jan/Feb 1988 issue of Micro Cornucopia #39 */
1297dd7cddfSDavid du Colombier /* */
1307dd7cddfSDavid du Colombier /* --rewritten for MSC 5.1 on 02/18/91 by Phillip Conrad */
1317dd7cddfSDavid du Colombier /****************************************************************/
1327dd7cddfSDavid du Colombier
1337dd7cddfSDavid du Colombier
1347dd7cddfSDavid du Colombier static const char paramg[12] = {0x35, 0x2d, 0x2e, 0x07, 0x5b, 0x02,
1357dd7cddfSDavid du Colombier 0x57, 0x57, 0x02, 0x03, 0x00, 0x00};
1367dd7cddfSDavid du Colombier /* (Never used)
1377dd7cddfSDavid du Colombier static const char paramt[12] = {0x61, 0x50, 0x52, 0x0f, 0x19, 0x06,
1387dd7cddfSDavid du Colombier 0x19, 0x19, 0x02, 0x0d, 0x0b, 0x0c};
1397dd7cddfSDavid du Colombier */
1407dd7cddfSDavid du Colombier
1417dd7cddfSDavid du Colombier /* Type and macro for frame buffer pointers. */
1427dd7cddfSDavid du Colombier /*** Intimately tied to the 80x86 (x<2) addressing architecture. ***/
1437dd7cddfSDavid du Colombier typedef byte far *fb_ptr;
1447dd7cddfSDavid du Colombier # define mk_fb_ptr(x, y)\
1457dd7cddfSDavid du Colombier (fb_ptr)((regen) + ((0x2000 * ((y) % 4) + (90 * ((y) >> 2))) + ((int)(x) >> 3)))
1467dd7cddfSDavid du Colombier
1477dd7cddfSDavid du Colombier
1487dd7cddfSDavid du Colombier /* Structure for operation parameters. */
1497dd7cddfSDavid du Colombier /* Note that this structure is known to assembly code. */
1507dd7cddfSDavid du Colombier /* Not all parameters are used for every operation. */
1517dd7cddfSDavid du Colombier typedef struct rop_params_s {
1527dd7cddfSDavid du Colombier fb_ptr dest; /* pointer to frame buffer */
1537dd7cddfSDavid du Colombier int draster; /* raster of frame buffer */
1547dd7cddfSDavid du Colombier const byte far *src; /* pointer to source data */
1557dd7cddfSDavid du Colombier int sraster; /* source raster */
1567dd7cddfSDavid du Colombier int width; /* width in bytes */
1577dd7cddfSDavid du Colombier int height; /* height in scan lines */
1587dd7cddfSDavid du Colombier int shift; /* amount to right shift source */
1597dd7cddfSDavid du Colombier int invert; /* 0 or -1 to invert source */
1607dd7cddfSDavid du Colombier int data; /* data for fill */
1617dd7cddfSDavid du Colombier int x_pos; /*>>added--2/24/91 */
1627dd7cddfSDavid du Colombier int y_pos;
1637dd7cddfSDavid du Colombier } rop_params;
1647dd7cddfSDavid du Colombier
1657dd7cddfSDavid du Colombier /* Define the device port and register numbers, and the regen map base */
1667dd7cddfSDavid du Colombier #define seq_addr 0x3b4 /* changed for HERC card (6845 ports)*/
1677dd7cddfSDavid du Colombier #define graph_mode 0x3b8
1687dd7cddfSDavid du Colombier #define graph_stat 0x3ba
1697dd7cddfSDavid du Colombier #define graph_config 0x3bf
1707dd7cddfSDavid du Colombier
1717dd7cddfSDavid du Colombier #ifndef regen
1727dd7cddfSDavid du Colombier #define regen 0xa0000000L
1737dd7cddfSDavid du Colombier #endif
1747dd7cddfSDavid du Colombier
1757dd7cddfSDavid du Colombier
1767dd7cddfSDavid du Colombier /* Initialize the display for Hercules graphics mode */
1777dd7cddfSDavid du Colombier int
herc_open(gx_device * dev)1787dd7cddfSDavid du Colombier herc_open(gx_device *dev)
1797dd7cddfSDavid du Colombier { int i;
1807dd7cddfSDavid du Colombier if ( herc_save_mode < 0 ) herc_save_mode = herc_get_mode();
1817dd7cddfSDavid du Colombier /* herc_set_mode(graphics_video_mode); */
1827dd7cddfSDavid du Colombier outportb(graph_config,3);
1837dd7cddfSDavid du Colombier for(i=0;i<sizeof(paramg);i++)
1847dd7cddfSDavid du Colombier {
1857dd7cddfSDavid du Colombier outport2(seq_addr,i,paramg[i]);
1867dd7cddfSDavid du Colombier
1877dd7cddfSDavid du Colombier }
1887dd7cddfSDavid du Colombier outportb(graph_mode,0x0a); /* set page 0 */
1897dd7cddfSDavid du Colombier for(i=0;i<0x3FFFL;i++) /* clear the screen */
1907dd7cddfSDavid du Colombier {
1917dd7cddfSDavid du Colombier int far *loc = (int far *)( regen +(2L*i));
1927dd7cddfSDavid du Colombier *loc = 0;
1937dd7cddfSDavid du Colombier }
1947dd7cddfSDavid du Colombier
1957dd7cddfSDavid du Colombier return 0;
1967dd7cddfSDavid du Colombier }
1977dd7cddfSDavid du Colombier
1987dd7cddfSDavid du Colombier /* Macro for testing bit-inclusion */
1997dd7cddfSDavid du Colombier #define bit_included_in(x,y) !((x)&~(y))
2007dd7cddfSDavid du Colombier
2017dd7cddfSDavid du Colombier /* Copy a monochrome bitmap. The colors are given explicitly. */
2027dd7cddfSDavid du Colombier /* Color = gx_no_color_index means transparent (no effect on the image). */
2037dd7cddfSDavid du Colombier int
herc_copy_mono(gx_device * dev,const byte * base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index izero,gx_color_index ione)2047dd7cddfSDavid du Colombier herc_copy_mono(gx_device *dev,
2057dd7cddfSDavid du Colombier const byte *base, int sourcex, int raster, gx_bitmap_id id,
2067dd7cddfSDavid du Colombier int x, int y, int w, int h, gx_color_index izero, gx_color_index ione)
2077dd7cddfSDavid du Colombier { rop_params params;
2087dd7cddfSDavid du Colombier #define czero (int)izero
2097dd7cddfSDavid du Colombier #define cone (int)ione
2107dd7cddfSDavid du Colombier int dleft, sleft, count;
2117dd7cddfSDavid du Colombier int invert, zmask, omask;
2127dd7cddfSDavid du Colombier byte mask, rmask;
2137dd7cddfSDavid du Colombier
2147dd7cddfSDavid du Colombier if ( cone == czero ) /* vacuous case */
2157dd7cddfSDavid du Colombier return herc_fill_rectangle(dev, x, y, w, h, izero);
2167dd7cddfSDavid du Colombier
2177dd7cddfSDavid du Colombier /* clip */
2187dd7cddfSDavid du Colombier fit_copy(dev, base, sourcex, raster, id, x, y, w, h);
2197dd7cddfSDavid du Colombier params.dest = mk_fb_ptr(x, y);
2207dd7cddfSDavid du Colombier params.draster = raster_x;
2217dd7cddfSDavid du Colombier params.src = base + (sourcex >> 3);
2227dd7cddfSDavid du Colombier params.sraster = raster;
2237dd7cddfSDavid du Colombier params.height = h;
2247dd7cddfSDavid du Colombier params.shift = (x - sourcex) & 7;
2257dd7cddfSDavid du Colombier params.y_pos = y;
2267dd7cddfSDavid du Colombier params.x_pos = x;
2277dd7cddfSDavid du Colombier params.width = w;
2287dd7cddfSDavid du Colombier
2297dd7cddfSDavid du Colombier if(czero > cone) params.invert = -1;
2307dd7cddfSDavid du Colombier
2317dd7cddfSDavid du Colombier /* Macros for writing partial bytes. */
2327dd7cddfSDavid du Colombier /* bits has already been inverted by xor'ing with invert. */
2337dd7cddfSDavid du Colombier
2347dd7cddfSDavid du Colombier #define write_byte_masked(ptr, bits, mask)\
2357dd7cddfSDavid du Colombier *ptr = ((bits | ~mask | zmask) & (*ptr | (bits & mask & omask)))
2367dd7cddfSDavid du Colombier
2377dd7cddfSDavid du Colombier #define write_byte(ptr, bits)\
2387dd7cddfSDavid du Colombier *ptr = ((bits | zmask) & (*ptr | (bits & omask)))
2397dd7cddfSDavid du Colombier
2407dd7cddfSDavid du Colombier invert = (czero == 1 || cone == 0 ? -1 : 0);
2417dd7cddfSDavid du Colombier /* invert = (czero == 1 || cone == 1 ? -1 : 0); */
2427dd7cddfSDavid du Colombier zmask = (czero == 0 || cone == 0 ? 0 : -1);
2437dd7cddfSDavid du Colombier omask = (czero == 1 || cone == 1 ? -1 : 0);
2447dd7cddfSDavid du Colombier
2457dd7cddfSDavid du Colombier #undef czero
2467dd7cddfSDavid du Colombier #undef cone
2477dd7cddfSDavid du Colombier
2487dd7cddfSDavid du Colombier /* Actually copy the bits. */
2497dd7cddfSDavid du Colombier
2507dd7cddfSDavid du Colombier sleft = 8 - (sourcex & 7);
2517dd7cddfSDavid du Colombier dleft = 8 - (x & 7);
2527dd7cddfSDavid du Colombier mask = 0xff >> (8 - dleft);
2537dd7cddfSDavid du Colombier count = w;
2547dd7cddfSDavid du Colombier if ( w < dleft )
2557dd7cddfSDavid du Colombier mask -= mask >> w,
2567dd7cddfSDavid du Colombier rmask = 0;
2577dd7cddfSDavid du Colombier else
2587dd7cddfSDavid du Colombier rmask = 0xff00 >> ((w - dleft) & 7);
2597dd7cddfSDavid du Colombier
2607dd7cddfSDavid du Colombier if (sleft == dleft) /* optimize the aligned case */
2617dd7cddfSDavid du Colombier {
2627dd7cddfSDavid du Colombier w -= dleft;
2637dd7cddfSDavid du Colombier while ( --h >= 0 )
2647dd7cddfSDavid du Colombier {
2657dd7cddfSDavid du Colombier register const byte *bptr = params.src;
2667dd7cddfSDavid du Colombier register byte *optr = mk_fb_ptr(params.x_pos,params.y_pos);
2677dd7cddfSDavid du Colombier register int bits = *bptr ^ invert; /* first partial byte */
2687dd7cddfSDavid du Colombier
2697dd7cddfSDavid du Colombier count = w;
2707dd7cddfSDavid du Colombier
2717dd7cddfSDavid du Colombier write_byte_masked(optr, bits, mask);
2727dd7cddfSDavid du Colombier
2737dd7cddfSDavid du Colombier /* Do full bytes. */
2747dd7cddfSDavid du Colombier
2757dd7cddfSDavid du Colombier while ((count -= 8) >= 0)
2767dd7cddfSDavid du Colombier {
2777dd7cddfSDavid du Colombier bits = *++bptr ^ invert;
2787dd7cddfSDavid du Colombier params.x_pos += 8;
2797dd7cddfSDavid du Colombier optr = mk_fb_ptr(params.x_pos,params.y_pos);
2807dd7cddfSDavid du Colombier write_byte(optr, bits);
2817dd7cddfSDavid du Colombier }
2827dd7cddfSDavid du Colombier /* Do last byte */
2837dd7cddfSDavid du Colombier
2847dd7cddfSDavid du Colombier if (count > -8)
2857dd7cddfSDavid du Colombier {
2867dd7cddfSDavid du Colombier bits = *++bptr ^ invert;
2877dd7cddfSDavid du Colombier params.x_pos += 8;
2887dd7cddfSDavid du Colombier optr = mk_fb_ptr(params.x_pos,params.y_pos);
2897dd7cddfSDavid du Colombier write_byte_masked(optr, bits, rmask);
2907dd7cddfSDavid du Colombier }
2917dd7cddfSDavid du Colombier /* dest += BPL; */
2927dd7cddfSDavid du Colombier params.y_pos++;
2937dd7cddfSDavid du Colombier params.x_pos = x;
2947dd7cddfSDavid du Colombier params.src += raster;
2957dd7cddfSDavid du Colombier }
2967dd7cddfSDavid du Colombier }
2977dd7cddfSDavid du Colombier else
2987dd7cddfSDavid du Colombier {
2997dd7cddfSDavid du Colombier int skew = (sleft - dleft) & 7;
3007dd7cddfSDavid du Colombier int cskew = 8 - skew;
3017dd7cddfSDavid du Colombier
3027dd7cddfSDavid du Colombier while (--h >= 0)
3037dd7cddfSDavid du Colombier {
3047dd7cddfSDavid du Colombier const byte *bptr = params.src;
3057dd7cddfSDavid du Colombier byte *optr = mk_fb_ptr(params.x_pos,params.y_pos);
3067dd7cddfSDavid du Colombier register int bits;
3077dd7cddfSDavid du Colombier
3087dd7cddfSDavid du Colombier count = w;
3097dd7cddfSDavid du Colombier
3107dd7cddfSDavid du Colombier /* Do the first partial byte */
3117dd7cddfSDavid du Colombier
3127dd7cddfSDavid du Colombier if (sleft >= dleft)
3137dd7cddfSDavid du Colombier {
3147dd7cddfSDavid du Colombier bits = *bptr >> skew;
3157dd7cddfSDavid du Colombier }
3167dd7cddfSDavid du Colombier else /* ( sleft < dleft ) */
3177dd7cddfSDavid du Colombier {
3187dd7cddfSDavid du Colombier bits = *bptr++ << cskew;
3197dd7cddfSDavid du Colombier if (count > sleft)
3207dd7cddfSDavid du Colombier bits += *bptr >> skew;
3217dd7cddfSDavid du Colombier }
3227dd7cddfSDavid du Colombier bits ^= invert;
3237dd7cddfSDavid du Colombier write_byte_masked(optr, bits, mask);
3247dd7cddfSDavid du Colombier count -= dleft;
3257dd7cddfSDavid du Colombier params.x_pos += 8;
3267dd7cddfSDavid du Colombier optr = mk_fb_ptr(params.x_pos,params.y_pos);
3277dd7cddfSDavid du Colombier
3287dd7cddfSDavid du Colombier /* Do full bytes. */
3297dd7cddfSDavid du Colombier
3307dd7cddfSDavid du Colombier while ( count >= 8 )
3317dd7cddfSDavid du Colombier {
3327dd7cddfSDavid du Colombier bits = *bptr++ << cskew;
3337dd7cddfSDavid du Colombier bits += *bptr >> skew;
3347dd7cddfSDavid du Colombier bits ^= invert;
3357dd7cddfSDavid du Colombier write_byte(optr, bits);
3367dd7cddfSDavid du Colombier count -= 8;
3377dd7cddfSDavid du Colombier params.x_pos += 8;
3387dd7cddfSDavid du Colombier optr = mk_fb_ptr(params.x_pos,params.y_pos);
3397dd7cddfSDavid du Colombier }
3407dd7cddfSDavid du Colombier
3417dd7cddfSDavid du Colombier /* Do last byte */
3427dd7cddfSDavid du Colombier
3437dd7cddfSDavid du Colombier if (count > 0)
3447dd7cddfSDavid du Colombier {
3457dd7cddfSDavid du Colombier bits = *bptr++ << cskew;
3467dd7cddfSDavid du Colombier if (count > skew)
3477dd7cddfSDavid du Colombier bits += *bptr >> skew;
3487dd7cddfSDavid du Colombier bits ^= invert;
3497dd7cddfSDavid du Colombier write_byte_masked(optr, bits, rmask);
3507dd7cddfSDavid du Colombier }
3517dd7cddfSDavid du Colombier /* dest += BPL;
3527dd7cddfSDavid du Colombier line += raster;
3537dd7cddfSDavid du Colombier */
3547dd7cddfSDavid du Colombier params.y_pos++;
3557dd7cddfSDavid du Colombier params.x_pos = x;
3567dd7cddfSDavid du Colombier params.src += raster;
3577dd7cddfSDavid du Colombier }
3587dd7cddfSDavid du Colombier }
3597dd7cddfSDavid du Colombier return 0;
3607dd7cddfSDavid du Colombier }
3617dd7cddfSDavid du Colombier
3627dd7cddfSDavid du Colombier /* Copy a color pixelmap. This is just like a bitmap, */
3637dd7cddfSDavid du Colombier int
herc_copy_color(gx_device * dev,const byte * base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h)3647dd7cddfSDavid du Colombier herc_copy_color(gx_device *dev,
3657dd7cddfSDavid du Colombier const byte *base, int sourcex, int raster, gx_bitmap_id id,
3667dd7cddfSDavid du Colombier int x, int y, int w, int h)
3677dd7cddfSDavid du Colombier { return herc_copy_mono(dev, base, sourcex, raster, id,
3687dd7cddfSDavid du Colombier x, y, w, h,(gx_color_index)0, (gx_color_index)1);
3697dd7cddfSDavid du Colombier }
3707dd7cddfSDavid du Colombier
3717dd7cddfSDavid du Colombier # define mk_fb_yptr(x, y)\
3727dd7cddfSDavid du Colombier (fb_ptr)((regen) + ((0x2000 * ((y) % 4) + (90 * ((y) >> 2))) + x))
3737dd7cddfSDavid du Colombier
3747dd7cddfSDavid du Colombier /* Fill a rectangle. */
3757dd7cddfSDavid du Colombier int
herc_fill_rectangle(gx_device * dev,int x,int y,int w,int h,gx_color_index color)3767dd7cddfSDavid du Colombier herc_fill_rectangle(gx_device *dev, int x, int y, int w, int h,
3777dd7cddfSDavid du Colombier gx_color_index color)
3787dd7cddfSDavid du Colombier { rop_params params;
3797dd7cddfSDavid du Colombier
3807dd7cddfSDavid du Colombier int x2, y2, xlen;
3817dd7cddfSDavid du Colombier byte led, red, d;
3827dd7cddfSDavid du Colombier byte far *ptr;
3837dd7cddfSDavid du Colombier int xloc;
3847dd7cddfSDavid du Colombier
3857dd7cddfSDavid du Colombier fit_fill(dev, x, y, w, h);
3867dd7cddfSDavid du Colombier
3877dd7cddfSDavid du Colombier params.dest = mk_fb_ptr(x, y);
3887dd7cddfSDavid du Colombier params.y_pos = y;
3897dd7cddfSDavid du Colombier params.x_pos = x;
3907dd7cddfSDavid du Colombier
3917dd7cddfSDavid du Colombier x2 = x + w - 1;
3927dd7cddfSDavid du Colombier y2 = y + h - 1;
3937dd7cddfSDavid du Colombier
3947dd7cddfSDavid du Colombier xlen = (x2 >> 3) - (x >> 3) - 1;
3957dd7cddfSDavid du Colombier led = 0xff >> (x & 7);
3967dd7cddfSDavid du Colombier red = 0xff << (7 - (x2 & 7));
3977dd7cddfSDavid du Colombier
3987dd7cddfSDavid du Colombier ptr = mk_fb_ptr(x,y);
3997dd7cddfSDavid du Colombier
4007dd7cddfSDavid du Colombier if (color)
4017dd7cddfSDavid du Colombier {
4027dd7cddfSDavid du Colombier /* here to set pixels */
4037dd7cddfSDavid du Colombier
4047dd7cddfSDavid du Colombier if (xlen == -1)
4057dd7cddfSDavid du Colombier {
4067dd7cddfSDavid du Colombier /* special for rectangles that fit in a byte */
4077dd7cddfSDavid du Colombier
4087dd7cddfSDavid du Colombier d = led & red;
4097dd7cddfSDavid du Colombier for(; h >= 0; h--, ptr = mk_fb_ptr(x,params.y_pos))
4107dd7cddfSDavid du Colombier {
4117dd7cddfSDavid du Colombier *ptr |= d;
4127dd7cddfSDavid du Colombier params.y_pos++;
4137dd7cddfSDavid du Colombier }
4147dd7cddfSDavid du Colombier return 0;
4157dd7cddfSDavid du Colombier }
4167dd7cddfSDavid du Colombier
4177dd7cddfSDavid du Colombier /* normal fill */
4187dd7cddfSDavid du Colombier
4197dd7cddfSDavid du Colombier xloc = params.x_pos >> 3;
4207dd7cddfSDavid du Colombier for(; h >= 0; h--, ptr = mk_fb_ptr(x,params.y_pos))
4217dd7cddfSDavid du Colombier { register int x_count = xlen;
4227dd7cddfSDavid du Colombier register byte far *p = ptr;
4237dd7cddfSDavid du Colombier *p |= led;
4247dd7cddfSDavid du Colombier /* params.x_pos += 8; */
4257dd7cddfSDavid du Colombier xloc++;
4267dd7cddfSDavid du Colombier p = mk_fb_yptr(xloc,params.y_pos);
4277dd7cddfSDavid du Colombier while ( x_count-- ) {
4287dd7cddfSDavid du Colombier *p = 0xff;
4297dd7cddfSDavid du Colombier /* params.x_pos += 8; */
4307dd7cddfSDavid du Colombier xloc++;
4317dd7cddfSDavid du Colombier p = mk_fb_yptr(xloc,params.y_pos);
4327dd7cddfSDavid du Colombier }
4337dd7cddfSDavid du Colombier *p |= red;
4347dd7cddfSDavid du Colombier /* params.x_pos = x; */
4357dd7cddfSDavid du Colombier xloc = params.x_pos >> 3;
4367dd7cddfSDavid du Colombier params.y_pos++;
4377dd7cddfSDavid du Colombier }
4387dd7cddfSDavid du Colombier }
4397dd7cddfSDavid du Colombier
4407dd7cddfSDavid du Colombier /* here to clear pixels */
4417dd7cddfSDavid du Colombier
4427dd7cddfSDavid du Colombier led = ~led;
4437dd7cddfSDavid du Colombier red = ~red;
4447dd7cddfSDavid du Colombier
4457dd7cddfSDavid du Colombier if (xlen == -1)
4467dd7cddfSDavid du Colombier {
4477dd7cddfSDavid du Colombier /* special for rectangles that fit in a byte */
4487dd7cddfSDavid du Colombier
4497dd7cddfSDavid du Colombier d = led | red;
4507dd7cddfSDavid du Colombier for(; h >= 0; h--, ptr = mk_fb_ptr(x,params.y_pos))
4517dd7cddfSDavid du Colombier {
4527dd7cddfSDavid du Colombier *ptr &= d;
4537dd7cddfSDavid du Colombier params.y_pos++;
4547dd7cddfSDavid du Colombier }
4557dd7cddfSDavid du Colombier return 0;
4567dd7cddfSDavid du Colombier }
4577dd7cddfSDavid du Colombier
4587dd7cddfSDavid du Colombier /* normal fill */
4597dd7cddfSDavid du Colombier
4607dd7cddfSDavid du Colombier xloc = x >> 3;
4617dd7cddfSDavid du Colombier for(; h >= 0; h--, ptr = mk_fb_ptr(x,params.y_pos))
4627dd7cddfSDavid du Colombier { register int x_count = xlen;
4637dd7cddfSDavid du Colombier register byte far *p = ptr;
4647dd7cddfSDavid du Colombier *p &= led;
4657dd7cddfSDavid du Colombier /* params.x_pos += 8; */
4667dd7cddfSDavid du Colombier xloc++;
4677dd7cddfSDavid du Colombier p = mk_fb_yptr(xloc,params.y_pos);
4687dd7cddfSDavid du Colombier while ( x_count-- ) {
4697dd7cddfSDavid du Colombier *p = 0x00;
4707dd7cddfSDavid du Colombier /* params.x_pos += 8; */
4717dd7cddfSDavid du Colombier xloc++;
4727dd7cddfSDavid du Colombier p = mk_fb_yptr(xloc,params.y_pos);
4737dd7cddfSDavid du Colombier }
4747dd7cddfSDavid du Colombier *p &= red;
4757dd7cddfSDavid du Colombier /* params.x_pos = x; */
4767dd7cddfSDavid du Colombier xloc = params.x_pos >> 3;
4777dd7cddfSDavid du Colombier params.y_pos++;
4787dd7cddfSDavid du Colombier }
4797dd7cddfSDavid du Colombier return 0;
4807dd7cddfSDavid du Colombier }
481