Previous 15994 Revisions Next

r985 Sunday 16th September, 2007 at 17:45:12 UTC by Wilbert Pol
[PCE] Made some internal functions a bit more generic, started adding some supergrafx support.
[src/mess/video]vdc.c vdc.h

src/mess/video/vdc.c
r984r985
4949   mame_bitmap   *bmp;
5050}VCE;
5151
52typedef struct {
53   UINT8 prio;
54   UINT8 vdc0_enabled;
55   UINT8 vdc1_enabled;
56} VPC_PRIO;
57
58typedef struct {
59   VPC_PRIO vpc_prio[4];
60   pair   priority;         /* Priority settings registers */
61   pair   window1;         /* Window 1 setting */
62   pair   window2;         /* Window 2 setting */
63   UINT8   vdc_select;         /* Which VDC do the ST0, ST1, and ST2 instructions write to */
64}VPC;
65
5266static VDC vdc[2];
5367static VCE vce;
68static VPC vpc;
5469
5570/* Function prototypes */
5671
5772static void vdc_advance_line(int which);
5873static void draw_black_line(int line);
5974static void draw_overscan_line(int line);
60static void pce_refresh_line(int which, int bitmap_line, int line, int external_input, UINT8 *drawn);
61static void pce_refresh_sprites(int which, int bitmap_line, int line, UINT8 *drawn);
75static void draw_sgx_overscan_line(int line);
76static void pce_refresh_line(int which, int line, int external_input, UINT8 *drawn, UINT16 *line_buffer);
77static void pce_refresh_sprites(int which, int line, UINT8 *drawn, UINT16 *line_buffer);
6278static void vdc_do_dma(int which);
79static void vpc_init( void );
6380
6481INTERRUPT_GEN( pce_interrupt )
6582{
r984r985
7592            1 - background pixel drawn
7693            otherwise is 2 + sprite# */
7794         UINT8 drawn[VDC_WPF];
95         /* our line buffer */
96         UINT16 *line_buffer = BITMAP_ADDR16( vce.bmp, vce.current_bitmap_line, 86 );
7897
7998         /* clear our priority/sprite collision detection buffer. */
8099         memset(drawn, 0, VDC_WPF);
r984r985
82101         vdc[0].y_scroll = ( vdc[0].current_segment_line == 0 ) ? vdc[0].vdc_data[BYR].w : ( vdc[0].y_scroll + 1 );
83102
84103         /* Draw VDC #0 background layer */
85         pce_refresh_line( 0, vce.current_bitmap_line, vdc[0].current_segment_line, 0, drawn );
104         pce_refresh_line( 0, vdc[0].current_segment_line, 0, drawn, line_buffer );
86105
87106         /* Draw VDC #0 sprite layer */
88107         if(vdc[0].vdc_data[CR].w & CR_SB) {
89            pce_refresh_sprites(0, vce.current_bitmap_line, vdc[0].current_segment_line, drawn);
108            pce_refresh_sprites(0, vdc[0].current_segment_line, drawn, line_buffer);
90109         }
91110      }
92111   } else {
r984r985
99118   vdc_advance_line( 0 );
100119}
101120
121INTERRUPT_GEN( sgx_interrupt )
122{
123   /* Draw the last scanline */
124   if ( vce.current_bitmap_line >= 14 && vce.current_bitmap_line < 14 + 242 ) {
125      /* We are in the active display area */
126      /* First fill the line with the overscan color */
127      draw_sgx_overscan_line( vce.current_bitmap_line );
128
129      /* Check if we need to draw more just the overscan color */
130      if ( vdc[0].current_segment == STATE_VDW ) {
131         /* 0 - no sprite and background pixels drawn
132            1 - background pixel drawn
133            otherwise is 2 + sprite# */
134         UINT8 drawn[2][VDC_WPF];
135         UINT16 *line_buffer;
136         UINT16 temp_buffer[2][512];
137         int i;
138
139         /* clear our priority/sprite collision detection buffer. */
140         memset(drawn, 0, sizeof(drawn));
141
142         vdc[0].y_scroll = ( vdc[0].current_segment_line == 0 ) ? vdc[0].vdc_data[BYR].w : ( vdc[0].y_scroll + 1 );
143         vdc[1].y_scroll = ( vdc[1].current_segment_line == 0 ) ? vdc[1].vdc_data[BYR].w : ( vdc[1].y_scroll + 1 );
144
145         /* Draw VDC #0 background layer */
146         pce_refresh_line( 0, vdc[0].current_segment_line, 0, drawn[0], temp_buffer[0] );
147
148         /* Draw VDC #0 sprite layer */
149         if(vdc[0].vdc_data[CR].w & CR_SB) {
150            pce_refresh_sprites( 0, vdc[0].current_segment_line, drawn[0], temp_buffer[0] );
151         }
152
153         /* Draw VDC #1 background layer */
154         pce_refresh_line( 1, vdc[1].current_segment_line, 1, drawn[1], temp_buffer[1] );
155
156         /* Draw VDC #1 sprite layer */
157         if ( vdc[1].vdc_data[CR].w & CR_SB ) {
158            pce_refresh_sprites( 1, vdc[1].current_segment_line, drawn[1], temp_buffer[1] );
159         }
160
161         line_buffer = BITMAP_ADDR16( vce.bmp, vce.current_bitmap_line, 86 );
162         /* Combine the output of both VDCs */
163         for( i = 0; i < 512; i++ ) {
164            int cur_prio = 2;
165
166            if ( vpc.vpc_prio[cur_prio].vdc0_enabled ) {
167               if ( vpc.vpc_prio[cur_prio].vdc1_enabled ) {
168                  switch( vpc.vpc_prio[cur_prio].prio ) {
169                  case 0:   /* BG1 SP1 BG0 SP0 */
170                     if ( drawn[0][i] ) {
171                        line_buffer[i] = temp_buffer[0][i];
172                     } else if ( drawn[1][i] ) {
173                        line_buffer[i] = temp_buffer[1][i];
174                     }
175                     break;
176                  case 1:   /* BG1 SP0 BG0 SP1 */
177//                     if ( drawn[0][i] ) {
178//                        if ( drawn[1][i] > 1 ) {
179//                           line_buffer[i] = temp_buffer[1][i];
180//                        } else {
181//                           line_buffer[i] = temp_buffer[0][i];
182//                        }
183//                     } else if ( drawn[1][i] ) {
184//                        line_buffer[i] = temp_buffer[1][i];
185//                     }
186//                     break;
187                  case 2:   /* BG1 BG0 SP1 SP0 */
188                     if ( drawn[0][i] ) {
189                        if ( drawn[0][i] > 1 ) {
190                           line_buffer[i] = temp_buffer[0][i];
191                        } else {
192                           if ( drawn[1][i] > 1 ) {
193                              line_buffer[i] = temp_buffer[1][i];
194                           } else {
195                              line_buffer[i] = temp_buffer[0][i];
196                           }
197                        }
198                     } else if ( drawn[1][i] ) {
199                        line_buffer[i] = temp_buffer[1][i];
200                     }
201                     break;
202                  }
203               } else {
204                  if ( drawn[0][i] ) {
205                     line_buffer[i] = temp_buffer[0][i];
206                  }
207               }
208            } else {
209               if ( vpc.vpc_prio[cur_prio].vdc1_enabled ) {
210                  if ( drawn[1][i] ) {
211                     line_buffer[i] = temp_buffer[1][i];
212                  }
213               }
214            }
215         }
216      }
217   } else {
218      /* We are in one of the blanking areas */
219      draw_black_line( vce.current_bitmap_line );
220   }
221
222   /* bump current scanline */
223   vce.current_bitmap_line = ( vce.current_bitmap_line + 1 ) % VDC_LPF;
224   vdc_advance_line( 0 );
225   vdc_advance_line( 1 );
226}
227
102228static void vdc_advance_line(int which) {
103229   int ret = 0;
104230
r984r985
215341   /* clear context */
216342   memset(&vdc, 0, sizeof(vdc));
217343   memset(&vce, 0, sizeof(vce));
344   memset(&vpc, 0, sizeof(vpc));
218345
219346   /* allocate VRAM */
220347   vdc[0].vram = auto_malloc(0x10000);
r984r985
227354
228355   vdc[0].inc = 1;
229356   vdc[1].inc = 1;
357
358   vpc_init();
230359}
231360
232361
r984r985
260389   
261390   for ( i = 0; i < VDC_WPF; i++ )
262391      line_buffer[i] = Machine->pens[color_base + vce.vce_data[0x100].w];
392}
263393
394static void draw_sgx_overscan_line(int line) {
395   int i;
396
397   /* Are we in greyscale mode or in color mode? */
398   int color_base = vce.vce_control & 0x80 ? 512 : 0;
399
400   /* our line buffer */
401   UINT16 *line_buffer = BITMAP_ADDR16( vce.bmp, line, 0 );
402   
403   for ( i = 0; i < VDC_WPF; i++ )
404      line_buffer[i] = Machine->pens[color_base + vce.vce_data[0].w];
264405}
265406
266407static void vram_write(int which, offs_t offset, UINT8 data)
r984r985
475616}
476617
477618
478static void pce_refresh_line(int which, int bitmap_line, int line, int external_input, UINT8 *drawn)
619static void pce_refresh_line(int which, int line, int external_input, UINT8 *drawn, UINT16 *line_buffer)
479620{
480621    static int width_table[4] = {5, 6, 7, 7};
481622
r984r985
495636    /* virtual X size (# bits to shift) */
496637    int v_width =        width_table[(vdc[which].vdc_data[MWR].w >> 4) & 3];
497638
498    /* our line buffer */
499    UINT16 *line_buffer = BITMAP_ADDR16( vce.bmp, bitmap_line, 86 );
500
501639    /* pointer to the name table (Background Attribute Table) in VRAM */
502640    UINT8 *bat = &(vdc[which].vram[nt_row << (v_width+1)]);
503641
r984r985
513651    /* character blanking bit */
514652    if(!(vdc[which].vdc_data[CR].w & CR_BB))
515653    {
516     draw_black_line(bitmap_line);
654      return;
517655    }
518656   else
519657   {
r984r985
554692               c &= 0x0F;
555693
556694            if ( phys_x >= 0 && phys_x < vdc[which].physical_width ) {
557               drawn[ phys_x ] = c ? 1 : 0;
695               drawn[ pixel ] = c ? 1 : 0;
558696               if ( c || ! external_input )
559697                  line_buffer[ pixel ] = Machine->pens[color_base + vce.vce_data[c].w];
560698               pixel++;
561699               if ( vdc[which].physical_width != 512 ) {
562700                  if ( pixel < ( ( ( phys_x + 1 ) * 512 ) / vdc[which].physical_width ) ) {
701                     drawn[ pixel ] = c ? 1 : 0;
563702                     if ( c || ! external_input )
564703                        line_buffer[ pixel ] = Machine->pens[color_base + vce.vce_data[c].w];
565704                     pixel++;
r984r985
605744   }
606745}
607746
608static void pce_refresh_sprites(int which, int bitmap_line, int line, UINT8 *drawn)
747static void pce_refresh_sprites(int which, int line, UINT8 *drawn, UINT16 *line_buffer)
609748{
610749    int i;
611750   UINT8 sprites_drawn=0;
612   UINT16 *line_buffer= BITMAP_ADDR16( vce.bmp, bitmap_line, 86 );
613751
614752   /* Are we in greyscale mode or in color mode? */
615753   int color_base = vce.vce_control & 0x80 ? 512 : 0;
r984r985
678816               if(((obj_x + x)<(vdc[which].physical_width))&&((obj_x + x)>=0))
679817               {
680818                  if ( buf[x] ) {
681                     if( drawn[obj_x+x] < 2 ) {
682                        if(priority || drawn[obj_x+x] == 0 ) {
819                     if( drawn[pixel_x] < 2 ) {
820                        drawn[pixel_x] = i + 2;
821                        if(priority || drawn[pixel_x] == 0 ) {
683822                           line_buffer[pixel_x] = Machine->pens[color_base + vce.vce_data[0x100 + (palette << 4) + buf[x]].w];
684823                           if ( vdc[which].physical_width != 512 ) {
685824                              if ( pixel_x + 1 < ( ( ( obj_x + x + 1 ) * 512 ) / vdc[which].physical_width ) ) {
825                                 drawn[pixel_x + 1] = i + 2;
686826                                 line_buffer[pixel_x + 1] = Machine->pens[color_base + vce.vce_data[0x100 + (palette << 4) + buf[x]].w];
687827                              }
688828                           }
689829                        }
690                        drawn[obj_x+x]=i+2;
691830                     }
692831                     /* Check for sprite #0 collision */
693                     else if (drawn[obj_x+x]==2)
832                     else if (drawn[pixel_x]==2)
694833                     {
695834                        if(vdc[which].vdc_data[CR].w&CR_CC)
696835                           cpunum_set_input_line(0, 0, ASSERT_LINE);
r984r985
718857               if(((obj_x + x)<(vdc[which].physical_width))&&((obj_x + x)>=0))
719858               {
720859                  if ( buf[x] ) {
721                     if( drawn[obj_x+x] < 2 ) {
722                        if ( priority || drawn[obj_x+x] == 0 ) {
860                     if( drawn[pixel_x] < 2 ) {
861                        drawn[pixel_x] = i + 2;
862                        if ( priority || drawn[pixel_x] == 0 ) {
723863                           line_buffer[pixel_x] = Machine->pens[color_base + vce.vce_data[0x100 + (palette << 4) + buf[x]].w];
724864                           if ( vdc[which].physical_width != 512 ) {
725865                              if ( pixel_x + 1 < ( ( ( obj_x + x + 1 ) * 512 ) / vdc[which].physical_width ) ) {
866                                 drawn[pixel_x + 1] = i + 2;
726867                                 line_buffer[pixel_x + 1] = Machine->pens[color_base + vce.vce_data[0x100 + (palette << 4) + buf[x]].w];
727868                              }
728869                           }
729870                        }
730                        drawn[obj_x + x]=i+2;
731871                     }
732872                     /* Check for sprite #0 collision */
733                     else if ( drawn[obj_x+x] == 2 ) {
873                     else if ( drawn[pixel_x] == 2 ) {
734874                        if(vdc[which].vdc_data[CR].w&CR_CC)
735875                           cpunum_set_input_line(0, 0, ASSERT_LINE);
736876                        vdc[which].status|=VDC_CR;
r984r985
760900                  if(((obj_x + 0x10 + x)<(vdc[which].physical_width))&&((obj_x + 0x10 + x)>=0))
761901                  {
762902                     if ( buf[x] ) {
763                        if( drawn[obj_x+0x10+x] < 2 ) {
764                           if( priority || drawn[obj_x+0x10+x] == 0 ) {
903                        if( drawn[pixel_x] < 2 ) {
904                           drawn[pixel_x] = i + 2;
905                           if( priority || drawn[pixel_x] == 0 ) {
765906                              line_buffer[pixel_x] = Machine->pens[color_base + vce.vce_data[0x100 + (palette << 4) + buf[x]].w];
766907                              if ( vdc[which].physical_width != 512 ) {
767908                                 if ( pixel_x + 1 < ( ( ( obj_x + x + 17 ) * 512 ) / vdc[which].physical_width ) ) {
909                                    drawn[pixel_x + 1] = i + 2;
768910                                    line_buffer[pixel_x + 1] = Machine->pens[color_base + vce.vce_data[0x100 + (palette << 4) + buf[x]].w];
769911                                 }
770912                              }                                   
771913                           }
772                           drawn[obj_x + 0x10 + x]=i+2;
773914                        }
774915                        /* Check for sprite #0 collision */
775                        else if ( drawn[obj_x+0x10+x]==2 ) {
916                        else if ( drawn[pixel_x]==2 ) {
776917                           if(vdc[which].vdc_data[CR].w&CR_CC)
777918                              cpunum_set_input_line(0, 0, ASSERT_LINE);
778919                           vdc[which].status|=VDC_CR;
r984r985
831972   }
832973   
833974}
975
976WRITE8_HANDLER( vpc_w ) {
977//printf("VPC write offset %02X, data %02X\n", offset, data );
978   switch( offset & 0x07 ) {
979   case 0x00:   /* Priority register #0 */
980      vpc.priority.b.l = data;
981      vpc.vpc_prio[0].prio = ( data >> 2 ) & 3;
982      vpc.vpc_prio[0].vdc0_enabled = data & 1;
983      vpc.vpc_prio[0].vdc1_enabled = data & 2;
984      vpc.vpc_prio[1].prio = ( data >> 6 ) & 3;
985      vpc.vpc_prio[1].vdc0_enabled = data & 0x10;
986      vpc.vpc_prio[1].vdc1_enabled = data & 0x20;
987      break;
988   case 0x01:   /* Priority register #1 */
989      vpc.priority.b.h = data;
990      vpc.vpc_prio[2].prio = ( data >> 2 ) & 3;
991      vpc.vpc_prio[2].vdc0_enabled = data & 1;
992      vpc.vpc_prio[2].vdc1_enabled = data & 2;
993      vpc.vpc_prio[3].prio = ( data >> 6 ) & 3;
994      vpc.vpc_prio[3].vdc0_enabled = data & 0x10;
995      vpc.vpc_prio[3].vdc1_enabled = data & 0x20;
996      break;
997   case 0x02:   /* Window 1 LSB */
998      vpc.window1.b.l = data;
999      break;
1000   case 0x03:   /* Window 1 MSB */
1001      vpc.window1.b.h = data & 3;
1002      break;
1003   case 0x04:   /* Window 2 LSB */
1004      vpc.window2.b.l = data;
1005      break;
1006   case 0x05:   /* Window 2 MSB */
1007      vpc.window2.b.h = data & 3;
1008      break;
1009   case 0x06:   /* VDC I/O select */
1010      vpc.vdc_select = data & 1;
1011      break;
1012   }
1013}
1014
1015READ8_HANDLER( vpc_r ) {
1016   UINT8 data = 0;
1017   switch( offset & 0x07 ) {
1018   case 0x00:  /* Priority register #0 */
1019      data = vpc.priority.b.l;
1020      break;
1021   case 0x01:  /* Priority register #1 */
1022      data = vpc.priority.b.h;
1023      break;
1024   case 0x02:  /* Window 1 LSB */
1025      data = vpc.window1.b.l;
1026      break;
1027   case 0x03:  /* Window 1 MSB; high bits are 0 or 1? */
1028      data = vpc.window1.b.h;
1029      break;
1030   case 0x04:  /* Window 2 LSB */
1031      data = vpc.window2.b.l;
1032      break;
1033   case 0x05:  /* Window 2 MSB; high bits are 0 or 1? */
1034      data = vpc.window2.b.h;
1035      break;
1036   }
1037   return data;
1038}
1039
1040static void vpc_init( void ) {
1041   vpc_w( 0, 0x11 );
1042   vpc_w( 1, 0x11 );
1043   vpc.window1.w = 0;
1044   vpc.window2.w = 0;
1045   vpc.vdc_select = 0;
1046}
1047
1048WRITE8_HANDLER( sgx_vdc_w ) {
1049   if ( vpc.vdc_select ) {
1050      vdc_1_w( offset, data );
1051   } else {
1052      vdc_0_w( offset, data );
1053   }
1054}
1055
1056READ8_HANDLER( sgx_vdc_r ) {
1057   return ( vpc.vdc_select ) ? vdc_1_r( offset ) : vdc_0_r( offset );
1058}
1059
src/mess/video/vdc.h
r984r985
1111PALETTE_INIT( vce );
1212 READ8_HANDLER ( vce_r );
1313WRITE8_HANDLER ( vce_w );
14WRITE8_HANDLER( vpc_w );
15 READ8_HANDLER( vpc_r );
16WRITE8_HANDLER( sgx_vdc_w );
17 READ8_HANDLER( sgx_vdc_r );
1418INTERRUPT_GEN( pce_interrupt );
19INTERRUPT_GEN( sgx_interrupt );
1520
1621/* Screen timing stuff */
1722

Previous 15994 Revisions Next


© 1998-2018 The MESS Team