Previous 15994 Revisions Next

r899 Friday 31st August, 2007 at 20:45:08 UTC by Wilbert Pol
[PCE] Some small VDC updates.
[src/mess/drivers]pce.c
[src/mess/video]vdc.c vdc.h

src/mess/video/vdc.c
r898r899
2525   memset(vdc.vram, 0, 0x10000);
2626
2727   /* create display bitmap */
28   vdc.bmp = auto_bitmap_alloc(360, 256, BITMAP_FORMAT_INDEXED16);
28   vdc.bmp = auto_bitmap_alloc(machine->screen[0].width, machine->screen[0].height, machine->screen[0].format);
2929}
3030
3131
3232VIDEO_UPDATE( pce )
3333{
34    /* only refresh the visible portion of the display */
35    rectangle pce_visible_area;
36
37    int center_x = ((360/2) - (vdc.physical_width/2));
38    int center_y = ((256/2) - (vdc.physical_height/2));
39
40    pce_visible_area.min_x = center_x;
41    pce_visible_area.min_y = center_y;
42    pce_visible_area.max_x = (center_x + vdc.physical_width) - 1;
43    pce_visible_area.max_y = (center_x + vdc.physical_height) - 1;
44
4534    /* copy our rendering buffer to the display */
46    copybitmap (bitmap,vdc.bmp,0,0,0,0,&pce_visible_area,TRANSPARENCY_NONE,0);
35    copybitmap (bitmap,vdc.bmp,0,0,0,0,cliprect,TRANSPARENCY_NONE,0);
4736   return 0;
4837}
4938
r898r899
5544    /* our line buffer */
5645    UINT16 *line_buffer = BITMAP_ADDR16( vdc.bmp, line, 0 );
5746   
58   for(i=0; i<360;i++)
59      line_buffer[i]=Machine->pens[0];
47   for( i=0; i< Machine->screen[0].width; i++ )
48      line_buffer[i] = Machine->pens[0];
6049}
6150
6251void draw_overscan_line(int line)
r898r899
6655    /* our line buffer */
6756    UINT16 *line_buffer = BITMAP_ADDR16( vdc.bmp, line, 0 );
6857   
69   for(i=0; i<360;i++)
70      line_buffer[i]=Machine->pens[0x100];
58   for( i=0; i< Machine->screen[0].width; i++ )
59      line_buffer[i] = Machine->pens[0x100];
7160}
7261
7362void vram_write(offs_t offset, UINT8 data)
r898r899
116105                     vdc.vdc_latch = data;
117106                     break;
118107
119          case BYR:
120         if(vdc.current_segment == STATE_ACTIVE)
121            vdc.y_scroll=vdc.vdc_data[BYR].w;
122         break;
108             case BYR:
109               vdc.y_scroll=vdc.vdc_data[BYR].w;
110               break;
123111
124112                case HDR:
125113                     vdc.physical_width = ((data & 0x003F) + 1) << 3;
r898r899
174162                     vdc.dvssr_write = 1;
175163                     break;
176164
177          case BYR:
178         if(vdc.current_segment == STATE_ACTIVE)
179            vdc.y_scroll=vdc.vdc_data[BYR].w;
180         break;
165             case BYR:
166               vdc.y_scroll=vdc.vdc_data[BYR].w;
167               break;
181168
182169                case LENR:
183170                  vdc_do_dma();
r898r899
299286{
300287    static int width_table[4] = {5, 6, 7, 7};
301288
302    int center_x = ((360/2) - (vdc.physical_width/2));
303
304    int scroll_y = (vdc.y_scroll & 0x01FF);
289    int scroll_y = ( vdc.y_scroll & 0x01FF);
305290    int scroll_x = (vdc.vdc_data[BXR].w & 0x03FF);
306291    int nt_index;
307292
r898r899
318303    int v_width =        width_table[(vdc.vdc_data[MWR].w >> 4) & 3];
319304
320305    /* our line buffer */
321    UINT16 *line_buffer = BITMAP_ADDR16( vdc.bmp, bitmap_line, center_x );
306    UINT16 *line_buffer = BITMAP_ADDR16( vdc.bmp, bitmap_line, 86 );
322307#ifdef MAME_DEBUG
323308   int line_buffer_size;
324309#endif
r898r899
345330    }
346331   else
347332   {
348      for(i=0;i<(vdc.physical_width >> 3)+1;i++)
333      int   pixel = 0;
334      for(i=0;i<(vdc.physical_width >> 3);i++)
349335      {
350336         nt_index = (i + (scroll_x >> 3)) & ((2 << (v_width-1))-1);
351337         nt_index *= 2;
r898r899
374360            i3 = (b3 >> (7-x)) & 1;
375361            c = (cell_palette << 4 | i3 << 3 | i2 << 2 | i1 << 1 | i0);
376362
377#ifdef MAME_DEBUG
378//apparently some kind of bounds check?
379            assert((i<<3)+x < (line_buffer_size));
380#endif
381            line_buffer[(i<<3)+x] = Machine->pens[c];
363            /* colour #0 always comes from palette #0 */
364            if ( ! ( c & 0x0F ) )
365               c &= 0x0F;
366
367            line_buffer[ pixel++ ] = Machine->pens[c];
368            if ( vdc.physical_width != 512 ) {
369               if ( pixel < ( ( ( i * 8 + x + 1 ) * 512 ) / vdc.physical_width ) ) {
370                  line_buffer[ pixel++ ] = Machine->pens[c];
371               }
372            }
382373         }
383374      }
384
385375   }
386376   /* Sprite rendering is independant of BG drawing! */
387377   if(vdc.vdc_data[CR].w & CR_SB)
r898r899
430420    static int cgx_table[] = {16, 32};
431421    static int cgy_table[] = {16, 32, 64, 64};
432422
433    int center_x = ((360/2) - (vdc.physical_width/2));
434//    int center_y = ((256/2) - (vdc.physical_height/2));
435
436423    int obj_x, obj_y, obj_i, obj_a;
437424    int obj_w, obj_h, obj_l, cgypos;
438425    int hf, vf;
r898r899
442429    char buf[16];
443430
444431   UINT8 sprites_drawn=0;
445   UINT16 *line_buffer= BITMAP_ADDR16( vdc.bmp, bitmap_line, center_x );
432   UINT16 *line_buffer= BITMAP_ADDR16( vdc.bmp, bitmap_line, 86 );
446433
447434   /* 0 -> no sprite pixels drawn, otherwise is sprite #+1 */
448   UINT8 drawn[(0x40 << 3) + 32];
449   if (!line_buffer)
450      return;
435   UINT8 drawn[Machine->screen[0].width];
451436
452437   //clear our sprite-to-sprite clipping buffer.
453   memset(drawn, 0, (0x40 << 3) + 32);
438   memset(drawn, 0, sizeof(drawn));
454439   /* count up: Highest priority is Sprite 0 */
455440   for(i=0; i<64; i++)
456441   {
457442      obj_y = (vdc.sprite_ram[(i<<2)+0] & 0x03FF) - 64;
458443      obj_x = (vdc.sprite_ram[(i<<2)+1] & 0x03FF) - 32;
459444
445      if ( vdc.vdc_data[MWR].w & 0x0030 ) {
446         obj_y -= ( vdc.vdc_data[BYR].w & (vdc.vdc_data[MWR].w & 0x0040 ? 0x1FF : 0x0FF) );
447      }
448
460449      if ((obj_y == -64) || (obj_y > line)) continue;
461450      if ((obj_x == -32) || (obj_x > vdc.physical_width)) continue;
462451
r898r899
497486
498487         if(cgx == 0)
499488         {
489            int pixel_x = ( ( obj_x * 512 ) / vdc.physical_width );
490
500491            conv_obj(obj_i + (cgypos << 2), obj_l, hf, vf, buf);
492
501493            for(x=0;x<16;x++)
502494            {
503495               if(((obj_x + x)<(vdc.physical_width))&&((obj_x + x)>=0))
r898r899
507499                  {
508500                     if(!drawn[obj_x+x])
509501                     {
510                        if(priority || (line_buffer[obj_x + x] == Machine->pens[0]))
511                           line_buffer[obj_x + x] = Machine->pens[0x100 + (palette << 4) + c];
512                        drawn[obj_x + x]=i+1;
502                        if(priority || (line_buffer[pixel_x] == Machine->pens[0])) {
503                           line_buffer[pixel_x] = Machine->pens[0x100 + (palette << 4) + c];
504                           if ( vdc.physical_width != 512 ) {
505                              if ( pixel_x + 1 < ( ( ( obj_x + x + 1 ) * 512 ) / vdc.physical_width ) ) {
506                                 line_buffer[pixel_x + 1] = Machine->pens[0x100 + (palette << 4) + c];
507                              }
508                           }
509                           drawn[obj_x+x]=i+1;
510                        }
513511                     }
514512                     else if (drawn[obj_x+x]==1)
515513                     {
r898r899
519517                     }
520518                  }
521519               }
520               pixel_x += 1;
521               if ( vdc.physical_width != 512 ) {
522                  if ( pixel_x < ( ( ( obj_x + x + 1 ) * 512 ) / vdc.physical_width ) ) {
523                     pixel_x += 1;
524                  }
525               }
522526            }
523527         }
524528         else
525529         {
530            int pixel_x = ( ( obj_x * 512 ) / vdc.physical_width );
531
526532            conv_obj(obj_i + (cgypos << 2) + (hf ? 2 : 0), obj_l, hf, vf, buf);
533
527534            for(x=0;x<16;x++)
528535            {
529536               if(((obj_x + x)<(vdc.physical_width))&&((obj_x + x)>=0))
r898r899
533540                  {
534541                     if(!drawn[obj_x+x])
535542                     {
536                        if(priority || (line_buffer[obj_x + x] == Machine->pens[0]))
537                           line_buffer[obj_x + x] = Machine->pens[0x100 + (palette << 4) + c];
538                        drawn[obj_x + x]=i+1;
543                        if(priority || (line_buffer[pixel_x] == Machine->pens[0])) {
544                           line_buffer[pixel_x] = Machine->pens[0x100 + (palette << 4) + c];
545                           if ( vdc.physical_width != 512 ) {
546                              if ( pixel_x + 1 < ( ( ( obj_x + x + 1 ) * 512 ) / vdc.physical_width ) ) {
547                                 line_buffer[pixel_x + 1] = Machine->pens[0x100 + (palette << 4) + c];
548                              }
549                           }
550                           drawn[obj_x + x]=i+1;
551                        }
539552                     }
540553                     else if (drawn[obj_x+x]==1)
541554                     {
r898r899
547560                     }
548561                  }
549562               }
563               pixel_x += 1;
564               if ( vdc.physical_width != 512 ) {
565                  if ( pixel_x < ( ( ( obj_x + x + 1 ) * 512 ) / vdc.physical_width ) ) {
566                     pixel_x += 1;
567                  }
568               }
550569            }
551570
552571            conv_obj(obj_i + (cgypos << 2) + (hf ? 0 : 2), obj_l, hf, vf, buf);
r898r899
559578                  {
560579                     if(!drawn[obj_x+0x10+x])
561580                     {
562                        if(priority || (line_buffer[obj_x + 0x10 + x] == Machine->pens[0]))
563                           line_buffer[obj_x + 0x10 + x] = Machine->pens[0x100 + (palette << 4) + c];
564                        drawn[obj_x + 0x10 + x]=i+1;
581                        if(priority || (line_buffer[pixel_x] == Machine->pens[0])) {
582                           line_buffer[pixel_x] = Machine->pens[0x100 + (palette << 4) + c];
583                           if ( vdc.physical_width != 512 ) {
584                              if ( pixel_x + 1 < ( ( ( obj_x + x + 17 ) * 512 ) / vdc.physical_width ) ) {
585                                 line_buffer[pixel_x + 1] = Machine->pens[0x100 + (palette << 4) + c];
586                              }
587                           }                                   
588                           drawn[obj_x + 0x10 + x]=i+1;
589                        }
565590                     }
566591                     else if (drawn[obj_x+0x10+x]==1)
567592                     {
r898r899
571596                     }
572597                  }
573598               }
599               pixel_x += 1;
600               if ( vdc.physical_width != 512 ) {
601                  if ( pixel_x < ( ( ( obj_x + x + 17 ) * 512 ) / vdc.physical_width ) ) {
602                     pixel_x += 1;
603                  }
604               }
574605            }
575606         }
576607      }
src/mess/video/vdc.h
r898r899
5959void draw_overscan_line(int line);
6060void vdc_delayed_irq(int unused);
6161
62/* VDC segments */
63#define STATE_TOPBLANK      0
64#define STATE_TOPFILL      1
65#define STATE_ACTIVE      2
66#define STATE_BOTTOMFILL   3
67
68/* define VCE frame specs, so some day  the emulator can behave right */
69#define FIRST_VISIBLE 14
70#define SYNC_AREA      3
71#define BLANK_AREA     4
72#define LAST_VISIBLE  (VDC_LPF-SYNC_AREA-BLANK_AREA)
73
7462/* the VDC context */
7563
7664typedef struct
r898r899
8977    pair vdc_data[32];
9078    int status;
9179    mame_bitmap *bmp;
92    int current_segment;
93    int current_segment_line;
94    int current_bitmap_line;
9580    int y_scroll;
9681    int top_blanking;
9782    int top_overscan;
src/mess/drivers/pce.c
r898r899
5151#include "sound/c6280.h"
5252#include "hash.h"
5353
54#define   MAIN_CLOCK   21477270
55
5456static INTERRUPT_GEN( pce_interrupt )
5557{
5658    int ret = 0;
5759
5860    /* bump current scanline */
5961    vdc.curline = (vdc.curline + 1) % VDC_LPF;
60   vdc.current_segment_line++;
6162
6263   if(vdc.curline==0)
6364   {
6465      //state is now in the VDS region, nothing even tries to draw here.
6566      vdc.top_blanking=(vdc.vdc_data[VPR].b.l&0x1F)+1;
6667      vdc.top_overscan=(vdc.vdc_data[VPR].b.h)+2;
67      vdc.current_bitmap_line=0;
68      vdc.current_segment=STATE_TOPBLANK;
69      vdc.current_segment_line=0;
7068      vdc.active_lines = vdc.physical_height = 1 + ( vdc.vdc_data[VDW].w & 0x01FF );
7169      vdc.bottomfill=vdc.vdc_data[VCR].b.l;
7270   }
7371
74   switch(vdc.current_segment)
75   {
76   case STATE_TOPBLANK:
77      {
78         if(vdc.current_segment_line == vdc.top_blanking)
79         {
80            vdc.current_segment=STATE_TOPFILL;
81            vdc.current_segment_line=0;
82         }
83         break;
72   if ( vdc.curline < vdc.top_blanking ) {
73      /* We are in the top blanking area */
74      draw_black_line( vdc.curline );
75   } else if ( vdc.curline < vdc.top_blanking + vdc.top_overscan ) {
76      /* We are in the top overscan area */
77      draw_overscan_line( vdc.curline );
78   } else if ( vdc.curline < vdc.top_blanking + vdc.top_overscan + vdc.active_lines ) {
79      /* We are in the active screen area */
80      if ( vdc.curline == vdc.top_blanking + vdc.top_overscan ) {
81         vdc.y_scroll = vdc.vdc_data[BYR].w;
8482      }
85   case STATE_TOPFILL:
86      {
87         if(vdc.current_segment_line == vdc.top_overscan)
88         {
89            vdc.current_segment=STATE_ACTIVE;
90            vdc.current_segment_line=0;
91            vdc.y_scroll = vdc.vdc_data[BYR].w;
92         }
93         break;
94      }
95   case STATE_ACTIVE:
96      {
97         if(vdc.current_segment_line == vdc.active_lines)
98         {
99            vdc.current_segment_line=0;
100            if(vdc.bottomfill != 0)
101            {
102               vdc.current_segment=STATE_BOTTOMFILL;
103               vdc.status |= VDC_VD;
104               if(vdc.vdc_data[CR].w & CR_VR)
105               {
106                 
83      pce_refresh_line( vdc.curline, vdc.curline - ( vdc.top_blanking + vdc.top_overscan ) );
84   } else {
85      /* We are in the bottom blanking area */
86      if ( vdc.curline == vdc.top_blanking + vdc.top_overscan + vdc.active_lines ) {
87         if ( vdc.bottomfill != 0 ) {
88            vdc.status |= VDC_VD;
89            if ( vdc.vdc_data[CR].w & CR_VR )
90               ret = 1;
91
92            /* do VRAM > SATB DMA if the enable bit is set or the DVSSR reg. was written to */
93            if( ( vdc.vdc_data[DCR].w & DCR_DSR ) || vdc.dvssr_write ) {
94               int i;
95               if ( vdc.dvssr_write )
96                  vdc.dvssr_write = 0;
97
98               for( i = 0; i < 256; i++ ) {
99                  vdc.sprite_ram[i] = ( vdc.vram[ ( vdc.vdc_data[DVSSR].w << 1 ) + i * 2 + 1 ] << 8 ) | vdc.vram[ ( vdc.vdc_data[DVSSR].w << 1 ) + i * 2 ];
100               }
101
102               vdc.status |= VDC_DS;   /* set satb done flag */
103
104               /* generate interrupt if needed */
105               if ( vdc.vdc_data[DCR].w & DCR_DSC )
107106                  ret = 1;
108               }           
109               
110               /* do VRAM > SATB DMA if the enable bit is set or the DVSSR reg. was written to */
111               if((vdc.vdc_data[DCR].w & DCR_DSR) || vdc.dvssr_write)
112               {
113                  int i;
114                  if(vdc.dvssr_write) vdc.dvssr_write = 0;
115                  for( i = 0; i < 256; i++ ) {
116                     vdc.sprite_ram[i] = ( vdc.vram[ ( vdc.vdc_data[DVSSR].w << 1 ) + i * 2 + 1 ] << 8 ) | vdc.vram[ ( vdc.vdc_data[DVSSR].w << 1 ) + i * 2 ];
117                  }
118                  vdc.status |= VDC_DS;   /* set satb done flag */
119                 
120                  /* generate interrupt if needed */
121                  if(vdc.vdc_data[DCR].w & DCR_DSC)
122                     ret = 1;
123               }           
124               
125            }
126            else vdc.current_segment=STATE_TOPBLANK;
107            }     
127108         }
128         break;
129109      }
130   case STATE_BOTTOMFILL:
131      {
132         if(vdc.current_segment_line == vdc.bottomfill)
133         {
134            vdc.current_segment_line=0;
135            vdc.current_segment=STATE_TOPBLANK;
136         }
137         break;
138      }
139
140   default:break;
110      draw_overscan_line( vdc.curline );
141111   }
142112
143    /* draw a line of the display */
144    if(vdc.curline >= FIRST_VISIBLE && vdc.curline < (LAST_VISIBLE))
145    {
146           switch(vdc.current_segment)
147         {
148         default:
149            draw_black_line(vdc.current_bitmap_line);
150            break;
151         case STATE_TOPFILL:
152         case STATE_BOTTOMFILL:
153            draw_overscan_line(vdc.current_bitmap_line);
154            break;
155         case STATE_ACTIVE:
156            pce_refresh_line(vdc.current_bitmap_line, vdc.current_segment_line);
157            break;
158         }
159         vdc.current_bitmap_line++;
160    }
161   else
162    {
163      //rendering can take place here, but it's never on screen!
164           switch(vdc.current_segment)
165         {
166         default:
167            draw_black_line(243);
168            break;
169         case STATE_TOPFILL:
170         case STATE_BOTTOMFILL:
171            draw_overscan_line(243);
172            break;
173         case STATE_ACTIVE:
174            pce_refresh_line(243, vdc.current_segment_line);
175            break;
176         }
177    }
178
179
180113    /* generate interrupt on line compare if necessary */
181114    if(vdc.vdc_data[CR].w & CR_RC)
182      if(vdc.curline == (((vdc.vdc_data[RCR].w-64)+vdc.top_blanking+vdc.top_overscan)%263))
115      if( vdc.curline == ( ( ( vdc.vdc_data[RCR].w-64 ) + vdc.top_blanking + vdc.top_overscan ) % ( VDC_LPF + 1 ) ))
183116    {
184117        vdc.status |= VDC_RR;
185118        ret = 1;
186119    }
187120
188121    /* handle frame events */
189    if(vdc.curline == 261 && vdc.current_segment != STATE_BOTTOMFILL)
122    if(vdc.curline == VDC_LPF - 1 && ( vdc.bottomfill == 0 || vdc.top_overscan + vdc.top_blanking + vdc.active_lines >= VDC_LPF ) )
190123    {
191124        vdc.status |= VDC_VD;   /* set vblank flag */
192125
r898r899
295228
296229static MACHINE_DRIVER_START( pce )
297230   /* basic machine hardware */
298   MDRV_CPU_ADD(H6280, 7195090)
231   MDRV_CPU_ADD(H6280, MAIN_CLOCK/3)
299232   MDRV_CPU_PROGRAM_MAP(pce_mem, 0)
300233   MDRV_CPU_IO_MAP(pce_io, 0)
301234   MDRV_CPU_VBLANK_INT(pce_interrupt, VDC_LPF)
r898r899
306239    /* video hardware */
307240   MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
308241   MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
309   MDRV_SCREEN_SIZE(45*8, 32*8)
310   MDRV_SCREEN_VISIBLE_AREA(0*8, 45*8-1, 0*8, 32*8-1)
242   MDRV_SCREEN_ADD("main",0)
243   MDRV_SCREEN_RAW_PARAMS(MAIN_CLOCK/2, 684, 0, 684, VDC_LPF, 0, VDC_LPF)
311244   /* MDRV_GFXDECODE( pce_gfxdecodeinfo ) */
312245   MDRV_PALETTE_LENGTH(512)
313246   MDRV_COLORTABLE_LENGTH(512)
r898r899
317250
318251   MDRV_NVRAM_HANDLER( pce )
319252   MDRV_SPEAKER_STANDARD_STEREO("left","right")
320   MDRV_SOUND_ADD(C6280, 21477270/6)
253   MDRV_SOUND_ADD(C6280, MAIN_CLOCK/6)
321254   MDRV_SOUND_ROUTE(0, "left", 1.00)
322255   MDRV_SOUND_ROUTE(1, "right", 1.00)
323256MACHINE_DRIVER_END

Previous 15994 Revisions Next


© 1998-2018 The MESS Team