In general, you are correct--JSR and RTS are complementary halves of a
subroutine linkage mechanism.
JSR first pushes the "return address" on the stack, then jumps to the entry
point of the subroutine. Upon completion of the subroutine, it executed an
RTS, which pops the return address off the stack and jumps to it,
"returning" to the instruction following the "calling" JSR.
This provides a simple method for calling a commonly used piece of code
from multiple places in a program.
The details are a bit more subtle, but are unimportant for straightforward
JSR/RTS subroutine linkage.
Now for the subtlety: the actual address pushed onto the stack is the
address of the third byte of the JSR, not the address of the first byte of
the following instruction, so the RTS increments the address it pops off
the stack by one before jumping to it. This is only important when using
the address on the stack for other purposes, or when explicitly placing an
address on the stack to be used by a subsequent RTS.
As in all other uses of the stack, it's important that "pushes" and "pops"
be balanced, so that the stack neither grows nor shrinks overall during
program execution.
--
-michael - NadaNet 3.1 and AppleCrate II:
http://michaeljmahon.com