]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/gfx/mw/v2_0/src/drivers/scr_herc.c
Initial revision
[karo-tx-redboot.git] / packages / services / gfx / mw / v2_0 / src / drivers / scr_herc.c
1 /*
2  * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
3  * Based on code by Jakob Eriksson.
4  *
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.
9  *
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.
13  *
14  *      The environment variable CHARHEIGHT if set will set the assumed rom
15  *      font character height, which defaults to 14.
16  */
17 #if ELKS
18 #include <linuxmt/ntty.h>
19 #endif
20 #include <stdio.h>
21 #include "device.h"
22 #include "vgaplan4.h"
23 #include "romfont.h"
24
25 /* assumptions for speed: NOTE: psd is ignored in these routines*/
26 #define SCREENADDR(offset)      MK_FP(0xb000, (offset))
27
28 #define SCREEN_ON               8
29 #define BLINKER_ON              0x20
30
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,
41                 MWPIXELVAL c);
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);
45
46 SCREENDEVICE    scrdev = {
47         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
48         HERC_open,
49         HERC_close,
50         HERC_getscreeninfo,
51         HERC_setpalette,
52         HERC_drawpixel,
53         HERC_readpixel,
54         HERC_drawhline,
55         HERC_drawvline,
56         HERC_fillrect,
57         pcrom_fonts,
58         HERC_blit,
59         NULL,                   /* PreSelect*/
60         NULL,                   /* DrawArea subdriver*/
61         NULL,                   /* SetIOPermissions*/
62         HERC_allocatememgc,
63         NULL,                   /* MapMemGC*/
64         NULL                    /* FreeMemGC*/
65 };
66
67 static PSD
68 HERC_open(PSD psd)
69 {
70 #if HAVEIOPERM
71         /* get permission to write to the hercules ports*/
72         if(ioperm(0x3b4, 0x0d, 1))
73                 return NULL;
74 #endif
75 #if ELKS
76         /* disallow console switching while in graphics mode*/
77         if(ioctl(0, DCGET_GRAPH) != 0)
78                 return NULL;
79 #endif
80
81         /* enter graphics mode*/
82         outportb(0x3bf, 1+2);
83         outportb(0x3b8, 0);
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 */
94
95         /* init driver variables*/
96         psd->xres = psd->xvirtres = 720;
97         psd->yres = psd->yvirtres = 350;
98         psd->planes = 1;
99         psd->bpp = 1;
100         psd->ncolors = 2;
101         psd->pixtype = MWPF_PALETTE;
102         psd->flags = PSF_SCREEN;
103         psd->addr = SCREENADDR(0);
104         psd->linelen = 90;
105
106         /* init pc rom font routines*/
107         pcrom_init(psd);
108
109         return psd;
110 }
111
112 static void
113 HERC_close(PSD psd)
114 {
115         int                     i;
116         volatile FARADDR        dst;
117         static char             herc_txt_tbl[12]= {
118                 0x61,0x50,0x52,0x0f,0x19,6,0x19,0x19,2,0x0d,0x0b,0x0c
119         };
120
121 #if ELKS
122         /* allow console switching again*/
123         ioctl(0, DCREL_GRAPH);
124 #endif
125
126         /* switch back to text mode*/
127         outportb(0x3bf, 0);
128         outportb(0x3b8, 0);
129
130         for(i = 0; i < 12; ++i) {
131                 outportb(0x3b4, i);
132                 outportb(0x3b5, herc_txt_tbl[i]);
133         }
134
135         /* blank screen*/
136         dst = SCREENADDR(0);
137         for(i = 0; i <= 0x3fff; ++i) {
138                 PUTBYTE_FP(dst++, 0x00);
139                 PUTBYTE_FP(dst++, 0x07);
140         }
141         outportb(0x3b8, BLINKER_ON | SCREEN_ON);
142 }
143
144 static void
145 HERC_getscreeninfo(PSD psd,PMWSCREENINFO psi)
146 {
147         psi->rows = psd->yvirtres;
148         psi->cols = psd->xvirtres;
149         psi->planes = psd->planes;
150         psi->bpp = psd->bpp;
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*/
156 }
157
158 static void
159 HERC_setpalette(PSD psd,int first,int count,MWPALENTRY *pal)
160 {
161         /* no palette available*/
162 }
163
164 static void
165 HERC_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c)
166 {
167         unsigned int            offset;
168         unsigned char           mask = 128;
169         volatile FARADDR        dst;
170
171         offset = 0x2000 * (y&3);
172         offset += 90*(y/4) + x/8;
173         dst = SCREENADDR(offset);
174         mask >>= x & 7;
175         if(c)
176                 ORBYTE_FP(dst, mask);
177         else ANDBYTE_FP(dst, ~mask);
178 }
179
180 static MWPIXELVAL
181 HERC_readpixel(PSD psd,MWCOORD x, MWCOORD y)
182 {
183         unsigned int            offset;
184         unsigned char           mask = 128;
185         volatile FARADDR        dst;
186
187         offset = 0x2000 * (y&3);
188         offset += 90*(y/4) + x/8;
189         dst = SCREENADDR(offset);
190         mask >>= x & 7;
191         return GETBYTE_FP(dst) & mask? 1: 0;
192 }
193
194 static void
195 HERC_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c)
196 {
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;
201
202         /*offset of the row */
203         rowoffset = 8192 * (y % 4) + (y / 4) * 90;
204         
205         /*offset of first byte in line */
206         x1yoffset = rowoffset + (x1 / 8);
207         
208         /*ofset of the last byte in line */
209         x2yoffset = rowoffset + (x2 / 8);
210
211
212         /*shift "11111111" > buy (x1%8) to fill with 0's*/
213         startbyte = 0xff >> (x1 % 8);
214         /*same but in < dir*
215         endbyte = 0xff << (x2 % 8);
216
217         /* convert x1yoffset to a screen address */
218         dst = SCREENADDR(x1yoffset);
219
220         if(c)
221                 ORBYTE_FP(dst, startbyte);    /* output byte to mem */
222         else ANDBYTE_FP(dst, ~startbyte);
223
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 */
227                 if(c)
228                         ORBYTE_FP(dst, 0xff); /*ouput bytes */
229                 else ANDBYTE_FP(dst, ~0xff);
230                 x1yoffset++;
231                 }
232
233         dst = SCREENADDR(x2yoffset); /* convert x2yoffset to a screen address */
234         if(c)
235                 ORBYTE_FP(dst, endbyte); /* output byte to mem */
236         else ANDBYTE_FP(dst, ~endbyte);
237
238
239
240         /*NON Optimized version left in case my one goes wroung */
241         /*while(x1 <= x2)
242           HERC_drawpixel(x1++, y, c);*/
243 }
244
245 static void
246 HERC_drawvline(PSD psd,MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c)
247 {
248         /* fixme write optimized vline*/
249         /*
250          * Driver doesn't support vline yet
251          */
252         while(y1 <= y2)
253                 HERC_drawpixel(x, y1++, c);
254 }
255
256 static void
257 HERC_fillrect(PSD psd,MWCOORD x1, MWCOORD y1, MWCOORD x2, MWCOORD y2, MWPIXELVAL c)
258 {
259         while(y1 <= y2)
260                 HERC_drawhline(x1, x2, y1++, c);
261 }
262
263 static void
264 HERC_blit(PSD dstpsd,MWCOORD destx,MWCOORD desty,MWCOORD w,MWCOORD h,
265         PSD srcpsd,MWCOORD srcx,MWCOORD srcy,long op)
266 {
267         /* FIXME*/
268 }
269
270 /* allocate a memory screen device*/
271 static PSD 
272 HERC_allocatememgc(PSD psd)
273 {
274         /* if driver doesn't have blit, fail*/
275         return NULL;
276 }