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

Diff of /trunk/src/devices/dev_sgi_gbe.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 12 by dpavlin, Mon Oct 8 16:18:38 2007 UTC revision 34 by dpavlin, Mon Oct 8 16:21:17 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_sgi_gbe.c,v 1.26 2005/08/16 05:37:12 debug Exp $   *  $Id: dev_sgi_gbe.c,v 1.35 2006/12/30 13:30:59 debug Exp $
29   *   *
30   *  SGI "gbe", graphics controller. Framebuffer.   *  SGI "gbe", graphics controller. Framebuffer.
31   *  Loosely inspired by Linux code.   *  Loosely inspired by Linux code.
# Line 49  Line 49 
49  #define GBE_DEBUG  #define GBE_DEBUG
50  /*  #define debug fatal  */  /*  #define debug fatal  */
51    
52  /* #define MTE_TEST */  #define MTE_TEST
53    
54  #define GBE_DEFAULT_XRES                640  #define GBE_DEFAULT_XRES                640
55  #define GBE_DEFAULT_YRES                480  #define GBE_DEFAULT_YRES                480
# Line 96  void dev_sgi_gbe_tick(struct cpu *cpu, v Line 96  void dev_sgi_gbe_tick(struct cpu *cpu, v
96          int tweaked = 1;          int tweaked = 1;
97    
98  #ifdef MTE_TEST  #ifdef MTE_TEST
99    /*  Actually just a return, but this fools the Compaq compiler...  */
100    if (cpu != NULL)
101  return;  return;
102  #endif  #endif
103    
# Line 124  tweaked = 0; Line 126  tweaked = 0;
126                  if (tweaked) {                  if (tweaked) {
127                          /*  Tweaked (linear) mode:  */                          /*  Tweaked (linear) mode:  */
128    
129                          /*  Copy data from this 64KB physical RAM block to the framebuffer:  */                          /*
130                          /*  NOTE: Copy it in smaller chunks than 64KB, in case the framebuffer                           *  Copy data from this 64KB physical RAM block to the
131                                  device can optimize away portions that aren't modified that way  */                           *  framebuffer:
132                             *
133                             *  NOTE: Copy it in smaller chunks than 64KB, in case
134                             *        the framebuffer device can optimize away
135                             *        portions that aren't modified that way.
136                             */
137                          copy_len = sizeof(buf);                          copy_len = sizeof(buf);
138                          copy_offset = 0;                          copy_offset = 0;
139    
140                          while (on_screen && copy_offset < 65536) {                          while (on_screen && copy_offset < 65536) {
141                                  if (old_fb_offset + copy_len > d->xres * d->yres * d->bitdepth / 8) {                                  if (old_fb_offset + copy_len > (uint64_t)
142                                          copy_len = d->xres * d->yres * d->bitdepth / 8 - old_fb_offset;                                      (d->xres * d->yres * d->bitdepth / 8)) {
143                                            copy_len = d->xres * d->yres *
144                                                d->bitdepth / 8 - old_fb_offset;
145                                          /*  Stop after copying this block...  */                                          /*  Stop after copying this block...  */
146                                          on_screen = 0;                                          on_screen = 0;
147                                  }                                  }
# Line 149  tweaked = 0; Line 158  tweaked = 0;
158                                  old_fb_offset += sizeof(buf);                                  old_fb_offset += sizeof(buf);
159                          }                          }
160                  } else {                  } else {
161                          /*  This is for non-tweaked (tiled) mode. Not really tested                          /*  This is for non-tweaked (tiled) mode. Not really
162                              with correct image data, but might work:  */                              tested with correct image data, but might work:  */
163    
164                          lines_to_copy = 128;                          lines_to_copy = 128;
165                          if (ybase + lines_to_copy > d->yres)                          if (ybase + lines_to_copy > d->yres)
# Line 198  for (i=0; i<pixels_per_line * d->bitdept Line 207  for (i=0; i<pixels_per_line * d->bitdept
207  /*  /*
208   *  dev_sgi_gbe_access():   *  dev_sgi_gbe_access():
209   */   */
210  int dev_sgi_gbe_access(struct cpu *cpu, struct memory *mem,  DEVICE_ACCESS(sgi_gbe)
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
211  {  {
212          struct sgi_gbe_data *d = extra;          struct sgi_gbe_data *d = extra;
213          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
214    
215          idata = memory_readmax64(cpu, data, len);          if (writeflag == MEM_WRITE)
216                    idata = memory_readmax64(cpu, data, len);
217    
218  #ifdef GBE_DEBUG  #ifdef GBE_DEBUG
219          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
220                  debug("[ sgi_gbe: DEBUG: write to address 0x%llx, data=0x%llx ]\n", (long long)relative_addr, (long long)idata);                  debug("[ sgi_gbe: DEBUG: write to address 0x%llx, data"
221                        "=0x%llx ]\n", (long long)relative_addr, (long long)idata);
222  #endif  #endif
223    
224          switch (relative_addr) {          switch (relative_addr) {
# Line 260  int dev_sgi_gbe_access(struct cpu *cpu, Line 269  int dev_sgi_gbe_access(struct cpu *cpu,
269                  else {                  else {
270                          /*  bit 31 = freeze, 23..12 = cury, 11.0 = curx  */                          /*  bit 31 = freeze, 23..12 = cury, 11.0 = curx  */
271                          odata = ((random() % (d->yres + 10)) << 12)                          odata = ((random() % (d->yres + 10)) << 12)
272                                 + (random() % (d->xres + 10)) + (d->freeze? ((uint32_t)1 << 31) : 0);                              + (random() % (d->xres + 10)) +
273                                (d->freeze? ((uint32_t)1 << 31) : 0);
274  odata = random();       /*  testhack for the ip32 prom  */  odata = random();       /*  testhack for the ip32 prom  */
275                  }                  }
276                  break;                  break;
277    
278          case 0x10004:           /*  vt_xymax, according to Linux  */          case 0x10004:           /*  vt_xymax, according to Linux  */
279                  odata = ((d->yres-1) << 12) + d->xres-1;        /*  ... 12 bits maxy, 12 bits maxx.  */                  odata = ((d->yres-1) << 12) + d->xres-1;
280                    /*  ... 12 bits maxy, 12 bits maxx.  */
281                  break;                  break;
282    
283          case 0x10034:           /*  vt_hpixen, according to Linux  */          case 0x10034:           /*  vt_hpixen, according to Linux  */
284                  odata = (0 << 12) + d->xres-1;  /*  ... 12 bits on, 12 bits off.  */                  odata = (0 << 12) + d->xres-1;
285                    /*  ... 12 bits on, 12 bits off.  */
286                  break;                  break;
287    
288          case 0x10038:           /*  vt_vpixen, according to Linux  */          case 0x10038:           /*  vt_vpixen, according to Linux  */
289                  odata = (0 << 12) + d->yres-1;  /*  ... 12 bits on, 12 bits off.  */                  odata = (0 << 12) + d->yres-1;
290                    /*  ... 12 bits on, 12 bits off.  */
291                  break;                  break;
292    
293          case 0x20004:          case 0x20004:
# Line 285  odata = random();      /*  testhack for the i Line 298  odata = random();      /*  testhack for the i
298                  break;                  break;
299    
300          case 0x30000:   /*  normal plane ctrl 0  */          case 0x30000:   /*  normal plane ctrl 0  */
301                  /*  bit 15 = fifo reset, 14..13 = depth, 12..5 = tile width, 4..0 = rhs  */                  /*  bit 15 = fifo reset, 14..13 = depth,
302                        12..5 = tile width, 4..0 = rhs  */
303                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
304                          d->plane0ctrl = idata;                          d->plane0ctrl = idata;
305                          d->bitdepth = 8 << ((d->plane0ctrl >> 13) & 3);                          d->bitdepth = 8 << ((d->plane0ctrl >> 13) & 3);
306                          debug("[ sgi_gbe: setting color depth to %i bits ]\n", d->bitdepth);                          debug("[ sgi_gbe: setting color depth to %i bits ]\n",
307                                d->bitdepth);
308                          if (d->bitdepth != 8)                          if (d->bitdepth != 8)
309                                  fatal("sgi_gbe: warning: bitdepth %i not really implemented yet\n", d->bitdepth);                                  fatal("sgi_gbe: warning: bitdepth %i not "
310                                        "really implemented yet\n", d->bitdepth);
311                  } else                  } else
312                          odata = d->plane0ctrl;                          odata = d->plane0ctrl;
313                  break;                  break;
# Line 304  odata = random();      /*  testhack for the i Line 320  odata = random();      /*  testhack for the i
320                  break;                  break;
321    
322          case 0x3000c:   /*  normal plane ctrl 3  */          case 0x3000c:   /*  normal plane ctrl 3  */
323                  /*  Writes to 3000c should be readable back at 30008? At least bit 0 (dma)  */                  /*
324                  /*  ctrl 3: Bits 31..9 = tile table pointer bits, Bit 1 = linear, Bit 0 = dma  */                   *  Writes to 3000c should be readable back at 30008?
325                     *  At least bit 0 (dma) ctrl 3.
326                     *
327                     *  Bits 31..9 = tile table pointer bits,
328                     *  Bit 1 = linear
329                     *  Bit 0 = dma
330                     */
331                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
332                          d->frm_control = idata;                          d->frm_control = idata;
333                          debug("[ sgi_gbe: frm_control = 0x%08x ]\n", d->frm_control);                          debug("[ sgi_gbe: frm_control = 0x%08x ]\n",
334                                d->frm_control);
335                  } else                  } else
336                          odata = d->frm_control;                          odata = d->frm_control;
337                  break;                  break;
# Line 321  odata = random();      /*  testhack for the i Line 344  odata = random();      /*  testhack for the i
344                  break;                  break;
345    
346          /*          /*
347           *  Linux/sgimips seems to write color palette data to offset 0x50000 - 0x503xx,           *  Linux/sgimips seems to write color palette data to offset 0x50000
348           *  and gamma correction data to 0x60000 - 0x603ff, as 32-bit values at addresses           *  to 0x503xx, and gamma correction data to 0x60000 - 0x603ff, as
349           *  divisible by 4 (formated as 0xrrggbb00).           *  32-bit values at addresses divisible by 4 (formated as 0xrrggbb00).
350           *           *
351           *  sgio2fb: initializing           *  sgio2fb: initializing
352           *  sgio2fb: I/O at 0xffffffffb6000000           *  sgio2fb: I/O at 0xffffffffb6000000
# Line 359  odata = random();      /*  testhack for the i Line 382  odata = random();      /*  testhack for the i
382                          d->fb_data->rgb_palette[color_nr * 3 + 2] = b;                          d->fb_data->rgb_palette[color_nr * 3 + 2] = b;
383    
384                          if (r != old_r || g != old_g || b != old_b) {                          if (r != old_r || g != old_g || b != old_b) {
385                                  /*  If the palette has been changed, the entire image needs to be redrawn...  :-/  */                                  /*  If the palette has been changed, the entire
386                                        image needs to be redrawn...  :-/  */
387                                  d->fb_data->update_x1 = 0;                                  d->fb_data->update_x1 = 0;
388                                  d->fb_data->update_x2 = d->fb_data->xsize - 1;                                  d->fb_data->update_x2 = d->fb_data->xsize - 1;
389                                  d->fb_data->update_y1 = 0;                                  d->fb_data->update_y1 = 0;
# Line 369  odata = random();      /*  testhack for the i Line 393  odata = random();      /*  testhack for the i
393                  }                  }
394    
395                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
396                          debug("[ sgi_gbe: unimplemented write to address 0x%llx, data=0x%llx ]\n", (long long)relative_addr, (long long)idata);                          debug("[ sgi_gbe: unimplemented write to address "
397                                "0x%llx, data=0x%llx ]\n",
398                                (long long)relative_addr, (long long)idata);
399                  else                  else
400                          debug("[ sgi_gbe: unimplemented read from address 0x%llx ]\n", (long long)relative_addr);                          debug("[ sgi_gbe: unimplemented read from address "
401                                "0x%llx ]\n", (long long)relative_addr);
402          }          }
403    
404          if (writeflag == MEM_READ) {          if (writeflag == MEM_READ) {
405  #ifdef GBE_DEBUG  #ifdef GBE_DEBUG
406                  debug("[ sgi_gbe: DEBUG: read from address 0x%llx: 0x%llx ]\n", (long long)relative_addr, (long long)odata);                  debug("[ sgi_gbe: DEBUG: read from address 0x%llx: 0x%llx ]\n",
407                        (long long)relative_addr, (long long)odata);
408  #endif  #endif
409                  memory_writemax64(cpu, data, len, odata);                  memory_writemax64(cpu, data, len, odata);
410          }          }
# Line 399  void dev_sgi_gbe_init(struct machine *ma Line 427  void dev_sgi_gbe_init(struct machine *ma
427                  exit(1);                  exit(1);
428          }          }
429          memset(d, 0, sizeof(struct sgi_gbe_data));          memset(d, 0, sizeof(struct sgi_gbe_data));
430    
431            /*  640x480 for Linux:  */
432          d->xres = GBE_DEFAULT_XRES;          d->xres = GBE_DEFAULT_XRES;
433          d->yres = GBE_DEFAULT_YRES;          d->yres = GBE_DEFAULT_YRES;
434          d->bitdepth = 8;          d->bitdepth = 8;
 #if 0  
