I have a snippet that clears memory before initializing a game in NES 6502 assembly. When I leave the code inside the reset proc like so, it works:
.proc reset
SEI
CLD
LDX #0
ClearRAM:
STA $000,x
STA $100,x
STA $200,x
STA $300,x
STA $400,x
STA $500,x
STA $600,x
STA $700,x
INX
BNE ClearRAM
.endproc
However, if I try to move this ClearRAM snippet inside a scoped proc:
.scope Memory
.proc clear
LDX #0
ClearRAM:
STA $000,x
STA $100,x
STA $200,x
STA $300,x
STA $400,x
STA $500,x
STA $600,x
STA $700,x
INX
BNE ClearRAM
RTS
.endproc
.endscope
And then load it like so:
.proc reset
SEI
CLD
JSR Memory::clear
.endproc
It stops working. It's like it loops forever in the ClearRAM loop.
Any idea what I am doing wrong?
Thank you!
Your code clears the first 2K of RAM memory. (I don't know if the NES has more than 2K of memory.)
Because the stack is always located in the first 1K of memory on systems using a 6502 CPU (to be more precise: in the range 100h...1FFh), your program also clears the stack.
The
JSRsaves the address where the program flow shall continue after theRTSto the stack and theRTSinstruction reads that address from the stack.If you erase the content of the stack,
RTSwill read some bad value from the stack and jump to that address.If the
Aregister in your program contained the value12h, theRTSinstruction will read1212hfrom the stack and program execution will continue at address1212h(after theRTSinstruction) instead of the instruction following theJSR.