Previous 199869 Revisions Next

r19848 Thursday 27th December, 2012 at 04:37:23 UTC by Angelo Salese
VGA: fixed PEL shift register and putted start address update behind a timer (that updates at vblank time). Fixes horizontal scrolling with anything that uses it [Angelo Salese]
[src/emu/video]pc_vga.c pc_vga.h

trunk/src/emu/video/pc_vga.c
r19847r19848
2626    per-game issues:
2727    - The Incredible Machine: fix partial updates
2828    - MAME 0.01: fix 92 Hz refresh rate bug (uses VESA register?).
29    - Alien Breed, Bio Menace: jerky H scrolling (uses VGA/EGA mode with pel shift)
3029    - Virtual Pool: ET4k unrecognized;
3130    - California Chase (calchase): various gfx bugs, CPU related?
31    - Jazz Jackrabbit: status bar is very jerky, but main screen scrolling is fine?
32   - Catacombs: weird resolution (untested)
3233
3334    ROM declarations:
3435
r19847r19848
193194{
194195}
195196
197
198/* VBLANK callback, start address definitely updates AT vblank, not before. */
199TIMER_CALLBACK_MEMBER(vga_device::vblank_timer_cb)
200{
201   vga.crtc.start_addr = vga.crtc.start_addr_latch;
202   m_vblank_timer->adjust( machine().primary_screen->time_until_pos(vga.crtc.vert_blank_start) );
203}
204
196205void vga_device::device_start()
197206{
198207   memset(&vga, 0, sizeof(vga));
r19847r19848
212221   vga.svga_intf.crtc_regcount = 0x19;
213222
214223   vga.memory   = auto_alloc_array_clear(machine(), UINT8, vga.svga_intf.vram_size);
224
225   m_vblank_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vga_device::vblank_timer_cb),this));
215226}
216227
217228void svga_device::device_start()
r19847r19848
370381   int height = vga.crtc.maximum_scan_line * (vga.crtc.scan_doubling + 1);
371382   UINT32 *bitmapline;
372383   pen_t pen;
384   int pel_shift = (vga.attribute.pel_shift);
373385
386//   popmessage("%08x %02x",EGA_START_ADDRESS,pel_shift);
387
374388   /**/
375389   for (addr=EGA_START_ADDRESS, pos=0, line=0; line<LINES;
376390       line += height, addr += EGA_LINE_LENGTH)
r19847r19848
379393      {
380394         bitmapline = &bitmap.pix32(line + yi);
381395
382         for (pos=addr, c=0, column=0; column<EGA_COLUMNS; column++, c+=8, pos=(pos+1)&0xffff)
396         for (pos=addr, c=0, column=0; column<EGA_COLUMNS+1; column++, c+=8, pos=(pos+1)&0xffff)
383397         {
384398            int data[4];
385399
r19847r19848
391405            for (i = 7; i >= 0; i--)
392406            {
393407               pen = vga.pens[(data[0]&1) | (data[1]&2) | (data[2]&4) | (data[3]&8)];
394               if(!machine().primary_screen->visible_area().contains(c+i, line + yi))
395                  continue;
396               bitmapline[c+i] = pen;
397408
398409               data[0]>>=1;
399410               data[1]>>=1;
400411               data[2]>>=1;
401412               data[3]>>=1;
413
414               if(!machine().primary_screen->visible_area().contains(c+i-pel_shift, line + yi))
415                  continue;
416               bitmapline[c+i-pel_shift] = pen;
402417            }
403418         }
404419      }
r19847r19848
414429   int height = vga.crtc.maximum_scan_line * (vga.crtc.scan_doubling + 1);
415430   int yi;
416431   int xi;
417   int pel_shift = 0;//vga.attribute.pel_shift; /* TODO: timing bug with this */
432   int pel_shift = (vga.attribute.pel_shift & 6);
418433
419434   /* line compare is screen sensitive */
420435   mask_comp = 0x3ff; //| (LINES & 0x300);
421436
437//   popmessage("%02x %02x",vga.attribute.pel_shift,vga.sequencer.data[4] & 0x08);
438
422439   curr_addr = 0;
423440   if(!(vga.sequencer.data[4] & 0x08))
424441   {
r19847r19848
431448            if((line + yi) == (vga.crtc.line_compare & mask_comp))
432449               curr_addr = 0;
433450            bitmapline = &bitmap.pix32(line + yi);
434            for (pos=curr_addr, c=0, column=0; column<VGA_COLUMNS; column++, c+=8, pos++)
451            for (pos=curr_addr, c=0, column=0; column<VGA_COLUMNS+1; column++, c+=8, pos++)
435452            {
436453               if(pos > 0x80000/4)
437454                  return;
438455
439456               for(xi=0;xi<8;xi++)
440457               {
441                  if(!machine().primary_screen->visible_area().contains(c+xi-pel_shift, line + yi))
458                  if(!machine().primary_screen->visible_area().contains(c+xi-(pel_shift), line + yi))
442459                     continue;
443                  bitmapline[c+xi-pel_shift] = machine().pens[vga.memory[(pos & 0xffff)+((xi >> 1)*0x10000)]];
460                  bitmapline[c+xi-(pel_shift)] = machine().pens[vga.memory[(pos & 0xffff)+((xi >> 1)*0x10000)]];
444461               }
445462            }
446463         }
r19847r19848
458475               curr_addr = 0;
459476            bitmapline = &bitmap.pix32(line + yi);
460477            //addr %= 0x80000;
461            for (pos=curr_addr, c=0, column=0; column<VGA_COLUMNS; column++, c+=0x10, pos+=0x8)
478            for (pos=curr_addr, c=0, column=0; column<VGA_COLUMNS+1; column++, c+=0x10, pos+=0x8)
462479            {
463480               if(pos + 0x08 > 0x80000)
464481                  return;
465482
466483               for(xi=0;xi<0x10;xi++)
467484               {
468                  if(!machine().primary_screen->visible_area().contains(c+xi-pel_shift, line + yi))
485                  if(!machine().primary_screen->visible_area().contains(c+xi-(pel_shift), line + yi))
469486                     continue;
470487                  bitmapline[c+xi-pel_shift] = machine().pens[vga.memory[(pos+(xi >> 1)) & 0xffff]];
471488               }
r19847r19848
939956
940957   return 0;
941958}
959
942960UINT32 svga_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
943961{
944962   UINT8 cur_mode = pc_vga_choosevideomode();
963
945964   switch(cur_mode)
946965   {
947966      case SCREEN_OFF:   bitmap.fill  (get_black_pen(machine()), cliprect);break;
r19847r19848
11581177         break;
11591178      case 0x0c:
11601179      case 0x0d:
1161         res  = (vga.crtc.start_addr >> ((index & 1) ^ 1)*8) & 0xff;
1180         res  = (vga.crtc.start_addr_latch >> ((index & 1) ^ 1)*8) & 0xff;
11621181         break;
11631182      case 0x0e:
11641183      case 0x0f:
r19847r19848
12311250
12321251   machine().primary_screen->configure((hblank_period), (vblank_period), visarea, refresh );
12331252//  popmessage("%d %d\n",vga.crtc.horz_total * 8,vga.crtc.vert_total);
1253
1254   m_vblank_timer->adjust( machine().primary_screen->time_until_pos(vga.crtc.vert_blank_start) );
12341255}
12351256
12361257void vga_device::recompute_params()
r19847r19848
13331354         break;
13341355      case 0x0c:
13351356      case 0x0d:
1336         vga.crtc.start_addr &= ~(0xff << (((index & 1)^1) * 8));
1337         vga.crtc.start_addr |= (data << (((index & 1)^1) * 8));
1357         vga.crtc.start_addr_latch &= ~(0xff << (((index & 1)^1) * 8));
1358         vga.crtc.start_addr_latch |= (data << (((index & 1)^1) * 8));
13381359         break;
13391360      case 0x0e:
13401361      case 0x0f:
r19847r19848
20452066   MCFG_SCREEN_UPDATE_DEVICE("vga", trident_vga_device, screen_update)
20462067
20472068   MCFG_PALETTE_LENGTH(0x100)
2048
20492069   MCFG_DEVICE_ADD("vga", TRIDENT_VGA, 0)
20502070MACHINE_CONFIG_END
20512071
r19847r19848
20552075   MCFG_SCREEN_UPDATE_DEVICE("vga", cirrus_vga_device, screen_update)
20562076
20572077   MCFG_PALETTE_LENGTH(0x100)
2058
20592078   MCFG_DEVICE_ADD("vga", CIRRUS_VGA, 0)
20602079MACHINE_CONFIG_END
20612080
r19847r19848
26602679            res = s3.cursor_pattern_y;
26612680            break;
26622681         case 0x51:
2663            res = (vga.crtc.start_addr & 0x0c0000) >> 18;
2682            res = (vga.crtc.start_addr_latch & 0x0c0000) >> 18;
26642683            break;
26652684         case 0x55:
26662685            res = s3.extended_dac_ctrl;
r19847r19848
26692688            res = s3.ext_misc_ctrl_2;
26702689            break;
26712690         case 0x69:
2672            res = vga.crtc.start_addr >> 16;
2691            res = vga.crtc.start_addr_latch >> 16;
26732692            break;
26742693         case 0x6a:
26752694            res = svga.bank_r & 0x7f;
r19847r19848
27812800      {
27822801         case 0x31: // CR31 Memory Configuration Register
27832802            s3.memory_config = data;
2784            vga.crtc.start_addr &= ~0x30000;
2785            vga.crtc.start_addr |= ((data & 0x30) << 12);
2803            vga.crtc.start_addr_latch &= ~0x30000;
2804            vga.crtc.start_addr_latch |= ((data & 0x30) << 12);
27862805            //popmessage("%02x",data);
27872806            s3_define_video_mode();
27882807            break;
r19847r19848
29302949            s3.cursor_pattern_y = data;
29312950            break;
29322951         case 0x51:
2933            vga.crtc.start_addr &= ~0xc0000;
2934            vga.crtc.start_addr |= ((data & 0x3) << 18);
2952            vga.crtc.start_addr_latch &= ~0xc0000;
2953            vga.crtc.start_addr_latch |= ((data & 0x3) << 18);
29352954            svga.bank_w = (svga.bank_w & 0xcf) | ((data & 0x0c) << 2);
29362955            svga.bank_r = svga.bank_r;
29372956            s3_define_video_mode();
r19847r19848
30223041            //printf("%02x X\n",data);
30233042            break;
30243043         case 0x69:
3025            vga.crtc.start_addr &= ~0x1f0000;
3026            vga.crtc.start_addr |= ((data & 0x1f) << 16);
3044            vga.crtc.start_addr_latch &= ~0x1f0000;
3045            vga.crtc.start_addr_latch |= ((data & 0x1f) << 16);
30273046            s3_define_video_mode();
30283047            break;
30293048         case 0x6a:
r19847r19848
49965015      switch(ati.ext_reg_select)
49975016      {
49985017      case 0x23:
4999         vga.crtc.start_addr = (vga.crtc.start_addr & 0xfffdffff) | ((data & 0x10) << 13);
5018         vga.crtc.start_addr_latch = (vga.crtc.start_addr_latch & 0xfffdffff) | ((data & 0x10) << 13);
50005019         vga.crtc.cursor_addr = (vga.crtc.cursor_addr & 0xfffdffff) | ((data & 0x08) << 14);
50015020         logerror("ATI: ATI23 write %02x\n",data);
50025021         break;
r19847r19848
50105029         logerror("ATI: ATI2D (extensions) write %02x\n",data);
50115030         break;
50125031      case 0x30:
5013         vga.crtc.start_addr = (vga.crtc.start_addr & 0xfffeffff) | ((data & 0x40) << 10);
5032         vga.crtc.start_addr_latch = (vga.crtc.start_addr_latch & 0xfffeffff) | ((data & 0x40) << 10);
50145033         vga.crtc.cursor_addr = (vga.crtc.cursor_addr & 0xfffeffff) | ((data & 0x04) << 14);
50155034         logerror("ATI: ATI30 write %02x\n",data);
50165035         break;
trunk/src/emu/video/pc_vga.h
r19847r19848
3838   virtual WRITE8_MEMBER(mem_w);
3939   virtual READ8_MEMBER(mem_linear_r);
4040   virtual WRITE8_MEMBER(mem_linear_w);
41   virtual TIMER_CALLBACK_MEMBER(vblank_timer_cb);
4142protected:
4243    // device-level overrides
4344    virtual void device_start();
r19847r19848
123124   /**/   UINT8 cursor_skew;
124125   /**/   UINT8 cursor_scan_end;
125126         UINT32 start_addr;
127         UINT32 start_addr_latch;
126128   /**/   UINT8 protect_enable;
127129   /**/   UINT8 bandwidth;
128130   /**/   UINT8 offset;
r19847r19848
184186      /* oak vga */
185187      struct { UINT8 reg; } oak;
186188   } vga;
189
190   emu_timer *m_vblank_timer;
187191};
188192
189193

Previous 199869 Revisions Next


© 1997-2024 The MAME Team