Skip to content
Permalink
Browse files

Merge pull request #8334 from hosaka-corp/vi-update-reorg

VideoInterface: start counting half-lines at 0 instead of 1
  • Loading branch information...
stenzek committed Aug 28, 2019
2 parents 230ff47 + 9e3b867 commit 71ff97cf1cf6ccaed34826a8f8d14cad0e292d7c
Showing with 36 additions and 18 deletions.
  1. +36 −18 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();

1 comment on commit 71ff97c

@rlnilsen

This comment has been minimized.

Copy link
Contributor

rlnilsen commented on 71ff97c Sep 12, 2019

If you enable progressive scan and disable PAL60 mode on 10888, Visual Controller Test is broken with a black screen.

https://bugs.dolphin-emu.org/issues/11851

Please sign in to comment.
You can’t perform that action at this time.