Reset handler/reset vector confusion?

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

User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Reset handler/reset vector confusion?

Post by FrankenGraphics »

Following the discussion on where to keep logic/state handling, i got a little confused.

In the thread, there's a recommendation to keep it in the reset handler. Pardon my inexperience.
My first impulse on what to put there is a routine that wipes RAM and sets the state handler(s) to point to title init (or point to start of program init directly). Or am i confusing the code at the address of the reset vector with something else? And if i'm not; why?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Reset handler/reset vector confusion?

Post by tokumaru »

Sometimes we call it "Reset" just because that's the entry point that eventually leads to the dedicated game loops. You can also call it the "main thread".

At the beginning of the reset handler you should indeed initialize the system (although I advocate against wiping the RAM, but let's not focus on that), but right after that you'd normally jump to the first game loop (introduction, title screen, whatever).
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: Reset handler/reset vector confusion?

Post by FrankenGraphics »

Thanks! So to verify, something like "keeping logic in the Reset handler" simply means "keeping logic in main", as opposed to NMI (or IRQ/BRK, even though not likely applicable here), and not necessarily assuming the very top of reset/main? The latter part is what i think originally confused me the most.

If you want to, i'd also be interested to hear your advice against wiping RAM.
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Reset handler/reset vector confusion?

Post by koitsu »

First time in my life I've ever heard someone say "reset" (particularly mention the RESET vector, because said thread was discussing NMI and RESET) referring to the main loop of a game. o_O;; I had the same reaction as WheelInventor but chose to say nothing.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Reset handler/reset vector confusion?

Post by tokumaru »

Yeah, calling the main thread "reset" can be a bit confusing, I wouldn't normally do that, but that's what the post I was replying to called it, and I didn't want to make things more confusing by changing the terminology.

The main thread does indeed start at the reset vector, but any game that's not trivially simple will not have any game loops particularly close to the reset code.
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 568
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: Reset handler/reset vector confusion?

Post by Jarhmander »

I did several smallish assembly programs for some small microcontrollers, and the main loop was right below the "Reset" label, so I named the main thread simply "reset"; the documentation would say, "[this subroutine] must be called from reset" instead of "(...) from main thread".
((λ (x) (x x)) (λ (x) (x x)))
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: Reset handler/reset vector confusion?

Post by FrankenGraphics »

Interesting. So, maybe it's a high level / low level programming discourse thing, possibly obscured by time, seeing less use? Or maybe an electronics engingeering / programming one.
Rahsennor
Posts: 479
Joined: Thu Aug 20, 2015 3:09 am

Re: Reset handler/reset vector confusion?

Post by Rahsennor »

My compiler traces seperate call graphs from each vector to avoid interrupts clobbering local variables without resorting to a software stack. So "called from RESET" vs. "called from NMI" makes perfect sense to me.
User avatar
mikejmoffitt
Posts: 1353
Joined: Sun May 27, 2012 8:43 pm

Re: Reset handler/reset vector confusion?

Post by mikejmoffitt »

Given the name of the vector, and what it represents, I think it's weird to say "put the logic in reset". I consider that the entry point that represents initialization, which then jumps to a main loop elsewhere. In the end, it's semantics and not functionally different.
Pokun
Posts: 2675
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Reset handler/reset vector confusion?

Post by Pokun »

WheelInventor wrote: If you want to, i'd also be interested to hear your advice against wiping RAM.
I think it's about hiding bugs. If you always make sure every RAM register that you are going to read is initialized there's no need to wipe the RAM (like in C you would also initialize every variable somehow). And if you forget to initialize a certain variable, something might not work as expected (since RAM can be anything at boot). But if you wipe RAM then initialization bugs won't show. FCEUX might not show these bugs though since it initializes RAM in a pattern at boot like: 0000FFFFF...

But I'm not sure how Tokumaru means wiping RAM is different from initializing variables. Most variables may be 0 anyway so it makes sense to use a loop that does it with much less code. Then you only need to initialize variables that shouldn't be 0.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Reset handler/reset vector confusion?

Post by tokumaru »

WheelInventor wrote:If you want to, i'd also be interested to hear your advice against wiping RAM.
Sorry, I missed this part!
Pokun wrote:I think it's about hiding bugs.
That, and I find it redundant. Every variable has to be initialized before it's used anyway (specially if it's reused!), so clearing everything to $00 at the beginning is pointless, since every variable, in theory, will be initialized afterwards anyway. My reasoning is that it wastes ROM (hey, you never know when you're gonna need every last byte of it! :mrgreen:) and may hide bugs, So I see absolutely no reason to do that.

In fact, during development, I often do the very opposite of clearing RAM, I fill it with garbage. I pick a seed for my random number generator and fill the RAM with crap. From time to time I change the seed to see if anything obvious changes, which would indicate that something wasn't being initialized properly.
But I'm not sure how Tokumaru means wiping RAM is different from initializing variables. Most variables may be 0 anyway so it makes sense to use a loop that does it with much less code. Then you only need to initialize variables that shouldn't be 0.
The problem with that is that the full wipe only happens once, but several parts of the program run more than once. Say you wipe all the RAM and everything appears to work when you do it the first time. The title screen, the title card, the first level. Then you die, the level restarts and everything is buggy. But why, since it was fine before? Well, you might very well have forgotten to initialize some gameplay variables, which were all $00 the first time but now have been corrupted after you played the level for the first time. My point is that most of the time you have to initialize the variables prior to using them, because they're often reused in games. And if you're gonna initialize the relevant variables before running each module of your game, why bother clearing it all in the beginning, since all it really does is hide bugs?

I guess that you you have a lot of state that survives the entire game without ever being reset, and the initial state for most of that is $00, then I guess you could save a little space by wiping the entire RAM in one go, but I personally never felt like I'd benefit from that. Very few things in my code begin at $00, and very few things live from power on to power off without ever needing to be reset, so...
Pokun
Posts: 2675
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Reset handler/reset vector confusion?

Post by Pokun »

OK now I see. Variables that are initialized more than once of course don't benefit from a RAM wipe.

I do have a lot of flags and other variables that needs to be initialized to 0 once though, so a simple RAM wipe loop is much smaller than clearing each variable individually.

Individually:

Code: Select all

init_variables:
  lda #$00              ;clear variables
  sta var0
  sta var1
  sta score
  sta graphic_flag
  sta ☆☆☆
  sta tjingtjong
  ...
  sta var100000
Simple loop:

Code: Select all

init_ram:
  lda #$00
  ldx #$00
@loop:
  sta $0000,x           ;clear each RAM page
  sta $0100,x
  sta $0200,x
  sta $0300,x
  sta $0400,x
  sta $0500,x
  sta $0600,x
  sta $0700,x
  inx
  bne @loop
Then I might skip page 2 and page 7 to use them as shadow OAM and highscore respectively. They'd need their own initialization loops.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Reset handler/reset vector confusion?

Post by rainwarrior »

Pokun wrote:
WheelInventor wrote: If you want to, i'd also be interested to hear your advice against wiping RAM.
I think it's about hiding bugs. If you always make sure every RAM register that you are going to read is initialized there's no need to wipe the RAM (like in C you would also initialize every variable somehow). And if you forget to initialize a certain variable, something might not work as expected (since RAM can be anything at boot). But if you wipe RAM then initialization bugs won't show. FCEUX might not show these bugs though since it initializes RAM in a pattern at boot like: 0000FFFFF...

But I'm not sure how Tokumaru means wiping RAM is different from initializing variables. Most variables may be 0 anyway so it makes sense to use a loop that does it with much less code. Then you only need to initialize variables that shouldn't be 0.
Almost all emulators initialize RAM to a consistent state on power on, not just FCEUX. The only exception I can think of is thefox's custom build of Nintendulator?

FCEUX now has an option to initialize it as random, if you like, but it is not the default setting.

Personally I don't believe that failing to initialize RAM is any kind of defense against bugs. What it will do is make bugs unreliable and difficult to reproduce (i.e. unlikely to be caught in production, and difficult to diagnose once released). If initializing it to 0 doesn't cause a bug to occur, then it's not a bug. :P

When you release software, it will always have bugs somewhere. Some of those bugs might read areas of RAM you didn't intend. If you initialize the whole thing, at least it's going to go wrong the same time every time, and you have some hope of the conditions on your test being the same as the conditions where it's failing on someone's playthrough.

If you want to track unexpected reads, put breakpoints on your empty memory regions, or use/write some other kind of memory dianostic tool. Leaving it uninitialized is probably the worst way I can think of to try and catch and fix that problem; there's a million better ways to do this.

So, if you're asking for opinions on whether to do this, I am 100% in the initialize everything you can camp.

(And use an emulator with randomized RAM on startup anyway, it's a good emulator feature and there's a reason I added it to FCEUX, I just don't think it's appropriate for the purpose stated-- you should STILL INITIALIZE RAM in your game's reset code.)
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Reset handler/reset vector confusion?

Post by tokumaru »

rainwarrior wrote:If initializing it to 0 doesn't cause a bug to occur, then it's not a bug. :P
But what If the bug doesn't occur the first time you forget to initialize a variable, but does occur the second time?

I know that randomizing RAM doesn't guarantee that bugs will manifest themselves sooner, but non-zero values tend to cause more obvious side effects. And randomizing RAM in your code (as opposed to letting the emulator do it every time) has the benefit that you can decide when to change the seed, because you may want to maintain a certain RAM configuration if it happens to expose a bug. If you randomize every time, a bug can vanish before you have the chance to debug it.
you should STILL INITIALIZE RAM in your game's reset code.)
Oh well, to each his own. FWIW, I never told him not to do it, I just said I don't do it.
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: Reset handler/reset vector confusion?

Post by thefox »

rainwarrior wrote:Almost all emulators initialize RAM to a consistent state on power on, not just FCEUX. The only exception I can think of is thefox's custom build of Nintendulator?
It's optional in NDX. When option is enabled, the randomization pattern is always the same after the emulator is started (and changes on each power-on). I decided to not seed the RNG for the reason that tokumaru mentioned (reproducibility of bugs), although it could be improved by allowing the user to specify the seed.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
Post Reply