JSR/RTS

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
JSR/RTS
by on (#9320)
Quick question about JSR/RTS. A source I read said that you need to decrement the value of the PC before pushing it onto the stack during JSR and again during RTS after you've popped it off. Wouldn't that place the PC on the low byte of the address to jump to in the JSR func? Thanks.

by on (#9321)
nm, my jsr/rts routines work fine. No subtracting anything. PC is already properly set when pushed onto the stack.

by on (#9322)
During a JSR, the address pushed onto the stack is that of the 3rd byte of the instruction - that is, 1 byte BEFORE the next instruction. This is because it pushes the program counter onto the stack BEFORE it fetches the final byte of the opcode (and, as such, before it can increment the PC past this point). To compensate for this, the RTS opcode increments the program counter during its 6th instruction cycle.

You MUST emulate this properly, as there are plenty of games which either perform a JSR and read the address pushed onto the stack OR push an address onto the stack and perform an RTS.

by on (#9325)
At first I ignored this method, and very little ran on my emulator. You might think that something like that has little significance, but you would be wrong.

by on (#9335)
So after it fetchs the low byte that's when it pushes the PC? Seems like subtracting twice would set you at the last byte of the previous op. Confusion :-P

by on (#9340)
Here is an example;

Code:
JSR

inline void OpticCode20()
{
   CPU.PC += 2;
   CPU.Memory[CPU.S + 0x100] = (CPU.PC >> 8);
   CPU.Memory[(unsigned char)(CPU.S - 1) + 0x100] = (unsigned char)CPU.PC;
   CPU.S -= 2;
   CPU.PC -= 2;
   CPU.PC = Absolute;
   CPU.CC += 6;
}

RTS

inline void OpticCode60()
{
   CPU.PC = CPU.Memory[(unsigned char)(CPU.S + 1) + 0x100] + (CPU.Memory[(unsigned char)(CPU.S + 2) + 0x100] << 8) + 1;
   CPU.S += 2;
   CPU.CC += 6;
}

Notice the +1 on the RTS.

by on (#9368)
Okay, I get it now. Thanks :-)[/code]