Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1992, 1996, 1997 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: gdevs3ga.c,v 1.5 2002/06/16 05:48:55 lpd Exp $ */
18
/* S3 86C911 driver */
19
#include "gx.h"
20
#include "gserrors.h"
21
#include "gxdevice.h"
22
#include "gdevpcfb.h"
23
#include "gdevsvga.h"
24
 
25
/* Shared routines from gdevsvga.c */
26
extern int vesa_get_mode(void);
27
extern void vesa_set_mode(int);
28
 
29
/* Macro for casting gx_device argument */
30
#define fb_dev ((gx_device_svga *)dev)
31
 
32
/* ------ The S3 86C911 device ------ */
33
 
34
private dev_proc_open_device(s3_open);
35
private dev_proc_fill_rectangle(s3_fill_rectangle);
36
private dev_proc_copy_mono(s3_copy_mono);
37
private const gx_device_procs s3_procs =
38
{
39
    s3_open,
40
    NULL,			/* get_initial_matrix */
41
    NULL,			/* sync_output */
42
    NULL,			/* output_page */
43
    svga_close,
44
    svga_map_rgb_color,
45
    svga_map_color_rgb,
46
    s3_fill_rectangle,
47
    NULL,			/* tile_rectangle */
48
    s3_copy_mono,
49
    svga_copy_color,
50
/****** DOESN'T WORK ******/
51
    NULL,			/* draw_line */
52
    svga_get_bits
53
/****** DOESN'T WORK ******/
54
};
55
gx_device_svga far_data gs_s3vga_device =
56
svga_device(s3_procs, "s3vga", vesa_get_mode, vesa_set_mode, NULL);
57
 
58
/* Keep track of the character bitmap cache in off-screen memory. */
59
#define log2_cell_width 5
60
#define cell_width (1 << log2_cell_width)
61
#define cache_x_bits (log2_cache_width_bits - log2_cell_width)
62
#define log2_cell_height 5
63
#define cell_height (1 << log2_cell_height)
64
#define cache_y_bits (log2_cache_height - log2_cell_height)
65
#define log2_cache_width_bits 10
66
#define log2_cache_width_bytes (log2_cache_width_bits - 3)
67
#define log2_cache_height 8
68
#define log2_cache_capacity (cache_x_bits + cache_y_bits)
69
#define cache_capacity (1 << log2_cache_capacity)
70
private gx_bitmap_id cache_ids[cache_capacity];
71
 
72
/* Define additional registers and I/O addresses. */
73
#define crtc_addr 0x3d4		/* (color) */
74
#define crt_lock 0x35
75
#define crt_s3_lock1 0x38
76
#define crt_s3_lock2 0x39
77
#define s3_y_pos 0x82e8
78
#define s3_x_pos 0x86e8
79
#define s3_y_dest 0x8ae8
80
#define s3_x_dest 0x8ee8
81
#define s3_width 0x96e8
82
#define s3_status 0x9ae8	/* read only */
83
#define s3_command 0x9ae8	/* write only */
84
#define s3_back_color 0xa2e8
85
#define s3_fore_color 0xa6e8
86
#define s3_write_mask 0xaae8
87
#define s3_read_mask 0xaee8
88
#define s3_back_mix 0xb6e8
89
#define s3_fore_mix 0xbae8
90
#define s3_height 0xbee8
91
#define s3_mf_control 0xbee8
92
#  define mf_data_ones 0xa000
93
#  define mf_data_cpu 0xa080
94
#  define mf_data_display 0xa0c0
95
#define s3_pixel_data 0xe2e8
96
/* Wait for the command FIFO to empty. */
97
#define s3_wait_fifo()\
98
  while ( inport(s3_status) & 0xff )
99
/* Load the parameters for a rectangle operation. */
100
#define out_s3_rect(x, y, w, h)\
101
  (outport(s3_x_pos, x), outport(s3_y_pos, y),\
102
   outport(s3_width, (w) - 1), outport(s3_height, (h) - 1))
103
 
104
private int
105
s3_open(gx_device * dev)
106
{
107
    static const mode_info mode_table[] =
108
    {
109
	{640, 480, 0x201},
110
	{800, 600, 0x203},
111
	{1024, 768, 0x205},
112
	{-1, -1, -1}
113
    };
114
    int code = svga_find_mode(dev, mode_table);
115
 
116
    if (code < 0)
117
	return_error(gs_error_rangecheck);
118
    /* The enhanced modes all use a 1024-pixel raster. */
119
    fb_dev->raster = 1024;
120
    code = svga_open(dev);
121
    if (code < 0)
122
	return code;
123
    /* Clear the cache */
124
    {
125
	int i;
126
 
127
	for (i = 0; i < cache_capacity; i++)
128
	    cache_ids[i] = gx_no_bitmap_id;
129
    }
130
    return 0;
131
}
132
 
