/[gxemul]/trunk/src/devices/dev_fb.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_fb.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 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_fb.c,v 1.90 2005/03/29 09:46:06 debug Exp $   *  $Id: dev_fb.c,v 1.110 2005/11/13 00:14:08 debug Exp $
29   *     *  
30   *  Generic framebuffer device.   *  Generic framebuffer device.
31   *   *
32   *      DECstation VFB01 monochrome framebuffer, 1024x864   *      DECstation VFB01 monochrome framebuffer, 1024x864
33   *      DECstation VFB02 8-bit color framebuffer, 1024x864   *      DECstation VFB02 8-bit color framebuffer, 1024x864
34   *      DECstation Maxine, 1024x768 8-bit color   *      DECstation Maxine, 1024x768 8-bit color
35   *      HPCmips framebuffer   *      HPC (mips, arm, ..) framebuffer
36   *      Playstation 2 (24-bit color)   *      Playstation 2 (24-bit color)
37   *      generic (any resolution, several bit depths possible)   *      generic (any resolution, several bit depths possible)
38   *   *
# Line 67  Line 67 
67    
68  #define FB_TICK_SHIFT           18  #define FB_TICK_SHIFT           18
69    
 #define LOGO_XSIZE              256  
 #define LOGO_YSIZE              256  
 #define LOGO_BOTTOM_MARGIN      60  
 /*  This must be a 256*256 pixels P4 ppm:  */  
 #include "fb_logo.c"  
 unsigned char *fb_logo = fb_logo_ppm + 11;  
   
