Previous 199869 Revisions Next

r30694 Wednesday 28th May, 2014 at 08:12:56 UTC by Dirk Best
Amiga: Rendering update, always render the full height to allow mixed
mode screens. LACE and LOF bits should now work closer to the real
system.
[src/mame/drivers]cubo.c
[src/mame/includes]amiga.h
[src/mame/machine]amiga.c
[src/mame/video]amiga.c amigaaga.c

trunk/src/mame/drivers/cubo.c
r30693r30694
10441044   MCFG_AKIKO_SDA_WRITE_HANDLER(DEVWRITELINE("i2cmem", i2cmem_device, write_sda))
10451045
10461046   // video hardware
1047   MCFG_SCREEN_ADD("screen", RASTER)
1048   MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK)
1049   MCFG_SCREEN_RAW_PARAMS(amiga_state::CLK_28M_PAL / 4 * 2, 910, 186, 910, 312, 29 /* 26 */, 312)
1047   MCFG_FRAGMENT_ADD(pal_video)
1048   MCFG_DEVICE_MODIFY("screen")
10501049   MCFG_SCREEN_UPDATE_DRIVER(amiga_state, screen_update_amiga_aga)
10511050
10521051   MCFG_VIDEO_START_OVERRIDE(amiga_state, amiga_aga)
trunk/src/mame/machine/amiga.c
r30693r30694
310310
311311void amiga_state::vblank()
312312{
313   // signal vblank irq
314   set_interrupt(INTENA_SETCLR | INTENA_VERTB);
315
316   // clock cia a (todo: this can be connected to either a fixed 50/60hz signal from the power supply, or the vblank)
317   m_cia_0->tod_w(1);
318   m_cia_0->tod_w(0);
319313}
320314
315// todo: cia a clock can be connected to either a fixed 50/60hz signal from the power supply, or the vblank
321316TIMER_CALLBACK_MEMBER( amiga_state::scanline_callback )
322317{
318   amiga_state *state = this;
323319   int scanline = param;
324320
325   // on the first scanline, we do some extra bookkeeping
321   // vblank start
326322   if (scanline == 0)
323   {
324      // signal vblank irq
325      set_interrupt(INTENA_SETCLR | INTENA_VERTB);
326
327      // clock tod
328      m_cia_0->tod_w(1);
329
330      // additional bookkeeping by drivers
327331      vblank();
332   }
328333
329   // on every scanline, clock the second cia tod
330   m_cia_1->tod_w(1);
331   m_cia_1->tod_w(0);
334   // vblank end
335   if (scanline == m_screen->visible_area().min_y)
336   {
337      m_cia_0->tod_w(0);
338   }
332339
333340   // render up to this scanline
334341   if (!m_screen->update_partial(scanline))
r30693r30694
336343      if (IS_AGA(this))
337344      {
338345         bitmap_rgb32 dummy_bitmap;
339         amiga_aga_render_scanline(machine(), dummy_bitmap, scanline);
346         aga_render_scanline(dummy_bitmap, scanline);
340347      }
341348      else
342349      {
r30693r30694
345352      }
346353   }
347354
355   // clock tod (if we actually render this scanline)
356   m_cia_1->tod_w((scanline & 1) ^ BIT(CUSTOM_REG(REG_VPOSR), 15));
357
348358   // force a sound update
349359   m_sound->update();
350360
r30693r30694
15231533            data &= ~BPLCON0_BPU0;
15241534         }
15251535         CUSTOM_REG(offset) = data;
1526         update_screenmode();
15271536         break;
15281537
15291538      case REG_COLOR00:   case REG_COLOR01:   case REG_COLOR02:   case REG_COLOR03:
trunk/src/mame/includes/amiga.h
r30693r30694
361361   m_centronics_perror(0),
362362   m_centronics_select(0),
363363   m_gayle_reset(false),
364   m_previous_lof(true),
364365   m_rx_shift(0),
365366   m_tx_shift(0),
366367   m_rx_state(0),
r30693r30694
417418   DECLARE_PALETTE_INIT( amiga );
418419
419420   void render_scanline(bitmap_ind16 &bitmap, int scanline);
421   void aga_render_scanline(bitmap_rgb32 &bitmap, int scanline);
420422   UINT32 screen_update_amiga(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
421423   UINT32 screen_update_amiga_aga(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
422424   void update_screenmode();
r30693r30694
472474   enum
473475   {
474476      SCREEN_WIDTH = 910,
475      SCREEN_HEIGHT_PAL = 312,
476      SCREEN_HEIGHT_NTSC = 262,
477      VBLANK_PAL = 29, // 26
478      VBLANK_NTSC = 21,
477      SCREEN_HEIGHT_PAL = 625,
478      SCREEN_HEIGHT_NTSC = 525,
479      VBLANK_PAL = 58, // 52
480      VBLANK_NTSC = 42,
479481      HBLANK = 186
480482   };
481483
r30693r30694
586588
587589   enum
588590   {
591      VPOSR_LOF = 0x8000   // long frame
592   };
593
594   enum
595   {
589596      ADKCON_UARTBRK = 0x800   // send break
590597   };
591598
r30693r30694
613620
614621   bool m_gayle_reset;
615622
623   bool m_previous_lof;
616624   bitmap_ind16 m_flickerfixer;
625   bitmap_ind32 m_flickerfixer32;
617626
618627   UINT16 m_rx_shift;
619628   UINT16 m_tx_shift;
r30693r30694
640649void amiga_chip_ram_w8(amiga_state *state, offs_t offset, UINT8 data);
641650
642651
643
644652/*----------- defined in video/amiga.c -----------*/
645653
646654extern const UINT16 amiga_expand_byte[256];
r30693r30694
653661void amiga_sprite_dma_reset(running_machine &machine, int which);
654662void amiga_sprite_enable_comparitor(running_machine &machine, int which, int enable);
655663
664MACHINE_CONFIG_EXTERN( pal_video );
665MACHINE_CONFIG_EXTERN( ntsc_video );
666
656667/*----------- defined in video/amigaaga.c -----------*/
657668
658void amiga_aga_render_scanline(running_machine &machine, bitmap_rgb32 &bitmap, int scanline);
659669void amiga_aga_palette_write(running_machine &machine, int color_reg, UINT16 data);
660670void amiga_aga_diwhigh_written(running_machine &machine, int written);
661MACHINE_CONFIG_EXTERN( pal_video );
662MACHINE_CONFIG_EXTERN( ntsc_video );
663671
664672#endif /* __AMIGA_H__ */
trunk/src/mame/video/amiga.c
r30693r30694
626626   UINT16 save_color0 = CUSTOM_REG(REG_COLOR00);
627627   int ddf_start_pixel = 0, ddf_stop_pixel = 0;
628628   int hires = 0, dualpf = 0, ham = 0;
629   bool lace = CUSTOM_REG(REG_BPLCON0) & BPLCON0_LACE;
630629   int hstart = 0, hstop = 0;
631630   int vstart = 0, vstop = 0;
632631   int pf1pri = 0, pf2pri = 0;
633632   int planes = 0;
634633
635   int x;
636634   UINT16 *dst = NULL;
637635   int ebitoffs = 0, obitoffs = 0;
638636   int ecolmask = 0, ocolmask = 0;
r30693r30694
646644   // we need to do a bit more work on the first scanline
647645   if (scanline == 0)
648646   {
649      // toggle lof if interlaced
650      if (lace)
651         CUSTOM_REG(REG_VPOSR) ^= 0x8000;
647      m_previous_lof = CUSTOM_REG(REG_VPOSR) & VPOSR_LOF;
652648
649      // toggle lof if enabled
650      if (CUSTOM_REG(REG_BPLCON0) & BPLCON0_LACE)
651         CUSTOM_REG(REG_VPOSR) ^= VPOSR_LOF;
652
653653      // reset copper and ham color
654654      amiga_copper_setpc(machine(), CUSTOM_REG_LONG(REG_COP1LCH));
655655      m_ham_color = CUSTOM_REG(REG_COLOR00);
r30693r30694
658658   // in visible area?
659659   if (bitmap.valid())
660660   {
661      // if interlace is enabled and this is not our turn to draw, copy the previous scanline
662      if (lace && ((scanline & 1) ^ BIT(CUSTOM_REG(REG_VPOSR), 15)) == 0)
661      bool lof = CUSTOM_REG(REG_VPOSR) & VPOSR_LOF;
662
663      if ((scanline & 1) ^ lof)
663664      {
664         memcpy(&bitmap.pix16(scanline), &m_flickerfixer.pix16(scanline), amiga_state::SCREEN_WIDTH * 2);
665         return;
665         // lof matches? then render this scanline
666         dst = &bitmap.pix16(scanline);
666667      }
667668      else
668         dst = &bitmap.pix16(scanline);
669      {
670         // lof doesn't match, we don't render this scanline
671         // if we didn't switch lof we have a full non-interlace screen,
672         // so we fill the black gaps with the contents of the previous scanline
673         // otherwise just render the contents of the previous frame's scanline
674         int shift = (m_previous_lof == lof) ? 1 : 0;
675
676         memcpy(&bitmap.pix16(scanline), &m_flickerfixer.pix16(scanline - shift), amiga_state::SCREEN_WIDTH * 2);
677         return;
678      }
669679   }
670680
671   if (lace)
672      scanline /= 2;
681   scanline /= 2;
673682
674683   m_last_scanline = scanline;
675684
r30693r30694
685694
686695   /* loop over the line */
687696   next_copper_x = 0;
688   for (x = 0; x < amiga_state::SCREEN_WIDTH / 2; x++)
697   for (int x = 0; x < amiga_state::SCREEN_WIDTH / 2; x++)
689698   {
690699      int sprpix;
691700
r30693r30694
987996#if GUESS_COPPER_OFFSET
988997   if (m_screen->frame_number() % 64 == 0 && scanline == 0)
989998   {
990      if (machine.input().code_pressed(KEYCODE_Q))
999      if (machine().input().code_pressed(KEYCODE_Q))
9911000         popmessage("%d", m_wait_offset -= 1);
992      if (machine.input().code_pressed(KEYCODE_W))
1001      if (machine().input().code_pressed(KEYCODE_W))
9931002         popmessage("%d", m_wait_offset += 1);
9941003   }
9951004#endif
r30693r30694
10381047   // frame period
10391048   attoseconds_t period = HZ_TO_ATTOSECONDS(m_screen->clock()) * SCREEN_WIDTH * height;
10401049
1041   // interlace mode?
1042   bool lace = CUSTOM_REG(REG_BPLCON0) & BPLCON0_LACE;
1043
1044   if (lace)
1045   {
1046      // this doubles our vertical resolution
1047      height *= 2;
1048      height++;
1049      vblank *= 2;
1050   }
1051
10521050   // adjust visible area
10531051   rectangle visarea = m_screen->visible_area();
10541052   visarea.sety(vblank, height - 1);
10551053
1056#if 0
1057   logerror("screenmode changed: %dx%d%s\n", SCREEN_WIDTH, height, lace ? " (interlace)" : "");
1058#endif
1059
10601054   // finally set our new mode
10611055   m_screen->configure(SCREEN_WIDTH, height, visarea, period);
10621056}
r30693r30694
10701064   MCFG_SCREEN_ADD("screen", RASTER)
10711065   MCFG_SCREEN_RAW_PARAMS
10721066   (
1073      amiga_state::CLK_28M_PAL / 4 * 2,
1067      (amiga_state::CLK_28M_PAL / 4) * 2 * 2,
10741068      amiga_state::SCREEN_WIDTH, amiga_state::HBLANK, amiga_state::SCREEN_WIDTH,
10751069      amiga_state::SCREEN_HEIGHT_PAL, amiga_state::VBLANK_PAL, amiga_state::SCREEN_HEIGHT_PAL
10761070   )
r30693r30694
10821076   MCFG_SCREEN_ADD("screen", RASTER)
10831077   MCFG_SCREEN_RAW_PARAMS
10841078   (
1085      amiga_state::CLK_28M_NTSC / 4 * 2,
1079      (amiga_state::CLK_28M_NTSC / 4) * 2 * 2,
10861080      amiga_state::SCREEN_WIDTH, amiga_state::HBLANK, amiga_state::SCREEN_WIDTH,
10871081      amiga_state::SCREEN_HEIGHT_NTSC, amiga_state::VBLANK_NTSC, amiga_state::SCREEN_HEIGHT_NTSC
10881082   )
trunk/src/mame/video/amigaaga.c
r30693r30694
7676   VIDEO_START_CALL_MEMBER( amiga );
7777
7878   m_aga_diwhigh_written = 0;
79   m_screen->register_screen_bitmap(m_flickerfixer32);
7980}
8081
8182
r30693r30694
442443 *
443444 *************************************/
444445
445void amiga_aga_render_scanline(running_machine &machine, bitmap_rgb32 &bitmap, int scanline)
446void amiga_state::aga_render_scanline(bitmap_rgb32 &bitmap, int scanline)
446447{
447   amiga_state *state = machine.driver_data<amiga_state>();
448   amiga_state *state = this;
448449   UINT16 save_color0 = CUSTOM_REG(REG_COLOR00);
449450   int ddf_start_pixel = 0, ddf_stop_pixel = 0;
450451   int hires = 0, dualpf = 0, ham = 0;
r30693r30694
453454   int pf1pri = 0, pf2pri = 0;
454455   int planes = 0;
455456
456   int x;
457457   UINT32 *dst = NULL;
458458   int ebitoffs = 0, obitoffs = 0;
459459   int ecolmask = 0, ocolmask = 0;
r30693r30694
461461   int next_copper_x;
462462   int pl;
463463   int defbitoffs = 0;
464   rgb_t *aga_palette = state->m_aga_palette;
464   rgb_t *aga_palette = m_aga_palette;
465465
466   state->m_last_scanline = scanline;
466   int save_scanline = scanline;
467467
468468   /* on the first scanline, reset the COPPER and HAM color */
469469   if (scanline == 0)
470470   {
471      amiga_copper_setpc(machine, CUSTOM_REG_LONG(REG_COP1LCH));
472      state->m_ham_color = CUSTOM_REG(REG_COLOR00);
471      m_previous_lof = CUSTOM_REG(REG_VPOSR) & VPOSR_LOF;
472
473      // toggle lof if enabled
474      if (CUSTOM_REG(REG_BPLCON0) & BPLCON0_LACE)
475         CUSTOM_REG(REG_VPOSR) ^= VPOSR_LOF;
476
477      amiga_copper_setpc(machine(), CUSTOM_REG_LONG(REG_COP1LCH));
478      m_ham_color = CUSTOM_REG(REG_COLOR00);
473479   }
474480
481   // in visible area?
482   if (bitmap.valid())
483   {
484      bool lof = CUSTOM_REG(REG_VPOSR) & VPOSR_LOF;
485
486      if ((scanline & 1) ^ lof)
487      {
488         // lof matches? then render this scanline
489         dst = &bitmap.pix32(scanline);
490      }
491      else
492      {
493         // lof doesn't match, we don't render this scanline
494         // if we didn't switch lof we have a full non-interlace screen,
495         // so we fill the black gaps with the contents of the previous scanline
496         // otherwise just render the contents of the previous frame's scanline
497         int shift = (m_previous_lof == lof) ? 1 : 0;
498
499         memcpy(&bitmap.pix32(scanline), &m_flickerfixer32.pix32(scanline - shift), amiga_state::SCREEN_WIDTH * 4);
500         return;
501      }
502   }
503
504   scanline /= 2;
505
506   m_last_scanline = scanline;
507
475508   /* update sprite data fetching */
476509   update_sprite_dma(state, scanline);
477510
478   /* start of a new line, signal we're not done with it and fill up vars */
479   if (bitmap.valid())
480      dst = &bitmap.pix32(scanline);
481
482511   /* all sprites off at the start of the line */
483   memset(state->m_sprite_remain, 0, sizeof(state->m_sprite_remain));
512   memset(m_sprite_remain, 0, sizeof(m_sprite_remain));
484513
485514   /* temporary set color 0 to the genlock color */
486   if (state->m_genlock_color != 0xffff)
487      CUSTOM_REG(REG_COLOR00) = state->m_genlock_color;
515   if (m_genlock_color != 0xffff)
516      CUSTOM_REG(REG_COLOR00) = m_genlock_color;
488517
489518   /* loop over the line */
490519   next_copper_x = 2;  /* copper runs on odd timeslots */
491   for (x = 0; x < 0xe8*2; x++)
520   for (int x = 0; x < amiga_state::SCREEN_WIDTH / 2; x++)
492521   {
493522      int sprpix;
494523
r30693r30694
497526      {
498527         /* execute the next batch, restoring and re-saving color 0 around it */
499528         CUSTOM_REG(REG_COLOR00) = save_color0;
500         next_copper_x = amiga_copper_execute_next(machine, x);
529         next_copper_x = amiga_copper_execute_next(machine(), x);
501530         save_color0 = CUSTOM_REG(REG_COLOR00);
502         if (state->m_genlock_color != 0xffff)
503            CUSTOM_REG(REG_COLOR00) = state->m_genlock_color;
531         if (m_genlock_color != 0xffff)
532            CUSTOM_REG(REG_COLOR00) = m_genlock_color;
504533
505534         /* compute update-related register values */
506535         planes = (CUSTOM_REG(REG_BPLCON0) & (BPLCON0_BPU0 | BPLCON0_BPU1 | BPLCON0_BPU2)) >> 12;
r30693r30694
532561         hstart = CUSTOM_REG(REG_DIWSTRT) & 0xff;
533562         hstop = (CUSTOM_REG(REG_DIWSTOP) & 0xff);
534563
535         if (state->m_aga_diwhigh_written)
564         if (m_aga_diwhigh_written)
536565         {
537566            hstart |= ((CUSTOM_REG(REG_DIWHIGH) >> 5) & 1) << 8;
538567            hstop |= ((CUSTOM_REG(REG_DIWHIGH) >> 13) & 1) << 8;
r30693r30694
550579         /* compute the vertical start/stop */
551580         vstart = CUSTOM_REG(REG_DIWSTRT) >> 8;
552581         vstop = (CUSTOM_REG(REG_DIWSTOP) >> 8);
553         if (state->m_aga_diwhigh_written)
582         if (m_aga_diwhigh_written)
554583         {
555584            vstart |= (CUSTOM_REG(REG_DIWHIGH) & 7) << 8;
556585            vstop |= ((CUSTOM_REG(REG_DIWHIGH) >> 8) & 7) << 8;
r30693r30694
598627         }
599628
600629         for (pl = 0; pl < 8; pl++)
601            state->m_aga_bpldat[pl] = 0;
630            m_aga_bpldat[pl] = 0;
602631      }
603632
604633      /* need to run the sprite engine every pixel to ensure display */
r30693r30694
758787               if (pix)
759788                  dst[x*2+0] = aga_palette[pix];
760789               else
761                  dst[x*2+0] = aga_palette[state->m_separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix0]];
790                  dst[x*2+0] = aga_palette[m_separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix0]];
762791
763792               /* mask out the sprite if it doesn't have priority */
764793               pix = sprpix & 0xff;
r30693r30694
774803               if (pix)
775804                  dst[x*2+1] = aga_palette[pix];
776805               else
777                  dst[x*2+1] = aga_palette[state->m_separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix1]];
806                  dst[x*2+1] = aga_palette[m_separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix1]];
778807            }
779808
780809            /* single playfield mode */
r30693r30694
839868   /* restore color00 */
840869   CUSTOM_REG(REG_COLOR00) = save_color0;
841870
871   // save
872   if (dst != NULL)
873      memcpy(&m_flickerfixer32.pix32(save_scanline), dst, amiga_state::SCREEN_WIDTH * 4);
874
842875#if GUESS_COPPER_OFFSET
843876   if (m_screen->frame_number() % 64 == 0 && scanline == 0)
844877   {
r30693r30694
860893
861894UINT32 amiga_state::screen_update_amiga_aga(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
862895{
863   int y;
896   if (cliprect.min_y != cliprect.max_y)
897      return 0;
864898
865   /* render each scanline in the visible region */
866   for (y = cliprect.min_y; y <= cliprect.max_y; y++)
867      amiga_aga_render_scanline(machine(), bitmap, y);
899   // render each scanline in the visible region
900   for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
901      aga_render_scanline(bitmap, y);
868902
869903   return 0;
870904}

Previous 199869 Revisions Next


© 1997-2024 The MAME Team