Previous 199869 Revisions Next

r30588 Wednesday 21st May, 2014 at 17:14:01 UTC by Dirk Best
Amiga: Add support for interlaced modes. Currently, this basically
emulates a "flickerfixer" device because the core doesn't have native
interlace support yet.
[src/mame/includes]amiga.h
[src/mame/machine]amiga.c
[src/mame/video]amiga.c

trunk/src/mame/machine/amiga.c
r30587r30588
338338      else
339339      {
340340         bitmap_ind16 dummy_bitmap;
341         amiga_render_scanline(machine(), dummy_bitmap, scanline);
341         render_scanline(dummy_bitmap, scanline);
342342      }
343343   }
344344
r30587r30588
11841184         return CUSTOM_REG(REG_DMACON);
11851185
11861186      case REG_VPOSR:
1187         CUSTOM_REG(REG_VPOSR) &= 0x7f00;
1187         CUSTOM_REG(REG_VPOSR) &= 0xff00;
11881188         CUSTOM_REG(REG_VPOSR) |= amiga_gethvpos(*m_screen) >> 16;
1189         if(CUSTOM_REG(REG_BPLCON0) & BPLCON0_LACE && m_screen->frame_number() & 0x1)
1190            CUSTOM_REG(REG_VPOSR) |= 0x8000; // LOF bit
11911189
11921190         return CUSTOM_REG(REG_VPOSR);
11931191
r30587r30588
14641462            logerror( "This game is doing funky planes stuff. (planes > 6)\n" );
14651463            data &= ~BPLCON0_BPU0;
14661464         }
1465         CUSTOM_REG(offset) = data;
1466         update_screenmode();
14671467         break;
14681468
14691469      case REG_COLOR00:   case REG_COLOR01:   case REG_COLOR02:   case REG_COLOR03:
r30587r30588
14981498         // only available on ecs agnus
14991499         if (m_agnus_id >= AGNUS_HR_PAL)
15001500         {
1501            int height = BIT(data, 5) ? SCREEN_HEIGHT_PAL : SCREEN_HEIGHT_NTSC;
1502            rectangle visarea = m_screen->visible_area();
1503            visarea.sety(BIT(data, 5) ? VBLANK_PAL : VBLANK_NTSC, height - 1);
1504            attoseconds_t period = HZ_TO_ATTOSECONDS(m_screen->clock()) * SCREEN_WIDTH * height;
1505            m_screen->configure(SCREEN_WIDTH, height, visarea, period);
1506
15071501            CUSTOM_REG(REG_BEAMCON0) = data;
1502            update_screenmode();
15081503         }
15091504         break;
15101505
trunk/src/mame/includes/amiga.h
r30587r30588
409409   DECLARE_VIDEO_START( amiga_aga );
410410   DECLARE_PALETTE_INIT( amiga );
411411
412   void render_scanline(bitmap_ind16 &bitmap, int scanline);
412413   UINT32 screen_update_amiga(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
413414   UINT32 screen_update_amiga_aga(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
415   void update_screenmode();
414416
415417   TIMER_CALLBACK_MEMBER( scanline_callback );
416418   TIMER_CALLBACK_MEMBER (amiga_irq_proc );
r30587r30588
574576   emu_timer *m_irq_timer;
575577
576578   bool m_gayle_reset;
579
580   bitmap_ind16 m_flickerfixer;
577581};
578582
579583
r30587r30588
594598
595599UINT32 amiga_gethvpos(screen_device &screen);
596600void amiga_set_genlock_color(running_machine &machine, UINT16 color);
597void amiga_render_scanline(running_machine &machine, bitmap_ind16 &bitmap, int scanline);
598601void amiga_sprite_dma_reset(running_machine &machine, int which);
599602void amiga_sprite_enable_comparitor(running_machine &machine, int which, int enable);
600603
trunk/src/mame/video/amiga.c
r30587r30588
132132   m_genlock_color = 0xffff;
133133
134134   m_sprite_ctl_written = 0;
135
136   m_screen->register_screen_bitmap(m_flickerfixer);
135137}
136138
137139
r30587r30588
618620 *
619621 *************************************/
620622
621void amiga_render_scanline(running_machine &machine, bitmap_ind16 &bitmap, int scanline)
623void amiga_state::render_scanline(bitmap_ind16 &bitmap, int scanline)
622624{
623   amiga_state *state = machine.driver_data<amiga_state>();
625   amiga_state *state = this;
624626   UINT16 save_color0 = CUSTOM_REG(REG_COLOR00);
625627   int ddf_start_pixel = 0, ddf_stop_pixel = 0;
626628   int hires = 0, dualpf = 0, ham = 0;
627   //int lace = 0;
629   bool lace = CUSTOM_REG(REG_BPLCON0) & BPLCON0_LACE;
628630   int hstart = 0, hstop = 0;
629631   int vstart = 0, vstop = 0;
630632   int pf1pri = 0, pf2pri = 0;
r30587r30588
639641   int pl;
640642   const int defbitoffs = 15;
641643
642   state->m_last_scanline = scanline;
644   int save_scanline = scanline;
643645
644   /* on the first scanline, reset the COPPER and HAM color */
646   // we need to do a bit more work on the first scanline
645647   if (scanline == 0)
646648   {
647      amiga_copper_setpc(machine, CUSTOM_REG_LONG(REG_COP1LCH));
648      state->m_ham_color = CUSTOM_REG(REG_COLOR00);
649      // toggle lof if interlaced
650      if (lace)
651         CUSTOM_REG(REG_VPOSR) ^= 0x8000;
652
653      // reset copper and ham color
654      amiga_copper_setpc(machine(), CUSTOM_REG_LONG(REG_COP1LCH));
655      m_ham_color = CUSTOM_REG(REG_COLOR00);
649656   }
650657
658   // in visible area?
659   if (bitmap.valid())
660   {
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)
663      {
664         memcpy(&bitmap.pix16(scanline), &m_flickerfixer.pix16(scanline), amiga_state::SCREEN_WIDTH * 2);
665         return;
666      }
667      else
668         dst = &bitmap.pix16(scanline);
669   }
670
671   if (lace)
672      scanline /= 2;
673
674   m_last_scanline = scanline;
675
651676   /* update sprite data fetching */
652677   update_sprite_dma(state, scanline);
653678
654   /* start of a new line, signal we're not done with it and fill up vars */
655   if (bitmap.valid())
656      dst = &bitmap.pix16(scanline);
657
658679   /* all sprites off at the start of the line */
659   memset(state->m_sprite_remain, 0, sizeof(state->m_sprite_remain));
680   memset(m_sprite_remain, 0, sizeof(m_sprite_remain));
660681
661682   /* temporary set color 0 to the genlock color */
662   if (state->m_genlock_color != 0xffff)
663      CUSTOM_REG(REG_COLOR00) = state->m_genlock_color;
683   if (m_genlock_color != 0xffff)
684      CUSTOM_REG(REG_COLOR00) = m_genlock_color;
664685
665686   /* loop over the line */
666687   next_copper_x = 0;
667   for (x = 0; x < 227.5*2; x++)
688   for (x = 0; x < amiga_state::SCREEN_WIDTH / 2; x++)
668689   {
669690      int sprpix;
670691
r30587r30588
673694      {
674695         /* execute the next batch, restoring and re-saving color 0 around it */
675696         CUSTOM_REG(REG_COLOR00) = save_color0;
676         next_copper_x = amiga_copper_execute_next(machine, x);
697         next_copper_x = amiga_copper_execute_next(machine(), x);
677698         save_color0 = CUSTOM_REG(REG_COLOR00);
678         if (state->m_genlock_color != 0xffff)
679            CUSTOM_REG(REG_COLOR00) = state->m_genlock_color;
699         if (m_genlock_color != 0xffff)
700            CUSTOM_REG(REG_COLOR00) = m_genlock_color;
680701
681702         /* compute update-related register values */
682703         planes = (CUSTOM_REG(REG_BPLCON0) & (BPLCON0_BPU0 | BPLCON0_BPU1 | BPLCON0_BPU2)) >> 12;
683704         hires = CUSTOM_REG(REG_BPLCON0) & BPLCON0_HIRES;
684705         ham = CUSTOM_REG(REG_BPLCON0) & BPLCON0_HOMOD;
685706         dualpf = CUSTOM_REG(REG_BPLCON0) & BPLCON0_DBLPF;
686         //lace = CUSTOM_REG(REG_BPLCON0) & BPLCON0_LACE;
687707
688708         /* compute the pixel fetch parameters */
689709         ddf_start_pixel = (CUSTOM_REG(REG_DDFSTRT) & (hires ? 0xfc : 0xf8)) * 2;
r30587r30588
902922               if (pix)
903923                  dst[x*2+0] = CUSTOM_REG(REG_COLOR00 + pix);
904924               else
905                  dst[x*2+0] = CUSTOM_REG(REG_COLOR00 + state->m_separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix0]);
925                  dst[x*2+0] = CUSTOM_REG(REG_COLOR00 + m_separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix0]);
906926
907927               /* mask out the sprite if it doesn't have priority */
908928               pix = sprpix & 0x1f;
r30587r30588
918938               if (pix)
919939                  dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + pix);
920940               else
921                  dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + state->m_separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix1]);
941                  dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + m_separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix1]);
922942            }
923943
924944            /* single playfield mode */
r30587r30588
945965      }
946966   }
947967
948#if 0
949   if ( machine.first_screen()->frame_number() % 64 == 0 && scanline == 100 )
950   {
951#if 0
952      const char *m_lores = "LORES";
953      const char *m_hires = "HIRES";
954      const char *m_ham = "HAM";
955      const char *m_dualpf = "DUALPF";
956      //const char *m_lace = "LACE";
957      //const char *m_hilace = "HI-LACE";
958      const char *p = m_lores;
959
960      if ( hires ) p = m_hires;
961      if ( ham ) p = m_ham;
962      if ( dualpf ) p = m_dualpf;
963      //if ( lace ) p = m_lace;
964
965      //if ( hires && lace ) p = m_hilace;
966#endif
967      //popmessage("%s(%d pl od=%04x ed=%04x start=%04x stop=%04x)", p, planes, odelay, edelay, CUSTOM_REG(REG_DDFSTRT), CUSTOM_REG(REG_DDFSTOP) );
968      //popmessage("%s(%d pl y=%d vstart=%04x vstop=%04x start=%04x stop=%04x)", p, planes, scanline, vstart, vstop, CUSTOM_REG(REG_DDFSTRT), CUSTOM_REG(REG_DDFSTOP) );
969      popmessage("DDFSTRT=%04x, DDFSTOP=%04x, DIWSTRT=%04x, DIWSTOP=%04x", CUSTOM_REG(REG_DDFSTRT), CUSTOM_REG(REG_DDFSTOP), CUSTOM_REG(REG_DIWSTRT), CUSTOM_REG(REG_DIWSTOP));
970   }
971#endif
972
973   /* end of the line: time to add the modulos */
968   // end of the line: time to add the modulos
974969   if (scanline >= vstart && scanline < vstop)
975970   {
976      /* update odd planes */
971      // update odd planes
977972      for (pl = 0; pl < planes; pl += 2)
978973         CUSTOM_REG_LONG(REG_BPL1PTH + pl * 2) += CUSTOM_REG_SIGNED(REG_BPL1MOD);
979974
980      /* update even planes */
975      // update even planes
981976      for (pl = 1; pl < planes; pl += 2)
982977         CUSTOM_REG_LONG(REG_BPL1PTH + pl * 2) += CUSTOM_REG_SIGNED(REG_BPL2MOD);
983
984      if (machine.input().code_pressed(KEYCODE_Q))
985         printf("%03d BPL1MOD=%04x BPL2MOD=%04x BPLCON1=%04x\n", scanline, CUSTOM_REG(REG_BPL1MOD), CUSTOM_REG(REG_BPL2MOD), CUSTOM_REG(REG_BPLCON1));
986978   }
987979
988   /* restore color00 */
980   // restore color00
989981   CUSTOM_REG(REG_COLOR00) = save_color0;
990982
983   // save
984   if (dst != NULL)
985      memcpy(&m_flickerfixer.pix16(save_scanline), dst, amiga_state::SCREEN_WIDTH * 2);
986
991987#if GUESS_COPPER_OFFSET
992988   if (m_screen->frame_number() % 64 == 0 && scanline == 0)
993989   {
994990      if (machine.input().code_pressed(KEYCODE_Q))
995         popmessage("%d", state->m_wait_offset -= 1);
991         popmessage("%d", m_wait_offset -= 1);
996992      if (machine.input().code_pressed(KEYCODE_W))
997         popmessage("%d", state->m_wait_offset += 1);
993         popmessage("%d", m_wait_offset += 1);
998994   }
999995#endif
1000996}
r30587r30588
10171013
10181014   // render each scanline in the visible region
10191015   for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
1020      amiga_render_scanline(machine(), bitmap, y);
1016      render_scanline(bitmap, y);
10211017
10221018   return 0;
10231019}
1020
1021void amiga_state::update_screenmode()
1022{
1023   amiga_state *state = this;
1024   bool pal;
1025
1026   // first let's see if we're PAL or NTSC
1027   if (m_agnus_id >= AGNUS_HR_PAL)
1028      // we support dynamic switching between PAL and NTSC, determine mode from register
1029      pal = CUSTOM_REG(REG_BEAMCON0) & 0x20;
1030   else
1031      // old agnus, agnus id determines PAL or NTSC
1032      pal = !(m_agnus_id & 0x10);
1033
1034   // basic height & vblank length
1035   int height = pal ? SCREEN_HEIGHT_PAL : SCREEN_HEIGHT_NTSC;
1036   int vblank = pal ? VBLANK_PAL : VBLANK_NTSC;
1037
1038   // frame period
1039   attoseconds_t period = HZ_TO_ATTOSECONDS(m_screen->clock()) * SCREEN_WIDTH * height;
1040
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
1052   // adjust visible area
1053   rectangle visarea = m_screen->visible_area();
1054   visarea.sety(vblank, height - 1);
1055
1056   logerror("screenmode changed: %dx%d%s\n", SCREEN_WIDTH, height, lace ? " (interlace)" : "");
1057
1058   // finally set our new mode
1059   m_screen->configure(SCREEN_WIDTH, height, visarea, period);
1060}

Previous 199869 Revisions Next


© 1997-2024 The MAME Team