70    
71  /*  #define FB_DEBUG  */  /*  #define FB_DEBUG  */
72    
# Line 115  void set_blackwhite_palette(struct vfb_d Line 108  void set_blackwhite_palette(struct vfb_d
108    
109    
110  /*  /*
111     *  dev_fb_resize():
112     *
113     *  Resize a framebuffer window. (This functionality is probably a bit buggy,
114     *  because I didn't think of including it from the start.)
115     */
116    void dev_fb_resize(struct vfb_data *d, int new_xsize, int new_ysize)
117    {
118            unsigned char *new_framebuffer;
119            int y, new_bytes_per_line;
120            size_t size;
121    
122            if (d == NULL) {
123                    fatal("dev_fb_resize(): d == NULL\n");
124                    return;
125            }
126    
127            new_bytes_per_line = new_xsize * d->bit_depth / 8;
128            size = new_ysize * new_bytes_per_line;
129    
130            new_framebuffer = malloc(size);
131            if (new_framebuffer == NULL) {
132                    fprintf(stderr, "dev_fb_resize(): out of memory\n");
133                    exit(1);
134            }
135    
136            /*  Copy the old framebuffer to the new:  */
137            if (d->framebuffer != NULL) {
138                    for (y=0; y<new_ysize; y++) {
139                            size_t fromofs = d->bytes_per_line * y;
140                            size_t toofs = new_bytes_per_line * y;
141                            size_t len_to_copy = d->bytes_per_line <
142                                new_bytes_per_line? d->bytes_per_line      
143                                : new_bytes_per_line;
144                            memset(new_framebuffer + toofs, 0, new_bytes_per_line);
145                            if (y < d->x11_ysize)
146                                    memmove(new_framebuffer + toofs,
147                                        d->framebuffer + fromofs, len_to_copy);
148                    }
149    
150                    free(d->framebuffer);
151            }
152    
153            d->framebuffer = new_framebuffer;
154            d->framebuffer_size = size;
155    
156            if (new_xsize > d->x11_xsize || new_ysize > d->x11_ysize) {
157                    d->update_x1 = d->update_y1 = 0;
158                    d->update_x2 = new_xsize - 1;
159                    d->update_y2 = new_ysize - 1;
160            }
161    
162            d->bytes_per_line = new_bytes_per_line;
163            d->x11_xsize = d->visible_xsize = new_xsize;
164            d->x11_ysize = d->visible_ysize = new_ysize;
165    
166    #ifdef WITH_X11
167            if (d->fb_window != NULL)
168                    x11_fb_resize(d->fb_window, new_xsize, new_ysize);
169    #endif
170    }
171    
172    
173    /*
174   *  dev_fb_setcursor():   *  dev_fb_setcursor():
175   */   */
176  void dev_fb_setcursor(struct vfb_data *d, int cursor_x, int cursor_y, int on,  void dev_fb_setcursor(struct vfb_data *d, int cursor_x, int cursor_y, int on,
# Line 235  void framebuffer_blockcopyfill(struct vf Line 291  void framebuffer_blockcopyfill(struct vf
291    
292  #ifdef WITH_X11  #ifdef WITH_X11
293  #define macro_put_pixel() {     \  #define macro_put_pixel() {     \
294                          /*  Combine the color into an X11 long and display it:  */      \          /*  Combine the color into an X11 long and display it:  */      \
295                          /*  TODO:  construct color in a more portable way:  */          \          /*  TODO:  construct color in a more portable way:  */          \
296                          switch (d->fb_window->x11_screen_depth) {                                       \          switch (d->fb_window->x11_screen_depth) {                       \
297                          case 24:                                                        \          case 24:                                                        \
298                                  if (d->fb_window->fb_ximage->byte_order)                \                  if (d->fb_window->fb_ximage->byte_order)                \
299                                          color = (b << 16) + (g << 8) + r;               \                          color = (b << 16) + (g << 8) + r;               \
300                                  else                                                    \                  else                                                    \
301                                          color = (r << 16) + (g << 8) + b;               \                          color = (r << 16) + (g << 8) + b;               \
302                                  break;                                                  \                  break;                                                  \
303                          case 16:                                                        \          case 16:                                                        \
304                                  r >>= 3; g >>= 2; b >>= 3;                              \                  r >>= 3; g >>= 2; b >>= 3;                              \
305                                  if (d->fb_window->fb_ximage->byte_order) {              \                  if (d->fb_window->fb_ximage->byte_order) {              \
306                                          /*  Big endian 16-bit X server:  */             \                          /*  Big endian 16-bit X server:  */             \
307                                          static int first = 1;                           \                          static int first = 1;                           \
308                                          if (first) {                                    \                          if (first) {                                    \
309                                                  fprintf(stderr, "\n*** Please report to the author whether 16-bit X11 colors are rendered correctly or not!\n\n"); \                                  fprintf(stderr, "\n*** Please report "  \
310                                                  first = 0;                              \                                      "to the author whether 16-bit X11 " \
311                                          }                                               \                                      "colors are rendered correctly or " \
312                                          color = (b << 11) + (g << 5) + r;               \                                      "not!\n\n");                        \
313                                  } else {                                                \                                  first = 0;                              \
314                                          /*  Little endian (eg PC) X servers:  */        \                          }                                               \
315                                          color = (r << 11) + (g << 5) + b;               \                          color = (b << 11) + (g << 5) + r;               \
316                                  }                                                       \                  } else {                                                \
317                                  break;                                                  \                          /*  Little endian (eg PC) X servers:  */        \
318                          case 15:                                                        \                          color = (r << 11) + (g << 5) + b;               \
319                                  r >>= 3; g >>= 3; b >>= 3;                              \                  }                                                       \
320                                  if (d->fb_window->fb_ximage->byte_order) {              \                  break;                                                  \
321                                          /*  Big endian 15-bit X server:  */             \          case 15:                                                        \
322                                          static int first = 1;                           \                  r >>= 3; g >>= 3; b >>= 3;                              \
323                                          if (first) {                                    \                  if (d->fb_window->fb_ximage->byte_order) {              \
324                                                  fprintf(stderr, "\n*** Please report to the author whether 15-bit X11 colors are rendered correctly or not!\n\n"); \                          /*  Big endian 15-bit X server:  */             \
325                                                  first = 0;                              \                          static int first = 1;                           \
326                                          }                                               \                          if (first) {                                    \
327                                          color = (b << 10) + (g << 5) + r;               \                                  fprintf(stderr, "\n*** Please report "  \
328                                  } else {                                                \                                      "to the author whether 15-bit X11 " \
329                                          /*  Little endian (eg PC) X servers:  */        \                                      "colors are rendered correctly or " \
330                                          color = (r << 10) + (g << 5) + b;               \                                      "not!\n\n");                        \
331                                  }                                                       \                                  first = 0;                              \
332                                  break;                                                  \                          }                                               \
333                          default:                                                        \                          color = (b << 10) + (g << 5) + r;               \
334                                  color = d->fb_window->x11_graycolor[15 * (r + g + b) / (255 * 3)].pixel; \                  } else {                                                \
335                          }                                                               \                          /*  Little endian (eg PC) X servers:  */        \
336                          if (x>=0 && x<d->x11_xsize && y>=0 && y<d->x11_ysize)           \                          color = (r << 10) + (g << 5) + b;               \
337                                  XPutPixel(d->fb_window->fb_ximage, x, y, color);        \                  }                                                       \
338                  }                  break;                                                  \
339            default:                                                        \
340                    color = d->fb_window->x11_graycolor[15 * (r + g + b)    \
341                        / (255 * 3)].pixel;                                 \
342            }                                                               \
343            if (x>=0 && x<d->x11_xsize && y>=0 && y<d->x11_ysize)           \
344                    XPutPixel(d->fb_window->fb_ximage, x, y, color);        \
345        }
346  #else  #else
347  /*  If not WITH_X11:  */  /*  If not WITH_X11:  */
348  #define macro_put_pixel() { }  #define macro_put_pixel() { }
# Line 325  void update_framebuffer(struct vfb_data Line 388  void update_framebuffer(struct vfb_data
388                                  c = d->framebuffer[fb_addr >> 3];                                  c = d->framebuffer[fb_addr >> 3];
389                                  fb_addr &= 7;                                  fb_addr &= 7;
390    
391                                  /*  HPCmips is reverse:  */                                  /*  HPC is reverse:  */
392                                  if (d->vfb_type == VFB_HPCMIPS)                                  if (d->vfb_type == VFB_HPC)
393                                          fb_addr = 8 - d->bit_depth - fb_addr;                                          fb_addr = 8 - d->bit_depth - fb_addr;
394    
395                                  c = (c >> fb_addr) & ((1<<d->bit_depth) - 1);                                  c = (c >> fb_addr) & ((1<<d->bit_depth) - 1);
# Line 372  void update_framebuffer(struct vfb_data Line 435  void update_framebuffer(struct vfb_data
435                                          break;                                          break;
436                                  /*  TODO: copy to the scaledown code below  */                                  /*  TODO: copy to the scaledown code below  */
437                                  case 16:                                  case 16:
438                                          if (d->vfb_type == VFB_HPCMIPS) {                                          if (d->vfb_type == VFB_HPC) {
439                                                  b = d->framebuffer[fb_addr] +                                                  b = d->framebuffer[fb_addr] +
440                                                      (d->framebuffer[fb_addr+1] << 8);                                                      (d->framebuffer[fb_addr+1]
441                                                        << 8);
442    
443                                                  if (d->color32k) {                                                  if (d->color32k) {
444                                                          r = b >> 11;                                                          r = b >> 11;
# Line 382  void update_framebuffer(struct vfb_data Line 446  void update_framebuffer(struct vfb_data
446                                                          r = r & 31;                                                          r = r & 31;
447                                                          g = (g & 31) * 2;                                                          g = (g & 31) * 2;
448                                                          b = b & 31;                                                          b = b & 31;
449                                                    } else if (d->psp_15bit) {
450                                                            int tmp;
451                                                            r = (b >> 10) & 0x1f;
452                                                            g = (b >>  5) & 0x1f;
453                                                            b = b & 0x1f;
454                                                            g <<= 1;
455                                                            tmp = r; r = b; b = tmp;
456                                                  } else {                                                  } else {
457                                                          r = (b >> 11) & 0x1f;                                                          r = (b >> 11) & 0x1f;
458                                                          g = (b >>  5) & 0x3f;                                                          g = (b >>  5) & 0x3f;
459                                                          b = b & 0x1f;                                                          b = b & 0x1f;
460                                                  }                                                  }
461                                          } else {                                          } else {
462                                                  r = d->framebuffer[fb_addr] >> 3;                                              r = d->framebuffer[fb_addr] >> 3;
463                                                  g = (d->framebuffer[fb_addr] << 5) +                                              g = (d->framebuffer[fb_addr] << 5) +
464                                                      (d->framebuffer[fb_addr + 1] >> 5);                                                (d->framebuffer[fb_addr + 1] >>5);
465                                                  b = d->framebuffer[fb_addr + 1] & 0x1f;                                              b = d->framebuffer[fb_addr + 1]&31;
466                                          }                                          }
467    
468                                          r *= 8;                                          r *= 8;
# Line 410  void update_framebuffer(struct vfb_data Line 481  void update_framebuffer(struct vfb_data
481                  return;                  return;
482          }          }
483    
484          /*  scaledown != 1:  */          /*  scaledown > 1:  */
485    
486          scaledown = d->vfb_scaledown;          scaledown = d->vfb_scaledown;
487          scaledownXscaledown = scaledown * scaledown;          scaledownXscaledown = scaledown * scaledown;
# Line 450  void update_framebuffer(struct vfb_data Line 521  void update_framebuffer(struct vfb_data
521                                  c = d->framebuffer[fb_addr >> 3];                                  c = d->framebuffer[fb_addr >> 3];
522                                  fb_addr &= 7;                                  fb_addr &= 7;
523    
524                                  /*  HPCmips is reverse:  */                                  /*  HPC is reverse:  */
525                                  if (d->vfb_type == VFB_HPCMIPS)                                  if (d->vfb_type == VFB_HPC)
526                                          fb_addr = 8 - d->bit_depth - fb_addr;                                          fb_addr = 8 - d->bit_depth - fb_addr;
527    
528                                  c = (c >> fb_addr) & ((1<<d->bit_depth) - 1);                                  c = (c >> fb_addr) & ((1<<d->bit_depth) - 1);
# Line 553  void dev_fb_tick(struct cpu *cpu, void * Line 624  void dev_fb_tick(struct cpu *cpu, void *
624          if (!cpu->machine->use_x11)          if (!cpu->machine->use_x11)
625                  return;                  return;
626    
 #ifdef BINTRANS  
