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

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

revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2006-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_pvr.c,v 1.17 2006/11/02 05:43:44 debug Exp $   *  $Id: dev_pvr.c,v 1.24 2007/06/15 19:57:33 debug Exp $
29   *     *  
30   *  PowerVR CLX2 (Graphics controller used in the Dreamcast). Implemented by   *  COMMENT: PowerVR CLX2 (graphics controller used in the Dreamcast)
31   *  reading http://www.ludd.luth.se/~jlo/dc/powervr-reg.txt and   *
32     *  Implemented by reading http://www.ludd.luth.se/~jlo/dc/powervr-reg.txt and
33   *  http://mc.pp.se/dc/pvr.html, source code of various demos and KalistOS,   *  http://mc.pp.se/dc/pvr.html, source code of various demos and KalistOS,
34   *  and doing a lot of guessing.   *  and doing a lot of guessing.
35   *   *
# Line 42  Line 43 
43   *              Color clipping.   *              Color clipping.
44   *              Wire-frame when running on a host without XGL?   *              Wire-frame when running on a host without XGL?
45   *   *
  *      x)  Border?  
  *  
46   *  Multiple lists of various kinds (6?).   *  Multiple lists of various kinds (6?).
47   *  Lists growing downwards!   *  Lists growing downwards!
48   *  Pixel clip for rendering.   *  Pixel clip for rendering.
# Line 75  Line 74 
74  #define PVR_FB_TICK_SHIFT       19  #define PVR_FB_TICK_SHIFT       19
75    
76  #define PVR_VBLANK_HZ           60.0  #define PVR_VBLANK_HZ           60.0
77    #define PVR_MARGIN              16
78    
79  struct pvr_data {  struct pvr_data {
80          struct vfb_data         *fb;          struct vfb_data         *fb;
# Line 103  struct pvr_data { Line 103  struct pvr_data {
103          int                     pixelmode;          int                     pixelmode;
104          int                     line_double;          int                     line_double;
105          int                     display_enabled;          int                     display_enabled;
106            /*  BRDCOLR:  */
107            int                     border_updated;
108          /*  SYNCCONF:  */          /*  SYNCCONF:  */
109          int                     video_enabled;          int                     video_enabled;
110          int                     broadcast_standard;          int                     broadcast_standard;
# Line 161  static void pvr_vblank_timer_tick(struct Line 163  static void pvr_vblank_timer_tick(struct
163   */   */
164  static void pvr_geometry_updated(struct pvr_data *d)  static void pvr_geometry_updated(struct pvr_data *d)
165  {  {
166            /*  Make sure to redraw border on geometry changes.  */
167            d->border_updated = 1;
168    
169          d->xsize = (REG(PVRREG_DIWSIZE) >> DIWSIZE_DPL_SHIFT) & DIWSIZE_MASK;          d->xsize = (REG(PVRREG_DIWSIZE) >> DIWSIZE_DPL_SHIFT) & DIWSIZE_MASK;
170          d->ysize = (REG(PVRREG_DIWSIZE) >> DIWSIZE_LPF_SHIFT) & DIWSIZE_MASK;          d->ysize = (REG(PVRREG_DIWSIZE) >> DIWSIZE_LPF_SHIFT) & DIWSIZE_MASK;
171    
# Line 415  static void pvr_ta_command(struct cpu *c Line 420  static void pvr_ta_command(struct cpu *c
420    
421  DEVICE_ACCESS(pvr_ta)  DEVICE_ACCESS(pvr_ta)
422  {  {
423          struct pvr_data *d = (struct pvr_data *) extra;          struct pvr_data *d = extra;
424          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
425    
426          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
# Line 440  DEVICE_ACCESS(pvr_ta) Line 445  DEVICE_ACCESS(pvr_ta)
445    
446  DEVICE_ACCESS(pvr)  DEVICE_ACCESS(pvr)
447  {  {
448          struct pvr_data *d = (struct pvr_data *) extra;          struct pvr_data *d = extra;
449          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
450    
451          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
# Line 473  DEVICE_ACCESS(pvr) Line 478  DEVICE_ACCESS(pvr)
478    
479          case PVRREG_RESET:          case PVRREG_RESET:
480                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
481                          debug("[ pvr: RESET ");                          if (idata != 0) {
482                          if (idata & PVR_RESET_PVR)                                  debug("[ pvr: RESET ");
483                                  pvr_reset(d);                                  if (idata & PVR_RESET_PVR)
484                          if (idata & PVR_RESET_TA)                                          pvr_reset(d);
485                                  pvr_reset_ta(d);                                  if (idata & PVR_RESET_TA)
486                          debug("]\n");                                          pvr_reset_ta(d);
487                                    debug("]\n");
488                            }
489                          idata = 0;                          idata = 0;
490                          DEFAULT_WRITE;                          DEFAULT_WRITE;
491                  }                  }
# Line 541  DEVICE_ACCESS(pvr) Line 548  DEVICE_ACCESS(pvr)
548                          debug("[ pvr: BRDCOLR set to 0x%06"PRIx32" ]\n",                          debug("[ pvr: BRDCOLR set to 0x%06"PRIx32" ]\n",
549                              (int)idata);                              (int)idata);
550                          DEFAULT_WRITE;                          DEFAULT_WRITE;
551                            d->border_updated = 1;
552                  }                  }
553                  break;                  break;
554    
# Line 979  DEVICE_TICK(pvr_fb) Line 987  DEVICE_TICK(pvr_fb)
987           *  Framebuffer update:           *  Framebuffer update:
988           */           */
989    
990            /*  Border changed?  */
991            if (d->border_updated) {
992                    /*  Fill border with border color:  */
993                    int rgb = REG(PVRREG_BRDCOLR), addr = 0;
994                    int x, y, b = rgb & 0xff, g = (rgb >> 8) & 0xff, r = rgb >> 16;
995                    int skiplen = (d->fb->xsize-2*PVR_MARGIN) * d->fb->bit_depth/8;
996    
997                    for (y=0; y<d->fb->ysize; y++) {
998                            int xskip = y < PVR_MARGIN || y >=
999                                d->fb->ysize - PVR_MARGIN? -1 : PVR_MARGIN;
1000                            for (x=0; x<d->fb->xsize; x++) {
1001                                    if (x == xskip) {
1002                                            x = d->fb->xsize - PVR_MARGIN;
1003                                            addr += skiplen;
1004                                    }
1005                                    fb[addr] = r;
1006                                    fb[addr+1] = g;
1007                                    fb[addr+2] = b;
1008                                    addr += 3;
1009                            }
1010                    }
1011    
1012                    /*  Full redraw of the framebuffer:  */
1013                    d->fb->update_x1 = 0; d->fb->update_x2 = d->fb->xsize - 1;
1014                    d->fb->update_y1 = 0; d->fb->update_y2 = d->fb->ysize - 1;
1015            }
1016    
1017          memory_device_dyntrans_access(cpu, cpu->mem, extra, &low, &high);          memory_device_dyntrans_access(cpu, cpu->mem, extra, &low, &high);
1018          if ((int64_t)low != -1)          if ((int64_t)low != -1)
1019                  extend_update_region(d, low, high);                  extend_update_region(d, low, high);
# Line 987  DEVICE_TICK(pvr_fb) Line 1022  DEVICE_TICK(pvr_fb)
1022                  return;                  return;
1023    
1024          /*  Copy (part of) the VRAM to the framebuffer:  */          /*  Copy (part of) the VRAM to the framebuffer:  */
1025          if (d->fb_update_x2 >= d->fb->xsize)          if (d->fb_update_x2 >= d->xsize)
1026                  d->fb_update_x2 = d->fb->xsize - 1;                  d->fb_update_x2 = d->xsize - 1;
1027          if (d->fb_update_y2 >= d->fb->ysize)          if (d->fb_update_y2 >= d->ysize)
1028                  d->fb_update_y2 = d->fb->ysize - 1;                  d->fb_update_y2 = d->ysize - 1;
1029    
1030          vram_ofs += d->fb_update_y1 * bytes_per_line;          vram_ofs += d->fb_update_y1 * bytes_per_line;
1031          vram_ofs += d->fb_update_x1 * d->bytes_per_pixel;          vram_ofs += d->fb_update_x1 * d->bytes_per_pixel;
1032          pixels_to_copy = (d->fb_update_x2 - d->fb_update_x1 + 1);          pixels_to_copy = (d->fb_update_x2 - d->fb_update_x1 + 1);
1033          fb_ofs = d->fb_update_y1 * d->fb->bytes_per_line;          fb_ofs = (d->fb_update_y1 + PVR_MARGIN) * d->fb->bytes_per_line;
1034          fb_ofs += d->fb_update_x1 * d->fb->bit_depth / 8;          fb_ofs += (d->fb_update_x1 + PVR_MARGIN) * d->fb->bit_depth / 8;
1035    
1036          /*  Copy the actual pixels: (Four manually inlined, for speed.)  */          /*  Copy the actual pixels: (Four manually inlined, for speed.)  */
1037    
# Line 1062  DEVICE_TICK(pvr_fb) Line 1097  DEVICE_TICK(pvr_fb)
1097           *  just written to:           *  just written to:
1098           */           */
1099    
1100            /*  Offset to take the margin into account first...  */
1101            d->fb_update_x1 += PVR_MARGIN; d->fb_update_y1 += PVR_MARGIN;
1102            d->fb_update_x2 += PVR_MARGIN; d->fb_update_y2 += PVR_MARGIN;
1103    
1104          if (d->fb_update_x1 < d->fb->update_x1 || d->fb->update_x1 < 0)          if (d->fb_update_x1 < d->fb->update_x1 || d->fb->update_x1 < 0)
1105                  d->fb->update_x1 = d->fb_update_x1;                  d->fb->update_x1 = d->fb_update_x1;
1106          if (d->fb_update_x2 > d->fb->update_x2 || d->fb->update_x2 < 0)          if (d->fb_update_x2 > d->fb->update_x2 || d->fb->update_x2 < 0)
# Line 1081  DEVICE_ACCESS(pvr_vram_alt) Line 1120  DEVICE_ACCESS(pvr_vram_alt)
1120  {  {
1121          struct pvr_data_alt *d_alt = extra;          struct pvr_data_alt *d_alt = extra;
1122          struct pvr_data *d = d_alt->d;          struct pvr_data *d = d_alt->d;
1123          int i;          size_t i;
1124    
1125          if (writeflag == MEM_READ) {          if (writeflag == MEM_READ) {
1126                  /*  Copy from real vram:  */                  /*  Copy from real vram:  */
# Line 1136  DEVICE_ACCESS(pvr_vram) Line 1175  DEVICE_ACCESS(pvr_vram)
1175  DEVINIT(pvr)  DEVINIT(pvr)
1176  {  {
1177          struct machine *machine = devinit->machine;          struct machine *machine = devinit->machine;
1178          struct pvr_data *d = malloc(sizeof(struct pvr_data));          struct pvr_data *d;
1179          struct pvr_data_alt *d_alt = malloc(sizeof(struct pvr_data_alt));          struct pvr_data_alt *d_alt;
1180          if (d == NULL) {  
1181                  fprintf(stderr, "out of memory\n");          CHECK_ALLOCATION(d = malloc(sizeof(struct pvr_data)));
                 exit(1);  
         }  
1182          memset(d, 0, sizeof(struct pvr_data));          memset(d, 0, sizeof(struct pvr_data));
1183    
1184            CHECK_ALLOCATION(d_alt = malloc(sizeof(struct pvr_data_alt)));
1185          memset(d_alt, 0, sizeof(struct pvr_data_alt));          memset(d_alt, 0, sizeof(struct pvr_data_alt));
1186    
1187          d_alt->d = d;          d_alt->d = d;
# Line 1173  DEVINIT(pvr) Line 1212  DEVINIT(pvr)
1212          d->bytes_per_pixel = 2;          d->bytes_per_pixel = 2;
1213    
1214          d->fb = dev_fb_init(machine, machine->memory, INTERNAL_FB_ADDR,          d->fb = dev_fb_init(machine, machine->memory, INTERNAL_FB_ADDR,
1215              VFB_GENERIC, 640,480, 640,480, 24, "Dreamcast PVR");              VFB_GENERIC, d->xsize + PVR_MARGIN*2, d->ysize + PVR_MARGIN*2,
1216                d->xsize + PVR_MARGIN*2, d->ysize + PVR_MARGIN*2,
1217                24, "Dreamcast PVR");
1218    
1219          d->vblank_timer = timer_add(PVR_VBLANK_HZ, pvr_vblank_timer_tick, d);          d->vblank_timer = timer_add(PVR_VBLANK_HZ, pvr_vblank_timer_tick, d);
1220    
# Line 1181  DEVINIT(pvr) Line 1222  DEVINIT(pvr)
1222          pvr_reset_ta(d);          pvr_reset_ta(d);
1223    
1224          machine_add_tickfunction(machine, dev_pvr_fb_tick, d,          machine_add_tickfunction(machine, dev_pvr_fb_tick, d,
1225              PVR_FB_TICK_SHIFT, 0.0);              PVR_FB_TICK_SHIFT);
1226    
1227          return 1;          return 1;
1228  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26