435          d->control = 0x20aa000;         /*  or 0x00000001?  */          d->control = 0x20aa000;         /*  or 0x00000001?  */
436  #endif  
437            /*  1280x1024 for booting the O2's PROM:  */
438            d->xres = 1280; d->yres = 1024;
439    
440          d->fb_data = dev_fb_init(machine, mem, FAKE_GBE_FB_ADDRESS,          d->fb_data = dev_fb_init(machine, mem, FAKE_GBE_FB_ADDRESS,
441              VFB_GENERIC, d->xres, d->yres, d->xres, d->yres, 8, "SGI GBE");              VFB_GENERIC, d->xres, d->yres, d->xres, d->yres, 8, "SGI GBE");
442          set_grayscale_palette(d->fb_data, 256);          set_grayscale_palette(d->fb_data, 256);
443    
444          memory_device_register(mem, "sgi_gbe", baseaddr, DEV_SGI_GBE_LENGTH,          memory_device_register(mem, "sgi_gbe", baseaddr, DEV_SGI_GBE_LENGTH,
445              dev_sgi_gbe_access, d, MEM_DEFAULT, NULL);              dev_sgi_gbe_access, d, DM_DEFAULT, NULL);
446          machine_add_tickfunction(machine, dev_sgi_gbe_tick, d, 18);          machine_add_tickfunction(machine, dev_sgi_gbe_tick, d, 18, 0.0);
447  }  }
448    

Legend:
Removed from v.12  
changed lines
  Added in v.34

  ViewVC Help
Powered by ViewVC 1.1.26