Clearing memory

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
User avatar
electro
Posts: 132
Joined: Tue Jan 29, 2008 11:12 am
Location: New York

Clearing memory

Post by electro »

Is there a better way to do this:

Code: Select all

txa ; x=0
clrmem:		
    sta $000,x  ; a = o
    sta $100,x
    sta $200,x
    sta $300,x
    sta $400,x
    sta $500,x
    sta $600,x
    sta $700,x  ; Remove this if you're storing reset-persistent data
    inx
    bne clrmem
   
why not just say;

clearmem
ldx with the number of memory registers you need to clear
lda $00
sta in the last memory address you want to clear, x (absolute indexing)
dex
bne clearmem

(sorry I'm a confused beginner)

T
Last edited by electro on Sat Mar 01, 2008 12:52 pm, edited 1 time in total.
Celius
Posts: 2159
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

Well if you do it that way, you'll be constantly reloading the value of X, because you keep loading it in your loop, which will result in an infinite loop and screw everything up. If you only want to clear a certain number of registers, you could do it that way, but just stick the lda #$00 and ldx "Desired Value" out of the loop, because they don't need to be in there. If you just stick lda #$00 out of the loop, it will save you a lot of time, because you only need to lda #$00 once.

But I don't know if I'm exactly sure what you're asking.
User avatar
electro
Posts: 132
Joined: Tue Jan 29, 2008 11:12 am
Location: New York

Post by electro »

Celius wrote:If you only want to clear a certain number of registers, you could do it that way, but just stick the lda #$00 and ldx "Desired Value" out of the loop, because they don't need to be in there.

If you just stick lda #$00 out of the loop, it will save you a lot of time, because you only need to lda #$00 once.

But I don't know if I'm exactly sure what you're asking.
Yes, in the case you want to clear only a certain number of registers.

So you would just need to put LDA #$00 outside the loop?

If LDA #$00 was left inside the loop, the loop wouldn't stop if the x register decrements to 0?

I think I know what you're saying about "saving time", you mean because we wouldn't have to constantly keep loading A with #$00?

If so, I see your point.

Does that also apply to LDX value?

Thanks for your help.
T
Celius
Posts: 2159
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

Take this loop for example:

Code: Select all

clearmem:
 ldx #5
 lda #$00
 sta $200,x
 dex
 bne clearmem
What's going to happen? You're going to load 5 into X. Then you're going to store 0 into $205 ($200 + X). Then X decreases by 1 to equal 4. Then this happens: bne clearmem. If X is not equal to 0, it will jump to the beginning of the loop. Since X is 4, it will jump to the beginning of the loop. What's at the beginning of the loop? "ldx #5". You are constantly telling X to be 5 every time the code goes through the loop. Since they only way to get out of the loop is if X is 0, the code will never stop looping. It will keep storing 0 into $205 forever and ever.

But if you did this:

Code: Select all

 ldx #5
clearmem:
 lda #$00
 sta $200,x
 dex
 bne clearmem
X would keep decreasing every time the code goes through the loop, and it would successfully clear $201-$205. There's another problem. Go through the loop in your mind with X being 1. It will clear $201, and then decrease X to equal 0. When that happens, it breaks out of the loop. It misses $200, which I'm assuming you want to have cleared. So you would have to make it this:

Code: Select all

 ldx #6
clearmem:
 lda #$00
 sta $1FF,x
 dex
 bne clearmem
Because by the time X equals zero, it won't clear $1FF. This will Clear $200-$205 successfully. Just go through the loop in your mind a couple of times.

Also, you don't NEED to put the lda #$00 out of the loop, it's just wise because it takes the CPU less time to do the loop. So this:

Code: Select all

 ldx #6
 lda #$00
clearmem:
 sta $1FF,x
 dex
 bne clearmem
Is how you'd want to do it.
User avatar
electro
Posts: 132
Joined: Tue Jan 29, 2008 11:12 am
Location: New York

Post by electro »

I see why LDX must be outside the loop, the same number would constantly be loaded in the x register.

Keeping LDA outside the loop doesn't effect the outcome, but does effect the time? (If it was outside the loop we would save time by not having to constantly load 0 in the A?

Why do some people do things like this:

txa ; x=0
clrmem:
sta $000,x ; a = o
sta $100,x
sta $200,x
sta $300,x
sta $400,x
sta $500,x
sta $600,x
sta $700,x ; Remove this if you're storing reset-persistent data
inx
bne clrmem


(I'm just a beginner, but could this code be improved in the manner we just explored? 5 lines of code that does the same thing 11 lines previous did?) I don't know...

Thanks again,
T
Celius
Posts: 2159
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

electro wrote:I see why LDX must be outside the loop, the same number would constantly be loaded in the x register.

Keeping LDA outside the loop doesn't effect the outcome, but does effect the time? (If it was outside the loop we would save time by not having to constantly load 0 in the A?
Yes, keeping LDA outside of the loop saves a lot of time. All that you said is correct.
electro wrote: Why do some people do things like this:

txa ; x=0
clrmem:
sta $000,x ; a = o
sta $100,x
sta $200,x
sta $300,x
sta $400,x
sta $500,x
sta $600,x
sta $700,x ; Remove this if you're storing reset-persistent data
inx
bne clrmem


(I'm just a beginner, but could this code be improved in the manner we just explored? 5 lines of code that does the same thing 11 lines previous did?) I don't know...
I don't see how this could be optimized. Since X can't go above $FF, you can only extend past a point by $FF. So you couldn't just have something like this:

Code: Select all

 ldx #0
 lda #$00
-
 sta $0,x
 inx
 cpx #$800
 bne -
Because the NES is an 8-bit system. #$800 is a 12-bit value. Even if you could do that, why would you want to? It'd take a lot longer to execute than the standard loop. I don't know if that is the type of thing you were asking about. But I really don't think that the clear memory loop could be improved very much.
User avatar
MottZilla
Posts: 2835
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla »

While it seems like a neat and tidy way to do things, to zero memory at startup, you don't need to do that. Any memory you use you should initialize before use anyway. By zeroing memory you may just be helping yourself not realize you forgot to initialize a value before use or maybe you just enjoy knowing the memory was zeroed. :p

I mean there's nothing wrong with it, but if you do things correctly it is totally unneeded. Atleast I can't think of a reason.
User avatar
electro
Posts: 132
Joined: Tue Jan 29, 2008 11:12 am
Location: New York

Post by electro »

Thank you, very helpful.

T
User avatar
electro
Posts: 132
Joined: Tue Jan 29, 2008 11:12 am
Location: New York

Post by electro »

MottZilla wrote:While it seems like a neat and tidy way to do things, to zero memory at startup, you don't need to do that. Any memory you use you should initialize before use anyway. By zeroing memory you may just be helping yourself not realize you forgot to initialize a value before use or maybe you just enjoy knowing the memory was zeroed. :p

I mean there's nothing wrong with it, but if you do things correctly it is totally unneeded. Atleast I can't think of a reason.

Is this true?

I did wonder why you had to clear everything at startup.

(My original question wasn't so much about why we clear the memory, I just saw something there in basic asm code that I didn't understand.) But now I wonder why we do it at all (clearing the memory)...

Thanks,

T (as in T.ee)
Celius
Posts: 2159
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

I suppose you don't really NEED to clear RAM, because you should initialize every variable you use. However, it's good for debugging things. Any value that's not being used will be $00. If it's not $00, it could indicate a bug.

After completing a game, and you know that everything has been coded just right, and it's all perfect, you can take the RAM clearing out of your code. I just think that it's also annoying to see the alternating columns of $FFs in FCEUXD. It's really not necessary in the end, but while programming, it can be useful.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Celius wrote:I suppose you don't really NEED to clear RAM, because you should initialize every variable you use.
In fact, just to make sure I'm not relying on uninitialized RAM locations, I do the opposite of clearing all RAM: I fill it with random junk. Then, if something behaves erratically, I'll know I haven't initialized something. When the game is done, I'll remove that part of the code.
Post Reply