It is currently Sun Dec 17, 2017 4:58 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 31 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Debugging the cpu core
PostPosted: Sun Sep 08, 2013 7:30 pm 
Offline
User avatar

Joined: Sat Jan 03, 2009 3:28 pm
Posts: 59
Location: Oregon
I thought I'd just make a new thread for this. I've been trying for weeks now to debug my cpu core and I just don't know where to go from here. My core passes some of blarg's tests. Here are what each of the tests do:

01-basics: passes
02-implied: passes
03-immediate: Doesn't pass. $6000 = $80 no matter how much time passes. Goes into an infinite BRK instruction after INC instruction is carried out at $03A1
04-zero_page: Doesn't pass. $6000 = $80 no matter how much time passes. Goes into infinite BRK after $03A1
05-zp_xy: Doesn't pass. $6000 = $80 no matter how much time passes.
06-absolute: Doesn't pass. $6000 = $80 no matter how much time passes.
07-abs_xy: Doesn't pass. $6000 = $80 no matter how much time passes.
08-ind_x: Fails but only illegal opcodes are output as being wrong (I'm only testing official opcodes)
09-ind_y: Same as ind_x
10-branches: passes
11-stack: passes
12-jmp_jsr: passes
13-rts: passes
14-rti:passes
15-brk: fails. $6000 = $80 no matter how much time passes.
16-special: fails. $6000 = $80 no matter how much time passes.

I have a debug function written that outputs all instructions like this, but the text file gets so big that I have no idea how it's helpful:
Quote:
E883 78 SEI A:00 X:00 Y:00 P:30 SP:FD CYC: 0
E884 4C B3 EC JMP $ECB3 A:00 X:00 Y:00 P:34 SP:FD CYC: 6
ECB3 8D 24 02 STA $0224 = 00 A:00 X:00 Y:00 P:34 SP:FD CYC: 15
ECB6 A9 00 LDA #$00 A:00 X:00 Y:00 P:34 SP:FD CYC: 27
ECB8 8D 00 20 STA $2000 = 00 A:00 X:00 Y:00 P:36 SP:FD CYC: 33
ECBB 8D 01 20 STA $2001 = 00 A:00 X:00 Y:00 P:36 SP:FD CYC: 45
ECBE 4C 87 E8 JMP $E887 A:00 X:00 Y:00 P:36 SP:FD CYC: 57


So, what is the best way of going about debugging this CPU core? All of the tests that fail get off track some way or another and never actually print any output ($6000 is always $80, so it's still running) because it gets stuck in an infinite BRK. I have no idea what opcodes to even start looking at.


Top
 Profile  
 
PostPosted: Sun Sep 08, 2013 8:09 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
There's always nestest with a log of correct execution to compare your CPU with. Pinpoints exactly where you go astray.


Top
 Profile  
 
PostPosted: Sun Sep 08, 2013 11:11 pm 
Offline
User avatar

Joined: Sat Jan 03, 2009 3:28 pm
Posts: 59
Location: Oregon
I was using that test originally, but I switched over to yours because the nestest tests illegal opcodes. My cpu is correct up until the illegal opcodes start. Some of my illegal opcodes aren't right and I couldn't figure out the correct behavior for their flags, so I turned them off.


Top
 Profile  
 
PostPosted: Mon Sep 09, 2013 12:56 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
My individual CPU tests also try unofficial opcodes, I'm pretty sure. Only the large multi-test ROMs have a version of only official opcodes. It's not too hard to have your core just skip unofficial instructions.


Top
 Profile  
 
PostPosted: Mon Sep 09, 2013 1:04 pm 
Offline
User avatar

Joined: Sat Jan 03, 2009 3:28 pm
Posts: 59
Location: Oregon
I tried a variant of my cpu core once before that moved the PC counter accordingly for the unoffical opcodes but nothing more. This caused a lot of issues on the nestest, however, because the processor status flags weren't correct when branch instructions came up. Maybe it would have a different affect on your tests?


Top
 Profile  
 
PostPosted: Mon Sep 09, 2013 1:47 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
My instruction tests do each one individually, so that a failing one won't affect others (unless it's an instruction used by the tests, like say CMP # or something basic). It'd be interesting to make the CPU test immune to emulators that treat unofficial instructions as one-byte NOPs. Maybe it could try executing them with zero-byte operands and if a BRK occurs, skip that instruction.


Top
 Profile  
 
PostPosted: Mon Sep 09, 2013 2:20 pm 
Offline

Joined: Thu Apr 14, 2011 9:27 pm
Posts: 85
You can generate known good logs of the tests you're failing with Nintendulator's debugger and then diff them with yours (assuming the format is the same). A lot of programs have trouble with 300mb log files, but Beyond Compare worked for that when I needed it.


Top
 Profile  
 
PostPosted: Mon Sep 09, 2013 11:35 pm 
Offline
User avatar

Joined: Sat Jan 03, 2009 3:28 pm
Posts: 59
Location: Oregon
I took Grapeshot's suggestion and went with it. I'm running through 03-immediate right now.

Somehow my $2C BIT test isn't working right. Everything matches up for 9000+ lines until Nestendulator just randomly switches up how $2C works. I can't post the lines in question because the formatting gets messed up, but here is what happens the best I can explain it:

A long loop occurs where $2C bit and BMI/BNE are alternated between. Opcode $2C is reading address $2002 during the entire loop which is always set to $FF. This leaves the processor status flags as $26 whenever the $2C opcode is ran UNTIL the last one that throws off my emulator. The last $2C opcode that breaks out of the loop sets the negative flag (making the processor status $A6 so that the next BMI branches) even though it's still bit testing $FF. I cannot for the life of me figure out why.

Here is my code for $2C. Originally, my processor status flags were wrong when running $2C. The wiki said that V and N were set to bits 6 and 7 of the data read. That didn't work so I tried the not of the bits and it worked up until the last bit test I mentioned above. So theres that for you.

Code:
case 0x2C:   //Absolute bit test
         temp = absolute(memory, ppu);
         data = memory->readRAM(temp, ppu);
         Z = !(A & data);
         V = !(data & 0x40);   //Gets the 6th bit only
         N = !(data & 0x80);   //Gets the 7th bit only
         debugAbs(opcode, memory->readRAM(PC + 1, ppu), memory->readRAM(PC, ppu), data, "BIT");
         cycles =  4;
         PC += 2;
         break;


Top
 Profile  
 
PostPosted: Mon Sep 09, 2013 11:51 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6535
Location: Seattle
$2002 should definitely not return $FF forever. At the very least, the MSB should be cleared after you read from it.


Top
 Profile  
 
PostPosted: Tue Sep 10, 2013 12:08 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
You're setting N and V to the opposite of what they should be. Add a bang:

V = !!(data & 0x40); //Gets the 6th bit only
N = !!(data & 0x80); //Gets the 7th bit only


Top
 Profile  
 
PostPosted: Tue Sep 10, 2013 12:31 am 
Offline
User avatar

Joined: Sat Jan 03, 2009 3:28 pm
Posts: 59
Location: Oregon
lidnariq wrote:
$2002 should definitely not return $FF forever. At the very least, the MSB should be cleared after you read from it.


That's what my code originally did but it was wrong according to Nintendulator. Nintendulator kept $FF in $2002 and I had $7F in $2002, which vimdiff didn't like since the log files didn't match.

blargg wrote:
You're setting N and V to the opposite of what they should be. Add a bang:

V = !!(data & 0x40); //Gets the 6th bit only
N = !!(data & 0x80); //Gets the 7th bit only


My original code looked like this, but my log file would have the wrong processor status after the first bit test occured.

Code:
V = data & 0x40;   //Gets the 6th bit only
N = data & 0x80;   //Gets the 7th bit only


Top
 Profile  
 
PostPosted: Tue Sep 10, 2013 8:47 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Dartht33bagger wrote:
My original code looked like this, but my log file would have the wrong processor status after the first bit test occured.

V = data & 0x40; //Gets the 6th bit only
N = data & 0x80; //Gets the 7th bit only

Maybe the data was wrong, rather than the instruction behavior?


Top
 Profile  
 
PostPosted: Tue Sep 10, 2013 1:57 pm 
Offline
User avatar

Joined: Sat Jan 03, 2009 3:28 pm
Posts: 59
Location: Oregon
Alright, I'm just going to post the lines in question from the two logs files the best that I can. My log file will be using code that doesn't not the V and N bits and clears bit 7 of $2002 after read.

From Nintendulator's log:

Quote:
E944 2C 02 20 BIT $2002 = FF A:00 X:01 Y:18 P:24 SP:FB CYC: 0 SL:171
E947 2C 02 20 BIT $2002 = FF A:00 X:01 Y:18 P:26 SP:FB CYC: 12 SL:171
E94A 30 06 BMI $E952 A:00 X:01 Y:18 P:26 SP:FB CYC: 24 SL:171
E94C CA DEX A:00 X:01 Y:18 P:26 SP:FB CYC: 30 SL:171
E94D D0 F8 BNE $E947 A:00 X:00 Y:18 P:26 SP:FB CYC: 36 SL:171
E94F 88 DEY A:00 X:00 Y:18 P:26 SP:FB CYC: 42 SL:171
E950 10 F5 BPL $E947 A:00 X:00 Y:17 P:24 SP:FB CYC: 48 SL:171
E947 2C 02 20 BIT $2002 = FF A:00 X:00 Y:17 P:24 SP:FB CYC: 57 SL:171


From my log on the same lines:
Quote:
E944 2C 02 20 BIT $2002 = FF A:00 X:01 Y:18 P:24 SP:FB CYC: 0 SL:171
E947 2C 02 20 BIT $2002 = 7F A:00 X:01 Y:18 P:E6 SP:FB CYC: 12 SL:171
E94A 30 06 BMI $E952 A:00 X:01 Y:18 P:66 SP:FB CYC: 24 SL:171
E94C CA DEX A:00 X:01 Y:18 P:66 SP:FB CYC: 30 SL:171
E94D D0 F8 BNE $E947 A:00 X:00 Y:18 P:66 SP:FB CYC: 36 SL:171
E94F 88 DEY A:00 X:00 Y:18 P:66 SP:FB CYC: 42 SL:171
E950 10 F5 BPL $E947 A:00 X:00 Y:17 P:64 SP:FB CYC: 48 SL:171
E947 2C 02 20 BIT $2002 = 7F A:00 X:00 Y:17 P:64 SP:FB CYC: 57 SL:171


Nintendulators N and V flags are always opposite to mine. It also keeps reading $FF from $2002. I'm stumped.


Top
 Profile  
 
PostPosted: Tue Sep 10, 2013 2:31 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Nintendulator's log doesn't even make sense, or it's lying about the value read from $2002.


Top
 Profile  
 
PostPosted: Tue Sep 10, 2013 2:38 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3076
Location: Brazil
...


Last edited by Zepper on Thu Sep 12, 2013 3:10 pm, edited 1 time in total.

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

All times are UTC - 7 hours


Who is online

Users browsing this forum: Bing [Bot], sdm and 8 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