133
/* Fill a rectangle. */
134
int
135
s3_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
136
		  gx_color_index color)
137
{
138
    fit_fill(dev, x, y, w, h);
139
    s3_wait_fifo();
140
    outport(s3_fore_mix, 0x27);
141
    outport(s3_fore_color, (int)color);
142
    outport(s3_mf_control, mf_data_ones);
143
    out_s3_rect(x, y, w, h);
144
    outport(s3_command, 0x40b3);
145
    return 0;
146
}
147
 
148
/* Copy a monochrome bitmap.  The colors are given explicitly. */
149
/* Color = gx_no_color_index means transparent (no effect on the image). */
150
private int
151
s3_copy_mono(gx_device * dev,
152
	     const byte * base, int sourcex, int raster, gx_bitmap_id id,
153
      int x, int y, int w, int h, gx_color_index czero, gx_color_index cone)
154
{
155
    int sbit;
156
    const byte *sptr;
157
    int run;
158
    byte lmask;
159
    byte lmerge = 0;
160
    int cache_index, cache_x, cache_y;
161
    int i, j;
162
 
163
    fit_copy(dev, base, sourcex, raster, id, x, y, w, h);
164
    sbit = sourcex & 7;
165
    sptr = base + (sourcex >> 3);
166
    run = (sbit + w + 7) >> 3;
167
    lmask = 0xff >> sbit;
168
    /* See whether the cache is applicable. */
169
    if (id != gx_no_bitmap_id && w <= cell_width - 7 &&
170
	h <= cell_height
171
	) {
172
	cache_index = (int)(id & (cache_capacity - 1));
173
	cache_x = ((cache_index & ((1 << cache_x_bits) - 1)) <<
174
		   log2_cell_width) + 7;
175
	cache_y = ((cache_index >> cache_x_bits) <<
176
		   log2_cell_height) + 768;
177
	if (cache_ids[cache_index] != id) {
178
	    cache_ids[cache_index] = id;
179
	    /* Copy the bitmap to the cache. */
180
	    s3_wait_fifo();
181
	    out_s3_rect(cache_x - sbit, cache_y, w + sbit, h);
182
	    outport(s3_fore_mix, 0x22);		/* 1s */
183
	    outport(s3_back_mix, 0x01);		/* 0s */
184
	    outport(s3_mf_control, mf_data_cpu);
185
	    outport(s3_command, 0x41b3);
186
	    {
187
		const int skip = raster - run;
188
 
189
		for (i = h; i > 0; i--, sptr += skip)
190
		    for (j = run; j > 0; j--, sptr++)
191
			outportb(s3_pixel_data, *sptr);
192
	    }
193
	}
194
	s3_wait_fifo();
195
    } else {
196
	cache_index = -1;
197
	if (lmask != 0xff) {	/* The hardware won't do the masking for us. */
198
	    if (czero != gx_no_color_index) {
199
		if (cone != gx_no_color_index) {
200
		    s3_fill_rectangle(dev, x, y, w, h, czero);
201
		    czero = gx_no_color_index;
202
		} else {
203
		    lmerge = ~lmask;
204
		}
205
	    }
206
	}
207
	s3_wait_fifo();
208
	out_s3_rect(x - sbit, y, w + sbit, h);
209
    }
210
    /* Load the colors for the real transfer. */
211
    if (cone != gx_no_color_index) {
212
	outport(s3_fore_mix, 0x27);
213
	outport(s3_fore_color, (int)cone);
214
    } else
215
	outport(s3_fore_mix, 0x63);
216
    if (czero != gx_no_color_index) {
217
	outport(s3_back_mix, 0x07);
218
	outport(s3_back_color, (int)czero);
219
    } else
220
	outport(s3_back_mix, 0x63);
221
    s3_wait_fifo();
222
    if (cache_index < 0) {	/* direct transfer */
223
	outport(s3_mf_control, mf_data_cpu);
224
	outport(s3_command, 0x41b3);
225
	if (run == 1 && !lmerge) {	/* special case for chars */
226
	    for (i = h; i > 0; i--, sptr += raster)
227
		outportb(s3_pixel_data, *sptr & lmask);
228
	} else {
229
	    const int skip = raster - run;
230
 
231
	    for (i = h; i > 0; i--, sptr += skip) {
232
		outportb(s3_pixel_data, (*sptr++ & lmask) | lmerge);
233
		for (j = run; j > 1; j--, sptr++)
234
		    outportb(s3_pixel_data, *sptr);
235
	    }
236
	}
237
    } else {			/* Copy the character from the cache to the screen. */
238
	out_s3_rect(cache_x, cache_y, w, h);
239
	outport(s3_x_dest, x);
240
	outport(s3_y_dest, y);
241
	outport(s3_mf_control, mf_data_display);
242
	outport(s3_command, 0xc0b3);
243
    }
244
    return 0;
245
}