dev_sgi_mardigras.cc Source File

Back to the index.

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