/[gxemul]/upstream/0.3.1/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

Contents of /upstream/0.3.1/devices/dev_sgi_mardigras.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show annotations)
Mon Oct 8 16:17:52 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 8648 byte(s)
0.3.1
1 /*
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