NES: Fix handling of internal and external open buses.#62
Open
NES: Fix handling of internal and external open buses.#62
Conversation
When reading from $4015, the internal and external CPU buses are isolated. This means the CPU reads the value from the internal $4015 register, which is not repeated onto the external bus, and any response to the read from an external device is not seen by the CPU (not even in the form of a bus conflict). As a result, the internal $4015 result updates only the internal open bus value, and any external result updates only the external open bus value. If the buses are isolated again on the next CPU cycle, then open bus bits on the internal bus read will not be affected by the external open bus value. This has been verified in a new test that lands a DMA-that-activates-$4015 on a $4015 read, so the two buses diverge on the DMA read cycle and $4015 is then read by the CPU on the next cycle to verify that the internal open bus was not affected by the DMA read. Furthermore, if the CPU then reads from external open bus afterward, it gets the DMA value from external open bus, which persisted but wasn't previously accessible due to bus isolation. Mesen previously had a bug where its GetInternalOpenBus function was returning the wrong bus value (_externalOpenBus instead of _internalOpenBus). Fixing this was not enough to fix the test, because SetOpenBus would update both buses on any external read. This change fixes the GetInternalOpenBus bug and changes SetOpenBus to be able to update either bus independently. This was tested with the new AccuracyCoin "Internal Data Bus" test.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When reading from $4015, the internal and external CPU buses are isolated. This means the CPU reads the value from the internal $4015 register, which is not repeated onto the external bus, and any response to the read from an external device is not seen by the CPU (not even in the form of a bus conflict).
As a result, the internal $4015 result updates only the internal open bus value, and any external result updates only the external open bus value. If the buses are isolated again on the next CPU cycle, then open bus bits on the internal bus read will not be affected by the external open bus value.
This has been verified in a new test that lands a DMA-that-activates-$4015 on a $4015 read, so the two buses diverge on the DMA read cycle and $4015 is then read by the CPU on the next cycle to verify that the internal open bus was not affected by the DMA read. Furthermore, if the CPU then reads from external open bus afterward, it gets the DMA value from external open bus, which persisted but wasn't previously accessible due to bus isolation.
Mesen previously had a bug where its GetInternalOpenBus function was returning the wrong bus value (_externalOpenBus instead of _internalOpenBus). Fixing this was not enough to fix the test, because SetOpenBus would update both buses on any external read. This change fixes the GetInternalOpenBus bug and changes SetOpenBus to be able to update either bus independently.
This was tested with the new AccuracyCoin "Internal Data Bus" test.