627          do {          do {
628                  uint64_t low = -1, high;                  uint64_t high, low = (uint64_t)(int64_t) -1;
629                  int x, y;                  int x, y;
630    
631                  memory_device_bintrans_access(cpu, cpu->mem,                  memory_device_dyntrans_access(cpu, cpu->mem,
632                      extra, &low, &high);                      extra, &low, &high);
633                  if ((int64_t)low == -1)                  if ((int64_t)low == -1)
634                          break;                          break;
# Line 619  void dev_fb_tick(struct cpu *cpu, void * Line 689  void dev_fb_tick(struct cpu *cpu, void *
689                          d->update_x2 = d->xsize-1;                          d->update_x2 = d->xsize-1;
690                  }                  }
691          } while (0);          } while (0);
 #endif  
692    
693  #ifdef WITH_X11  #ifdef WITH_X11
694          /*  Do we need to redraw the cursor?  */          /*  Do we need to redraw the cursor?  */
# Line 631  void dev_fb_tick(struct cpu *cpu, void * Line 700  void dev_fb_tick(struct cpu *cpu, void *
700                  need_to_redraw_cursor = 1;                  need_to_redraw_cursor = 1;
701    
702          if (d->update_x2 != -1) {          if (d->update_x2 != -1) {
703                  if ( (d->update_x1 >= d->fb_window->OLD_cursor_x &&                  if (((d->update_x1 >= d->fb_window->OLD_cursor_x &&
704                        d->update_x1 < (d->fb_window->OLD_cursor_x + d->fb_window->OLD_cursor_xsize)) ||                        d->update_x1 < (d->fb_window->OLD_cursor_x +
705                          d->fb_window->OLD_cursor_xsize)) ||
706                       (d->update_x2 >= d->fb_window->OLD_cursor_x &&                       (d->update_x2 >= d->fb_window->OLD_cursor_x &&
707                        d->update_x2 < (d->fb_window->OLD_cursor_x + d->fb_window->OLD_cursor_xsize)) ||                        d->update_x2 < (d->fb_window->OLD_cursor_x +
708                          d->fb_window->OLD_cursor_xsize)) ||
709                       (d->update_x1 <  d->fb_window->OLD_cursor_x &&                       (d->update_x1 <  d->fb_window->OLD_cursor_x &&
710                        d->update_x2 >= (d->fb_window->OLD_cursor_x + d->fb_window->OLD_cursor_xsize)) ) {                        d->update_x2 >= (d->fb_window->OLD_cursor_x +
711                          if ( (d->update_y1 >= d->fb_window->OLD_cursor_y &&                        d->fb_window->OLD_cursor_xsize)) ) &&
712                                d->update_y1 < (d->fb_window->OLD_cursor_y + d->fb_window->OLD_cursor_ysize)) ||                     ( (d->update_y1 >= d->fb_window->OLD_cursor_y &&
713                               (d->update_y2 >= d->fb_window->OLD_cursor_y &&                        d->update_y1 < (d->fb_window->OLD_cursor_y +
714                                d->update_y2 < (d->fb_window->OLD_cursor_y + d->fb_window->OLD_cursor_ysize)) ||                        d->fb_window->OLD_cursor_ysize)) ||
715                               (d->update_y1 <  d->fb_window->OLD_cursor_y &&                       (d->update_y2 >= d->fb_window->OLD_cursor_y &&
716                                d->update_y2 >= (d->fb_window->OLD_cursor_y + d->fb_window->OLD_cursor_ysize)) )                        d->update_y2 < (d->fb_window->OLD_cursor_y +
717                                  need_to_redraw_cursor = 1;                        d->fb_window->OLD_cursor_ysize)) ||
718                  }                       (d->update_y1 <  d->fb_window->OLD_cursor_y &&
719                          d->update_y2 >= (d->fb_window->OLD_cursor_y +
720                         d->fb_window->OLD_cursor_ysize)) ) )
721                            need_to_redraw_cursor = 1;
722          }          }
723    
724          if (need_to_redraw_cursor) {          if (need_to_redraw_cursor) {
# Line 658  void dev_fb_tick(struct cpu *cpu, void * Line 732  void dev_fb_tick(struct cpu *cpu, void *
732                              d->fb_window->OLD_cursor_x/d->vfb_scaledown,                              d->fb_window->OLD_cursor_x/d->vfb_scaledown,
733                              d->fb_window->OLD_cursor_y/d->vfb_scaledown,                              d->fb_window->OLD_cursor_y/d->vfb_scaledown,
734                              d->fb_window->OLD_cursor_xsize/d->vfb_scaledown + 1,                              d->fb_window->OLD_cursor_xsize/d->vfb_scaledown + 1,
735                              d->fb_window->OLD_cursor_ysize/d->vfb_scaledown + 1);                              d->fb_window->OLD_cursor_ysize/d->vfb_scaledown +1);
736                  }                  }
737          }          }
738  #endif  #endif
# Line 666  void dev_fb_tick(struct cpu *cpu, void * Line 740  void dev_fb_tick(struct cpu *cpu, void *
740          if (d->update_x2 != -1) {          if (d->update_x2 != -1) {
741                  int y, addr, addr2, q = d->vfb_scaledown;                  int y, addr, addr2, q = d->vfb_scaledown;
742    
743                  if (d->update_x1 >= d->visible_xsize)   d->update_x1 = d->visible_xsize - 1;                  if (d->update_x1 >= d->visible_xsize)
744                  if (d->update_x2 >= d->visible_xsize)   d->update_x2 = d->visible_xsize - 1;                          d->update_x1 = d->visible_xsize - 1;
745                  if (d->update_y1 >= d->visible_ysize)   d->update_y1 = d->visible_ysize - 1;                  if (d->update_x2 >= d->visible_xsize)
746                  if (d->update_y2 >= d->visible_ysize)   d->update_y2 = d->visible_ysize - 1;                          d->update_x2 = d->visible_xsize - 1;
747                    if (d->update_y1 >= d->visible_ysize)
748                            d->update_y1 = d->visible_ysize - 1;
749                    if (d->update_y2 >= d->visible_ysize)
750                            d->update_y2 = d->visible_ysize - 1;
751    
752                  /*  Without these, we might miss the right most / bottom pixel:  */                  /*  Without these, we might miss the rightmost/bottom pixel:  */
753                  d->update_x2 += (q - 1);                  d->update_x2 += (q - 1);
754                  d->update_y2 += (q - 1);                  d->update_y2 += (q - 1);
755    
# Line 680  void dev_fb_tick(struct cpu *cpu, void * Line 758  void dev_fb_tick(struct cpu *cpu, void *
758                  d->update_y1 = d->update_y1 / q * q;                  d->update_y1 = d->update_y1 / q * q;
759                  d->update_y2 = d->update_y2 / q * q;                  d->update_y2 = d->update_y2 / q * q;
760    
761                  addr  = d->update_y1 * d->bytes_per_line + d->update_x1 * d->bit_depth / 8;                  addr  = d->update_y1 * d->bytes_per_line +
762                  addr2 = d->update_y1 * d->bytes_per_line + d->update_x2 * d->bit_depth / 8;                      d->update_x1 * d->bit_depth / 8;
763                    addr2 = d->update_y1 * d->bytes_per_line +
764                        d->update_x2 * d->bit_depth / 8;
765    
766                  for (y=d->update_y1; y<=d->update_y2; y+=q) {                  for (y=d->update_y1; y<=d->update_y2; y+=q) {
767                          update_framebuffer(d, addr, addr2 - addr);                          update_framebuffer(d, addr, addr2 - addr);
# Line 690  void dev_fb_tick(struct cpu *cpu, void * Line 770  void dev_fb_tick(struct cpu *cpu, void *
770                  }                  }
771    
772  #ifdef WITH_X11  #ifdef WITH_X11
773                  XPutImage(d->fb_window->x11_display, d->fb_window->x11_fb_window, d->fb_window->x11_fb_gc, d->fb_window->fb_ximage,                  XPutImage(d->fb_window->x11_display, d->fb_window->
774                      d->update_x1/d->vfb_scaledown, d->update_y1/d->vfb_scaledown,                      x11_fb_window, d->fb_window->x11_fb_gc, d->fb_window->
775                      d->update_x1/d->vfb_scaledown, d->update_y1/d->vfb_scaledown,                      fb_ximage, d->update_x1/d->vfb_scaledown, d->update_y1/
776                        d->vfb_scaledown, d->update_x1/d->vfb_scaledown,
777                        d->update_y1/d->vfb_scaledown,
778                      (d->update_x2 - d->update_x1)/d->vfb_scaledown + 1,                      (d->update_x2 - d->update_x1)/d->vfb_scaledown + 1,
779                      (d->update_y2 - d->update_y1)/d->vfb_scaledown + 1);                      (d->update_y2 - d->update_y1)/d->vfb_scaledown + 1);
780    
# Line 707  void dev_fb_tick(struct cpu *cpu, void * Line 789  void dev_fb_tick(struct cpu *cpu, void *
789          if (need_to_redraw_cursor) {          if (need_to_redraw_cursor) {
790                  /*  Paint new cursor:  */                  /*  Paint new cursor:  */
791                  if (d->fb_window->cursor_on) {                  if (d->fb_window->cursor_on) {
792                          x11_redraw_cursor(cpu->machine, d->fb_window->fb_number);                          x11_redraw_cursor(cpu->machine,
793                                d->fb_window->fb_number);
794                          d->fb_window->OLD_cursor_on = d->fb_window->cursor_on;                          d->fb_window->OLD_cursor_on = d->fb_window->cursor_on;
795                          d->fb_window->OLD_cursor_x = d->fb_window->cursor_x;                          d->fb_window->OLD_cursor_x = d->fb_window->cursor_x;
796                          d->fb_window->OLD_cursor_y = d->fb_window->cursor_y;                          d->fb_window->OLD_cursor_y = d->fb_window->cursor_y;
797                          d->fb_window->OLD_cursor_xsize = d->fb_window->cursor_xsize;                          d->fb_window->OLD_cursor_xsize = d->fb_window->
798                          d->fb_window->OLD_cursor_ysize = d->fb_window->cursor_ysize;                              cursor_xsize;
799                            d->fb_window->OLD_cursor_ysize = d->fb_window->
800                                cursor_ysize;
801                  }                  }
802          }          }
803  #endif  #endif
# Line 750  int dev_fb_access(struct cpu *cpu, struc Line 835  int dev_fb_access(struct cpu *cpu, struc
835          }          }
836  #endif  #endif
837    
838            if (relative_addr >= d->framebuffer_size)
839                    return 0;
840    
841          /*  See if a write actually modifies the framebuffer contents:  */          /*  See if a write actually modifies the framebuffer contents:  */
842          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
843                  for (i=0; i<len; i++) {                  for (i=0; i<len; i++) {
# Line 835  int dev_fb_access(struct cpu *cpu, struc Line 923  int dev_fb_access(struct cpu *cpu, struc
923  /*  /*
924   *  dev_fb_init():   *  dev_fb_init():
925   *   *
926   *  xsize and ysize are ignored if vfb_type is VFB_DEC_VFB01 or 02.   *  This function is big and ugly, but the point is to initialize a framebuffer
927     *  device. :-)
928     *
929     *  visible_xsize and visible_ysize are the sizes of the visible display area.
930     *  xsize and ysize tell how much memory is actually allocated (for example
931     *  visible_xsize could be 640, but xsize could be 1024, for better alignment).
932     *
933     *  vfb_type is useful for selecting special features.
934     *
935     *  type = VFB_GENERIC is the most useful type, especially when bit_depth = 24.
936     *
937     *  VFB_DEC_VFB01, _VFB02, and VFB_DEC_MAXINE are DECstation specific.
938     *
939     *  If type is VFB_HPC, then color encoding differs from the generic case.
940     *
941     *  If bit_depth = -15 (note the minus sign), then a special hack is used for
942     *  the Playstation Portable's 5-bit R, 5-bit G, 5-bit B.
943   */   */
944  struct vfb_data *dev_fb_init(struct machine *machine, struct memory *mem,  struct vfb_data *dev_fb_init(struct machine *machine, struct memory *mem,
945          uint64_t baseaddr, int vfb_type, int visible_xsize, int visible_ysize,          uint64_t baseaddr, int vfb_type, int visible_xsize, int visible_ysize,
946          int xsize, int ysize, int bit_depth, char *name, int logo)          int xsize, int ysize, int bit_depth, char *name)
947  {  {
948          struct vfb_data *d;          struct vfb_data *d;
949          size_t size;          size_t size, nlen;
950          int x, y;          int flags;
951          char title[400];          char title[400];
952          char *name2;          char *name2;
         int flags;  
953    
954          d = malloc(sizeof(struct vfb_data));          d = malloc(sizeof(struct vfb_data));
955          if (d == NULL) {          if (d == NULL) {
# Line 866  struct vfb_data *dev_fb_init(struct mach Line 969  struct vfb_data *dev_fb_init(struct mach
969          if (bit_depth == 15) {          if (bit_depth == 15) {
970                  d->color32k = 1;                  d->color32k = 1;
971                  bit_depth = d->bit_depth = 16;                  bit_depth = d->bit_depth = 16;
972            } else if (bit_depth == -15) {
973                    d->psp_15bit = 1;
974                    bit_depth = d->bit_depth = 16;
975          }          }
976    
977          /*  Specific types:  */          /*  Specific types:  */
# Line 925  struct vfb_data *dev_fb_init(struct mach Line 1031  struct vfb_data *dev_fb_init(struct mach
1031          d->update_x2 = d->update_y2 = -1;          d->update_x2 = d->update_y2 = -1;
1032    
1033    
1034          /*  A nice bootup logo:  */          /*  Don't set the title to include the size of the framebuffer for
1035          if (logo) {              VGA, since then the resolution might change during runtime.  */
1036                  int logo_bottom_margin = LOGO_BOTTOM_MARGIN;          if (strcmp(name, "VGA") == 0)
1037                    snprintf(title, sizeof(title),"GXemul: %s framebuffer", name);
1038                  d->update_x1 = 0;          else
1039                  d->update_x2 = LOGO_XSIZE-1;                  snprintf(title, sizeof(title),"GXemul: %ix%ix%i %s framebuffer",
1040                  d->update_y1 = d->visible_ysize-LOGO_YSIZE-logo_bottom_margin;                      d->visible_xsize, d->visible_ysize, d->bit_depth, name);
                 d->update_y2 = d->visible_ysize-logo_bottom_margin;  
                 for (y=0; y<LOGO_YSIZE; y++)  
                         for (x=0; x<LOGO_XSIZE; x++) {  
                                 int s, a = ((y + d->visible_ysize - LOGO_YSIZE  
                                     - logo_bottom_margin)*d->xsize + x)  
                                     * d->bit_depth / 8;  
                                 int b = fb_logo[(y*LOGO_XSIZE+x) / 8] &  
                                     (128 >> (x&7));  
                                 for (s=0; s<d->bit_depth / 8; s++)  
                                         d->framebuffer[a+s] = b? 0 : 255;  
                         }  
         }  
   
         snprintf(title, sizeof(title), "GXemul: %ix%ix%i %s framebuffer",  
             d->visible_xsize, d->visible_ysize, d->bit_depth, name);  
1041          title[sizeof(title)-1] = '\0';          title[sizeof(title)-1] = '\0';
1042    
1043  #ifdef WITH_X11  #ifdef WITH_X11
# Line 957  struct vfb_data *dev_fb_init(struct mach Line 1048  struct vfb_data *dev_fb_init(struct mach
1048  #endif  #endif
1049                  d->fb_window = NULL;                  d->fb_window = NULL;
1050    
1051          name2 = malloc(strlen(name) + 10);          nlen = strlen(name) + 10;
1052            name2 = malloc(nlen);
1053          if (name2 == NULL) {          if (name2 == NULL) {
1054                  fprintf(stderr, "out of memory in dev_fb_init()\n");                  fprintf(stderr, "out of memory in dev_fb_init()\n");
1055                  exit(1);                  exit(1);
1056          }          }
1057          sprintf(name2, "fb [%s]", name);          snprintf(name2, nlen, "fb [%s]", name);
1058    
1059          flags = MEM_DEFAULT;          flags = DM_DEFAULT;
1060          if ((baseaddr & 0xfff) == 0)          if ((baseaddr & 0xfff) == 0)
1061                  flags = MEM_BINTRANS_OK | MEM_BINTRANS_WRITE_OK;                  flags = DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK;
1062    
1063            flags |= DM_READS_HAVE_NO_SIDE_EFFECTS;
1064    
1065          memory_device_register(mem, name2, baseaddr, size, dev_fb_access,          memory_device_register(mem, name2, baseaddr, size, dev_fb_access,
1066              d, flags, d->framebuffer);              d, flags, d->framebuffer);

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

  ViewVC Help
Powered by ViewVC 1.1.26