/[gxemul]/upstream/0.3.3.1/src/devices/dev_sgi_mardigras.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 /upstream/0.3.3.1/src/devices/dev_sgi_mardigras.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Mon Oct 8 16:18:14 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 8648 byte(s)
0.3.3.1
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_sgi_mardigras.c,v 1.17 2005/02/26 11:56:42 debug Exp $
29     *
30     * "MardiGras" graphics controller on SGI IP30 (Octane).
31     *
32     * Most of this is just guesses based on the behaviour of Linux/Octane.
33     *
34     * TODO
35     */
36    
37     #include <stdio.h>
38     #include <stdlib.h>
39     #include <string.h>
40    
41     #include "cpu.h"
42     #include "device.h"
43     #include "devices.h"
44     #include "memory.h"
45     #include "machine.h"
46     #include "misc.h"
47    
48    
49     #define debug fatal
50    
51    
52     #define DEV_SGI_MARDIGRAS_LENGTH 0x800000
53    
54     #define MARDIGRAS_FAKE_OFFSET 0x500000000ULL /* hopefully available */
55     #define MARDIGRAS_DEFAULT_XSIZE 1280
56     #define MARDIGRAS_DEFAULT_YSIZE 1024
57    
58     #define MICROCODE_START 0x50000
59     #define MICROCODE_END 0x55000
60    
61     static int mardigras_xsize = MARDIGRAS_DEFAULT_XSIZE;
62     static int mardigras_ysize = MARDIGRAS_DEFAULT_YSIZE;
63    
64     struct sgi_mardigras_data {
65     struct vfb_data *fb;
66     unsigned char microcode_ram[MICROCODE_END - MICROCODE_START];
67     uint64_t palette_reg_select;
68     int currentx;
69     int currenty;
70     int color;
71     int startx;
72     int starty;
73     int stopx;
74     int stopy;
75     uint64_t draw_mode;
76     };
77    
78    
79     /*
80     * mardigras_20400():
81     */
82     void mardigras_20400(struct cpu *cpu, struct sgi_mardigras_data *d,
83     uint64_t idata)
84     {
85     int i, x, y, r,g,b, len, addr;
86     unsigned char pixels[3 * 8000];
87    
88     /* Get rgb from palette: */
89     r = d->fb->rgb_palette[d->color * 3 + 0];
90     g = d->fb->rgb_palette[d->color * 3 + 1];
91     b = d->fb->rgb_palette[d->color * 3 + 2];
92    
93     /* Set color: */
94     if ((idata & 0x00ffffff00000000ULL) == 0x00185C0400000000ULL) {
95     int color = (idata >> 12) & 0xff;
96     d->color = color;
97     return;
98     }
99    
100     /* Set start XY: */
101     if ((idata & 0x00ffffff00000000ULL) == 0x0018460400000000ULL) {
102     d->startx = (idata >> 16) & 0xffff;
103     d->starty = idata & 0xffff;
104     if (d->startx >= mardigras_xsize)
105     d->startx = 0;
106     if (d->starty >= mardigras_ysize)
107     d->starty = 0;
108     d->currentx = d->startx;
109     d->currenty = d->starty;
110     return;
111     }
112    
113     /* Set stop XY: */
114     if ((idata & 0x00ffffff00000000ULL) == 0x0018470400000000ULL) {
115     d->stopx = (idata >> 16) & 0xffff;
116     d->stopy = idata & 0xffff;
117     if (d->stopx >= mardigras_xsize)
118     d->stopx = 0;
119     if (d->stopy >= mardigras_ysize)
120     d->stopy = 0;
121     return;
122     }
123    
124     /* Draw modes: (Rectangle or Bitmap, respectively) */
125     if (idata == 0x0019100400018000ULL ||
126     idata == 0x0019100400418008ULL) {
127     d->draw_mode = idata;
128     return;
129     }
130    
131     /* Send command: */
132     if (idata == 0x001C130400000018ULL) {
133     switch (d->draw_mode) {
134     /* Rectangle: */
135     case 0x0019100400018000ULL:
136     /* Fill pixels[] with pixels: */
137     len = 0;
138     for (x=d->startx; x<=d->stopx; x++) {
139     pixels[len + 0] = r;
140     pixels[len + 1] = g;
141     pixels[len + 2] = b;
142     len += 3;
143     }
144     if (len == 0)
145     break;
146     for (y=d->starty; y<=d->stopy; y++) {
147     addr = (mardigras_xsize * (mardigras_ysize -
148     1 - y) + d->startx) * 3;
149     /* printf("addr = %i\n", addr); */
150    
151     /* Write a line: */
152     dev_fb_access(cpu, cpu->mem,
153     addr, pixels, len, MEM_WRITE, d->fb);
154     }
155     break;
156     /* Bitmap: */
157     case 0x0019100400418008ULL:
158     break;
159     default:
160     fatal("[ sgi_mardigras: unknown draw mode ]\n");
161     }
162     return;
163     }
164    
165     /* Send a line of bitmap data: */
166     if ((idata & 0x00ffffff00000000ULL) == 0x001C700400000000ULL) {
167     addr = (mardigras_xsize * (mardigras_ysize - 1 - d->currenty)
168     + d->currentx) * 3;
169     /*
170     printf("addr=%08x curx,y=%4i,%4i startx,y=%4i,%4i "
171     "stopx,y=%4i,%4i\n", addr, d->currentx, d->currenty,
172     d->startx, d->starty, d->stopx, d->stopy);
173     */
174     len = 8*3;
175    
176     if (addr > mardigras_xsize * mardigras_ysize * 3 || addr < 0)
177     return;
178    
179     /* Read a line: */
180     dev_fb_access(cpu, cpu->mem,
181     addr, pixels, len, MEM_READ, d->fb);
182    
183     i = 0;
184     while (i < 8) {
185     if ((idata >> (24 + (7-i))) & 1) {
186     pixels[i*3 + 0] = r;
187     pixels[i*3 + 1] = g;
188     pixels[i*3 + 2] = b;
189     }
190     i ++;
191    
192     d->currentx ++;
193     if (d->currentx > d->stopx) {
194     d->currentx = d->startx;
195     d->currenty ++;
196     if (d->currenty > d->stopy)
197     d->currenty = d->starty;
198     }
199     }
200    
201     /* Write a line: */
202     dev_fb_access(cpu, cpu->mem,
203     addr, pixels, len, MEM_WRITE, d->fb);
204    
205     return;
206     }
207    
208     debug("mardigras_20400(): 0x%016llx\n", (long long)idata);
209     }
210    
211    
212     /*
213     * dev_sgi_mardigras_access():
214     */
215     int dev_sgi_mardigras_access(struct cpu *cpu, struct memory *mem,
216     uint64_t relative_addr, unsigned char *data, size_t len,
217     int writeflag, void *extra)
218     {
219     uint64_t idata = 0, odata = 0;
220     struct sgi_mardigras_data *d = extra;
221     int i;
222    
223     idata = memory_readmax64(cpu, data, len);
224    
225     /* Accessing the microcode_ram works like ordinary ram: */
226     if (relative_addr >= MICROCODE_START &&
227     relative_addr < MICROCODE_END) {
228     relative_addr -= MICROCODE_START;
229     if (writeflag == MEM_WRITE)
230     memcpy(d->microcode_ram + relative_addr, data, len);
231     else
232     memcpy(data, d->microcode_ram + relative_addr, len);
233     return 1;
234     }
235    
236     switch (relative_addr) {
237     case 0x00004:
238     /* xtalk data: (according to Linux/IP30) */
239     /* (mfgr & 0x7ff) << 1 */
240     /* (part & 0xffff) << 12 */
241     /* (rev & 0xf) << 28 */
242     odata = (2 << 28) | (0xc003 << 12) | (0x2aa << 1);
243     break;
244     case 0x20008: /* Fifo status */
245     break;
246     case 0x20200:
247     break;
248     case 0x20400:
249     if (writeflag == MEM_WRITE)
250     mardigras_20400(cpu, d, idata);
251     else
252     debug("[ sgi_mardigras: read from 0x20400? ]\n");
253     break;
254     case 0x58040:
255     /* HQ4 microcode stuff */
256     break;
257     case 0x70c30:
258     /* Palette register select? */
259     if (writeflag == MEM_WRITE)
260     d->palette_reg_select = idata;
261     else
262     odata = d->palette_reg_select;
263     break;
264     case 0x70d18:
265     /* Palette register read/write? */
266     i = 3 * ((d->palette_reg_select >> 8) & 0xff);
267     if (writeflag == MEM_WRITE) {
268     d->fb->rgb_palette[i + 0] = (idata >> 24) & 0xff;
269     d->fb->rgb_palette[i + 1] = (idata >> 16) & 0xff;
270     d->fb->rgb_palette[i + 2] = (idata >> 8) & 0xff;
271     } else {
272     odata = (d->fb->rgb_palette[i+0] << 24) +
273     (d->fb->rgb_palette[i+1] << 16) +
274     (d->fb->rgb_palette[i+2] << 8);
275     }
276     break;
277     case 0x71208:
278     odata = 8;
279     break;
280     default:
281     if (writeflag==MEM_READ) {
282     debug("[ sgi_mardigras: read from 0x%08lx ]\n",
283     (long)relative_addr);
284     } else {
285     debug("[ sgi_mardigras: write to 0x%08lx: 0x%016llx"
286     " ]\n", (long)relative_addr, (long long)idata);
287     }
288     }
289    
290     if (writeflag == MEM_READ)
291     memory_writemax64(cpu, data, len, odata);
292    
293     return 1;
294     }
295    
296    
297     /*
298     * devinit_sgi_mardigras():
299     */
300     int devinit_sgi_mardigras(struct devinit *devinit)
301     {
302     struct sgi_mardigras_data *d;
303    
304     d = malloc(sizeof(struct sgi_mardigras_data));
305     if (d == NULL) {
306     fprintf(stderr, "out of memory\n");
307     exit(1);
308     }
309     memset(d, 0, sizeof(struct sgi_mardigras_data));
310    
311     d->fb = dev_fb_init(devinit->machine, devinit->machine->memory,
312     MARDIGRAS_FAKE_OFFSET, VFB_GENERIC,
313     mardigras_xsize, mardigras_ysize,
314     mardigras_xsize, mardigras_ysize, 24, "SGI MardiGras", 1);
315     if (d->fb == NULL) {
316     fprintf(stderr, "dev_sgi_mardigras_init(): out of memory\n");
317     exit(1);
318     }
319    
320     memory_device_register(devinit->machine->memory, devinit->name,
321     devinit->addr, DEV_SGI_MARDIGRAS_LENGTH, dev_sgi_mardigras_access,
322     d, MEM_DEFAULT, NULL);
323    
324     return 1;
325     }
326    

  ViewVC Help
Powered by ViewVC 1.1.26