/[gxemul]/upstream/0.4.2/src/devices/dev_igsfb.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/0.4.2/src/devices/dev_igsfb.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations)
Mon Oct 8 16:20:48 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 11328 byte(s)
0.4.2
1 /*
2 * Copyright (C) 2006 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: dev_igsfb.c,v 1.4 2006/08/11 17:43:30 debug Exp $
29 *
30 * Integraphics Systems "igsfb" Framebuffer (graphics) card, used in at
31 * least the NetWinder.
32 *
33 * TODO: This is hardcoded to 1024x768x8 right now, and only supports the
34 * two acceleration commands used by NetBSD for scrolling the
35 * framebuffer. The cursor is hardcoded to 12x22 pixels, as that is
36 * what NetBSD/netwinder uses.
37 */
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42
43 #include "console.h"
44 #include "device.h"
45 #include "devices.h"
46 #include "machine.h"
47 #include "memory.h"
48 #include "misc.h"
49
50 #include "igsfbreg.h"
51 #include "vga.h"
52
53
54 struct dev_igsfb_data {
55 int xres;
56 int yres;
57 int bitdepth;
58 struct vfb_data *vfb_data;
59
60 /* VGA palette stuff: */
61 int palette_write_index;
62 int palette_write_subindex;
63
64 /*
65 * Various graphics controller registers. See igsfbreg.h for a
66 * brief explanation of what these do.
67 */
68 int src_map_width;
69 int src2_map_width;
70 int dst_map_width;
71 int src_start;
72 int src2_start;
73 int dst_start;
74 int map_fmt;
75 int ctl;
76 int fg_mix;
77 int bg_mix;
78 int width;
79 int height;
80 int fg;
81 int bg;
82 int pixel_op_0;
83 int pixel_op_1;
84 int pixel_op_2;
85 int pixel_op_3;
86
87 uint8_t ext_reg_select;
88 uint8_t ext_reg[256];
89 };
90
91
92 /*
93 * recalc_sprite_position():
94 *
95 * TODO: This is hardcoded for NetBSD/netwinder's 12x22 pixel cursor.
96 */
97 static void recalc_sprite_position(struct dev_igsfb_data *d)
98 {
99 int x = d->ext_reg[IGS_EXT_SPRITE_HSTART_LO] +
100 d->ext_reg[IGS_EXT_SPRITE_HSTART_HI] * 256;
101 int y = d->ext_reg[IGS_EXT_SPRITE_VSTART_LO] +
102 d->ext_reg[IGS_EXT_SPRITE_VSTART_HI] * 256;
103
104 dev_fb_setcursor(d->vfb_data, x, y, 1, 12, 22);
105 }
106
107
108 /*
109 * dev_igsfb_op3_written():
110 *
111 * This function is called after the pixel_op_3 register has been written to.
112 * I guess this is what triggers accelerated functions to start executing.
113 *
114 * NOTE/TODO: Only those necessary to run NetBSD/netwinder have been
115 * implemented.
116 */
117 static void dev_igsfb_op3_written(struct dev_igsfb_data *d)
118 {
119 if (d->pixel_op_0 == 0x00 && d->pixel_op_1 == 0x80 &&
120 d->pixel_op_2 == 0x00 && d->pixel_op_3 == 0x28 &&
121 d->fg_mix == 0x03 && d->ctl == 0x00) {
122 /* NetBSD scroll-up */
123 framebuffer_blockcopyfill(d->vfb_data, 0, 0,0,0,
124 d->dst_start % d->xres, d->dst_start / d->xres,
125 d->dst_start % d->xres + d->width,
126 d->dst_start / d->xres + d->height,
127 d->src_start % d->xres, d->src_start / d->xres);
128 return;
129 }
130
131 if (d->pixel_op_0 == 0x00 && d->pixel_op_1 == 0x80 &&
132 d->pixel_op_2 == 0x00 && d->pixel_op_3 == 0x08 &&
133 d->fg_mix == 0x03 && d->ctl == 0x00) {
134 /* NetBSD fill */
135 /* TODO: Color! */
136 framebuffer_blockcopyfill(d->vfb_data, 1, 0,0,0,
137 d->dst_start % d->xres, d->dst_start / d->xres,
138 d->dst_start % d->xres + d->width,
139 d->dst_start / d->xres + d->height,
140 0, 0);
141 return;
142 }
143
144 fatal("\nUnimplemented igsfb accelerated framebuffer command:\n");
145 fatal("pixel_op_0 = 0x%02x\n", d->pixel_op_0);
146 fatal("pixel_op_1 = 0x%02x\n", d->pixel_op_1);
147 fatal("pixel_op_2 = 0x%02x\n", d->pixel_op_2);
148 fatal("pixel_op_3 = 0x%02x\n", d->pixel_op_3);
149 fatal("fg_mix = 0x%02x\n", d->fg_mix);
150 fatal("ctl = 0x%02x\n", d->ctl);
151 fatal("src_start = 0x%x\n", d->src_start);
152 fatal("dst_start = 0x%x\n", d->dst_start);
153 fatal("width = %i\n", d->width);
154 fatal("height = %i\n", d->height);
155 exit(1);
156 }
157
158
159 DEVICE_ACCESS(igsfb)
160 {
161 uint64_t idata = 0, odata = 0;
162 struct dev_igsfb_data *d = extra;
163
164 if (writeflag == MEM_WRITE)
165 idata = memory_readmax64(cpu, data, len);
166
167 if (relative_addr >= 0x3c0 && relative_addr <= 0x3df) {
168 switch (relative_addr - 0x3c0) {
169 case VGA_DAC_ADDR_WRITE: /* 0x08 */
170 if (writeflag == MEM_WRITE) {
171 d->palette_write_index = idata;
172 d->palette_write_subindex = 0;
173 } else {
174 fatal("[ igsdb: WARNING: Read from "
175 "VGA_DAC_ADDR_WRITE? ]\n");
176 odata = d->palette_write_index;
177 }
178 break;
179 case VGA_DAC_DATA: /* 0x09 */
180 if (writeflag == MEM_WRITE) {
181 /* Note: 8-bit color, not 6, so it isn't
182 exactly like normal VGA palette: */
183 int new = idata & 0xff;
184 int old = d->vfb_data->rgb_palette[d->
185 palette_write_index*3+d->
186 palette_write_subindex];
187 d->vfb_data->rgb_palette[d->palette_write_index
188 * 3 + d->palette_write_subindex] = new;
189 /* Redraw whole screen, if the
190 palette changed: */
191 if (new != old) {
192 d->vfb_data->update_x1 =
193 d->vfb_data->update_y1 = 0;
194 d->vfb_data->update_x2 = d->xres - 1;
195 d->vfb_data->update_y2 = d->yres - 1;
196 }
197 d->palette_write_subindex ++;
198 if (d->palette_write_subindex == 3) {
199 d->palette_write_index ++;
200 d->palette_write_subindex = 0;
201 }
202 }
203 /* Note/TODO: Reading from the palette isn't
204 implemented here. */
205 break;
206 case 0xe: /* IGSFB extended register select */
207 if (writeflag == MEM_WRITE)
208 d->ext_reg_select = idata;
209 else
210 odata = d->ext_reg_select;
211 break;
212 case 0xf: /* IGSFB extended register data */
213 if (writeflag == MEM_READ)
214 odata = d->ext_reg[d->ext_reg_select];
215 else {
216 d->ext_reg[d->ext_reg_select] = idata;
217 switch (d->ext_reg_select) {
218 /* case IGS_EXT_SPRITE_HSTART_LO:
219 case IGS_EXT_SPRITE_HSTART_HI:
220 case IGS_EXT_SPRITE_VSTART_LO: */
221 case IGS_EXT_SPRITE_VSTART_HI:
222 recalc_sprite_position(d);
223 break;
224 }
225 }
226 break;
227 }
228 return 1;
229 }
230
231 if (relative_addr >= IGS_COP_BASE_A &&
232 relative_addr < IGS_COP_BASE_A + IGS_COP_SIZE) {
233 fatal("[ igsfb: BASE A not implemented yet, only BASE B ]\n");
234 exit(1);
235 }
236
237 switch (relative_addr) {
238
239 case IGS_VDO:
240 if (writeflag == MEM_WRITE) {
241 if (idata & ~(IGS_VDO_ENABLE | IGS_VDO_SETUP)) {
242 fatal("[ igsfb: Unimplemented IGS_VDO flags:"
243 " 0x%08x ]\n", (int)idata);
244 exit(1);
245 }
246 }
247 break;
248
249 case IGS_VSE:
250 if (writeflag == MEM_WRITE) {
251 if (idata & ~(IGS_VSE_ENABLE)) {
252 fatal("[ igsfb: Unimplemented IGS_VSE flags:"
253 " 0x%08x ]\n", (int)idata);
254 exit(1);
255 }
256 }
257 break;
258
259 case IGS_COP_BASE_B + IGS_COP_SRC_MAP_WIDTH_REG:
260 if (writeflag == MEM_WRITE)
261 d->src_map_width = idata & 0x3ff;
262 else
263 odata = d->src_map_width;
264 break;
265
266 case IGS_COP_BASE_B + IGS_COP_SRC2_MAP_WIDTH_REG:
267 if (writeflag == MEM_WRITE)
268 d->src2_map_width = idata & 0x3ff;
269 else
270 odata = d->src2_map_width;
271 break;
272
273 case IGS_COP_BASE_B + IGS_COP_DST_MAP_WIDTH_REG:
274 if (writeflag == MEM_WRITE)
275 d->dst_map_width = idata & 0x3ff;
276 else
277 odata = d->dst_map_width;
278 break;
279
280 case IGS_COP_BASE_B + IGS_COP_MAP_FMT_REG:
281 if (writeflag == MEM_WRITE)
282 d->map_fmt = idata;
283 else
284 odata = d->map_fmt;
285 break;
286
287 case IGS_COP_BASE_B + IGS_COP_CTL_REG:
288 if (writeflag == MEM_WRITE)
289 d->ctl = idata;
290 else
291 odata = d->ctl;
292 break;
293
294 case IGS_COP_BASE_B + IGS_COP_FG_MIX_REG:
295 if (writeflag == MEM_WRITE)
296 d->fg_mix = idata;
297 else
298 odata = d->fg_mix;
299 break;
300
301 case IGS_COP_BASE_B + IGS_COP_BG_MIX_REG:
302 if (writeflag == MEM_WRITE)
303 d->bg_mix = idata;
304 else
305 odata = d->bg_mix;
306 break;
307
308 case IGS_COP_BASE_B + IGS_COP_WIDTH_REG:
309 if (writeflag == MEM_WRITE)
310 d->width = idata & 0x3ff;
311 else
312 odata = d->width;
313 break;
314
315 case IGS_COP_BASE_B + IGS_COP_HEIGHT_REG:
316 if (writeflag == MEM_WRITE)
317 d->height = idata & 0x3ff;
318 else
319 odata = d->height;
320 break;
321
322 case IGS_COP_BASE_B + IGS_COP_SRC_START_REG:
323 if (writeflag == MEM_WRITE)
324 d->src_start = idata & 0x3fffff;
325 else
326 odata = d->src_start;
327 break;
328
329 case IGS_COP_BASE_B + IGS_COP_SRC2_START_REG:
330 if (writeflag == MEM_WRITE)
331 d->src2_start = idata & 0x3fffff;
332 else
333 odata = d->src2_start;
334 break;
335
336 case IGS_COP_BASE_B + IGS_COP_DST_START_REG:
337 if (writeflag == MEM_WRITE)
338 d->dst_start = idata & 0x3fffff;
339 else
340 odata = d->dst_start;
341 break;
342
343 case IGS_COP_BASE_B + IGS_COP_FG_REG:
344 if (writeflag == MEM_WRITE)
345 d->fg = idata;
346 else
347 odata = d->fg;
348 break;
349
350 case IGS_COP_BASE_B + IGS_COP_BG_REG:
351 if (writeflag == MEM_WRITE)
352 d->bg = idata;
353 else
354 odata = d->bg;
355 break;
356
357 case IGS_COP_BASE_B + IGS_COP_PIXEL_OP_0_REG:
358 if (writeflag == MEM_WRITE)
359 d->pixel_op_0 = idata;
360 else
361 odata = d->pixel_op_0;
362 break;
363
364 case IGS_COP_BASE_B + IGS_COP_PIXEL_OP_1_REG:
365 if (writeflag == MEM_WRITE)
366 d->pixel_op_1 = idata;
367 else
368 odata = d->pixel_op_1;
369 break;
370
371 case IGS_COP_BASE_B + IGS_COP_PIXEL_OP_2_REG:
372 if (writeflag == MEM_WRITE)
373 d->pixel_op_2 = idata;
374 else
375 odata = d->pixel_op_2;
376 break;
377
378 case IGS_COP_BASE_B + IGS_COP_PIXEL_OP_3_REG:
379 if (writeflag == MEM_WRITE) {
380 d->pixel_op_3 = idata;
381 dev_igsfb_op3_written(d);
382 } else {
383 odata = d->pixel_op_3;
384 }
385 break;
386
387 default:if (writeflag == MEM_WRITE) {
388 fatal("[ igsfb: unimplemented write to address 0x%x"
389 " data=0x%02x ]\n", (int)relative_addr, (int)idata);
390 } else {
391 fatal("[ igsfb: unimplemented read from address 0x%x "
392 "]\n", (int)relative_addr);
393 }
394 exit(1);
395 }
396
397 if (writeflag == MEM_READ)
398 memory_writemax64(cpu, data, len, odata);
399
400 return 1;
401 }
402
403
404 DEVINIT(igsfb)
405 {
406 struct dev_igsfb_data *d;
407 d = malloc(sizeof(struct dev_igsfb_data));
408 if (d == NULL) {
409 fprintf(stderr, "out of memory\n");
410 exit(1);
411 }
412 memset(d, 0, sizeof(struct dev_igsfb_data));
413
414 d->xres = 1024;
415 d->yres = 768;
416 d->bitdepth = 8;
417 d->vfb_data = dev_fb_init(devinit->machine, devinit->machine->memory,
418 0x400000 + devinit->addr, VFB_GENERIC, d->xres, d->yres,
419 d->xres, d->yres, d->bitdepth, "igsfb");
420
421 /* TODO: Palette control etc at 0x3c0 + IGS_MEM_MMIO_SELECT */
422
423 memory_device_register(devinit->machine->memory, devinit->name,
424 devinit->addr + IGS_MEM_MMIO_SELECT, 0x100000,
425 dev_igsfb_access, d, DM_DEFAULT, NULL);
426
427 return 1;
428 }
429

  ViewVC Help
Powered by ViewVC 1.1.26