I'm down to line 6352 in nestest, but my accumulator is set incorrectly..
Nintendulator nestest log:
Based on this info ISB/ISC does this:
1. Add one to the value at the address
2. Subtract that value from the accumulator
Based on the log we can see the memory location contained 0xEB and the accumulator contained 0x40. I calculate that 0x40 - (0xEB + 1) = 0x54. If I subtract the original value (0xEB) then I get 0x55. Neither of these match the 0x53 in the log.
My code currently looks like this (this gives 0x54, which is one higher than expected):
I've tried looking for other emulators online to see how they handle this, but many don't seem to have the extra opcodes implemented. I found the nintendulator source but I don't entirely understand it (I don't know C/C++). I think it might be related to the Carry flag (based on "mov ah,FC"?), but since my Carry flag is 0 at this point I'm not sure that would affect anything.
Can anyone explain, or know of an implementation in a higher-level language that has this implemented?
Nintendulator nestest log:
Code:
EB9E E3 45 *ISB ($45,X) @ 47 = 0647 = EB A:40 X:02 Y:AA P:64 SP:FB CYC:310 SL:139
EBA0 EA NOP A:53 X:02 Y:AA P:24 SP:FB CYC:334 SL:139
EBA0 EA NOP A:53 X:02 Y:AA P:24 SP:FB CYC:334 SL:139
Based on this info ISB/ISC does this:
1. Add one to the value at the address
2. Subtract that value from the accumulator
Based on the log we can see the memory location contained 0xEB and the accumulator contained 0x40. I calculate that 0x40 - (0xEB + 1) = 0x54. If I subtract the original value (0xEB) then I get 0x55. Neither of these match the 0x53 in the log.
My code currently looks like this (this gives 0x54, which is one higher than expected):
Code:
void ISC(ushort address)
{
var value = (byte)(Ram.Read(address) + 1);
Ram.Write(address, value);
//Overflow = // TODO
Accumulator -= value;
SetZN(Accumulator);
}
{
var value = (byte)(Ram.Read(address) + 1);
Ram.Write(address, value);
//Overflow = // TODO
Accumulator -= value;
SetZN(Accumulator);
}
I've tried looking for other emulators online to see how they handle this, but many don't seem to have the extra opcodes implemented. I found the nintendulator source but I don't entirely understand it (I don't know C/C++). I think it might be related to the Carry flag (based on "mov ah,FC"?), but since my Carry flag is 0 at this point I'm not sure that would affect anything.
Code:
static __forceinline void IV_ISB (void)
{ // INC + SBC
EI.DbgOut(_T("Invalid opcode $%02X (ISB) encountered at $%04X"), Opcode, OpAddr);
TmpData = MemGet(CalcAddr);
MemSet(CalcAddr, TmpData);
__asm
{
inc TmpData
mov ah,FC
sub ah,1
mov al,TmpData
sbb A,al
setnc FC
setz FZ
sets FN
seto FV
}
MemSet(CalcAddr, TmpData);
}
{ // INC + SBC
EI.DbgOut(_T("Invalid opcode $%02X (ISB) encountered at $%04X"), Opcode, OpAddr);
TmpData = MemGet(CalcAddr);
MemSet(CalcAddr, TmpData);
__asm
{
inc TmpData
mov ah,FC
sub ah,1
mov al,TmpData
sbb A,al
setnc FC
setz FZ
sets FN
seto FV
}
MemSet(CalcAddr, TmpData);
}
Can anyone explain, or know of an implementation in a higher-level language that has this implemented?