Error checking

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Error checking

Post by Movax12 »

I've been contemplating a lot of things, getting ready to do more serious stuff for the NES, (lower level 'driver' kind of things) and I was wondering if anyone codes runtime error messages into their games. Something like:

Code: Select all


( ...some code..)

#ifdef _DEBUG_
   cpx #MAX_VALUE
   bcc continue
   pha
   lda #ERROR_CODE_X_OUT_OF_RANGE
   jsr display_message_halt                    ;clears screen and displays message indexed by reg A, maybe dumps all registers
#end

continue:

(..more code..)
I know the debugging tools are pretty good, but something like this might be helpful too.
Last edited by Movax12 on Wed Jun 27, 2012 9:19 am, edited 1 time in total.
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Post by Kasumi »

The closest I have is this macro:

Code: Select all

.macro trap;{
	
traplabel\@
	jmp traplabel\@
	
	.endm;}
If I put trap somewhere in my code, it will be stuck in an endless loop. I use it to find where problems are occurring, and occasionally to look at what's in the registers at a particular point since they obviously won't change while this is running.

Edit: Well... until the NMI hits :o
Last edited by Kasumi on Wed Jun 27, 2012 9:08 am, edited 1 time in total.
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru »

There should be no runtime errors in games at all. For debugging purposes, this has a problem - you would need to have full font in the CHR ROM, which is not always possible. So I think it is better to either just put an error code into a certain RAM address with filling whole screen with a color, or use an emulator to display actual messages (i.e. write an error message into a special register that'll be redirected to the PC console).
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Post by Movax12 »

Good points. I have seen the halt trick before somewhere, I guess it is not too hard to trace that. If you are always going to have characters in CHR this could work, and even though it is extra coding, sometimes I find stepping code and checking regs a chore.

I think (assuming you have a valid character set) this might help if you have some code from weeks before that you felt was solid suddenly not working right with no reason to check it. I guess an endless loop would still do the job there too.. Thanks for the feedback..

EDIT:Trivial to turn off NMI in your macro..
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Post by Kasumi »

Following Shiru's input, this isn't a bad idea if used with a LUA script to print the info. Then you don't need any characters in CHR.

I once used an FCEUX LUA script that paused the emulator whenever my character was traveling faster than 8 pixels per frame (which is as fast as the game can scroll), but because of how LUA works it only stopped on the beginning of the next frame rather than directly when it occurred. I had to use it in conjunction with input movies to know which frame to start my breakpoint that detected writes to that variable. Otherwise, the game would have been unplayable breaking X times a frame while I try to find the rare case where the max speed check wasn't working.

It would have been a bit of a pain to place a check at each place that variable had its value updated, but probably no worse than what I ended up doing. I also keep a few debug defines around now that I think about it. One that doesn't run the sprite logic and rigs scrolling to the buttons so I can debug scrolling updates, and various ones that enable cycle counting emulator register writes for various parts of the program. I guess I've just never thought about the sort of debugging you're suggesting. Not a bad idea, though.

And yeah, true about the NMI. I just honestly hadn't thought about it at all until I reread the post. "Oh, wait. The registers CAN be changed in that loop!"
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

Shiru wrote:So I think it is better to either just put an error code into a certain RAM address
For Thwaite, I just had the engine put various condition codes in an otherwise unused part of the status bar. (I wonder if I left the "C0DE" for that in 0.03.) The emulators for Linux that run anywhere near full speed on my laptop don't have debugging, and I hadn't yet thought about trying to run FCEUX for Windows in Wine.
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Post by Movax12 »

I like the idea of using emulator scripts. Or I like Shiru was saying - a special register for error codes - I suppose this would require an open source emulator and knowledge of how to create this feature.
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru »

Actually there is an emulator with many useful debug features including (similar) to this one.
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Post by Movax12 »

I didn't look that over in detail, and while that looks very powerful, it appears to depend entirely on CC65 based software. Unless I am missing something, it doesn't have generic special registers for writing error codes, does it?
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru »

It does it in a more comfortable way - you just put this code:

Code: Select all

 sta $4040
 jmp .skip
 db "error message text is here",0
.skip
The emulator intercepts the write into a non-existing register $4040 and puts a null terminated string from PC+3 into output console. So you can make a simple macro instead of a loop that would read string and write it byte by byte. It is not related to CC65, it is a debug feature of the emulator.
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Post by Movax12 »

Very nice! I'll give that a try. Thanks for explaining.
User avatar
Hamtaro126
Posts: 783
Joined: Thu Jan 19, 2006 5:08 pm

Post by Hamtaro126 »

Shiru wrote:It does it in a more comfortable way - you just put this code:

Code: Select all

 sta $4040
 jmp .skip
 db "error message text is here",0
.skip
The emulator intercepts the write into a non-existing register $4040 and puts a null terminated string from PC+3 into output console. So you can make a simple macro instead of a loop that would read string and write it byte by byte. It is not related to CC65, it is a debug feature of the emulator.
Some mappers require some form of usage around $4020-$40FF, Like my upcoming mapper that may first be a powerpak mapper...

Same with FDS Images, The RAM take up $4020-$40FF for extra mapper regs.
AKA SmilyMZX/AtariHacker.
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru »

When you will be adding support for your mapper in this exact emulator, you'll be able to change the $4040 to $4100 or something easily, I think.
doppelganger
Posts: 183
Joined: Tue Apr 05, 2005 7:30 pm

Post by doppelganger »

Or, if you have access to number tiles, you could simply, say, put some sprites in the upper-left corner with an error code number if an error ever occurs.
Be whatever the situation demands.
Post Reply