1806 Standard Call and Return Instructions
The 1802 has no native subroutine call and return operations. For small programs there’s a very quick way of switching program counters that’s arguably better and for more general cases there’s a Standard Call and Return convention(SCRT) that uses registers 4,5 and 6. It’s very well designed though a bit slow and it does tie up 3 registers. The 1806 incorporates two new instructions SCAL(688N) and SRET(689N) that speed up the process and avoids dedicating registers 4,5 and 6 (you still need a register for the return address but it doesn’t have to be 6).
Unfortunately for me the 1806 SCAL/SRET are different from the routines I use in the compiler. They assume that the stack pointer points to the first byte free byte below the stack and can be used freely. The compiler assumes that the stack pointer addresses the last USED byte on the stack and needs to be decremented to point to free memory.
This affects the way parameters and variables are stored and addressed on the stack. One of the parts of LCC that I had the toughest time coming to grips with. I think I could paper over part of them by decrementing SP before each SCAL and incrementing it before each SRET. I would then have to add one to the offset for accessing parameters but variable addressing wouldn’t change. I’ll have to fire up some test cases and try them on an emulator that supports the 1806 instruction set.
For insurance I’ll also make sure that R2 is the X register on each call. It’s an extra instruction but it has saved me from myself in the past.
;Standard Call routine invoked as D4xxxx - big-endian stack convention sep R3 ;go to subroutine _call sex SP ;make sure X=SP glo retAddr ;save previous return pointer on stack dec sp stxd ghi retAddr str sp glo RPC ;copy old PC to retAddr plo retAddr ghi RPC phi retAddr lda retAddr ;pick up subroutine address into RPC phi RPC lda retAddr plo RPC br _call-1 ;Standard subroutine return sep RPC ;return to the original program _return glo retAddr ;transfer the current return address to RPC plo RPC ghi retAddr phi RPC lda SP ;pick up old return address phi retAddr lda SP plo retAddr br _return-1