/[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 4 by dpavlin, Mon Oct 8 16:18:00 2007 UTC revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2006  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.21 2005/02/11 09:29:48 debug Exp $   *  $Id: dev_sgi_gbe.c,v 1.32 2006/01/01 13:17:17 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 47  Line 47 
47  #define FAKE_GBE_FB_ADDRESS     0x38000000  #define FAKE_GBE_FB_ADDRESS     0x38000000
48    
49  #define GBE_DEBUG  #define GBE_DEBUG
50    /*  #define debug fatal  */
51    
52    #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 87  void dev_sgi_gbe_tick(struct cpu *cpu, v Line 90  void dev_sgi_gbe_tick(struct cpu *cpu, v
90          unsigned char tileptr_buf[sizeof(uint16_t)];          unsigned char tileptr_buf[sizeof(uint16_t)];
91          uint64_t tileptr, tiletable;          uint64_t tileptr, tiletable;
92          int lines_to_copy, pixels_per_line, y;          int lines_to_copy, pixels_per_line, y;
93          unsigned char buf[16384];               /*  must be power of 2, at most 65536  */          unsigned char buf[16384];       /*  must be power of 2, at most 65536 */
94          int copy_len, copy_offset;          int copy_len, copy_offset;
95          uint64_t old_fb_offset = 0;          uint64_t old_fb_offset = 0;
96          int tweaked = 1;          int tweaked = 1;
97    
98    #ifdef MTE_TEST
99    return;
100    #endif
101    
102          /*  debug("[ sgi_gbe: dev_sgi_gbe_tick() ]\n");  */          /*  debug("[ sgi_gbe: dev_sgi_gbe_tick() ]\n");  */
103    
104          tiletable = (d->frm_control & 0xfffffe00);          tiletable = (d->frm_control & 0xfffffe00);
105          if (tiletable == 0)          if (tiletable == 0)
106                  on_screen = 0;                  on_screen = 0;
107    /*
108    tweaked = 0;
109    */
110          while (on_screen) {          while (on_screen) {
111                  /*  Get pointer to a tile:  */                  /*  Get pointer to a tile:  */
112                  cpu->memory_rw(cpu, cpu->mem, tiletable +                  cpu->memory_rw(cpu, cpu->mem, tiletable +
# Line 115  void dev_sgi_gbe_tick(struct cpu *cpu, v Line 124  void dev_sgi_gbe_tick(struct cpu *cpu, v
124                  if (tweaked) {                  if (tweaked) {
125                          /*  Tweaked (linear) mode:  */                          /*  Tweaked (linear) mode:  */
126    
127                          /*  Copy data from this 64KB physical RAM block to the framebuffer:  */                          /*
128                          /*  NOTE: Copy it in smaller chunks than 64KB, in case the framebuffer                           *  Copy data from this 64KB physical RAM block to the
129                                  device can optimize away portions that aren't modified that way  */                           *  framebuffer:
130                             *
131                             *  NOTE: Copy it in smaller chunks than 64KB, in case
132                             *        the framebuffer device can optimize away
133                             *        portions that aren't modified that way.
134                             */
135                          copy_len = sizeof(buf);                          copy_len = sizeof(buf);
136                          copy_offset = 0;                          copy_offset = 0;
137    
138                          while (on_screen && copy_offset < 65536) {                          while (on_screen && copy_offset < 65536) {
139                                  if (old_fb_offset + copy_len > d->xres * d->yres * d->bitdepth / 8) {                                  if (old_fb_offset + copy_len > (uint64_t)
140                                          copy_len = d->xres * d->yres * d->bitdepth / 8 - old_fb_offset;                                      (d->xres * d->yres * d->bitdepth / 8)) {
141                                            copy_len = d->xres * d->yres *
142                                                d->bitdepth / 8 - old_fb_offset;
143                                          /*  Stop after copying this block...  */                                          /*  Stop after copying this block...  */
144                                          on_screen = 0;                                          on_screen = 0;
145                                  }                                  }
# Line 140  void dev_sgi_gbe_tick(struct cpu *cpu, v Line 156  void dev_sgi_gbe_tick(struct cpu *cpu, v
156                                  old_fb_offset += sizeof(buf);                                  old_fb_offset += sizeof(buf);
157                          }                          }
158                  } else {                  } else {
159                          /*  This is for non-tweaked (tiled) mode. Not really tested                          /*  This is for non-tweaked (tiled) mode. Not really
160                              with correct image data, but might work:  */                              tested with correct image data, but might work:  */
161    
162                          lines_to_copy = 128;                          lines_to_copy = 128;
163                          if (ybase + lines_to_copy > d->yres)                          if (ybase + lines_to_copy > d->yres)
# Line 155  void dev_sgi_gbe_tick(struct cpu *cpu, v Line 171  void dev_sgi_gbe_tick(struct cpu *cpu, v
171                                  cpu->memory_rw(cpu, cpu->mem, tileptr + 512 * y,                                  cpu->memory_rw(cpu, cpu->mem, tileptr + 512 * y,
172                                      buf, pixels_per_line * d->bitdepth / 8,                                      buf, pixels_per_line * d->bitdepth / 8,
173                                      MEM_READ, NO_EXCEPTIONS | PHYSICAL);                                      MEM_READ, NO_EXCEPTIONS | PHYSICAL);
174    #if 0
175    {
176    int i;
177    for (i=0; i<pixels_per_line * d->bitdepth / 8; i++)
178            buf[i] ^= (random() & 0x20);
179    }
180    #endif
181                                  dev_fb_access(cpu, cpu->mem, ((ybase + y) *                                  dev_fb_access(cpu, cpu->mem, ((ybase + y) *
182                                      d->xres + xbase) * d->bitdepth / 8,                                      d->xres + xbase) * d->bitdepth / 8,
183                                      buf, pixels_per_line * d->bitdepth / 8,                                      buf, pixels_per_line * d->bitdepth / 8,
# Line 183  void dev_sgi_gbe_tick(struct cpu *cpu, v Line 205  void dev_sgi_gbe_tick(struct cpu *cpu, v
205  /*  /*
206   *  dev_sgi_gbe_access():   *  dev_sgi_gbe_access():
207   */   */
208  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)  
209  {  {
210          struct sgi_gbe_data *d = extra;          struct sgi_gbe_data *d = extra;
211          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
212    
213          idata = memory_readmax64(cpu, data, len);          if (writeflag == MEM_WRITE)
214                    idata = memory_readmax64(cpu, data, len);
215    
216  #ifdef GBE_DEBUG  #ifdef GBE_DEBUG
217          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
218                  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"
219                        "=0x%llx ]\n", (long long)relative_addr, (long long)idata);
220  #endif  #endif
221    
222          switch (relative_addr) {          switch (relative_addr) {
# Line 245  int dev_sgi_gbe_access(struct cpu *cpu, Line 267  int dev_sgi_gbe_access(struct cpu *cpu,
267                  else {                  else {
268                          /*  bit 31 = freeze, 23..12 = cury, 11.0 = curx  */                          /*  bit 31 = freeze, 23..12 = cury, 11.0 = curx  */
269                          odata = ((random() % (d->yres + 10)) << 12)                          odata = ((random() % (d->yres + 10)) << 12)
270                                 + (random() % (d->xres + 10)) + (d->freeze? ((uint32_t)1 << 31) : 0);                              + (random() % (d->xres + 10)) +
271                                (d->freeze? ((uint32_t)1 << 31) : 0);
272  odata = random();       /*  testhack for the ip32 prom  */  odata = random();       /*  testhack for the ip32 prom  */
273                  }                  }
274                  break;                  break;
275    
276          case 0x10004:           /*  vt_xymax, according to Linux  */          case 0x10004:           /*  vt_xymax, according to Linux  */
277                  odata = ((d->yres-1) << 12) + d->xres-1;        /*  ... 12 bits maxy, 12 bits maxx.  */                  odata = ((d->yres-1) << 12) + d->xres-1;
278                    /*  ... 12 bits maxy, 12 bits maxx.  */
279                  break;                  break;
280    
281          case 0x10034:           /*  vt_hpixen, according to Linux  */          case 0x10034:           /*  vt_hpixen, according to Linux  */
282                  odata = (0 << 12) + d->xres-1;  /*  ... 12 bits on, 12 bits off.  */                  odata = (0 << 12) + d->xres-1;
283                    /*  ... 12 bits on, 12 bits off.  */
284                  break;                  break;
285    
286          case 0x10038:           /*  vt_vpixen, according to Linux  */          case 0x10038:           /*  vt_vpixen, according to Linux  */
287                  odata = (0 << 12) + d->yres-1;  /*  ... 12 bits on, 12 bits off.  */                  odata = (0 << 12) + d->yres-1;
288                    /*  ... 12 bits on, 12 bits off.  */
289                  break;                  break;
290    
291          case 0x20004:          case 0x20004:
# Line 270  odata = random();      /*  testhack for the i Line 296  odata = random();      /*  testhack for the i
296                  break;                  break;
297    
298          case 0x30000:   /*  normal plane ctrl 0  */          case 0x30000:   /*  normal plane ctrl 0  */
299                  /*  bit 15 = fifo reset, 14..13 = depth, 12..5 = tile width, 4..0 = rhs  */                  /*  bit 15 = fifo reset, 14..13 = depth,
300                        12..5 = tile width, 4..0 = rhs  */
301                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
302                          d->plane0ctrl = idata;                          d->plane0ctrl = idata;
303                          d->bitdepth = 8 << ((d->plane0ctrl >> 13) & 3);                          d->bitdepth = 8 << ((d->plane0ctrl >> 13) & 3);
304                          debug("[ sgi_gbe: setting color depth to %i bits ]\n", d->bitdepth);                          debug("[ sgi_gbe: setting color depth to %i bits ]\n",
305                                d->bitdepth);
306                          if (d->bitdepth != 8)                          if (d->bitdepth != 8)
307                                  fatal("sgi_gbe: warning: bitdepth %i not really implemented yet\n", d->bitdepth);                                  fatal("sgi_gbe: warning: bitdepth %i not "
308                                        "really implemented yet\n", d->bitdepth);
309                  } else                  } else
310                          odata = d->plane0ctrl;                          odata = d->plane0ctrl;
311                  break;                  break;
# Line 289  odata = random();      /*  testhack for the i Line 318  odata = random();      /*  testhack for the i
318                  break;                  break;
319    
320          case 0x3000c:   /*  normal plane ctrl 3  */          case 0x3000c:   /*  normal plane ctrl 3  */
321                  /*  Writes to 3000c should be readable back at 30008? At least bit 0 (dma)  */                  /*
322                  /*  ctrl 3: Bits 31..9 = tile table pointer bits, Bit 1 = linear, Bit 0 = dma  */                   *  Writes to 3000c should be readable back at 30008?
323                     *  At least bit 0 (dma) ctrl 3.
324                     *
325                     *  Bits 31..9 = tile table pointer bits,
326                     *  Bit 1 = linear
327                     *  Bit 0 = dma
328                     */
329                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
330                          d->frm_control = idata;                          d->frm_control = idata;
331                          debug("[ sgi_gbe: frm_control = 0x%08x ]\n", d->frm_control);                          debug("[ sgi_gbe: frm_control = 0x%08x ]\n",
332                                d->frm_control);
333                  } else                  } else
334                          odata = d->frm_control;                          odata = d->frm_control;
335                  break;                  break;
# Line 306  odata = random();      /*  testhack for the i Line 342  odata = random();      /*  testhack for the i
342                  break;                  break;
343    
344          /*          /*
345           *  Linux/sgimips seems to write color palette data to offset 0x50000 - 0x503xx,           *  Linux/sgimips seems to write color palette data to offset 0x50000
346           *  and gamma correction data to 0x60000 - 0x603ff, as 32-bit values at addresses           *  to 0x503xx, and gamma correction data to 0x60000 - 0x603ff, as
347           *  divisible by 4 (formated as 0xrrggbb00).           *  32-bit values at addresses divisible by 4 (formated as 0xrrggbb00).
348           *           *
349           *  sgio2fb: initializing           *  sgio2fb: initializing
350           *  sgio2fb: I/O at 0xffffffffb6000000           *  sgio2fb: I/O at 0xffffffffb6000000
# Line 344  odata = random();      /*  testhack for the i Line 380  odata = random();      /*  testhack for the i
380                          d->fb_data->rgb_palette[color_nr * 3 + 2] = b;                          d->fb_data->rgb_palette[color_nr * 3 + 2] = b;
381    
382                          if (r != old_r || g != old_g || b != old_b) {                          if (r != old_r || g != old_g || b != old_b) {
383                                  /*  If the palette has been changed, the entire image needs to be redrawn...  :-/  */                                  /*  If the palette has been changed, the entire
384                                        image needs to be redrawn...  :-/  */
385                                  d->fb_data->update_x1 = 0;                                  d->fb_data->update_x1 = 0;
386                                  d->fb_data->update_x2 = d->fb_data->xsize - 1;                                  d->fb_data->update_x2 = d->fb_data->xsize - 1;
387                                  d->fb_data->update_y1 = 0;                                  d->fb_data->update_y1 = 0;
# Line 354  odata = random();      /*  testhack for the i Line 391  odata = random();      /*  testhack for the i
391                  }                  }
392    
393                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
394                          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 "
395                                "0x%llx, data=0x%llx ]\n",
396                                (long long)relative_addr, (long long)idata);
397                  else                  else
398                          debug("[ sgi_gbe: unimplemented read from address 0x%llx ]\n", (long long)relative_addr);                          debug("[ sgi_gbe: unimplemented read from address "
399                                "0x%llx ]\n", (long long)relative_addr);
400          }          }
401    
402          if (writeflag == MEM_READ) {          if (writeflag == MEM_READ) {
403  #ifdef GBE_DEBUG  #ifdef GBE_DEBUG
404                  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",
405                        (long long)relative_addr, (long long)odata);
406  #endif  #endif
407                  memory_writemax64(cpu, data, len, odata);                  memory_writemax64(cpu, data, len, odata);
408          }          }
# Line 384  void dev_sgi_gbe_init(struct machine *ma Line 425  void dev_sgi_gbe_init(struct machine *ma
425                  exit(1);                  exit(1);
426          }          }
427          memset(d, 0, sizeof(struct sgi_gbe_data));          memset(d, 0, sizeof(struct sgi_gbe_data));
428    
429            /*  640x480 for Linux:  */
430          d->xres = GBE_DEFAULT_XRES;          d->xres = GBE_DEFAULT_XRES;
431          d->yres = GBE_DEFAULT_YRES;          d->yres = GBE_DEFAULT_YRES;
432          d->bitdepth = 8;          d->bitdepth = 8;
433          d->control = 0x20aa000;         /*  or 0x00000001?  */          d->control = 0x20aa000;         /*  or 0x00000001?  */
434    
435            /*  1280x1024 for booting the O2's PROM:  */
436            d->xres = 1280; d->yres = 1024;
437    
438          d->fb_data = dev_fb_init(machine, mem, FAKE_GBE_FB_ADDRESS,          d->fb_data = dev_fb_init(machine, mem, FAKE_GBE_FB_ADDRESS,
439              VFB_GENERIC, d->xres, d->yres, d->xres, d->yres, 8, "SGI GBE", 0);              VFB_GENERIC, d->xres, d->yres, d->xres, d->yres, 8, "SGI GBE");
440          set_grayscale_palette(d->fb_data, 256);          set_grayscale_palette(d->fb_data, 256);
441    
442          memory_device_register(mem, "sgi_gbe", baseaddr, DEV_SGI_GBE_LENGTH,          memory_device_register(mem, "sgi_gbe", baseaddr, DEV_SGI_GBE_LENGTH,
443              dev_sgi_gbe_access, d, MEM_DEFAULT, NULL);              dev_sgi_gbe_access, d, DM_DEFAULT, NULL);
444          machine_add_tickfunction(machine, dev_sgi_gbe_tick, d, 18);          machine_add_tickfunction(machine, dev_sgi_gbe_tick, d, 18);
445  }  }
446    

Legend:
Removed from v.4  
changed lines
  Added in v.22

  ViewVC Help
Powered by ViewVC 1.1.26