Need someone to clarify on the SPC700 PCALL instruction

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Need someone to clarify on the SPC700 PCALL instruction
by on (#156335)
In Anomie's SPC700 Cycle Doc $Revision: 1126 $

Code:
 32b PCALL
  (PCALL)
  (2 bytes)
  (6 cycles)
        1       PC      Op Code         1
        2       SP      PCH             0
        3       SP-1    PCL             0
        4       PC+1    U               1
        5       Vec     AAL             1
        6       Vec+1   AAH             1
       (1)      new PC  Op Code         1
    * Order of reading new addr and pushing old addr may be wrong.

 32c TCALL
  (TCALL)
  (1 byte)
  (8 cycles)
        1       PC      Op Code         1
        2       SP      PCH             0
        3       SP-1    PCL             0
        4       ??      IO              ?
        5       Vec     AAL             1
        6       Vec+1   AAH             1
        7       ??      IO              ?
        8       ??      IO              ?
       (1)      new PC  Op Code         1
    * WTF with all the IO cycles?
    * Order of reading new addr and pushing old addr may be wrong.


PCall is implemented as an indirect jump to a table of 2-bytes ( word) vector address entries in page $FFxx


In http://wiki.superfamicom.org/snes/show/SPC700+Reference

Code:
CALL !a   (SP--)=PCh, (SP--)=PCl, PC=a
..
PCALL u   CALL $FF00+u   4F   ——–   2   6
..
TCALL 0   CALL [$FFDE]   01   ——–   1   8



This mean the wiki said if you execute an instruction of the following mnemonic
PCALL $DE

it actually will fetch the code at $FFDE and treat it as an Opcode. ie.. Next_OPC <= [$FFDE]

While Anomie actually meant that it will fetch the byte at $FFDE and treat it as the lower byte address of the next opcode.
which is PCALL $DE is equivalent to TCALL 0 which is PCL <= [$FFDE] PCH <= [$FFDF] Next_OPC <= [PCH,PCL]


*************************

Although I think Anomie is correct, ( The wiki should re-wrote the operation by adding square brackets to PCALL )
Code:
..
PCALL u   CALL [$FF00+u]   4F   ——–   2   6
..


I test both implementation of PCALL and try using blargg's 12 test suite and both implementation pass.

Therefore I am not 100% certain which is the correct implementation and I wish someone knowledagble and tell me :)
Re: Need someone to clarify on the SPC700 PCALL instruction
by on (#156352)
Oh rats. I just realized I myself was misusing the PCALL instruction (not to mention I never executed any of my programs, thank goodness...). I mistook PCALL for using it as an indirect jumping table that could use the entire address range (in contrast to TCALL).

Terranigma made me realize I really had mis-interpreted the opcode when I discovered code there rather than a series of pointers.

The PCALL instruction means that you're doing the equivalent of CALL $FFxx (xx being your opcode parameter), and that means that you're executing code in that address range. Thus, no square brackets are required, because you're not using the $FFxx area as an indirect table to code in a different part of memory (unlike TCALL).
Re: Need someone to clarify on the SPC700 PCALL instruction
by on (#156420)
Thanks for the reply..
To clarify things further, it meant the wiki is correct and Anomie's document should be rewritten as

Code:
32b PCALL
  (PCALL)
  (2 bytes)
  (6 cycles)
        1       PC       Op Code         1
        2       PC+1     U               1
        3       SP       PCH             0
        4       SP-1     PCL             0
        5       ??       IO              ?
        6       ??       IO              ?
       (1)      $FF00+U  Op Code         1
    * Order of reading new addr and pushing old addr may be wrong.




It is an educated guess that U should be read first and PC incremented (pointing to opcode after the PCALL) before pushing on stack, as the hardware is much eaiser to design in this way.

Is that actually what we agree here ?
Re: Need someone to clarify on the SPC700 PCALL instruction
by on (#156426)
This is tangential, but this sounds identical to the 6502-derivative Mitsubishi 740 series microcontroller, which has a JSR $FFxx instruction. (The documentation refers to this as the "special page").