/[gxemul]/trunk/src/devices/dev_bt459.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

Annotation of /trunk/src/devices/dev_bt459.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 18 - (hide annotations)
Mon Oct 8 16:19:11 2007 UTC (13 years, 3 months ago) by dpavlin
File MIME type: text/plain
File size: 17081 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1004 2005/10/27 14:01:10 debug Exp $
20051011        Passing -A as the default boot arg for CATS (works fine with
                OpenBSD/cats).
20051012	Fixing the VGA cursor offset bug, and speeding up framebuffer
		redraws if character cells contain the same thing as during
		the last redraw.
20051013	Adding a slow strd ARM instruction hack.
20051017	Minor updates: Adding a dummy i80321 Verde controller (for
		XScale emulation), fixing the disassembly of the ARM "ldrd"
		instruction, adding "support" for less-than-4KB pages for ARM
		(by not adding them to translation tables).
20051020	Continuing on some HPCarm stuff. A NetBSD/hpcarm kernel prints
		some boot messages on an emulated Jornada 720.
		Making dev_ram work better with dyntrans (speeds up some things
		quite a bit).
20051021	Automatically generating some of the most common ARM load/store
		multiple instructions.
20051022	Better statistics gathering for the ARM load/store multiple.
		Various other dyntrans and device updates.
