2 * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
3 * Based on code by Jakob Eriksson.
5 * Hercules Graphics Screen Driver, PC bios version
6 * This driver uses int10 bios to to get the address of the
7 * ROM character font which is used for the character bitmaps.
8 * All other access to the hardware is controlled through this driver.
10 * All text/font drawing code is based on the above routines and
11 * the included entry points for getting the ROM bitmap data. Compiled
12 * in fonts aren't supported for size reasons. scr_bogl supports them.
14 * The environment variable CHARHEIGHT if set will set the assumed rom
15 * font character height, which defaults to 14.
18 #include <linuxmt/ntty.h>
25 /* assumptions for speed: NOTE: psd is ignored in these routines*/
26 #define SCREENADDR(offset) MK_FP(0xb000, (offset))
29 #define BLINKER_ON 0x20
31 /* HERC driver entry points*/
32 static PSD HERC_open(PSD psd);
33 static void HERC_close(PSD psd);
34 static void HERC_getscreeninfo(PSD psd,PMWSCREENINFO psi);;
35 static void HERC_setpalette(PSD psd,int first,int count,MWPALENTRY *pal);
36 static void HERC_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c);
37 static MWPIXELVAL HERC_readpixel(PSD psd,MWCOORD x, MWCOORD y);
38 static void HERC_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c);
39 static void HERC_drawvline(PSD psd,MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c);
40 static void HERC_fillrect(PSD psd,MWCOORD x1,MWCOORD y1,MWCOORD x2,MWCOORD y2,
42 static void HERC_blit(PSD dstpsd,MWCOORD destx,MWCOORD desty,MWCOORD w,MWCOORD h,
43 PSD srcpsd,MWCOORD srcx,MWCOORD srcy,long op);
44 static PSD HERC_allocatememgc(PSD psd);
46 SCREENDEVICE scrdev = {
47 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
60 NULL, /* DrawArea subdriver*/
61 NULL, /* SetIOPermissions*/
71 /* get permission to write to the hercules ports*/
72 if(ioperm(0x3b4, 0x0d, 1))
76 /* disallow console switching while in graphics mode*/
77 if(ioctl(0, DCGET_GRAPH) != 0)
81 /* enter graphics mode*/
84 outport(0x3b4, 0x3500);
85 outport(0x3b4, 0x2d01);
86 outport(0x3b4, 0x2e02); /* Linesync at 46th character */
87 outport(0x3b4, 0x0703); /* linesync width 7 chrclock ticks */
88 outport(0x3b4, 0x5b04); /* height 92 chars (368 lines) */
89 outport(0x3b4, 0x0205); /* height adjust */
90 outport(0x3b4, 0x5706); /* lines / picture (348 lines) */
91 outport(0x3b4, 0x5707); /* picturesync: after 87 character lines */
92 outport(0x3b4, 0x0309); /* character height: 4 lines / char */
93 outportb(0x3b8, 2+8); /* Allow graphics mode and video on */
95 /* init driver variables*/
96 psd->xres = psd->xvirtres = 720;
97 psd->yres = psd->yvirtres = 350;
101 psd->pixtype = MWPF_PALETTE;
102 psd->flags = PSF_SCREEN;
103 psd->addr = SCREENADDR(0);
106 /* init pc rom font routines*/
116 volatile FARADDR dst;
117 static char herc_txt_tbl[12]= {
118 0x61,0x50,0x52,0x0f,0x19,6,0x19,0x19,2,0x0d,0x0b,0x0c
122 /* allow console switching again*/
123 ioctl(0, DCREL_GRAPH);
126 /* switch back to text mode*/
130 for(i = 0; i < 12; ++i) {
132 outportb(0x3b5, herc_txt_tbl[i]);
137 for(i = 0; i <= 0x3fff; ++i) {
138 PUTBYTE_FP(dst++, 0x00);
139 PUTBYTE_FP(dst++, 0x07);
141 outportb(0x3b8, BLINKER_ON | SCREEN_ON);
145 HERC_getscreeninfo(PSD psd,PMWSCREENINFO psi)
147 psi->rows = psd->yvirtres;
148 psi->cols = psd->xvirtres;
149 psi->planes = psd->planes;
151 psi->ncolors = psd->ncolors;
152 psi->pixtype = psd->pixtype;
153 psi->fonts = NUMBER_FONTS;
154 psi->xdpcm = 30; /* assumes screen width of 24 cm*/
155 psi->ydpcm = 19; /* assumes screen height of 18 cm*/
159 HERC_setpalette(PSD psd,int first,int count,MWPALENTRY *pal)
161 /* no palette available*/
165 HERC_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c)
168 unsigned char mask = 128;
169 volatile FARADDR dst;
171 offset = 0x2000 * (y&3);
172 offset += 90*(y/4) + x/8;
173 dst = SCREENADDR(offset);
176 ORBYTE_FP(dst, mask);
177 else ANDBYTE_FP(dst, ~mask);
181 HERC_readpixel(PSD psd,MWCOORD x, MWCOORD y)
184 unsigned char mask = 128;
185 volatile FARADDR dst;
187 offset = 0x2000 * (y&3);
188 offset += 90*(y/4) + x/8;
189 dst = SCREENADDR(offset);
191 return GETBYTE_FP(dst) & mask? 1: 0;
195 HERC_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c)
197 /*Optimized HERC_drawhline() by thomas_d_stewart@hotmail.com*/
198 unsigned int rowoffset, x1yoffset, x2yoffset;
199 unsigned int startbyte, endbyte;
200 volatile FARADDR dst;
202 /*offset of the row */
203 rowoffset = 8192 * (y % 4) + (y / 4) * 90;
205 /*offset of first byte in line */
206 x1yoffset = rowoffset + (x1 / 8);
208 /*ofset of the last byte in line */
209 x2yoffset = rowoffset + (x2 / 8);
212 /*shift "11111111" > buy (x1%8) to fill with 0's*/
213 startbyte = 0xff >> (x1 % 8);
215 endbyte = 0xff << (x2 % 8);
217 /* convert x1yoffset to a screen address */
218 dst = SCREENADDR(x1yoffset);
221 ORBYTE_FP(dst, startbyte); /* output byte to mem */
222 else ANDBYTE_FP(dst, ~startbyte);
224 x1yoffset++; /* increment so we are writing to the next byte */
225 while(x1yoffset < x2yoffset) {
226 dst = SCREENADDR(x1yoffset); /*convert x1yoffset to a scr address */
228 ORBYTE_FP(dst, 0xff); /*ouput bytes */
229 else ANDBYTE_FP(dst, ~0xff);
233 dst = SCREENADDR(x2yoffset); /* convert x2yoffset to a screen address */
235 ORBYTE_FP(dst, endbyte); /* output byte to mem */
236 else ANDBYTE_FP(dst, ~endbyte);
240 /*NON Optimized version left in case my one goes wroung */
242 HERC_drawpixel(x1++, y, c);*/
246 HERC_drawvline(PSD psd,MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c)
248 /* fixme write optimized vline*/
250 * Driver doesn't support vline yet
253 HERC_drawpixel(x, y1++, c);
257 HERC_fillrect(PSD psd,MWCOORD x1, MWCOORD y1, MWCOORD x2, MWCOORD y2, MWPIXELVAL c)
260 HERC_drawhline(x1, x2, y1++, c);
264 HERC_blit(PSD dstpsd,MWCOORD destx,MWCOORD desty,MWCOORD w,MWCOORD h,
265 PSD srcpsd,MWCOORD srcx,MWCOORD srcy,long op)
270 /* allocate a memory screen device*/
272 HERC_allocatememgc(PSD psd)
274 /* if driver doesn't have blit, fail*/