It is currently Wed Dec 13, 2017 5:48 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 15 posts ] 
Author Message
PostPosted: Wed Aug 26, 2015 8:44 am 
Offline
User avatar

Joined: Wed Aug 26, 2015 8:24 am
Posts: 21
Location: Ontario, Canada
Hi all!

I'm yet another person writing yet another NES emulator. My reason is mostly for self enrichment, not so much to replace any thing that is out there already. I've called it ALIAneS and am building it on OS X in C++. I have CPU emulation nearly complete, with only a handful of opcodes left to write. I do not have any PPU or controller emulation.

For fun I loaded up nestest.nes and ran it in ALIAneS, starting execution at 0xc000. I spent half an hour comparing line by line output with the Nintendulator log... before realizing it was 8000 lines long...

Without any visual or sound output other than an execution log, is there any good way to test opcodes without comparing line by line? Would just comparing the execution addresses be sufficient?
Thanks!


Attachments:
File comment: Showing the output I have available, and the known good log.
Screen Shot 2015-08-26 at 11.39.38 AM.png
Screen Shot 2015-08-26 at 11.39.38 AM.png [ 767.09 KiB | Viewed 2693 times ]

_________________
Aliasmk- GitHub :: Twitter :: Website
Current ALIAneS Emulator Progress: CPU complete, PPU indev - we have graphics and sprites!
Top
 Profile  
 
PostPosted: Wed Aug 26, 2015 9:17 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5896
Location: Canada
Couldn't you write a program to make the comparison for you?


Top
 Profile  
 
PostPosted: Wed Aug 26, 2015 10:16 am 
Offline
User avatar

Joined: Wed Aug 26, 2015 8:24 am
Posts: 21
Location: Ontario, Canada
Yes but what would be best to test for? Would it be enough to just compare execution addresses and fix problems when they differ from the known good log, or would I miss some issues that way? What I'm also curious about is if during execution, nestest stores test results somewhere in memory. That way I could just fetch the memory corresponding to each test to determine its result (assuming thats how it works).

_________________
Aliasmk- GitHub :: Twitter :: Website
Current ALIAneS Emulator Progress: CPU complete, PPU indev - we have graphics and sprites!


Top
 Profile  
 
PostPosted: Wed Aug 26, 2015 1:48 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19342
Location: NE Indiana, USA (NTSC)
Aliasmk wrote:
Without any visual or sound output other than an execution log, is there any good way to test opcodes without comparing line by line? Would just comparing the execution addresses be sufficient?

Yes. Have your emulator output a log of PC before each instruction, and then write another program to compare this log against the PC values in a known-good log. If the logs diverge, the problem is related to something in the prior dozen or so lines. If you're stumped as to the cause of a divergence, you can have your emulator output a more detailed log including A, X, Y, P, and S as well to pinpoint the exact instruction that caused the problem.


Top
 Profile  
 
PostPosted: Wed Aug 26, 2015 2:59 pm 
Offline
User avatar

Joined: Wed Dec 06, 2006 8:18 pm
Posts: 2806
If you make your emulator log exactly the same format as a known good log file you can just use a hex editor's compare files feature and see if and where they differ. No need to write your own program to compare log files.


Top
 Profile  
 
PostPosted: Wed Aug 26, 2015 5:40 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2982
Location: Tampere, Finland
MottZilla wrote:
If you make your emulator log exactly the same format as a known good log file you can just use a hex editor's compare files feature and see if and where they differ. No need to write your own program to compare log files.

Or fc on Windows, diff on *nix.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Wed Aug 26, 2015 5:47 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19342
Location: NE Indiana, USA (NTSC)
MottZilla wrote:
If you make your emulator log exactly the same format as a known good log file you can just use a hex editor's compare files feature and see if and where they differ. No need to write your own program to compare log files.

But then you'd have to implement all the features of Nintendulator's logging, including disassembly of each instruction. I imagine it'd be easier to write your own compare program.


Top
 Profile  
 
PostPosted: Wed Aug 26, 2015 6:00 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3076
Location: Brazil
Well... if there's a problem or bug in your CPU emulator, I dunno it would appear after 8000 lines, or should I say 8000 instructions..? At any rate, checking the timing of an instruction isn't so hard, as far as you have a fair way of writting the CPU emulator (code architecture). A huge block of case statements isn't a good idea, or a piece of code for each instruction. It difficults the debugging. My way of doing the things right (TM) is the following:

a) take the instruction opcode -> addressing mode -> decode it (1 or 2 bytes).
b) jump to the instruction code block (yup, jump tables). This is well condensed, since most of the opcodes only differ in the addressing mode.

About comparing line by line, well... as I said, if there's a bug, it should appear soon. I always get focused on timing (NMI or IRQ).


Top
 Profile  
 
PostPosted: Wed Aug 26, 2015 8:06 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2982
Location: Tampere, Finland
tepples wrote:
MottZilla wrote:
If you make your emulator log exactly the same format as a known good log file you can just use a hex editor's compare files feature and see if and where they differ. No need to write your own program to compare log files.

