Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/planix-v0/sys/src/cmd/gs/src/gdevherc.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1990, 1991, 1993 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: gdevherc.c,v 1.5 2002/06/16 05:48:55 lpd Exp $*/
18
/* IBM PC-compatible Hercules Graphics display driver */
19
/* using direct access to frame buffer */
20
 
21
#define FB_RASTER 90
22
#define SCREEN_HEIGHT 350
23
#define SCREEN_ASPECT_RATIO (54.0/35.0)
24
#define VIDEO_MODE 0x07
25
#define regen 0xb0000000L
26
 
27
#define interrupt			/* patch ANSI incompatibility */
28
#include "dos_.h"
29
typedef union REGS registers;
30
#include "gx.h"
31
#include "gsmatrix.h"			/* for gxdevice.h */
32
#include "gxbitmap.h"
33
#include "gxdevice.h"
34
 
35
/* outportb is defined in dos_.h */
36
#define outport2(port, index, data)\
37
  (outportb(port, index), outportb((port)+1, data))
38
/* Define the nominal page height in inches. */
39
#ifdef A4
40
#  define PAGE_HEIGHT_INCHES 11.69
41
#else
42
#  define PAGE_HEIGHT_INCHES 11.0
43
#endif
44
 
45
/* Dimensions of screen */
46
#define screen_size_x (FB_RASTER * 8)
47
#define screen_size_y SCREEN_HEIGHT
48
/* Other display parameters */
49
#define raster_x FB_RASTER
50
#define aspect_ratio SCREEN_ASPECT_RATIO
51
#define graphics_video_mode VIDEO_MODE
52
 
53
/* Procedures */
54
 
55
	/* See gxdevice.h for the definitions of the procedures. */
56
 
57
dev_proc_open_device(herc_open);
58
dev_proc_close_device(herc_close);
59
dev_proc_fill_rectangle(herc_fill_rectangle);
60
dev_proc_copy_mono(herc_copy_mono);
61
dev_proc_copy_color(herc_copy_color);
62
 
63
/* The device descriptor */
64
private gx_device_procs herc_procs = {
65
	herc_open,
66
	gx_default_get_initial_matrix,
67
	gx_default_sync_output,
68
	gx_default_output_page,
69
	herc_close,
70
	gx_default_map_rgb_color,
71
	gx_default_map_color_rgb,
72
	herc_fill_rectangle,
73
	gx_default_tile_rectangle,
74
	herc_copy_mono,
75
	herc_copy_color
76
};
77
 
78
gx_device far_data gs_herc_device = {
79
	std_device_std_body(gx_device, &herc_procs, "herc",
80
	  screen_size_x, screen_size_y,
81
	/* The following parameters map an appropriate fraction of */
82
	/* the screen to a full-page coordinate space. */
83
	/* This may or may not be what is desired! */
84
	  (screen_size_y * aspect_ratio) / PAGE_HEIGHT_INCHES,	/* x dpi */
85
	  screen_size_y / PAGE_HEIGHT_INCHES		/* y dpi */
86
	)
87
};
88
 
89
 
90
/* Forward declarations */
91
private int herc_get_mode(void);
92
private void herc_set_mode(int);
93
 
94
/* Save the HERC mode */
95
private int herc_save_mode = -1;
96
 
97
/* Reinitialize the herc for text mode */
98
int
99
herc_close(gx_device *dev)
100
{	if ( herc_save_mode >= 0 ) herc_set_mode(herc_save_mode);
101
	return 0;
102
}
103
 
104
/* ------ Internal routines ------ */
105
 
106
/* Read the device mode */
107
private int
108
herc_get_mode(void)
109
{	registers regs;
110
	regs.h.ah = 0xf;
111
	int86(0x10, &regs, &regs);
112
	return regs.h.al;
113
}
114
 
115
/* Set the device mode */
116
private void
117
herc_set_mode(int mode)
118
{	registers regs;
119
	regs.h.ah = 0;
120
	regs.h.al = mode;
121
	int86(0x10, &regs, &regs);
122
}
123
 
124
 
125
/****************************************************************/
126
/* Hercules graphics card functions				*/
127
/*								*/
128
/* -- Taken from Jan/Feb 1988 issue of Micro Cornucopia #39	*/
129
/*								*/
130
/* --rewritten for MSC 5.1 on 02/18/91 by Phillip Conrad	*/
131
/****************************************************************/
132
 
133
 
134
static const char paramg[12] = {0x35, 0x2d, 0x2e, 0x07, 0x5b, 0x02,
135
			      0x57, 0x57, 0x02, 0x03, 0x00, 0x00};
136
/* (Never used)
137
static const char paramt[12] = {0x61, 0x50, 0x52, 0x0f, 0x19, 0x06,
138
			      0x19, 0x19, 0x02, 0x0d, 0x0b, 0x0c};
139
*/
140
 
141
/* Type and macro for frame buffer pointers. */
142
/*** Intimately tied to the 80x86 (x<2) addressing architecture. ***/
143
typedef byte far *fb_ptr; 
144
#  define mk_fb_ptr(x, y)\
145
    (fb_ptr)((regen) + ((0x2000 * ((y) % 4) + (90 * ((y) >> 2))) + ((int)(x) >> 3)))
146
 
147
 
148
/* Structure for operation parameters. */
149
/* Note that this structure is known to assembly code. */
150
/* Not all parameters are used for every operation. */
151
typedef struct rop_params_s {
152
	fb_ptr dest;			/* pointer to frame buffer */
153
	int draster;			/* raster of frame buffer */
154
	const byte far *src;		/* pointer to source data */
155
	int sraster;			/* source raster */
156
	int width;			/* width in bytes */
157
	int height;			/* height in scan lines */
158
	int shift;			/* amount to right shift source */
159
	int invert;			/* 0 or -1 to invert source */
160
	int data;			/* data for fill */
161
	int x_pos;		/*>>added--2/24/91 */
162
	int y_pos;
163
} rop_params;
164
 
165
/* Define the device port and register numbers, and the regen map base */
166
#define seq_addr 0x3b4		/* changed for HERC card (6845 ports)*/
167
#define graph_mode 0x3b8
168
#define graph_stat 0x3ba
169
#define graph_config 0x3bf
170
 
171
#ifndef regen
172
#define regen 0xa0000000L
173
#endif
174
 
175
 
176
/* Initialize the display for Hercules graphics mode */
177
int
178
herc_open(gx_device *dev)
179
{	int i;
180
	if ( herc_save_mode < 0 ) herc_save_mode = herc_get_mode();
181
/*	herc_set_mode(graphics_video_mode);  */
182
	outportb(graph_config,3);
183
	for(i=0;i<sizeof(paramg);i++)
184
	{
185
		outport2(seq_addr,i,paramg[i]); 
186
 
187
	}
188
	outportb(graph_mode,0x0a);	/* set page 0 */
189
	for(i=0;i<0x3FFFL;i++)	/* clear the screen */
190
		{
191
		int far *loc = (int far *)( regen  +(2L*i));
192
		*loc = 0;
193
		}
194
 
195
	return 0;
196
}
197
 
198
/* Macro for testing bit-inclusion */
199
#define bit_included_in(x,y) !((x)&~(y))
200
 
201
/* Copy a monochrome bitmap.  The colors are given explicitly. */
202
/* Color = gx_no_color_index means transparent (no effect on the image). */
203
int
204
herc_copy_mono(gx_device *dev,
205
  const byte *base, int sourcex, int raster, gx_bitmap_id id,
206
  int x, int y, int w, int h, gx_color_index izero, gx_color_index ione)
207
{	rop_params params;
208
#define czero (int)izero
209
#define cone (int)ione
210
	int dleft, sleft, count;
211
	int invert, zmask, omask;
212
	byte mask, rmask;
213
 
214
	if ( cone == czero )		/* vacuous case */
215
		return herc_fill_rectangle(dev, x, y, w, h, izero);
216
 
217
	/* clip */
218
	fit_copy(dev, base, sourcex, raster, id, x, y, w, h);
219
	params.dest = mk_fb_ptr(x, y);
220
	params.draster = raster_x;
221
	params.src = base + (sourcex >> 3);
222
	params.sraster = raster;
223
	params.height = h;
224
	params.shift = (x - sourcex) & 7;
225
	params.y_pos = y;
226
	params.x_pos = x;
227
	params.width = w;
228
 
229
	if(czero > cone) params.invert = -1;
230
 
231
	/* Macros for writing partial bytes. */
232
	/* bits has already been inverted by xor'ing with invert. */
233
 
234
#define write_byte_masked(ptr, bits, mask)\
235
  *ptr = ((bits | ~mask | zmask) & (*ptr | (bits & mask & omask)))
236
 
237
#define write_byte(ptr, bits)\
238
  *ptr = ((bits | zmask) & (*ptr | (bits & omask)))
239
 
240
	invert = (czero == 1 || cone == 0 ? -1 : 0); 
241
/*	invert = (czero == 1 || cone == 1 ? -1 : 0); */
242
	zmask = (czero == 0 || cone == 0 ? 0 : -1);
243
	omask = (czero == 1 || cone == 1 ? -1 : 0);
244
 
245
#undef czero
246
#undef cone
247
 
248
	/* Actually copy the bits. */
249
 
250
	sleft = 8 - (sourcex & 7);
251
	dleft = 8 - (x & 7);
252
	mask = 0xff >> (8 - dleft);
253
	count = w;
254
	if ( w < dleft )
255
		mask -= mask >> w,
256
		rmask = 0;
257
	else
258
		rmask = 0xff00 >> ((w - dleft) & 7);
259
 
260
	if (sleft == dleft)		/* optimize the aligned case */
261
	{
262
		w -= dleft;
263
		while ( --h >= 0 )
264
		{
265
			register const byte *bptr = params.src;
266
			register byte *optr = mk_fb_ptr(params.x_pos,params.y_pos);
267
			register int bits = *bptr ^ invert;	/* first partial byte */
268
 
269
			count = w;
270
 
271
			write_byte_masked(optr, bits, mask);
272
 
273
			/* Do full bytes. */
274
 
275
			while ((count -= 8) >= 0)
276
			{
277
				bits = *++bptr ^ invert;
278
				params.x_pos += 8;
279
				optr = mk_fb_ptr(params.x_pos,params.y_pos);
280
				write_byte(optr, bits);
281
			}
282
			/* Do last byte */
283
 
284
			if (count > -8)
285
			{
286
				bits = *++bptr ^ invert;
287
				params.x_pos += 8;
288
				optr = mk_fb_ptr(params.x_pos,params.y_pos);
289
				write_byte_masked(optr, bits, rmask);
290
			}
291
/*			dest += BPL; */
292
			params.y_pos++;
293
			params.x_pos = x;
294
			params.src += raster;
295
		}
296
	}
297
	else
298
	{
299
		int skew = (sleft - dleft) & 7;
300
		int cskew = 8 - skew;
301
 
302
		while (--h >= 0)
303
		{
304
			const byte *bptr = params.src;
305
			byte *optr = mk_fb_ptr(params.x_pos,params.y_pos);
306
			register int bits;
307
 
308
			count = w;
309
 
310
			/* Do the first partial byte */
311
 
312
			if (sleft >= dleft)
313
			{
314
				bits = *bptr >> skew;
315
			}	
316
			else /* ( sleft < dleft ) */
317
			{
318
				bits = *bptr++ << cskew;
319
				if (count > sleft)
320
					bits += *bptr >> skew;
321
			}
322
			bits ^= invert;
323
			write_byte_masked(optr, bits, mask);
324
			count -= dleft;
325
			params.x_pos += 8;
326
			optr = mk_fb_ptr(params.x_pos,params.y_pos);
327
 
328
			/* Do full bytes. */
329
 
330
			while ( count >= 8 )
331
			{
332
				bits = *bptr++ << cskew;
333
				bits += *bptr >> skew;
334
				bits ^= invert;
335
				write_byte(optr, bits);
336
				count -= 8;
337
				params.x_pos += 8;
338
				optr = mk_fb_ptr(params.x_pos,params.y_pos);
339
			}
340
 
341
			/* Do last byte */
342
 
343
			if (count > 0)
344
			{
345
				bits = *bptr++ << cskew;
346
 				if (count > skew)
347
					bits += *bptr >> skew;
348
				bits ^= invert;
349
				write_byte_masked(optr, bits, rmask);
350
			}
351
/*			dest += BPL;
352
			line += raster;
353
*/
354
			params.y_pos++;
355
			params.x_pos = x;
356
			params.src += raster;
357
		}
358
	}
359
	return 0;
360
}
361
 
