Init Code Questions

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
cartlemmy
Posts: 193
Joined: Fri Sep 24, 2010 4:41 pm
Location: California, USA
Contact:

Init Code Questions

Post by cartlemmy »

There were a few instructions of the init code that I wasn't sure about, and I was hoping someone could give me some insight.

Code: Select all

Reset:
	SEI	
	CLD
	LDX #$40
	STX $4017
	LDX #$FF	
	TXS			; I'm not sure why this is done, are we manually resetting the stack? can someone give me a hint?
	INX			; Increments X, which rolls X over its max value back to 0. I'm assuming we do this because it uses less memory than writing LDX #$00. Is that correct?
	STX $2000
	STX $2001
	STX $4010 
Sorry that it's not good enough for me to 'just know that it works, and don't worry about why'. :)
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Init Code Questions

Post by tepples »

cartlemmy wrote:There were a few instructions of the init code that I wasn't sure about, and I was hoping someone could give me some insight.

Code: Select all

	LDX #$FF	
	TXS			; I'm not sure why this is done, are we manually resetting the stack? can someone give me a hint?
The power-on value of the stack pointer might vary from one CPU revision to another. It'll certainly vary when the user presses the NES's reset button in the middle of a subroutine.

Code: Select all

	INX			; Increments X, which rolls X over its max value back to 0. I'm assuming we do this because it uses less memory than writing LDX #$00. Is that correct?
Yes. It saves 1 byte and 0 cycles over LDX #$00.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Init Code Questions

Post by tokumaru »

cartlemmy wrote:; I'm not sure why this is done, are we manually resetting the stack? can someone give me a hint?
Yeah, it's good practice to initialize the stack pointer. Your program might still work if you don't though, since the stack pointer wraps around, as long as you don't use page 1 ($0100-$01FF) for anything else. But if you plan on using page 1 for other purposes besides the stack, or if you plan on accessing the stack using using index registers (LDA $0101, X; LDA $0102, X; etc.) you have to initialize it.
; Increments X, which rolls X over its max value back to 0. I'm assuming we do this because it uses less memory than writing LDX #$00. Is that correct?
Yes, this is correct.
User avatar
cartlemmy
Posts: 193
Joined: Fri Sep 24, 2010 4:41 pm
Location: California, USA
Contact:

Post by cartlemmy »

Thanks guys, you're awesome!
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

Yes, unfortunately many code aimed at new programmers needlessly optimizes it, making the task of learning more difficult. Assembly is difficult enough as it is; save the optimizations until after you've learned how to initialize the NES.

Another reason is to allow easy access to the stack via indexed addressing. Sometimes you push some things on the stack, and then want to access one of the earlier things without pulling everything back off. You do this by transferring S to X, and then using $100+offset,x to access earlier things. If the stack pointer might have wrapped since pushing those, this will fail.

A final reason to initialize the stack pointer is consistency of behavior, in case your code ever depends ons value. Having it random makes debugging harder, since it's something that might differ without your knowledge.
User avatar
cartlemmy
Posts: 193
Joined: Fri Sep 24, 2010 4:41 pm
Location: California, USA
Contact:

Post by cartlemmy »

Yeah, I don't have a problem with optimizations in tutorials, as long as there is an explanation. Thanks for the info Blargg.
User avatar
cartlemmy
Posts: 193
Joined: Fri Sep 24, 2010 4:41 pm
Location: California, USA
Contact:

Post by cartlemmy »

One more question (in comments).

Code: Select all

clrmem:
	LDA #$00
	STA $0000, x
	STA $0100, x
	STA $0200, x ;Isn't this sort of redundant, since we are setting it to #$FE later? Or am I missing something?
	STA $0400, x
	STA $0500, x
	STA $0600, x
	STA $0700, x
	LDA #$FE
	STA $0200, x
	INX
	BNE clrmem
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

Yeah, it's redundant. Sometimes you start with code that's known to work, then make changes that you are sure won't break it, and don't mind leaving some inefficiency if it means the program is easier to prove correct. Though here, it reduces clarity, because you wonder why it's doing a clear followed by a fill, whether there is something you aren't seeing.

If I were doing that, I'd have no problem with using a standard memory clear and avoiding modifying it, and then doing the fill separately later in the code. It's a combination of a well-tested memory clear that you use in EVERY program, and some extra code that's easy to prove correct.

So the coding style I use emphasizes correctness first, even if that sometimes results in inefficiencies. As long as they aren't in critical sections of code, it might not even have any noticeable impact on the program speed, and thus show that it was the right choice: trade some unimportant speed for always-important correctness and clarity.
User avatar
cartlemmy
Posts: 193
Joined: Fri Sep 24, 2010 4:41 pm
Location: California, USA
Contact:

Post by cartlemmy »

Thanks Blarrg, that's what I was looking for.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

cartlemmy wrote:

Code: Select all

clrmem:
	LDA #$00
	STA $0000, x
	STA $0100, x
	STA $0200, x ;Isn't this sort of redundant, since we are setting it to #$FE later? Or am I missing something?
	STA $0400, x
; [...]
	LDA #$FE
	STA $0200, x
	INX
	BNE clrmem
I'm pretty sure the first instance of $0200,x is a typo for $0300,x. Where did you find this code? I just checked the wiki and the error isn't there.
User avatar
cartlemmy
Posts: 193
Joined: Fri Sep 24, 2010 4:41 pm
Location: California, USA
Contact:

Post by cartlemmy »

tepples wrote:
cartlemmy wrote:

Code: Select all

clrmem:
	LDA #$00
	STA $0000, x
	STA $0100, x
	STA $0200, x ;Isn't this sort of redundant, since we are setting it to #$FE later? Or am I missing something?
	STA $0400, x
; [...]
	LDA #$FE
	STA $0200, x
	INX
	BNE clrmem
I'm pretty sure the first instance of $0200,x is a typo for $0300,x. Where did you find this code? I just checked the wiki and the error isn't there.
I though I found it on that Nerdy Nights tutorial... But upon review, I couldn't find this error. Perhaps I screwed something up somehow, and in that case I apologize for the trouble.
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

IMO, this has been one of the more interesting discussions, even though it's about something so basic. The basics never get boring.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

I like when we discuss code... I mean, not those "here's my wall of code - find my error for me" situations, but more when we talk about a good way to do this or that...
Post Reply