But then you'd have to implement all the features of Nintendulator's logging, including disassembly of each instruction. I imagine it'd be easier to write your own compare program.

Or just trim out the unnecessary information from the Nintendulator log. Not too hard to do in any decent text editor.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Sat Aug 29, 2015 9:21 pm 
Offline
User avatar

Joined: Wed Aug 26, 2015 8:24 am
Posts: 21
Location: Ontario, Canada
Thanks all for your suggestions. I'm current writing a program to take the outputted logs of my emulator and compare the executed addresses of the known good log. Comparing the two log files exactly is a good idea but I would have to match the formatting of the Nintendulator exactly, or remove information (which would probably require macros or code anyway). If this doesn't work I'll try something else.

Zepper wrote:
Well... if there's a problem or bug in your CPU emulator, I dunno it would appear after 8000 lines, or should I say 8000 instructions..?


I did means instructions yes. The logs list each instruction executed on a new line, sorry for the confusion.

Zepper wrote:
a) take the instruction opcode -> addressing mode -> decode it (1 or 2 bytes).
b) jump to the instruction code block (yup, jump tables). This is well condensed, since most of the opcodes only differ in the addressing mode.


Interesting. I believe I've implemented a hybrid of what you suggested and what you say is bad practice. I break down the opcode into AAABBBCC as described here (http://www.llx.com/~nparker/a2/opcodes.html). I then have one case statement that tests for instructions and addressmodes based on the decoded pattern (long, but better than a GIANT case switch for every single opcode. Each instruction is only defined once, addresses and values are written and read from based on addressing mode code earlier. It is slightly off topic, but what are your thoughts on this method?

Also, before I test for timings I need to make sure all the operations work :)

_________________
Aliasmk- GitHub :: Twitter :: Website
Current ALIAneS Emulator Progress: CPU complete, PPU indev - we have graphics and sprites!


Top
 Profile  
 
PostPosted: Sun Aug 30, 2015 6:51 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3076
Location: Brazil
Why "bad practice"? The C code is small, well organized and... the only "bad" thing is about the jump table - it seems the compiler cannot optimize it so much. Other than that, I don't see anything SO wrong.


Top
 Profile  
 
PostPosted: Sun Aug 30, 2015 7:18 am 
Offline
User avatar

Joined: Wed Aug 26, 2015 8:24 am
Posts: 21
Location: Ontario, Canada
Zepper wrote:
Why "bad practice"? The C code is small, well organized and... the only "bad" thing is about the jump table - it seems the compiler cannot optimize it so much. Other than that, I don't see anything SO wrong.


Because you previously said

Zepper wrote:
A huge block of case statements isn't a good idea, or a piece of code for each instruction.


And I have a bit of both of these in my code.

Anyway, back on topic, I'll compare execution and see where any errors happen. If it works well I'll report back. Thanks again!

_________________
Aliasmk- GitHub :: Twitter :: Website
Current ALIAneS Emulator Progress: CPU complete, PPU indev - we have graphics and sprites!


Top
 Profile  
 
PostPosted: Sun Aug 30, 2015 9:43 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5896
Location: Canada
A well organized switch/case can be compiled into a jump table implementation by many common C/C++ compilers. (Frequently this optimization requires that all the case statements be contiguous values, in-order.) YMMV, but implementing an explicit jump table in C isn't necessarily a performance benefit vs a switch block. (some info here)

There are plenty of non-performance reasons to prefer one over the other, but in the absence of a real performance benefit there's really nothing wrong with a switch block for this kind of thing. Of course, measure performance to determine the truth, and check your compiler's assembly output if you need to know what it's doing with your code.


Top
 Profile  
 
PostPosted: Thu Oct 08, 2015 1:51 pm 
Offline
User avatar

Joined: Wed Aug 26, 2015 8:24 am
Posts: 21
Location: Ontario, Canada
Update: the comparison code is working and I'm working my way down the NESTest code, fixing issues as they come up. Thanks all!


Attachments:
Screen Shot 2015-10-08 at 4.48.54 PM.png
Screen Shot 2015-10-08 at 4.48.54 PM.png [ 606.4 KiB | Viewed 2337 times ]

_________________
Aliasmk- GitHub :: Twitter :: Website
Current ALIAneS Emulator Progress: CPU complete, PPU indev - we have graphics and sprites!
Top
 Profile  
 
PostPosted: Tue Dec 15, 2015 1:41 pm 
Offline

Joined: Sun Oct 25, 2015 4:16 pm
Posts: 7
I know this has been answered before but I just wanted to chime in with my solution in case someone else stumbles onto this thread. I basically write my own log file that looks like the Nestest logs, and once the program exits I use diff to compare the two files, like so:

Code:
diff –wu my_log.log nestest.log > diff_result.log


This should highlight the lines where the log files mismatch.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: Gilbert and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group