362
/* Copy a color pixelmap.  This is just like a bitmap, */
363
int
364
herc_copy_color(gx_device *dev,
365
  const byte *base, int sourcex, int raster, gx_bitmap_id id,
366
  int x, int y, int w, int h)
367
{	return herc_copy_mono(dev, base, sourcex, raster, id,
368
		x, y, w, h,(gx_color_index)0, (gx_color_index)1);
369
}
370
 
371
#  define mk_fb_yptr(x, y)\
372
    (fb_ptr)((regen) + ((0x2000 * ((y) % 4) + (90 * ((y) >> 2))) + x))
373
 
374
/* Fill a rectangle. */
375
int
376
herc_fill_rectangle(gx_device *dev, int x, int y, int w, int h,
377
  gx_color_index color)
378
{	rop_params params;
379
 
380
	int x2, y2, xlen;
381
	byte led, red, d;
382
	byte far *ptr;
383
	int xloc;
384
 
385
	fit_fill(dev, x, y, w, h);
386
 
387
	params.dest = mk_fb_ptr(x, y);
388
	params.y_pos = y;
389
	params.x_pos = x;
390
 
391
	x2 = x + w - 1;
392
	y2 = y + h - 1;
393
 
394
	xlen = (x2 >> 3) - (x >> 3) - 1;
395
	led = 0xff >> (x & 7);
396
	red = 0xff << (7 - (x2 & 7));
397
 
398
	ptr =  mk_fb_ptr(x,y);
399
 
400
	if (color)
401
	{
402
		/* here to set pixels */
403
 
404
		if (xlen == -1)
405
		{
406
			/* special for rectangles that fit in a byte */
407
 
408
			d = led & red;
409
			for(; h >= 0; h--, ptr = mk_fb_ptr(x,params.y_pos))
410
			{
411
				*ptr |= d;
412
				params.y_pos++;
413
			}
414
			return 0;
415
		}
416
 
417
		/* normal fill */
418
 
419
		xloc = params.x_pos >> 3;
420
		for(; h >= 0; h--, ptr = mk_fb_ptr(x,params.y_pos))
421
		{	register int x_count = xlen;
422
			register byte far *p = ptr;
423
			*p |= led;
424
/*			 params.x_pos += 8; */
425
			xloc++;
426
			 p = mk_fb_yptr(xloc,params.y_pos);
427
			while ( x_count-- ) {
428
				 *p = 0xff;
429
/*				 params.x_pos += 8; */
430
				xloc++;
431
				 p = mk_fb_yptr(xloc,params.y_pos);
432
				}
433
			*p |= red;
434
/*			params.x_pos = x; */
435
			xloc = params.x_pos >> 3;
436
			params.y_pos++;
437
		}
438
	}
439
 
440
	/* here to clear pixels */
441
 
442
	led = ~led;
443
	red = ~red;
444
 
445
	if (xlen == -1)
446
	{
447
		/* special for rectangles that fit in a byte */
448
 
449
		d = led | red;
450
		for(; h >= 0; h--, ptr  = mk_fb_ptr(x,params.y_pos))
451
			{
452
			*ptr &= d;
453
			params.y_pos++;
454
			}
455
		return 0;
456
	}
457
 
458
	/* normal fill */
459
 
460
	xloc = x >> 3;
461
	for(; h >= 0; h--, ptr = mk_fb_ptr(x,params.y_pos))
462
	{	register int x_count = xlen;
463
		register byte far *p = ptr;
464
		*p &= led;
465
/*		 params.x_pos += 8; */
466
		xloc++;
467
		 p = mk_fb_yptr(xloc,params.y_pos);
468
		while ( x_count-- ) {
469
			 *p = 0x00;
470
/*			 params.x_pos += 8; */
471
			xloc++;
472
			 p = mk_fb_yptr(xloc,params.y_pos);
473
			}
474
		*p &= red;
475
/*		params.x_pos = x; */
476
		xloc = params.x_pos >> 3;
477
		params.y_pos++;
478
	}
479
	return 0;
480
}