diff options
| author | Connor McLaughlin <stenzek@gmail.com> | 2019-08-28 16:07:37 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-08-28 16:07:37 +1000 |
| commit | 71ff97cf1cf6ccaed34826a8f8d14cad0e292d7c (patch) | |
| tree | 8e4701895dc6007de1664ccca441a3150a95bfcf /Source/Core | |
| parent | 230ff47c0a9482bf24d6da63ce599d4973f3d62c (diff) | |
| parent | 9e3b867c6ae41df296ebf3112db6dd14c47abb37 (diff) | |
Merge pull request #8334 from hosaka-corp/vi-update-reorg
VideoInterface: start counting half-lines at 0 instead of 1
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/HW/VideoInterface.cpp | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/Source/Core/Core/HW/VideoInterface.cpp b/Source/Core/Core/HW/VideoInterface.cpp index ccd9700663..9af6f9f46a 100644 --- a/Source/Core/Core/HW/VideoInterface.cpp +++ b/Source/Core/Core/HW/VideoInterface.cpp @@ -191,7 +191,7 @@ void Preset(bool _bNTSC) m_BorderHBlank.Hex = 0; s_ticks_last_line_start = 0; - s_half_line_count = 1; + s_half_line_count = 0; s_half_line_of_next_si_poll = num_half_lines_for_si_poll; // first sampling starts at vsync s_current_field = FieldType::Odd; @@ -317,7 +317,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) // MMIOs with unimplemented writes that trigger warnings. mmio->Register( base | VI_VERTICAL_BEAM_POSITION, - MMIO::ComplexRead<u16>([](u32) { return 1 + (s_half_line_count - 1) / 2; }), + MMIO::ComplexRead<u16>([](u32) { return 1 + (s_half_line_count) / 2; }), MMIO::ComplexWrite<u16>([](u32, u16 val) { WARN_LOG(VIDEOINTERFACE, "Changing vertical beam position to 0x%04x - not documented or implemented yet", @@ -733,12 +733,30 @@ static void EndField() // Run when: When a frame is scanned (progressive/interlace) void Update(u64 ticks) { + // If an SI poll is scheduled to happen on this half-line, do it! + if (s_half_line_of_next_si_poll == s_half_line_count) { SerialInterface::UpdateDevices(); - s_half_line_of_next_si_poll += 2 * SerialInterface::GetPollXLines(); } + + // If this half-line is at the actual boundary of either field, schedule an SI poll to happen + // some number of half-lines in the future + + if (s_half_line_count == 0) + { + s_half_line_of_next_si_poll = num_half_lines_for_si_poll; // first results start at vsync + } + if (s_half_line_count == GetHalfLinesPerEvenField()) + { + s_half_line_of_next_si_poll = GetHalfLinesPerEvenField() + num_half_lines_for_si_poll; + } + + // If this half-line is at some boundary of the "active video lines" in either field, we either + // need to (a) send a request to the GPU thread to actually render the XFB, or (b) increment + // the number of frames we've actually drawn + if (s_half_line_count == s_even_field_first_hl) { BeginField(FieldType::Even, ticks); @@ -756,30 +774,30 @@ void Update(u64 ticks) EndField(); } - for (UVIInterruptRegister& reg : m_InterruptRegister) - { - if (s_half_line_count + 1 == 2u * reg.VCT) - { - reg.IR_INT = 1; - } - } + // Move to the next half-line and potentially roll-over the count to zero. If we've reached + // the beginning of a new full-line, update the timer s_half_line_count++; - - if (s_half_line_count > GetHalfLinesPerEvenField() + GetHalfLinesPerOddField()) + if (s_half_line_count == GetHalfLinesPerEvenField() + GetHalfLinesPerOddField()) { - s_half_line_count = 1; - s_half_line_of_next_si_poll = num_half_lines_for_si_poll; // first results start at vsync + s_half_line_count = 0; } - if (s_half_line_count == GetHalfLinesPerEvenField()) + if (!(s_half_line_count & 1)) { - s_half_line_of_next_si_poll = GetHalfLinesPerEvenField() + num_half_lines_for_si_poll; + s_ticks_last_line_start = CoreTiming::GetTicks(); } - if (s_half_line_count & 1) + // Check if we need to assert IR_INT. Note that the granularity of our current horizontal + // position is limited to half-lines. + + for (UVIInterruptRegister& reg : m_InterruptRegister) { - s_ticks_last_line_start = CoreTiming::GetTicks(); + u32 target_halfline = (reg.HCT > m_HTiming0.HLW) ? 1 : 0; + if ((1 + (s_half_line_count) / 2 == reg.VCT) && ((s_half_line_count & 1) == target_halfline)) + { + reg.IR_INT = 1; + } } UpdateInterrupts(); |
