Mercurial > ecos
diff packages/services/gfx/mw/current/src/drivers/scr_herc.c @ 208:e0c0827131d1 ecos
Merge from eCos master repository on 2002-05-20-20:11:54-BST
| author | jlarmour |
|---|---|
| date | Mon, 20 May 2002 22:19:26 +0000 |
| parents | |
| children |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/services/gfx/mw/current/src/drivers/scr_herc.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 1999 Greg Haerr <greg@censoft.com> + * Based on code by Jakob Eriksson. + * + * Hercules Graphics Screen Driver, PC bios version + * This driver uses int10 bios to to get the address of the + * ROM character font which is used for the character bitmaps. + * All other access to the hardware is controlled through this driver. + * + * All text/font drawing code is based on the above routines and + * the included entry points for getting the ROM bitmap data. Compiled + * in fonts aren't supported for size reasons. scr_bogl supports them. + * + * The environment variable CHARHEIGHT if set will set the assumed rom + * font character height, which defaults to 14. + */ +#if ELKS +#include <linuxmt/ntty.h> +#endif +#include <stdio.h> +#include "device.h" +#include "vgaplan4.h" +#include "romfont.h" + +/* assumptions for speed: NOTE: psd is ignored in these routines*/ +#define SCREENADDR(offset) MK_FP(0xb000, (offset)) + +#define SCREEN_ON 8 +#define BLINKER_ON 0x20 + +/* HERC driver entry points*/ +static PSD HERC_open(PSD psd); +static void HERC_close(PSD psd); +static void HERC_getscreeninfo(PSD psd,PMWSCREENINFO psi);; +static void HERC_setpalette(PSD psd,int first,int count,MWPALENTRY *pal); +static void HERC_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c); +static MWPIXELVAL HERC_readpixel(PSD psd,MWCOORD x, MWCOORD y); +static void HERC_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c); +static void HERC_drawvline(PSD psd,MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c); +static void HERC_fillrect(PSD psd,MWCOORD x1,MWCOORD y1,MWCOORD x2,MWCOORD y2, + MWPIXELVAL c); +static void HERC_blit(PSD dstpsd,MWCOORD destx,MWCOORD desty,MWCOORD w,MWCOORD h, + PSD srcpsd,MWCOORD srcx,MWCOORD srcy,long op); +static PSD HERC_allocatememgc(PSD psd); + +SCREENDEVICE scrdev = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, + HERC_open, + HERC_close, + HERC_getscreeninfo, + HERC_setpalette, + HERC_drawpixel, + HERC_readpixel, + HERC_drawhline, + HERC_drawvline, + HERC_fillrect, + pcrom_fonts, + HERC_blit, + NULL, /* PreSelect*/ + NULL, /* DrawArea subdriver*/ + NULL, /* SetIOPermissions*/ + HERC_allocatememgc, + NULL, /* MapMemGC*/ + NULL /* FreeMemGC*/ +}; + +static PSD +HERC_open(PSD psd) +{ +#if HAVEIOPERM + /* get permission to write to the hercules ports*/ + if(ioperm(0x3b4, 0x0d, 1)) + return NULL; +#endif +#if ELKS + /* disallow console switching while in graphics mode*/ + if(ioctl(0, DCGET_GRAPH) != 0) + return NULL; +#endif + + /* enter graphics mode*/ + outportb(0x3bf, 1+2); + outportb(0x3b8, 0); + outport(0x3b4, 0x3500); + outport(0x3b4, 0x2d01); + outport(0x3b4, 0x2e02); /* Linesync at 46th character */ + outport(0x3b4, 0x0703); /* linesync width 7 chrclock ticks */ + outport(0x3b4, 0x5b04); /* height 92 chars (368 lines) */ + outport(0x3b4, 0x0205); /* height adjust */ + outport(0x3b4, 0x5706); /* lines / picture (348 lines) */ + outport(0x3b4, 0x5707); /* picturesync: after 87 character lines */ + outport(0x3b4, 0x0309); /* character height: 4 lines / char */ + outportb(0x3b8, 2+8); /* Allow graphics mode and video on */ + + /* init driver variables*/ + psd->xres = psd->xvirtres = 720; + psd->yres = psd->yvirtres = 350; + psd->planes = 1; + psd->bpp = 1; + psd->ncolors = 2; + psd->pixtype = MWPF_PALETTE; + psd->flags = PSF_SCREEN; + psd->addr = SCREENADDR(0); + psd->linelen = 90; + + /* init pc rom font routines*/ + pcrom_init(psd); + + return psd; +} + +static void +HERC_close(PSD psd) +{ + int i; + volatile FARADDR dst; + static char herc_txt_tbl[12]= { + 0x61,0x50,0x52,0x0f,0x19,6,0x19,0x19,2,0x0d,0x0b,0x0c + }; + +#if ELKS + /* allow console switching again*/ + ioctl(0, DCREL_GRAPH); +#endif + + /* switch back to text mode*/ + outportb(0x3bf, 0); + outportb(0x3b8, 0); + + for(i = 0; i < 12; ++i) { + outportb(0x3b4, i); + outportb(0x3b5, herc_txt_tbl[i]); + } + + /* blank screen*/ + dst = SCREENADDR(0); + for(i = 0; i <= 0x3fff; ++i) { + PUTBYTE_FP(dst++, 0x00); + PUTBYTE_FP(dst++, 0x07); + } + outportb(0x3b8, BLINKER_ON | SCREEN_ON); +} + +static void +HERC_getscreeninfo(PSD psd,PMWSCREENINFO psi) +{ + psi->rows = psd->yvirtres; + psi->cols = psd->xvirtres; + psi->planes = psd->planes; + psi->bpp = psd->bpp; + psi->ncolors = psd->ncolors; + psi->pixtype = psd->pixtype; + psi->fonts = NUMBER_FONTS; + psi->xdpcm = 30; /* assumes screen width of 24 cm*/ + psi->ydpcm = 19; /* assumes screen height of 18 cm*/ +} + +static void +HERC_setpalette(PSD psd,int first,int count,MWPALENTRY *pal) +{ + /* no palette available*/ +} + +static void +HERC_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c) +{ + unsigned int offset; + unsigned char mask = 128; + volatile FARADDR dst; + + offset = 0x2000 * (y&3); + offset += 90*(y/4) + x/8; + dst = SCREENADDR(offset); + mask >>= x & 7; + if(c) + ORBYTE_FP(dst, mask); + else ANDBYTE_FP(dst, ~mask); +} + +static MWPIXELVAL +HERC_readpixel(PSD psd,MWCOORD x, MWCOORD y) +{ + unsigned int offset; + unsigned char mask = 128; + volatile FARADDR dst; + + offset = 0x2000 * (y&3); + offset += 90*(y/4) + x/8; + dst = SCREENADDR(offset); + mask >>= x & 7; + return GETBYTE_FP(dst) & mask? 1: 0; +} + +static void +HERC_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c) +{ + /*Optimized HERC_drawhline() by thomas_d_stewart@hotmail.com*/ + unsigned int rowoffset, x1yoffset, x2yoffset; + unsigned int startbyte, endbyte; + volatile FARADDR dst; + + /*offset of the row */ + rowoffset = 8192 * (y % 4) + (y / 4) * 90; + + /*offset of first byte in line */ + x1yoffset = rowoffset + (x1 / 8); + + /*ofset of the last byte in line */ + x2yoffset = rowoffset + (x2 / 8); + + + /*shift "11111111" > buy (x1%8) to fill with 0's*/ + startbyte = 0xff >> (x1 % 8); + /*same but in < dir* + endbyte = 0xff << (x2 % 8); + + /* convert x1yoffset to a screen address */ + dst = SCREENADDR(x1yoffset); + + if(c) + ORBYTE_FP(dst, startbyte); /* output byte to mem */ + else ANDBYTE_FP(dst, ~startbyte); + + x1yoffset++; /* increment so we are writing to the next byte */ + while(x1yoffset < x2yoffset) { + dst = SCREENADDR(x1yoffset); /*convert x1yoffset to a scr address */ + if(c) + ORBYTE_FP(dst, 0xff); /*ouput bytes */ + else ANDBYTE_FP(dst, ~0xff); + x1yoffset++; + } + + dst = SCREENADDR(x2yoffset); /* convert x2yoffset to a screen address */ + if(c) + ORBYTE_FP(dst, endbyte); /* output byte to mem */ + else ANDBYTE_FP(dst, ~endbyte); + + + + /*NON Optimized version left in case my one goes wroung */ + /*while(x1 <= x2) + HERC_drawpixel(x1++, y, c);*/ +} + +static void +HERC_drawvline(PSD psd,MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c) +{ + /* fixme write optimized vline*/ + /* + * Driver doesn't support vline yet + */ + while(y1 <= y2) + HERC_drawpixel(x, y1++, c); +} + +static void +HERC_fillrect(PSD psd,MWCOORD x1, MWCOORD y1, MWCOORD x2, MWCOORD y2, MWPIXELVAL c) +{ + while(y1 <= y2) + HERC_drawhline(x1, x2, y1++, c); +} + +static void +HERC_blit(PSD dstpsd,MWCOORD destx,MWCOORD desty,MWCOORD w,MWCOORD h, + PSD srcpsd,MWCOORD srcx,MWCOORD srcy,long op) +{ + /* FIXME*/ +} + +/* allocate a memory screen device*/ +static PSD +HERC_allocatememgc(PSD psd) +{ + /* if driver doesn't have blit, fail*/ + return NULL; +}
