diff --git a/Components/9918/9918.cpp b/Components/9918/9918.cpp index 2830be0c6..b4fa64485 100644 --- a/Components/9918/9918.cpp +++ b/Components/9918/9918.cpp @@ -102,6 +102,7 @@ TMS9918::TMS9918(Personality p): } void TMS9918::set_tv_standard(TVStandard standard) { + tv_standard_ = standard; switch(standard) { case TVStandard::PAL: mode_timing_.total_lines = 313; @@ -569,22 +570,30 @@ uint8_t TMS9918::get_current_line() { ? (write_pointer_.row + mode_timing_.total_lines - 1)%mode_timing_.total_lines : write_pointer_.row; - // This assumes NTSC 192-line. TODO: other modes. - if(source_row >= 0xdb) source_row -= 6; -// printf("Current row: %d -> %d\n", row_, source_row); + if(tv_standard_ == TVStandard::NTSC) { + if(mode_timing_.pixel_lines == 240) { + // NTSC 256x240: 00-FF, 00-06 + } else if(mode_timing_.pixel_lines == 224) { + // NTSC 256x224: 00-EA, E5-FF + if(source_row >= 0xeb) source_row -= 6; + } else { + // NTSC 256x192: 00-DA, D5-FF + if(source_row >= 0xdb) source_row -= 6; + } + } else { + if(mode_timing_.pixel_lines == 240) { + // PAL 256x240: 00-FF, 00-0A, D2-FF + if(source_row >= 267) source_row -= 0x39; + } else if(mode_timing_.pixel_lines == 224) { + // PAL 256x224: 00-FF, 00-02, CA-FF + if(source_row >= 259) source_row -= 0x39; + } else { + // PAL 256x192: 00-F2, BA-FF + if(source_row >= 0xf3) source_row -= 0x39; + } + } return static_cast(source_row); - -/* - TODO: Full proper sequence of current lines: - - NTSC 256x192 00-DA, D5-FF - NTSC 256x224 00-EA, E5-FF - NTSC 256x240 00-FF, 00-06 - PAL 256x192 00-F2, BA-FF - PAL 256x224 00-FF, 00-02, CA-FF - PAL 256x240 00-FF, 00-0A, D2-FF -*/ } uint8_t TMS9918::get_latched_horizontal_counter() { diff --git a/Components/9918/9918.hpp b/Components/9918/9918.hpp index efedee23f..6e6225d47 100644 --- a/Components/9918/9918.hpp +++ b/Components/9918/9918.hpp @@ -38,13 +38,6 @@ class TMS9918: public Base { */ TMS9918(Personality p); - enum TVStandard { - /*! i.e. 50Hz output at around 312.5 lines/field */ - PAL, - /*! i.e. 60Hz output at around 262.5 lines/field */ - NTSC - }; - /*! Sets the TV standard for this TMS, if that is hard-coded in hardware. */ void set_tv_standard(TVStandard standard); diff --git a/Components/9918/Implementation/9918Base.hpp b/Components/9918/Implementation/9918Base.hpp index efffc4925..c22b06bba 100644 --- a/Components/9918/Implementation/9918Base.hpp +++ b/Components/9918/Implementation/9918Base.hpp @@ -27,6 +27,13 @@ enum Personality { GGVDP, }; +enum class TVStandard { + /*! i.e. 50Hz output at around 312.5 lines/field */ + PAL, + /*! i.e. 60Hz output at around 262.5 lines/field */ + NTSC +}; + #define is_sega_vdp(x) x >= SMSVDP class Base { @@ -69,6 +76,7 @@ class Base { Personality personality_; std::unique_ptr crt_; + TVStandard tv_standard_ = TVStandard::NTSC; // Holds the contents of this VDP's connected DRAM. std::vector ram_; diff --git a/Machines/MasterSystem/MasterSystem.cpp b/Machines/MasterSystem/MasterSystem.cpp index 944ac366b..cc73a2e90 100644 --- a/Machines/MasterSystem/MasterSystem.cpp +++ b/Machines/MasterSystem/MasterSystem.cpp @@ -149,7 +149,7 @@ class ConcreteMachine: vdp_.reset(new TI::TMS::TMS9918(model_ == Target::Model::SG1000 ? TI::TMS::TMS9918A : TI::TMS::SMSVDP)); vdp_->set_tv_standard( (region_ == Target::Region::Europe) ? - TI::TMS::TMS9918::TVStandard::PAL : TI::TMS::TMS9918::TVStandard::NTSC); + TI::TMS::TVStandard::PAL : TI::TMS::TVStandard::NTSC); get_crt()->set_video_signal(Outputs::CRT::VideoSignal::Composite); }