dev_igsfb.cc Source File

Back to the index.

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

Generated on Tue Aug 25 2020 19:25:06 for GXemul by doxygen 1.8.18