Is resetting the stack truly necessary? As long as your code causes the stack to start and end at one place in the 256 byte stack page, it doesn't seem like it should matter due to wraparound.
If you intend to use page 1 for anything else in addition to the stack, you need to reset the stack.
I used to consider stack initialization unecessary, until I realized that I used very little of it and could use a large portion of page 1 for other things, like Dwedit said.
Good point! I'll keep that in mind.
Another reason to initialize the stack pointer is if you transfer it to the X register (TSX) and access previously pushed values using different base addresses ($0101, $0102, $0103 and so on). If the stack pointer has wrapped around, that won't work.
In case you're wondering what to do with stack memory you aren't using:
Just like a lot of games reserve $0200-$02FF or $0300-$03FF for a sprite display list to be copied to OAM, my more recent efforts tend to reserve the first 160 bytes of the stack page ($0100 through $019F) for VRAM transfer buffers. The code that runs during draw time (lines 0-240) prepares data to be copied, and then the code that runs during vertical blanking (lines 241-261) blasts this to the screen with a somewhat unrolled loop that takes advantage of a convenient aspect of 6502 addressing modes: LDA $010F,X and LDA $010F,Y are as fast as LDA $010F as long as they don't wrap. So I make a routine that copies 32 bytes starting at $0100+Y and call it with different starting addresses in Y, and the same routine can efficiently update a row of nametable entries, two tiles in CHR RAM, or the palette.
I like to use page 1 for variables, because it's the natural continuation of page 0, where most of my variables usually are. I don't use pages 3 and up for small variables, just for the big tables/buffers/lists.
Another thing I often have in page 1 is the copy of the attribute tables (128 bytes), something some times of projects benefit from (scrollers where you need to read-modify-write attribute bytes, for example).
I think we can all agree that stack initialization, while not required, is good practice.
My original question was provoked because I was jumping directly to some bankswitching code in my fixed bank, paying no attention to the calls that eventually got to that jump. The result was that on a game state change, the stack would start at a different location. I have since modified this system so I don't directly jump to the bankswitching code, and this change preserves the stack. So now, I'm free to use the lower portions of the stack page if I need it. Even if I don't need it, it still feels cleaner this way. Leaving addresses on the stack, even if it worked by coincidence, just felt dirty =)
Gradualore wrote:
So now, I'm free to use the lower portions of the stack page if I need it.
Or the upper parts, if you initialize the stack pointer to something lower than $FF. Personally I'd only use the lower or the upper part of page 1, not both with the stack in the middle, because that could be confusing! =)
I mentioned this because sometimes it matters where the data is. I have used a trick before where you access a table using a lower base address than the actual address (lda Table-$80, x or something like this) so that the value of the index was more convenient for some of the math involved. So I needed the table to be on the upper part of page so that there was no page crossing while reading from it.
I remember on my game Munchie Attack, I had a bug where I did a PHA with no corresponding PLA (why, I have no idea). But the game was released like that until I fixed it, it always ran just just fine. The stack page looked hilarious in a memory viewer though.