/[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 4 - (hide annotations)
Mon Oct 8 16:18:00 2007 UTC (12 years, 4 months ago) by dpavlin
File MIME type: text/plain
File size: 17051 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.707 2005/04/27 16:37:33 debug Exp $
20050408	Some minor updates to the wdc. Linux now doesn't complain
		anymore if a disk is non-present.
20050409	Various minor fixes (a bintrans bug, and some other things).
		The wdc seems to work with Playstation2 emulation, but there
		is a _long_ annoying delay when disks are detected.
		Fixing a really important bintrans bug (when devices and RAM
		are mixed within 4KB pages), which was triggered with
		NetBSD/playstation2 kernels.
20050410	Adding a dummy dev_ps2_ether (just so that NetBSD doesn't
		complain as much during bootup).
		Symbols starting with '$' are now ignored.
		Renaming dev_ps2_ohci.c to dev_ohci.c, etc.
20050411	Moving the bintrans-cache-isolation check from cpu_mips.c to
		cpu_mips_coproc.c. (I thought this would give a speedup, but
		it's not noticable.)
		Better playstation2 sbus interrupt code.
		Skip ahead many ticks if the count register is read manually.
		(This increases the speed of delay-loops that simply read
		the count register.)
20050412	Updates to the playstation2 timer/interrupt code.
		Some other minor updates.
20050413	NetBSD/cobalt runs from a disk image :-) including userland;
		updating the documentation on how to install NetBSD/cobalt
		using NetBSD/pmax (!).
		Some minor bintrans updates (no real speed improvement) and
		other minor updates (playstation2 now uses the -o options).
20050414	Adding a dummy x86 (and AMD64) mode.
20050415	Adding some (32-bit and 16-bit) x86 instructions.
		Adding some initial support for non-SCSI, non-IDE floppy
		images. (The x86 mode can boot from these, more or less.)
		Moving the devices/ and include/ directories to src/devices/
		and src/include/, respectively.
20050416	Continuing on the x86 stuff. (Adding pc_bios.c and some simple
		support for software interrupts in 16-bit mode.)
20050417	Ripping out most of the x86 instruction decoding stuff, trying
		to rewrite it in a cleaner way.
		Disabling some of the least working CPU families in the
		configure script (sparc, x86, alpha, hppa), so that they are
		not enabled by default.
20050418	Trying to fix the bug which caused problems when turning on
		and off bintrans interactively, by flushing the bintrans cache
		whenever bintrans is manually (re)enabled.
20050419	Adding the 'lswi' ppc instruction.
		Minor updates to the x86 instruction decoding.
20050420	Renaming x86 register name indices from R_xx to X86_R_xx (this
		makes building on Tru64 nicer).
20050422	Adding a check for duplicate MIPS TLB entries on tlbwr/tlbwi.
20050427	Adding screenshots to guestoses.html.
		Some minor fixes and testing for the next release.

==============  RELEASE 0.3.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     * $Id: dev_bt459.c,v 1.59 2005/02/22 12:15:29 debug Exp $
29     *
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     idata = memory_readmax64(cpu, data, len);
361    
362     #ifdef BT459_DEBUG
363     fatal("[ bt459: IRQ ack ]\n");
364     #endif
365    
366     d->interrupts_enable = 1;
367     if (d->irq_nr > 0)
368     cpu_interrupt_ack(cpu, d->irq_nr);
369    
370     if (writeflag == MEM_READ)
371     memory_writemax64(cpu, data, len, odata);
372    
373     return 1;
374     }
375    
376    
377     /*
378     * dev_bt459_access():
379     */
380     int dev_bt459_access(struct cpu *cpu, struct memory *mem,
381     uint64_t relative_addr, unsigned char *data, size_t len,
382     int writeflag, void *extra)
383     {
384     struct bt459_data *d = (struct bt459_data *) extra;
385     uint64_t idata = 0, odata = 0;
386     int btaddr, old_cursor_on = d->cursor_on, modified;
387    
388     idata = memory_readmax64(cpu, data, len);
389    
390     #ifdef BT459_DEBUG
391     if (writeflag == MEM_WRITE)
392     fatal("[ bt459: write to addr 0x%02x: %08x ]\n",
393     (int)relative_addr, (int)idata);
394     #endif
395    
396     /*
397     * Vertical retrace interrupts are acked either by
398     * accessing a normal BT459 register, or the irq register,
399     * or by simply "missing" it.
400     */
401     if (d->irq_nr > 0)
402     cpu_interrupt_ack(cpu, d->irq_nr);
403    
404     /* ID register is read-only, should always be 0x4a or 0x4a4a4a: */
405     if (d->planes == 24)
406     d->bt459_reg[BT459_REG_ID] = 0x4a4a4a;
407     else {
408     /*
409     * TODO: Is it really 0x4a, or 0x4a0000?
410     * Ultrix panics with a "bad VDAC ID" message if 0x4a
411     * is returned.
412     */
413     d->bt459_reg[BT459_REG_ID] = 0x4a0000;
414     }
415    
416     btaddr = ((d->cur_addr_hi << 8) + d->cur_addr_lo) % DEV_BT459_NREGS;
417    
418     /* Read from/write to the bt459: */
419     switch (relative_addr) {
420     case 0x00: /* Low byte of address: */
421     if (writeflag == MEM_WRITE) {
422     if (!quiet_mode)
423     debug("[ bt459: write to Low Address Byte, "
424     "0x%02x ]\n", (int)idata);
425     d->cur_addr_lo = idata;
426     d->palette_sub_offset = 0;
427     } else {
428     odata = d->cur_addr_lo;
429     if (!quiet_mode)
430     debug("[ bt459: read from Low Address Byte: "
431     "0x%0x ]\n", (int)odata);
432     }
433     break;
434     case 0x04: /* High byte of address: */
435     if (writeflag == MEM_WRITE) {
436     if (!quiet_mode)
437     debug("[ bt459: write to High Address Byte, "
438     "0x%02x ]\n", (int)idata);
439     d->cur_addr_hi = idata;
440     d->palette_sub_offset = 0;
441     } else {
442     odata = d->cur_addr_hi;
443     if (!quiet_mode)
444     debug("[ bt459: read from High Address Byte: "
445     "0x%0x ]\n", (int)odata);
446     }
447     break;
448     case 0x08: /* Register access: */
449     if (writeflag == MEM_WRITE) {
450     if (!quiet_mode)
451     debug("[ bt459: write to BT459 register "
452     "0x%04x, value 0x%02x ]\n", btaddr,
453     (int)idata);
454     modified = (d->bt459_reg[btaddr] != idata);
455     d->bt459_reg[btaddr] = idata;
456    
457     switch (btaddr) {
458     case BT459_REG_CCOLOR_1:
459     case BT459_REG_CCOLOR_2:
460     case BT459_REG_CCOLOR_3:
461     if (modified)
462     d->need_to_update_cursor_shape = 1;
463     break;
464     case BT459_REG_PRM:
465     /*
466     * NetBSD writes 0x00 to this register to
467     * blank the screen (video off), and 0xff
468     * to turn the screen on.
469     */
470     switch (idata & 0xff) {
471     case 0: d->video_on = 0;
472     memset(d->rgb_palette, 0, 256*3);
473     d->need_to_redraw_whole_screen = 1;
474     debug("[ bt459: video OFF ]\n");
475     break;
476     default:d->video_on = 1;
477     memcpy(d->rgb_palette,
478     d->local_rgb_palette, 256*3);
479     d->need_to_redraw_whole_screen = 1;
480     debug("[ bt459: video ON ]\n");
481     }
482     break;
483     case BT459_REG_CCR:
484     /* Cursor control register: */
485     switch (idata & 0xff) {
486     case 0x00: d->cursor_on = 0; break;
487     case 0xc0:
488     case 0xc1: d->cursor_on = 1; break;
489     default:
490     fatal("[ bt459: unimplemented CCR "
491     "value 0x%08x ]\n", (int)idata);
492     }
493     if (modified)
494     d->need_to_update_cursor_shape = 1;
495     break;
496     default:
497     if (btaddr < 0x100)
498     fatal("[ bt459: write to BT459 "
499     "register 0x%04x, value 0x%02x ]\n",
500     btaddr, (int)idata);
501     }
502    
503     /* Write to cursor bitmap: */
504     if (btaddr >= BT459_REG_CRAM_BASE && modified)
505     d->need_to_update_cursor_shape = 1;
506     } else {
507     odata = d->bt459_reg[btaddr];
508    
509     /* Perhaps this hack is not necessary: */
510     if (btaddr == BT459_REG_ID && len==1)
511     odata = (odata >> 16) & 255;
512    
513     if (!quiet_mode)
514     debug("[ bt459: read from BT459 register "
515     "0x%04x, value 0x%02x ]\n", btaddr,
516     (int)odata);
517     }
518    
519     /* Go to next register: */
520     d->cur_addr_lo ++;
521     if (d->cur_addr_lo == 0)
522     d->cur_addr_hi ++;
523     break;
524     case 0xc: /* Color map: */
525     if (writeflag == MEM_WRITE) {
526     idata &= 255;
527     if (!quiet_mode)
528     debug("[ bt459: write to BT459 colormap "
529     "0x%04x subaddr %i, value 0x%02x ]\n",
530     btaddr, d->palette_sub_offset, (int)idata);
531    
532     if (btaddr < 0x100) {
533     if (d->video_on &&
534     d->local_rgb_palette[(btaddr & 0xff) * 3
535     + d->palette_sub_offset] != idata)
536     d->need_to_redraw_whole_screen = 1;
537    
538     /*
539     * Actually, the palette should only be
540     * updated after the third write,
541     * but this should probably work fine too:
542     */
543     d->local_rgb_palette[(btaddr & 0xff) * 3
544     + d->palette_sub_offset] = idata;
545    
546     if (d->video_on)
547     d->rgb_palette[(btaddr & 0xff) * 3
548     + d->palette_sub_offset] = idata;
549     }
550     } else {
551     if (btaddr < 0x100)
552     odata = d->local_rgb_palette[(btaddr & 0xff)
553     * 3 + d->palette_sub_offset];
554     if (!quiet_mode)
555     debug("[ bt459: read from BT459 colormap "
556     "0x%04x subaddr %i, value 0x%02x ]\n",
557     btaddr, d->palette_sub_offset, (int)odata);
558     }
559    
560     d->palette_sub_offset ++;
561     if (d->palette_sub_offset >= 3) {
562     d->palette_sub_offset = 0;
563    
564     d->cur_addr_lo ++;
565     if (d->cur_addr_lo == 0)
566     d->cur_addr_hi ++;
567     }
568    
569     break;
570     default:
571     if (writeflag == MEM_WRITE) {
572     debug("[ bt459: unimplemented write to address 0x%x, "
573     "data=0x%02x ]\n", (int)relative_addr, (int)idata);
574     } else {
575     debug("[ bt459: unimplemented read from address "
576     "0x%x ]\n", (int)relative_addr);
577     }
578     }
579    
580    
581     bt459_update_cursor_position(d, old_cursor_on);
582    
583     if (writeflag == MEM_READ)
584     memory_writemax64(cpu, data, len, odata);
585    
586     #ifdef BT459_DEBUG
587     if (writeflag == MEM_READ)
588     fatal("[ bt459: read from addr 0x%02x: %08x ]\n",
589     (int)relative_addr, (int)idata);
590     #endif
591    
592     return 1;
593     }
594    
595    
596     /*
597     * dev_bt459_init():
598     */
599     void dev_bt459_init(struct machine *machine, struct memory *mem,
600     uint64_t baseaddr, uint64_t baseaddr_irq, struct vfb_data *vfb_data,
601     int planes, int irq_nr, int type)
602     {
603     struct bt459_data *d = malloc(sizeof(struct bt459_data));
604     if (d == NULL) {
605     fprintf(stderr, "out of memory\n");
606     exit(1);
607     }
608    
609     memset(d, 0, sizeof(struct bt459_data));
610    
611     d->vfb_data = vfb_data;
612     d->rgb_palette = vfb_data->rgb_palette;
613     d->planes = planes;
614     d->irq_nr = irq_nr;
615     d->type = type;
616     d->cursor_x = -1;
617     d->cursor_y = -1;
618     d->cursor_xsize = d->cursor_ysize = 0; /* anything */
619     d->video_on = 1;
620    
621     /*
622     * These offsets are based on those mentioned in NetBSD,
623     * and then adjusted to look good with both NetBSD and
624     * Ultrix:
625     */
626     switch (d->type) {
627     case BT459_PX:
628     d->cursor_x_add = 370;
629     d->cursor_y_add = 37;
630     break;
631     case BT459_BA:
632     d->cursor_x_add = 220;
633     d->cursor_y_add = 35;
634     break;
635     case BT459_BBA:
636     if (vfb_data->xsize == 1280) {
637     /* 1280x1024: */
638     d->cursor_x_add = 368;
639     d->cursor_y_add = 38;
640     } else {
641     /* 1024x864: */
642     d->cursor_x_add = 220;
643     d->cursor_y_add = 35;
644     }
645     break;
646     }
647    
648     d->interrupt_time_reset_value = 500;
649    
650     memory_device_register(mem, "bt459", baseaddr, DEV_BT459_LENGTH,
651     dev_bt459_access, (void *)d, MEM_DEFAULT, NULL);
652    
653     if (baseaddr_irq != 0)
654     memory_device_register(mem, "bt459_irq", baseaddr_irq, 0x10000,
655     dev_bt459_irq_access, (void *)d, MEM_DEFAULT, NULL);
656    
657     machine_add_tickfunction(machine, dev_bt459_tick, d, BT459_TICK_SHIFT);
658    
659     memory_device_register_statefunction(mem, d, bt459_state);
660     }
661    

  ViewVC Help
Powered by ViewVC 1.1.26