It is currently Sun Oct 22, 2017 12:31 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 39 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Sun Jan 11, 2009 8:15 pm 
Offline
User avatar

Joined: Wed Dec 06, 2006 8:18 pm
Posts: 2801
As I mentioned in other threads, I'm working on a Gameboy (and later Gameboy Color) emulator. I've got a good bunch of games running but there are still problems that I think could be CPU related and not Gameboy emulation related. On the NES I was able to take advantage of Blargg's CPU Test. I've seen no such thing for Gameboy so I'm wondering if anyone has any good ideas for debugging? I know I can always go through each opcode one by one trying to spot errors but this will take awhile so I was just wondering if anyone had any tips.

Also if you have any ideas of something I could have been confused about and done wrong that I should check for, please let me know.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 12, 2009 4:31 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
This tests a good number of instructions (wla-dx source included): gb_cpu_test.zip


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 12, 2009 5:04 pm 
Offline

Joined: Thu Aug 28, 2008 1:17 am
Posts: 591
I'm interested to know if the CPU really does have 4 T states to a single cpu cycle or if that was just assumed from some docs. Similar to docs for the z80 that are incorrect and/or don't give the T state counts or reduced/extended T states for some situations.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 12, 2009 9:38 pm 
Offline
User avatar

Joined: Wed Dec 06, 2006 8:18 pm
Posts: 2801
I'm not sure exactly what you mean, but the Gameboy documents are pretty strange with Cycle counts. Sometimes people say something takes 1 cycle, others say that same opcode takes 4 cycles. Not what you want to get mixed up when you are trying to sync the PPU and CPU. Originally I did this with a 4x gap, so the PPU ran 4 times faster than it should, or you could say the Cpu ran 1/4th the speed it should.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 12, 2009 10:11 pm 
Offline
User avatar

Joined: Sun Jun 05, 2005 2:04 pm
Posts: 2131
Location: Minneapolis, Minnesota, United States
Yeah, I didn't have much luck either trying to find GB/GBC cycle counts. It'd be nice if there was some straight forward documentation about such things.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 12, 2009 10:33 pm 
Offline

Joined: Thu Aug 28, 2008 1:17 am
Posts: 591
Well, on the Z80 you have the instructions listed in M cycles. Most docs list M cycle as 3 (or 4 depending on the doc) external clock source cycles, but really M cycles don't show the whole picture. An M cycle is made up of a variable accumulation of T states depending on the operation and also depending on the previous instruction from what I've read.

On the GB docs, they list an M cycle as 4 external clock cycles and instruction timings are given in M cycles. Since the GB cpu is a variant of the z80, who's to say that the same misunderstanding isn't applied to it was well. There are many processor documents with incorrect instruction timing information out there, so this would be the first if it were true.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 14, 2009 3:44 am 
Offline

Joined: Thu Oct 05, 2006 6:29 am
Posts: 911
Is there a list of what the expected values for A and F are for each iteration of the DAA test?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 14, 2009 6:18 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
This code matches execution on a DMG/CGB. Flag bit masks below are named by flag name and hex value, for clarity.
Code:
if ( !(flags & N40) )
{
    if ( (flags & H20) || (a & 0x0F) > 9 )
        a += 6;

    if ( (flags & C10) || a > 0x9F )
        a += 0x60;
}
else
{
    if ( flags & H20 )
        a = (a - 6) & 0xFF;

    if ( flags & C10 )
        a -= 0x60;
}

flags &= ~(H20 | Z80);
if ( a & 0x100 )
    flags |= C10;

a &= 0xFF;
if ( !a )
    flags |= Z80;


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 14, 2009 7:39 am 
Offline

Joined: Thu Oct 05, 2006 6:29 am
Posts: 911
Ah, cool. Now I get "01-- 02". So I take it everything passed, but what does the 02 mean in that case?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 14, 2009 8:26 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
This is the correct result:
Code:
01-- 02-- 03-- 04--
05-- 06-- 07-- 08--
09-- 10--
Passed all tests

The -- are where an error code would be printed if that test failed. The test numbers correspond to the files in source/, for example test 02 is instruction timing. It takes a while to run all the tests.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 15, 2009 2:57 am 
Offline

Joined: Thu Oct 05, 2006 6:29 am
Posts: 911
Code:
-    nop       ; 12
     nop
     nop
     wreg IF,0 ; 20
     lda  IF   ; 12
     bit  2,a  ; 8
     push af   ; 28
     pop  af
     jr   z,-  ; 12


I thought writing 0 to IF would reset all bits in IF. In that case, how is this loop ever supposed to finish? Is it waiting until a timer overflow occurs right after "wreg IF,0"? Because that seems like it could take a while, if it ever happens.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 15, 2009 6:36 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
It's just my standard exact-synchronization loop. In timing.a, timing_init sets the timer to run every 96 clocks. The loop takes 92 clocks per iteration, so at most it could take 24 iterations before the timer expires within that critical window. By adjusting the delay after the coarse synchronization loop, worst-case is reduced.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 15, 2009 6:37 am 
Offline

Joined: Thu Oct 05, 2006 6:29 am
Posts: 911
Nevermind, I fixed that.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 15, 2009 8:03 am 
Offline

Joined: Thu Oct 05, 2006 6:29 am
Posts: 911
How do you find out which subtest is failing in those tests that doesn't use set_result? E.g. if subtest 02 of test 07 fails, which instruction is that?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 15, 2009 8:26 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Argh, I just noticed I already built each one individually, in the individual/ directory. If a main test fails, run that one individually to get the full output.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 39 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 2 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