Merge pull request #8334 from hosaka-corp/vi-update-reorg
VideoInterface: start counting half-lines at 0 instead of 1
This commit is contained in:
commit
71ff97cf1c
|
@ -191,7 +191,7 @@ void Preset(bool _bNTSC)
|
||||||
m_BorderHBlank.Hex = 0;
|
m_BorderHBlank.Hex = 0;
|
||||||
|
|
||||||
s_ticks_last_line_start = 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_half_line_of_next_si_poll = num_half_lines_for_si_poll; // first sampling starts at vsync
|
||||||
s_current_field = FieldType::Odd;
|
s_current_field = FieldType::Odd;
|
||||||
|
|
||||||
|
@ -317,7 +317,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
// MMIOs with unimplemented writes that trigger warnings.
|
// MMIOs with unimplemented writes that trigger warnings.
|
||||||
mmio->Register(
|
mmio->Register(
|
||||||
base | VI_VERTICAL_BEAM_POSITION,
|
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) {
|
MMIO::ComplexWrite<u16>([](u32, u16 val) {
|
||||||
WARN_LOG(VIDEOINTERFACE,
|
WARN_LOG(VIDEOINTERFACE,
|
||||||
"Changing vertical beam position to 0x%04x - not documented or implemented yet",
|
"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)
|
// Run when: When a frame is scanned (progressive/interlace)
|
||||||
void Update(u64 ticks)
|
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)
|
if (s_half_line_of_next_si_poll == s_half_line_count)
|
||||||
{
|
{
|
||||||
SerialInterface::UpdateDevices();
|
SerialInterface::UpdateDevices();
|
||||||
|
|
||||||
s_half_line_of_next_si_poll += 2 * SerialInterface::GetPollXLines();
|
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)
|
if (s_half_line_count == s_even_field_first_hl)
|
||||||
{
|
{
|
||||||
BeginField(FieldType::Even, ticks);
|
BeginField(FieldType::Even, ticks);
|
||||||
|
@ -756,32 +774,32 @@ void Update(u64 ticks)
|
||||||
EndField();
|
EndField();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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())
|
||||||
|
{
|
||||||
|
s_half_line_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(s_half_line_count & 1))
|
||||||
|
{
|
||||||
|
s_ticks_last_line_start = CoreTiming::GetTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
for (UVIInterruptRegister& reg : m_InterruptRegister)
|
||||||
{
|
{
|
||||||
if (s_half_line_count + 1 == 2u * reg.VCT)
|
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;
|
reg.IR_INT = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s_half_line_count++;
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s_half_line_count == GetHalfLinesPerEvenField())
|
|
||||||
{
|
|
||||||
s_half_line_of_next_si_poll = GetHalfLinesPerEvenField() + num_half_lines_for_si_poll;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s_half_line_count & 1)
|
|
||||||
{
|
|
||||||
s_ticks_last_line_start = CoreTiming::GetTicks();
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateInterrupts();
|
UpdateInterrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue