DougBrunelle wrote:
1. If we want to keep the .A, .X, and .Y registers in the main program safe from possible destruction by subroutines, how best to structure this?
I expect a subroutine to clobber A, X and Y unless it's an explicit feature of the subroutine to not do that. If you write a subroutine that promises not to clobber Y then, if it later evolves to do so, it's its responsibility to save/restore Y to maintain the promise.
Quote:
In some cases, I have stored the registers in memory locations- other times, I have pushed them onto the stack and popped them off the stack after subroutine calls.
Both a valid approaches. I usually save/restore A via the stack, but X and Y I'll save in memory as its cumbersome to push them via A. The exception is if the saving subroutine might be called recursively. That would be a special case and handled via the stack. These things aren't a surprise in the code I've written.
Quote:
A related question-- should it be the responsibility of the main program to save the registers, or should it be done by each subroutine? Seems to me that we should be able to jsr to any subroutine and assume that our registers will not be changed upon return from the subroutine.
Different CPUs have different calling conventions. In some CPUs there are caller-saved (ones you can expect a subroutine to clobber) vs. callee-saved (ones that will retain their value). With only three registers, I'd rather not make it a rule.
Quote:
2. How best to implement other variables? If, for example, I have a main program which uses a zero-page pointer "ScrPtr" at $fb, should the main program be the only code block which manipulates ScrPtr, or is it common practice for subroutines to work with this kind of variable (global)?
Global variables are common in 6502 programs as trying to be overly "structured programming" about it leads to very slow and cumbersome code. That doesn't mean it's a free for all... Rather there should be variables that are public and variables that are private. You can use variable names to convey this, or #include files that only export certain names. Whatever you do, it should not be ambiguous.
Quote:
I have heard that, ideally, our Main code block should be just a list of subroutine calls.
If you ask three people you'll get four different answers. It's advisable if you're just starting out to err on the structured side so that you can keep track of everything and not get lost if you have to come back to a program a week, month or year later. With more experience you'll develop your own preferences, and will be able to let go of overly rigid structures in order to gain speed or reduce code size; all whilst maintaining a supportable level of structure.