/[gxemul]/upstream/0.4.6/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.6/src/devices/dev_igsfb.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26