Skip to content

Commit

Permalink
Attempting to fix NMI timing issue. Now edge is properly detected and…
Browse files Browse the repository at this point in the history
… delay is properly 1 cycle.
  • Loading branch information
L-Spiro committed Mar 15, 2023
1 parent a80124d commit 6e5cff6
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 21 deletions.
12 changes: 8 additions & 4 deletions Src/Cpu/LSNCpu6502.cpp
Expand Up @@ -1085,7 +1085,9 @@ namespace lsn {
m_ui8DmaPos( 0 ),
m_ui8DmaValue( 0 ),
m_bNmiStatusLine( false ),
m_bLastNmiStatusLine( false ),
m_bHandleNmi( false ),
m_bDetectedNmi( false ),
m_bIrqStatusLine( false ),
m_bHandleIrq( false ),
m_bIsReadCycle( true ),
Expand Down Expand Up @@ -1128,7 +1130,7 @@ namespace lsn {

pc.PC = m_pbBus->Read( 0xFFFC ) | (m_pbBus->Read( 0xFFFD ) << 8);

m_bHandleNmi = m_bNmiStatusLine = false;
m_bHandleNmi = m_bDetectedNmi = m_bLastNmiStatusLine = m_bNmiStatusLine = false;
m_bHandleIrq = m_bIrqStatusLine = false;
}

Expand All @@ -1142,7 +1144,9 @@ namespace lsn {
(this->*m_pfTickFunc)();

//m_bHandleNmi |= (m_bNmiStatusLine && --m_ui8NmiCounter == 0);
m_bHandleNmi |= m_bNmiStatusLine;
m_bHandleNmi = m_bDetectedNmi;
m_bDetectedNmi |= (!m_bLastNmiStatusLine && m_bNmiStatusLine);
m_bLastNmiStatusLine = m_bNmiStatusLine;
m_bHandleIrq |= m_bIrqStatusLine;

++m_ui64CycleCount;
Expand Down Expand Up @@ -1709,7 +1713,7 @@ namespace lsn {
LSN_PUSH( m_ui8Status | uint8_t( LSN_STATUS_FLAGS::LSN_SF_BREAK ) );
// It is also at this point that the branch vector is determined. Store it in LSN_CPU_CONTEXT::a.ui16Address.
m_ccCurContext.a.ui16Address = m_bHandleNmi ? uint16_t( LSN_VECTORS::LSN_V_NMI ) : uint16_t( LSN_VECTORS::LSN_V_IRQ_BRK );
if ( m_bHandleNmi ) { m_bHandleNmi = false; }
if ( m_bHandleNmi ) { m_bHandleNmi = m_bDetectedNmi = false; }
}

/** Pushes status without B. */
Expand All @@ -1721,7 +1725,7 @@ namespace lsn {
LSN_PUSH( ui8Status );
// It is also at this point that the branch vector is determined. Store it in LSN_CPU_CONTEXT::a.ui16Address.
m_ccCurContext.a.ui16Address = m_bHandleNmi ? uint16_t( LSN_VECTORS::LSN_V_NMI ) : uint16_t( LSN_VECTORS::LSN_V_IRQ_BRK );
if ( m_bHandleNmi ) { m_bHandleNmi = false; }
if ( m_bHandleNmi ) { m_bHandleNmi = m_bDetectedNmi = false; }
}

/** Pushes status an decrements S. */
Expand Down
10 changes: 6 additions & 4 deletions Src/Cpu/LSNCpu6502.h
@@ -1,4 +1,4 @@
/**
/**
* Copyright L. Spiro 2021
*
* Written by: Shawn (L. Spiro) Wilcoxen
Expand Down Expand Up @@ -225,7 +225,9 @@ namespace lsn {
uint8_t m_ui8DmaPos; /**< The DMA transfer offset.*/
uint8_t m_ui8DmaValue; /**< The DMA transfer value.*/
bool m_bNmiStatusLine; /**< The status line for NMI. */
bool m_bHandleNmi; /**< Once an NMI edge is detected, this is set to indicate that it needs to be handled. */
bool m_bLastNmiStatusLine; /**< THe last status line for NMI. */
bool m_bDetectedNmi; /**< The edge detector for the φ2 part of the cycle. */
bool m_bHandleNmi; /**< Once an NMI edge is detected, this is set to indicate that it needs to be handled on the φ1 of the next cycle. */
bool m_bIrqStatusLine; /**< The status line for IRQ. */
bool m_bHandleIrq; /**< Once the IRQ status line is detected as having triggered, this tells us to handle an IRQ on the next instruction. */
bool m_bIsReadCycle; /**< Is this CPU cycle a read cycle? */
Expand Down Expand Up @@ -754,9 +756,9 @@ namespace lsn {
inline void CCpu6502::Cmp( uint8_t _ui8RegVal, uint8_t _ui8OpVal ) {
// If the value in the accumulator is equal or greater than the compared value, the Carry will be set.
SetBit<uint8_t( LSN_STATUS_FLAGS::LSN_SF_CARRY )>( m_ui8Status, _ui8RegVal >= _ui8OpVal );
// The equal (Z) and negative (N) flags will be set based on equality or lack thereof…
// The equal (Z) and negative (N) flags will be set based on equality or lack thereof
SetBit<uint8_t( LSN_STATUS_FLAGS::LSN_SF_ZERO )>( m_ui8Status, _ui8RegVal == _ui8OpVal );
// …and the sign (IE A>=$80) of the accumulator.
// and the sign (IE A>=$80) of the accumulator.
SetBit<uint8_t( LSN_STATUS_FLAGS::LSN_SF_NEGATIVE )>( m_ui8Status, ((_ui8RegVal - _ui8OpVal) & 0x80) != 0 );
}

Expand Down
29 changes: 16 additions & 13 deletions Src/Ppu/LSNPpu2C0X.h
Expand Up @@ -748,19 +748,22 @@ namespace lsn {
*/
static void LSN_FASTCALL Read2002( void * _pvParm0, uint16_t /*_ui16Parm1*/, uint8_t * /*_pui8Data*/, uint8_t &_ui8Ret ) {
CPpu2C0X * ppPpu = reinterpret_cast<CPpu2C0X *>(_pvParm0);
// Reading $2002 within a few PPU clocks of when VBL is set results in special-case behavior.
if ( ppPpu->m_ui16CurY == (_tPreRender + _tRender + _tPostRender) ) {
// Reading one PPU clock before reads it as clear and never sets the flag or generates NMI for that frame.
if ( ppPpu->m_ui16CurX == (1 - 1) ) {
ppPpu->m_bSuppressNmi = true;
ppPpu->m_psPpuStatus.s.ui8VBlank = 0;
//::OutputDebugStringA( ("ULTIMATE MOVE: SUPPRESSION!!\r\n") );
}
else if ( ppPpu->m_ui16CurX == (1 - 0) || ppPpu->m_ui16CurX == (1 + 1) ) {
// Reading on the same PPU clock or one later reads it as set, clears it, and suppresses the NMI for that frame.
ppPpu->m_bSuppressNmi = true;
ppPpu->m_psPpuStatus.s.ui8VBlank = 1;
//::OutputDebugStringA( ("ULTIMATE MOVE: SUPPRESSION!!\r\n") );
if ( ppPpu->m_pcPpuCtrl.s.ui8Nmi ) {
// Reading $2002 within a few PPU clocks of when VBL is set results in special-case behavior.
if ( ppPpu->m_ui16CurY == (_tPreRender + _tRender + _tPostRender) ) {
// Reading one PPU clock before reads it as clear and never sets the flag or generates NMI for that frame.
if ( ppPpu->m_ui16CurX == (1 - 1) ) {
ppPpu->m_bSuppressNmi = true;
ppPpu->m_psPpuStatus.s.ui8VBlank = 0;
//::OutputDebugStringA( ("ULTIMATE MOVE: SUPPRESSION!!\r\n") );
}
else if ( ppPpu->m_ui16CurX == (1 - 0) || ppPpu->m_ui16CurX == (1 + 1) ) {
// Reading on the same PPU clock or one later reads it as set, clears it, and suppresses the NMI for that frame.
ppPpu->m_bSuppressNmi = true;
ppPpu->m_psPpuStatus.s.ui8VBlank = 1;
//::OutputDebugStringA( ("ULTIMATE MOVE: SUPPRESSION!!\r\n") );
}
//ppPpu->m_bSuppressNmi = false; // This line changes nothing whether present or absent.
}
}

Expand Down

0 comments on commit 6e5cff6

Please sign in to comment.