/[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 14 by dpavlin, Mon Oct 8 16:18:51 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 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.27 2005/08/16 20:17:32 debug Exp $   *  $Id: dev_sgi_gbe.c,v 1.37 2007/06/15 19:57:34 debug Exp $
29     *
30     *  COMMENT: SGI "gbe", graphics controller + framebuffer
31   *   *
  *  SGI "gbe", graphics controller. Framebuffer.  
32   *  Loosely inspired by Linux code.   *  Loosely inspired by Linux code.
33   */   */
34    
# Line 83  struct sgi_gbe_data { Line 84  struct sgi_gbe_data {
84   *  These numbers (when << 16 bits) are pointers to the tiles. Tiles are   *  These numbers (when << 16 bits) are pointers to the tiles. Tiles are
85   *  512x128 in 8-bit mode, 256x128 in 16-bit mode, and 128x128 in 32-bit mode.   *  512x128 in 8-bit mode, 256x128 in 16-bit mode, and 128x128 in 32-bit mode.
86   */   */
87  void dev_sgi_gbe_tick(struct cpu *cpu, void *extra)  DEVICE_TICK(sgi_gbe)
88  {  {
89          struct sgi_gbe_data *d = extra;          struct sgi_gbe_data *d = extra;
90          int tile_nr = 0, on_screen = 1, xbase = 0, ybase = 0;          int tile_nr = 0, on_screen = 1, xbase = 0, ybase = 0;
# Line 96  void dev_sgi_gbe_tick(struct cpu *cpu, v Line 97  void dev_sgi_gbe_tick(struct cpu *cpu, v
97          int tweaked = 1;          int tweaked = 1;
98    
99  #ifdef MTE_TEST  #ifdef MTE_TEST
100    /*  Actually just a return, but this fools the Compaq compiler...  */
101    if (cpu != NULL)
102  return;  return;
103  #endif  #endif
104    
# Line 124  tweaked = 0; Line 127  tweaked = 0;
127                  if (tweaked) {                  if (tweaked) {
128                          /*  Tweaked (linear) mode:  */                          /*  Tweaked (linear) mode:  */
129    
130                          /*  Copy data from this 64KB physical RAM block to the framebuffer:  */                          /*
131                          /*  NOTE: Copy it in smaller chunks than 64KB, in case the framebuffer                           *  Copy data from this 64KB physical RAM block to the
132                                  device can optimize away portions that aren't modified that way  */                           *  framebuffer:
133                             *
134                             *  NOTE: Copy it in smaller chunks than 64KB, in case
135                             *        the framebuffer device can optimize away
136                             *        portions that aren't modified that way.
137                             */
138                          copy_len = sizeof(buf);                          copy_len = sizeof(buf);
139                          copy_offset = 0;                          copy_offset = 0;
140    
141                          while (on_screen && copy_offset < 65536) {                          while (on_screen && copy_offset < 65536) {
142                                  if (old_fb_offset + copy_len > d->xres * d->yres * d->bitdepth / 8) {                                  if (old_fb_offset + copy_len > (uint64_t)
143                                          copy_len = d->xres * d->yres * d->bitdepth / 8 - old_fb_offset;                                      (d->xres * d->yres * d->bitdepth / 8)) {
144                                            copy_len = d->xres * d->yres *
145                                                d->bitdepth / 8 - old_fb_offset;
146                                          /*  Stop after copying this block...  */                                          /*  Stop after copying this block...  */
147                                          on_screen = 0;                                          on_screen = 0;
148                                  }                                  }
# Line 149  tweaked = 0; Line 159  tweaked = 0;
159                                  old_fb_offset += sizeof(buf);                                  old_fb_offset += sizeof(buf);
160                          }                          }
161                  } else {                  } else {
162                          /*  This is for non-tweaked (tiled) mode. Not really tested                          /*  This is for non-tweaked (tiled) mode. Not really
163                              with correct image data, but might work:  */                              tested with correct image data, but might work:  */
164    
165                          lines_to_copy = 128;                          lines_to_copy = 128;
166                          if (ybase + lines_to_copy > d->yres)                          if (ybase + lines_to_copy > d->yres)
# Line 195  for (i=0; i<pixels_per_line * d->bitdept Line 205  for (i=0; i<pixels_per_line * d->bitdept
205  }  }
206    
207    
208  /*  DEVICE_ACCESS(sgi_gbe)
  *  dev_sgi_gbe_access():  
  */  
 int dev_sgi_gbe_access(struct cpu *cpu, struct memory *mem,  
         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 260  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 285  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 304  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 321  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 359  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 369  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 385  odata = random();      /*  testhack for the i Line 411  odata = random();      /*  testhack for the i
411  }  }
412    
413    
 /*  
  *  dev_sgi_gbe_init():  
  */  
414  void dev_sgi_gbe_init(struct machine *machine, struct memory *mem,  void dev_sgi_gbe_init(struct machine *machine, struct memory *mem,
415          uint64_t baseaddr)          uint64_t baseaddr)
416  {  {
417          struct sgi_gbe_data *d;          struct sgi_gbe_data *d;
418    
419          d = malloc(sizeof(struct sgi_gbe_data));          CHECK_ALLOCATION(d = malloc(sizeof(struct sgi_gbe_data)));
         if (d == NULL) {  
                 fprintf(stderr, "out of memory\n");  
                 exit(1);  
         }  
420          memset(d, 0, sizeof(struct sgi_gbe_data));          memset(d, 0, sizeof(struct sgi_gbe_data));
421    
422          /*  640x480 for Linux:  */          /*  640x480 for Linux:  */
# Line 414  void dev_sgi_gbe_init(struct machine *ma Line 433  void dev_sgi_gbe_init(struct machine *ma
433          set_grayscale_palette(d->fb_data, 256);          set_grayscale_palette(d->fb_data, 256);
434    
435          memory_device_register(mem, "sgi_gbe", baseaddr, DEV_SGI_GBE_LENGTH,          memory_device_register(mem, "sgi_gbe", baseaddr, DEV_SGI_GBE_LENGTH,
436              dev_sgi_gbe_access, d, MEM_DEFAULT, NULL);              dev_sgi_gbe_access, d, DM_DEFAULT, NULL);
437          machine_add_tickfunction(machine, dev_sgi_gbe_tick, d, 18);          machine_add_tickfunction(machine, dev_sgi_gbe_tick, d, 18);
438  }  }
439    

Legend:
Removed from v.14  
changed lines
  Added in v.42

  ViewVC Help
Powered by ViewVC 1.1.26