You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The 6502 opcodes need an extra cycle when the referenced address crosses a page, e.g.
// with X=0
LDA $FFFC,X
needs 4 cycles, but
// with X=4
LDA $FFFC,X
needs 5 cycles.
The handling of extra cycles is implemented in CPU.cpp, however it's currently not working, since the execution order is incorrect.
The extra cycle handling is implemented in the CHECK_PAGE_CHANGE macro:
#define CHECK_PAGE_CHANGE if (bSlowerOnPagecross) { \
if ((base ^ addr) & 0xFF00) \
uExtraCycles=1; \
}
This macro is called by the "ABSX", "ABSY", "INDY" macros: #define ABSX base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; CHECK_PAGE_CHANGE;
So, the 'extra cycle' effect is only considered when bSlowerOnPagecross==1. This flag is to be set by the respective opcode. And it is indeed correctly set for LDA:
However, the LDA macro is only called after the ABSX macro - so ABSX will never add any extra cycles, since the bSlowerOnPagecross flag is set too late:
case 0xBD:
ABSX
LDA
CYC(4)
break;
It is the same for all other opcodes. As a result the execution timing is incorrect.
I compared with the original AppleWin sources. AppleWin is correctly emulating the extra cycle for page crossing operations. The whole "bSlowerOnPagecross" logic is absent in the original AppleWin sources. Indeed, it seems removing the bSlowerOnPagecross from CPU.cpp altogether results in proper timing. No idea why the bSlowerOnPagecross was introduced in the first place: it seems the CHECK_PAGE_CHANGE is called for those opcodes anyway, which are indeed affected by the extra page crossing cycle effect in the first place.
The text was updated successfully, but these errors were encountered:
@ThorstenBr is a temporary fix to comment out / remove the if (bSlowerOnPagecross) condition on line 194 (leaving the if ((base ^ addr) & 0xFF00) condition)?
I gather you are officially recommending the removal of all bSlowerOnPagecross = 0|1 statements, but do see that AppleWin sources are using the uExtraCycles flag also in use by LinApple.
The 6502 opcodes need an extra cycle when the referenced address crosses a page, e.g.
needs 4 cycles, but
needs 5 cycles.
The handling of extra cycles is implemented in CPU.cpp, however it's currently not working, since the execution order is incorrect.
The extra cycle handling is implemented in the CHECK_PAGE_CHANGE macro:
This macro is called by the "ABSX", "ABSY", "INDY" macros:
#define ABSX base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; CHECK_PAGE_CHANGE;
So, the 'extra cycle' effect is only considered when bSlowerOnPagecross==1. This flag is to be set by the respective opcode. And it is indeed correctly set for LDA:
However, the LDA macro is only called after the ABSX macro - so ABSX will never add any extra cycles, since the bSlowerOnPagecross flag is set too late:
It is the same for all other opcodes. As a result the execution timing is incorrect.
I compared with the original AppleWin sources. AppleWin is correctly emulating the extra cycle for page crossing operations. The whole "bSlowerOnPagecross" logic is absent in the original AppleWin sources. Indeed, it seems removing the bSlowerOnPagecross from CPU.cpp altogether results in proper timing. No idea why the bSlowerOnPagecross was introduced in the first place: it seems the CHECK_PAGE_CHANGE is called for those opcodes anyway, which are indeed affected by the extra page crossing cycle effect in the first place.
The text was updated successfully, but these errors were encountered: