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 71ff97c
Showing 1 changed file with 36 additions and 18 deletions.
@@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.