20051023	Various minor updates.
20051024	Continuing; minor device and dyntrans fine-tuning. Adding the
		first "reasonable" instruction combination hacks for ARM (the
		cores of NetBSD/cats' memset and memcpy).
20051025	Fixing a dyntrans-related bug in dev_vga. Also changing the
		dyntrans low/high access notification to only be updated on
		writes, not reads. Hopefully it will be enough. (dev_vga in
		charcell mode now seems to work correctly with both reads and
		writes.)
		Experimenting with gathering dyntrans statistics (which parts
		of emulated RAM that are actually executed), and adding
		instruction combination hacks for cache cleaning and a part of
		NetBSD's scanc() function.
20051026	Adding a bitmap for ARM emulation which indicates if a page is
		(specifically) user accessible; loads and stores with the t-
		flag set can now use the translation arrays, which results in
		a measurable speedup.
20051027	Dyntrans updates; adding an extra bitmap array for 32-bit
		emulation modes, speeding up the check whether a physical page
		has any code translations or not (O(n) -> O(1)). Doing a
		similar reduction of O(n) to O(1) by avoiding the scan through
		the translation entries on a translation update (32-bit mode
		only).
		Various other minor hacks.
20051029	Quick release, without any testing at all.

==============  RELEASE 0.3.6.2  ==============


1 dpavlin 4 /*
2     * Copyright (C) 2003-2005 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 dpavlin 18 * $Id: dev_bt459.c,v 1.60 2005/10/26 14:37:03 debug Exp $
29 dpavlin 4 *
30     * Brooktree 459 vdac, used by TURBOchannel graphics cards.
31     */
32    
33     #include <stdio.h>
34     #include <stdlib.h>
35     #include <string.h>
36    
37     #include "cpu.h"
38     #include "devices.h"
39     #include "machine.h"
40     #include "memory.h"
41     #include "misc.h"
42     #include "x11.h"
43    
44     #include "bt459.h"
45    
46    
47     #ifdef WITH_X11
48     #include <X11/Xlib.h>
49     #include <X11/Xutil.h>
50     #endif
51    
52     extern int quiet_mode;
53    
54    
55     /* #define BT459_DEBUG */
56     /* #define WITH_CURSOR_DEBUG */
57     #define BT459_TICK_SHIFT 14
58    
59     struct bt459_data {
60     uint32_t bt459_reg[DEV_BT459_NREGS];
61    
62     unsigned char cur_addr_hi;
63     unsigned char cur_addr_lo;
64    
65     int planes;
66     int type;
67    
68     int irq_nr;
69     int interrupts_enable;
70     int interrupt_time;
71     int interrupt_time_reset_value;
72    
73     int cursor_x_add;
74     int cursor_y_add;
75    
76     int need_to_redraw_whole_screen;
77    
78     int need_to_update_cursor_shape;
79     int cursor_on;
80     int cursor_x;
81     int cursor_y;
82     int cursor_xsize;
83     int cursor_ysize;
84    
85     int palette_sub_offset; /* 0, 1, or 2 */
86    
87     struct vfb_data *vfb_data;
88    
89     /*
90     * There is one pointer to the framebuffer's RGB palette,
91     * and then a local copy of the palette. 256 * 3 bytes (r,g,b).
92     * The reason for this is that when we need to blank the screen
93     * (ie video_on = 0), we can set the framebuffer's palette to all
94     * zeroes, but keep our own copy intact, to be reused later again
95     * when the screen is unblanked.
96     */
97     int video_on;
98     unsigned char *rgb_palette; /* 256 * 3 (r,g,b) */
99     unsigned char local_rgb_palette[256 * 3];
100     };
101    
102    
103     /*
104     * bt459_state():
105     */
106     int bt459_state(struct cpu *cpu, struct memory *mem, void *extra, int wf,
107     int nr, int *type, char **namep, void **data, size_t *len)
108     {
109     struct bt459_data *d = (struct bt459_data *) extra;
110    
111     switch (nr) {
112     case 0: if (wf) {
113     memcpy(&d->cursor_on, *data, *len);
114     } else {
115     (*namep) = "cursor_on";
116     (*type) = DEVICE_STATE_TYPE_INT;
117     *len = sizeof(d->cursor_on);
118     *data = &d->cursor_on;
119     }
120     break;
121     case 1: if (wf) {
122     memcpy(&d->cursor_x, *data, *len);
123     } else {
124     (*namep) = "cursor_x";
125     (*type) = DEVICE_STATE_TYPE_INT;
126     *len = sizeof(d->cursor_x);
127     *data = &d->cursor_x;
128     }
129     break;
130     case 2: if (wf) {
131     memcpy(&d->cursor_y, *data, *len);
132     } else {
133     (*namep) = "cursor_y";
134     (*type) = DEVICE_STATE_TYPE_INT;
135     *len = sizeof(d->cursor_y);
136     *data = &d->cursor_y;
137     }
138     break;
139     case 3: if (wf) {
140     memcpy(&d->cursor_xsize, *data, *len);
141     } else {
142     (*namep) = "cursor_xsize";
143     (*type) = DEVICE_STATE_TYPE_INT;
144     *len = sizeof(d->cursor_xsize);
145     *data = &d->cursor_xsize;
146     }
147     break;
148     case 4: if (wf) {
149     memcpy(&d->cursor_ysize, *data, *len);
150     } else {
151     (*namep) = "cursor_ysize";
152     (*type) = DEVICE_STATE_TYPE_INT;
153     *len = sizeof(d->cursor_ysize);
154     *data = &d->cursor_ysize;
155     }
156     break;
157     default:
158     return 0;
159     }
160    
161     return 1;
162     }
163    
164    
165     /*
166     * bt459_update_X_cursor():
167     *
168     * This routine takes the color values in the cursor RAM area, and put them
169     * in the framebuffer window's cursor_pixels.
170     *
171     * d->cursor_xsize and ysize are also updated.
172     */
173     static void bt459_update_X_cursor(struct cpu *cpu, struct bt459_data *d)
174     {
175     int i, x,y, xmax=0, ymax=0;
176     int bw_only = 1;
177    
178     /* First, let's calculate the size of the cursor: */
179     for (y=0; y<64; y++)
180     for (x=0; x<64; x+=4) {
181     int reg = BT459_REG_CRAM_BASE + y*16 + x/4;
182     unsigned char data = d->bt459_reg[reg];
183    
184     if (data)
185     ymax = y;
186    
187     for (i=0; i<4; i++) {
188     int color = (data >> (6-2*i)) & 3;
189     if (color != 0)
190     xmax = x + i;
191     if (color != 0 && color != 3)
192     bw_only = 0;
193     }
194     }
195    
196     d->cursor_xsize = xmax + 1;
197     d->cursor_ysize = ymax + 1;
198    
199     /*
200     * The 'bw_only' hack is because it is nicer to have the b/w
201     * text cursor invert whatever it is standing on, not just overwrite
202     * it with a big white box.
203     *
204     * The following seems to work with NetBSD/OpenBSD/Ultrix/Sprite:
205     * 0 = transparent, 1 and 2 = use the color specified by
206     * BT459_REG_CCOLOR_2, 3 = reverse of color 1/2.
207     */
208    
209     #ifdef WITH_X11
210     if (cpu->machine->use_x11 && d->vfb_data->fb_window != NULL) {
211     for (y=0; y<=ymax; y++) {
212     for (x=0; x<=xmax; x+=4) {
213     struct fb_window *win = d->vfb_data->fb_window;
214     int reg = BT459_REG_CRAM_BASE + y*16 + x/4;
215     unsigned char data = d->bt459_reg[reg];
216    
217     for (i=0; i<4; i++) {
218     int color = (data >> (6-2*i)) & 3;
219     int pixelvalue;
220    
221     if (bw_only) {
222     if (color)
223     pixelvalue =
224     CURSOR_COLOR_INVERT;
225     else
226     pixelvalue = 0;
227     } else {
228     pixelvalue =
229     CURSOR_COLOR_TRANSPARENT;
230     switch (color) {
231     case 1:
232     case 2: pixelvalue = (d->
233     bt459_reg[
234     BT459_REG_CCOLOR_2]
235     >> 4) & 0xf;
236     break;
237     case 3: pixelvalue = 15 -
238     ((d->bt459_reg[
239     BT459_REG_CCOLOR_2]
240     >> 4) & 0xf);
241     break;
242     }
243     }
244    
245     win->cursor_pixels[y][x+i] =
246     pixelvalue;
247     #ifdef WITH_CURSOR_DEBUG
248     printf("%i", color);
249     #endif
250     }
251     }
252     #ifdef WITH_CURSOR_DEBUG
253     printf("\n");
254     #endif
255     }
256     #ifdef WITH_CURSOR_DEBUG
257     printf("color 1,2,3 = 0x%02x, 0x%02x, 0x%02x\n",
258     d->bt459_reg[BT459_REG_CCOLOR_1],
259     d->bt459_reg[BT459_REG_CCOLOR_2],
260     d->bt459_reg[BT459_REG_CCOLOR_3]);
261     printf("\n");
262     #endif
263     /*
264     * Make sure the cursor is redrawn, if it is on:
265     *
266     * How does this work? Well, 0 is off, and non-zero is on,
267     * but if the old and new differ, the cursor is redrawn.
268     * (Hopefully this will "never" overflow.)
269     */
270     if (d->cursor_on)
271     d->cursor_on ++;
272     }
273     #endif
274     }
275    
276    
277     /*
278     * bt459_update_cursor_position():
279     */
280     static void bt459_update_cursor_position(struct bt459_data *d,
281     int old_cursor_on)
282     {
283     int new_cursor_x = (d->bt459_reg[BT459_REG_CXLO] & 255) +
284     ((d->bt459_reg[BT459_REG_CXHI] & 255) << 8) - d->cursor_x_add;
285     int new_cursor_y = (d->bt459_reg[BT459_REG_CYLO] & 255) +
286     ((d->bt459_reg[BT459_REG_CYHI] & 255) << 8) - d->cursor_y_add;
287    
288     if (new_cursor_x != d->cursor_x || new_cursor_y != d->cursor_y ||
289     d->cursor_on != old_cursor_on) {
290     int on;
291    
292     d->cursor_x = new_cursor_x;
293     d->cursor_y = new_cursor_y;
294    
295     if (!quiet_mode)
296     debug("[ bt459: cursor = %03i,%03i ]\n",
297     d->cursor_x, d->cursor_y);
298    
299     on = d->cursor_on;
300     if (d->cursor_xsize == 0 || d->cursor_ysize == 0)
301     on = 0;
302    
303     dev_fb_setcursor(d->vfb_data, d->cursor_x, d->cursor_y,
304     on, d->cursor_xsize, d->cursor_ysize);
305     }
306     }
307    
308    
309     /*
310     * dev_bt459_tick():
311     */
312     void dev_bt459_tick(struct cpu *cpu, void *extra)
313     {
314     struct bt459_data *d = extra;
315     int old_cursor_on = d->cursor_on;
316    
317     if (d->need_to_update_cursor_shape) {
318     d->need_to_update_cursor_shape = 0;
319     bt459_update_X_cursor(cpu, d);
320     bt459_update_cursor_position(d, old_cursor_on);
321     }
322    
323     if (d->need_to_redraw_whole_screen) {
324     d->vfb_data->update_x1 = 0;
325     d->vfb_data->update_x2 = d->vfb_data->xsize - 1;
326     d->vfb_data->update_y1 = 0;
327     d->vfb_data->update_y2 = d->vfb_data->ysize - 1;
328     d->need_to_redraw_whole_screen = 0;
329     }
330    
331     /*
332     * Vertical retrace interrupts. (This hack is kind of ugly.)
333     * Once every 'interrupt_time_reset_value', the interrupt is
334     * asserted. It is acked either manually (by someone reading
335     * a normal BT459 register or the Interrupt ack register),
336     * or after another tick has passed. (This is to prevent
337     * lockups from unhandled interrupts.)
338     */
339     if (d->type != BT459_PX && d->interrupts_enable && d->irq_nr > 0) {
340     d->interrupt_time --;
341     if (d->interrupt_time < 0) {
342     d->interrupt_time = d->interrupt_time_reset_value;
343     cpu_interrupt(cpu, d->irq_nr);
344     } else
345     cpu_interrupt_ack(cpu, d->irq_nr);
346     }
347     }
348    
349    
350     /*
351     * dev_bt459_irq_access():
352     */
353     int dev_bt459_irq_access(struct cpu *cpu, struct memory *mem,
354     uint64_t relative_addr, unsigned char *data, size_t len,
355     int writeflag, void *extra)
356     {
357     struct bt459_data *d = (struct bt459_data *) extra;
358     uint64_t idata = 0, odata = 0;
359    
360 dpavlin 18 if (writeflag == MEM_WRITE)
361     idata = memory_readmax64(cpu, data, len);
362 dpavlin 4
363     #ifdef BT459_DEBUG
364     fatal("[ bt459: IRQ ack ]\n");
365     #endif
366    
367     d->interrupts_enable = 1;
368     if (d->irq_nr > 0)
369     cpu_interrupt_ack(cpu, d->irq_nr);
370    
371     if (writeflag == MEM_READ)
372     memory_writemax64(cpu, data, len, odata);
373    
374     return 1;
375     }
376    
377    
378     /*
379     * dev_bt459_access():
380     */
381     int dev_bt459_access(struct cpu *cpu, struct memory *mem,
382     uint64_t relative_addr, unsigned char *data, size_t len,
383     int writeflag, void *extra)
384     {
385     struct bt459_data *d = (struct bt459_data *) extra;
386     uint64_t idata = 0, odata = 0;
387     int btaddr, old_cursor_on = d->cursor_on, modified;
388    
389     idata = memory_readmax64(cpu, data, len);
390    
391     #ifdef BT459_DEBUG
392     if (writeflag == MEM_WRITE)
393     fatal("[ bt459: write to addr 0x%02x: %08x ]\n",
394     (int)relative_addr, (int)idata);
395     #endif
396    
397     /*
398     * Vertical retrace interrupts are acked either by
399     * accessing a normal BT459 register, or the irq register,
400     * or by simply "missing" it.
401     */
402     if (d->irq_nr > 0)
403     cpu_interrupt_ack(cpu, d->irq_nr);
404    
405     /* ID register is read-only, should always be 0x4a or 0x4a4a4a: */
406     if (d->planes == 24)
407     d->bt459_reg[BT459_REG_ID] = 0x4a4a4a;
408     else {
409     /*
410     * TODO: Is it really 0x4a, or 0x4a0000?
411     * Ultrix panics with a "bad VDAC ID" message if 0x4a
412     * is returned.
413     */
414     d->bt459_reg[BT459_REG_ID] = 0x4a0000;
415     }
416    
417     btaddr = ((d->cur_addr_hi << 8) + d->cur_addr_lo) % DEV_BT459_NREGS;
418    
419     /* Read from/write to the bt459: */
420     switch (relative_addr) {
421     case 0x00: /* Low byte of address: */
422     if (writeflag == MEM_WRITE) {
423     if (!quiet_mode)
424     debug("[ bt459: write to Low Address Byte, "
425     "0x%02x ]\n", (int)idata);
426     d->cur_addr_lo = idata;
427     d->palette_sub_offset = 0;
428     } else {
429     odata = d->cur_addr_lo;
430     if (!quiet_mode)
431     debug("[ bt459: read from Low Address Byte: "
432     "0x%0x ]\n", (int)odata);
433     }
434     break;
435     case 0x04: /* High byte of address: */
436     if (writeflag == MEM_WRITE) {
437     if (!quiet_mode)
438     debug("[ bt459: write to High Address Byte, "
439     "0x%02x ]\n", (int)idata);
440     d->cur_addr_hi = idata;
441     d->palette_sub_offset = 0;
442     } else {
443     odata = d->cur_addr_hi;
444     if (!quiet_mode)
445     debug("[ bt459: read from High Address Byte: "
446     "0x%0x ]\n", (int)odata);
447     }
448     break;
449     case 0x08: /* Register access: */
450     if (writeflag == MEM_WRITE) {
451     if (!quiet_mode)
452     debug("[ bt459: write to BT459 register "
453     "0x%04x, value 0x%02x ]\n", btaddr,
454     (int)idata);
455     modified = (d->bt459_reg[btaddr] != idata);
456     d->bt459_reg[btaddr] = idata;
457    
458     switch (btaddr) {
459     case BT459_REG_CCOLOR_1:
460     case BT459_REG_CCOLOR_2:
461     case BT459_REG_CCOLOR_3:
462     if (modified)
463     d->need_to_update_cursor_shape = 1;
464     break;
465     case BT459_REG_PRM:
466     /*
467     * NetBSD writes 0x00 to this register to
468     * blank the screen (video off), and 0xff
469     * to turn the screen on.
470     */
471     switch (idata & 0xff) {
472     case 0: d->video_on = 0;
473     memset(d->rgb_palette, 0, 256*3);
474     d->need_to_redraw_whole_screen = 1;
475     debug("[ bt459: video OFF ]\n");
476     break;
477     default:d->video_on = 1;
478     memcpy(d->rgb_palette,
479     d->local_rgb_palette, 256*3);
480     d->need_to_redraw_whole_screen = 1;
481     debug("[ bt459: video ON ]\n");
482     }
483     break;
484     case BT459_REG_CCR:
485     /* Cursor control register: */
486     switch (idata & 0xff) {
487     case 0x00: d->cursor_on = 0; break;
488     case 0xc0:
489     case 0xc1: d->cursor_on = 1; break;
490     default:
491     fatal("[ bt459: unimplemented CCR "
492     "value 0x%08x ]\n", (int)idata);
493     }
494     if (modified)
495     d->need_to_update_cursor_shape = 1;
496     break;
497     default:
498     if (btaddr < 0x100)
499     fatal("[ bt459: write to BT459 "
500     "register 0x%04x, value 0x%02x ]\n",
501     btaddr, (int)idata);
502     }
503    
504     /* Write to cursor bitmap: */
505     if (btaddr >= BT459_REG_CRAM_BASE && modified)
506     d->need_to_update_cursor_shape = 1;
507     } else {
508     odata = d->bt459_reg[btaddr];
509    
510     /* Perhaps this hack is not necessary: */
511     if (btaddr == BT459_REG_ID && len==1)
512     odata = (odata >> 16) & 255;
513    
514     if (!quiet_mode)
515     debug("[ bt459: read from BT459 register "
516     "0x%04x, value 0x%02x ]\n", btaddr,
517     (int)odata);
518     }
519    
520     /* Go to next register: */
521     d->cur_addr_lo ++;
522     if (d->cur_addr_lo == 0)
523     d->cur_addr_hi ++;
524     break;
525     case 0xc: /* Color map: */
526     if (writeflag == MEM_WRITE) {
527     idata &= 255;
528     if (!quiet_mode)
529     debug("[ bt459: write to BT459 colormap "
530     "0x%04x subaddr %i, value 0x%02x ]\n",
531     btaddr, d->palette_sub_offset, (int)idata);
532    
533     if (btaddr < 0x100) {
534     if (d->video_on &&
535     d->local_rgb_palette[(btaddr & 0xff) * 3
536     + d->palette_sub_offset] != idata)
537     d->need_to_redraw_whole_screen = 1;
538    
539     /*
540     * Actually, the palette should only be
541     * updated after the third write,
542     * but this should probably work fine too:
543     */
544     d->local_rgb_palette[(btaddr & 0xff) * 3
545     + d->palette_sub_offset] = idata;
546    
547     if (d->video_on)
548     d->rgb_palette[(btaddr & 0xff) * 3
549     + d->palette_sub_offset] = idata;
550     }
551     } else {
552     if (btaddr < 0x100)
553     odata = d->local_rgb_palette[(btaddr & 0xff)
554     * 3 + d->palette_sub_offset];
555     if (!quiet_mode)
556     debug("[ bt459: read from BT459 colormap "
557     "0x%04x subaddr %i, value 0x%02x ]\n",
558     btaddr, d->palette_sub_offset, (int)odata);
559     }
560    
561     d->palette_sub_offset ++;
562     if (d->palette_sub_offset >= 3) {
563     d->palette_sub_offset = 0;
564    
565     d->cur_addr_lo ++;
566     if (d->cur_addr_lo == 0)
567     d->cur_addr_hi ++;
568     }
569    
570     break;
571     default:
572     if (writeflag == MEM_WRITE) {
573     debug("[ bt459: unimplemented write to address 0x%x, "
574     "data=0x%02x ]\n", (int)relative_addr, (int)idata);
575     } else {
576     debug("[ bt459: unimplemented read from address "
577     "0x%x ]\n", (int)relative_addr);
578     }
579     }
580    
581    
582     bt459_update_cursor_position(d, old_cursor_on);
583    
584     if (writeflag == MEM_READ)
585     memory_writemax64(cpu, data, len, odata);
586    
587     #ifdef BT459_DEBUG
588     if (writeflag == MEM_READ)
589     fatal("[ bt459: read from addr 0x%02x: %08x ]\n",
590     (int)relative_addr, (int)idata);
591     #endif
592    
593     return 1;
594     }
595    
596    
597     /*
598     * dev_bt459_init():
599     */
600     void dev_bt459_init(struct machine *machine, struct memory *mem,
601     uint64_t baseaddr, uint64_t baseaddr_irq, struct vfb_data *vfb_data,
602     int planes, int irq_nr, int type)
603     {
604     struct bt459_data *d = malloc(sizeof(struct bt459_data));
605     if (d == NULL) {
606     fprintf(stderr, "out of memory\n");
607     exit(1);
608     }
609    
610     memset(d, 0, sizeof(struct bt459_data));
611    
612     d->vfb_data = vfb_data;
613     d->rgb_palette = vfb_data->rgb_palette;
614     d->planes = planes;
615     d->irq_nr = irq_nr;
616     d->type = type;
617     d->cursor_x = -1;
618     d->cursor_y = -1;
619     d->cursor_xsize = d->cursor_ysize = 0; /* anything */
620     d->video_on = 1;
621    
622     /*
623     * These offsets are based on those mentioned in NetBSD,
624     * and then adjusted to look good with both NetBSD and
625     * Ultrix:
626     */
627     switch (d->type) {
628     case BT459_PX:
629     d->cursor_x_add = 370;
630     d->cursor_y_add = 37;
631     break;
632     case BT459_BA:
633     d->cursor_x_add = 220;
634     d->cursor_y_add = 35;
635     break;
636     case BT459_BBA:
637     if (vfb_data->xsize == 1280) {
638     /* 1280x1024: */
639     d->cursor_x_add = 368;
640     d->cursor_y_add = 38;
641     } else {
642     /* 1024x864: */
643     d->cursor_x_add = 220;
644     d->cursor_y_add = 35;
645     }
646     break;
647     }
648    
649     d->interrupt_time_reset_value = 500;
650    
651     memory_device_register(mem, "bt459", baseaddr, DEV_BT459_LENGTH,
652     dev_bt459_access, (void *)d, MEM_DEFAULT, NULL);
653    
654     if (baseaddr_irq != 0)
655     memory_device_register(mem, "bt459_irq", baseaddr_irq, 0x10000,
656     dev_bt459_irq_access, (void *)d, MEM_DEFAULT, NULL);
657    
658     machine_add_tickfunction(machine, dev_bt459_tick, d, BT459_TICK_SHIFT);
659    
660     memory_device_register_statefunction(mem, d, bt459_state);
661     }
662    

  ViewVC Help
Powered by ViewVC 1.1.26