It is currently Wed Nov 22, 2017 1:05 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 32 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: New CPU test ROM
PostPosted: Sat Jan 12, 2008 3:12 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
I've been working on a new test framework that can run multiple groups of tests and give better feedback. As a first use of it, here's a set of CPU tests that do most instructions, testing several edge cases. If it fails, it prints the opcode and instruction name. It only tests official instructions right now.

blargg_nes_cpu_test5.zip

These tests work like zexall, trying each instruction with all interesting combinations of inputs and checksumming the registers afterwards. After all the different combinations have been fed to a particular instruction, the checksum is compared with the correct one to determine pass/fail.

EDIT: Replaced with version that doesn't stop on failure, so you get a list of all the instructions that failed.


Last edited by blargg on Sat Jan 19, 2008 8:31 pm, edited 2 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 12, 2008 3:14 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3950
Can you make it continue after an instruction fails?

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 12, 2008 5:12 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3075
Location: Brazil
Woot! Mine passed ok!

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 12, 2008 8:55 pm 
Offline

Joined: Sat Sep 22, 2007 8:32 am
Posts: 82
Location: Seattle, WA
Thank you for your work on these test case ROMs, I found some more bugs!


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 12, 2008 9:18 pm 
Offline
User avatar

Joined: Fri Jun 29, 2007 10:25 pm
Posts: 324
Location: Earth, Milkyway Galaxy, The Universe, M-Theory
Any idea if you're going to add illegal opcode support?

_________________
Code:
          *=$0000
loop      JMP loop
          .eof


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 15, 2008 5:52 pm 
Offline

Joined: Sat Sep 22, 2007 8:32 am
Posts: 82
Location: Seattle, WA
I've been trying to get this to pass since you've posted it. How exactly is this testing the functions? I'm failing several but is failing of one dependent on the others? I'm getting this (at bottom) but as I go over the functions, everything seems right. Example: ASL, a
Code:
/* ASL */
#define ARITHMATIC_SHIFT_LEFT_A(CYCLES){
   addr = (memory[program_counter + 1] << 8) | memory[program_counter];
   tmp = memory_read(addr);
   carry_flag = (carry_flag & 0xFE) | ((tmp >> 7) & 0x01);
   tmp <<= 1;
   write_memory(addr, tmp);
   sign_flag = tmp & 0x80;
   zero_flag = !(tmp);
   program_counter += 2;
   cycle_count -= CYCLES;
   break;
}

Image


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 15, 2008 8:49 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Is tmp an 8-bit variable, or more? It could be that one of the instructions used to do the tests isn't working correctly. What does kevtris' nestest say?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 16, 2008 6:13 am 
Offline

Joined: Sat Sep 22, 2007 8:32 am
Posts: 82
Location: Seattle, WA
The variable tmp is an unsigned int; nestest gives all OK as does the older NEStress. Though not all of your other test pass yet if that matters too.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 16, 2008 7:21 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
If tmp is an int, then your code calculates the Z flag wrong!

tmp = memory_read(addr);
tmp <<= 1;
zero_flag = !(tmp);

What happens if this reads 0x80 from memory into tmp? After the <<= 1, tmp=0x100 when it should be 0, and the zero flag is erroneously clear!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 17, 2008 5:20 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
New version, tests most unofficial instructions now, more thorough instruction coverage, and includes some documentation and full source code. Switched to MMC1, since apparently UxROM doesn't strictly support CHR ROM. Thanks to bunnyboy and thefox for testing help:
blargg_nes_cpu_test5.zip


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 30, 2008 3:06 pm 
Offline
User avatar

Joined: Thu Mar 24, 2005 3:17 pm
Posts: 355
I like it, I got errors with cpu.nes on AB ATX, 9C SYA, 9E SXA. I was able to fix ATX by ORing A with $FF, according to documents it's ORed with $EE, $EF, $FE, or $FF depending on CPU internal state like the program counter. Maybe on the NES it's always ORed with $FF, at least it makes your test program a bit happier on my emu.

I couldn't fix my SYA and SXA implementations, can someone explain how these work? I'm currently using this method:

http://www.s-direktnet.de/homepages/k_nadj/opcodes.html
Code:
SAY    ***
This opcode ANDs the contents of the Y register with  and stores the
result in memory.

One supported mode:

SAY abcd,X      ;9C cd ab    ;No. Cycles= 5

Example:

SAY $7700,X     ;9C 00 77

Equivalent instructions:

PHA
TYA
AND #$78
STA $7700,X
PLA

XAS    ***
This opcode ANDs the contents of the X register with  and stores the
result in memory.

One supported mode:

XAS abcd,Y      ;9E cd ab    ;No. Cycles= 5

Example:

XAS $6430,Y     ;9E 30 64

Equivalent instructions:

PHA
TXA
AND #$65
STA $6430,Y
PLA


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 30, 2008 5:13 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19245
Location: NE Indiana, USA (NTSC)
hap wrote:
I was able to fix ATX by ORing A with $FF, according to documents it's ORed with $EE, $EF, $FE, or $FF depending on CPU internal state like the program counter.

$EF in particular looks like the mask for a carry coming out of the lower nibble, as might be seen in hardware handling packed binary-coded decimal, such as the original 6502 CPU manufactured by MOS Technology.

Quote:
Maybe on the NES it's always ORed with $FF, at least it makes your test program a bit happier on my emu.

This might be the case for the NES, which for patent reasons uses a cut-down 6502 core lacking decimal mode.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 31, 2008 6:28 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
I just tested and 9C and 9E are screwey. I need to take them off the test. Depending on X and Y they sometimes write to $700, among other things. Maybe someone else can figure them out properly.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 31, 2008 6:56 pm 
Offline

Joined: Wed Mar 22, 2006 8:00 am
Posts: 354
Opcode $AB is known to work differently depending on the machine. Possible outcomes I've seen reported:

1. OR with $EE always
2. OR with $EE, $EF, $FE, or $FF based on the contents of other registers
3. OR with a seemingly random value (possibly influenced by DMA transfers)
4. Perform no OR operation at all (go straight to the AND step)

I think this opcode is triggering a bus conflict, causing the bits in A to get forced high in some cases (machine-dependent). Unless people test this opcode on multiple NES's to see if it works the same on all of them or not, we should assume the exact behavior to be unpredictable.

Exactly what is causing errors with $9C and $9E? Specifically, do problems show up during page boundary crossing, when there's no page crossing, or both? I suspect that since the store value is affected by the upper byte of the target address (the "fixed" version, with 1 added to it), it's possible that a page crossing would also cause an issue with the upper address lines during the store cycle. I haven't seen any docs that give light to this possibility, but that may be because no one tested it.

_________________
"Last version was better," says Floyd. "More bugs. Bugs make game fun."


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 08, 2008 7:35 am 
Offline
User avatar

Joined: Thu Mar 24, 2005 3:17 pm
Posts: 355
Quote:
Specifically, do problems show up during page boundary crossing, when there's no page crossing, or both? I suspect that since the store value is affected by the upper byte of the target address (the "fixed" version, with 1 added to it), it's possible that a page crossing would also cause an issue with the upper address lines during the store cycle.
You're right. Not that I've verified this on the NES, but blargg_nes_cpu_test5 passes on my emu if I mask the high address byte with $00 if there's a page crossing on SYA or SXA. Simply ignoring the write on page crossing made it pass too. Though, ORing it with $700 on page crossing (making it sometimes write to $700 like blargg said), makes it fail.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 32 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 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