It is currently Sun Oct 22, 2017 5:54 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sat Jul 30, 2005 1:29 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
I've finally completed more test ROMs and new information about exact timing of the frame counter. The test ROMs check the frame counter and length counter behavior that can be verified by the NES CPU.

The archive has a readme with the new information, a set of 11 test ROMs with around five tests each, a description of the tests and result codes, and most of the source code for the tests.

blargg_apu_2005.07.30.zip (24K)

Things on my to-do list: write tests for initial APU state and reset behavior, information and tests about behavior when changing modes just as current mode is executing a step, tests for proper DMC implementation, tests for other APU behavior that can't be checked by the NES CPU, and tests of basic NES CPU operation and perhaps some PPU stuff as well.

Feedback welcome on 1) the new information, 2) any problems implementing it in your emulator, and 3) how easy the test ROMs were to use.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2005 9:52 am 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
I didn't get around to testing these yet (I haven't been working on my emu recently), but I've read the documentation and this looks absolutly fantastic. The test ROMs look like they're built to be much more clear than your older ones (beeping error/success codes is a good idea). And of course test ROMs for this kind of thing are extremely valuable for emu authors.


I know you put a lot of work into this blargg, and I didn't want you to think it's not appreciated. Despite the lack of replies to the topic, myself and I'm sure several others are very grateful for the research, documentation -- and how you even went that extra mile to make test ROMs to verify emu behavior ... I mean that kind of thing really helps when developing your emu =D

So yeah.. keep it up.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2005 11:30 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Thanks for the feedback.

The test ROMs look like they're built to be much more clear than your older ones (beeping error/success codes is a good idea).

Remember that the previous tests were for things that the NES CPU couldn't check, thus couldn't give a nice clean result code for; the only thing that can be done is to amplify any minor problems (like in the recent square divide-by-two test). With the result code you could even automate your emulator to run all the tests and check the result by watching the appropriate VRAM locations.

If/when I complete an test suite for all APU operation, the frame counter, length counter, and DMC will have result codes, and the rest will be ad-hoc things to listen for. I need to work on improving the latter by making the result as clear as possible and pointing out any aspects that don't matter (like clicks).

What about designing a simplified model of the APU? Some of the new behavior like ignored length reload is pathological, and the complexity of changing modes when a step is just about to occur is a real mess (and not even complete). I'm just thinking that to someone first implementing the APU, they might want a simpler subset that the test ROMs will still be useful for.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2005 4:00 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
I'm sorry, but there's something wrong... If an entire frame has 341*262 = 89342 PPU cycles per frame, or 22335,5 PPU cycles per quarter, making 7445 CPU cycles per quarter.

blargg, why do you use the hell 7456 instead of 7445 CPU cycles??? Am I misundestanding anything else???

Secondly, you wrote about "odd and even" frames... What is this? Pair cycles? Finally, about "CLOCK", do you mean "delayed by 1 CPU clock cycle" OR "delayed by 1 APU clock", meaning 1/4th of frame???

The test ROMs were fine for 1,2 and 3 in my emulator. For the rest, most of them give me error #2 (too soon) which I believe relies on CPU quarter frame cycles.

Next, the only way to clear the I flag (and this way triggering IRQs) is to execute a CLI, am I right?

Heh, I'm without internet connection on my (new) home, so I'm in a hurry... ^_^;;

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2005 4:59 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
The APU frame sequencer does not run at the same rate as the PPU's frame. The number of PPU cycles that makes up a frame is irrelevant, as it has no effect on how the APU runs.

1 APU "frame" != 1 PPU frame

I actually find the word frame a little misleading.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2005 8:28 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
As Disch said, the APU frame and PPU frame are different things. For both "frame" refers to the repeating nature of the sequence of events. The duration of a PPU frame (even or odd) is similar to that of an APU frame, but not the same. A lot of confusion would be avoided by having better high-level documentation of the overall NES architecture. Haste makes waste (but at least gives experience).

You wrote about "odd and even" frames... What is this? Pair cycles? Finally, about "CLOCK", do you mean "delayed by 1 CPU clock cycle" OR "delayed by 1 APU clock", meaning 1/4th of frame???

Quick summary: A write to $4017 changes the APU mode (and restart it). Depending on when the write occurs, the mode change might be delayed by a single CPU clock, as if you wrote to $4017 one clock later.

The APU's master clock is at 1.79 MHz, same as the CPU clock. This can be divided into even and odd clocks. The first few clocks are even, odd, even, odd, etc. When the CPU writes to $4017, the APU starts the new mode. If this write occurs on an odd clock, the new mode is delayed by 1 clock before starting. At power-up and after reset, the APU's even clocks might correspond to the CPU's even clocks, or they might be reversed where the APU's even clock corresponds to the CPU's odd clock, and vice-versa.

To simplify things, assume that even CPU clocks correspond to even APU clocks in this example. The first write to $4017 occurs on an odd APU clock, thus starts the mode with an extra clock delay. The second write to $4017 occurs on an even APU clock so the mode starts immediately.

Code:
nop         ; 2 clock delay
lda #$00
sta $4017   ; mode is delayed a clock
pha         ; 3 clock delay
lda #$00
sta $4017   ; mode starts immediately


This code has the same effect as far as the APU is concerned:

Code:
pha         ; 3 clock delay
lda #$00
sta $4017   ; mode starts immediately
nop         ; 2 clock delay
lda #$00
sta $4017   ; mode starts immediately


Figuring out that the APU was doing this was necessary before I could test the exact timing of the length and linear clocks.

Next, the only way to clear the I flag (and this way triggering IRQs) is to execute a CLI, am I right?

CLI, PLP, and RTI have the ability to clear the I flag. The CPU only invokes the IRQ routine when the I flag is clear and the IRQ line is asserted. I'm not sure exactly when this needs to be asserted to be recognized, perhaps during the next-to-last or last cycle of an instruction. All that matters in the IRQ timing test is that the IRQ occurs wherever it occurs when running on a NES.

The APU asserts the IRQ line as long as either the frame IRQ or DMC IRQ flags are set.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 02, 2005 12:23 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
From apu_ref.txt:
The divider generates an output clock rate of just under 240 Hz, and appears to be derived by dividing the 21.47727 MHz system clock by 89490. The sequencer is clocked by the divider's output.

In math... 89490 / 12 = 7457,5 (CPU cycles per quarter).

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 02, 2005 1:07 pm 
I have a crazy theory (although I'm probably not a credible source - I am merely browsing these boards for the heck of it). It seems to me the frame counter is clocking every 7457.5 CPU cycles, but the APU isn't responding to the clock until the next odd cycle. The first clock arrives at 7457.5, so the APU responds at cycle 7459. The second clock arrives at cycle 14915, so the APU responds then. The third arrives at cycle 22372.5, so the APU responds at cycle 22373. The last clock comes at cycle 29830, so the APU responds at cycle 29831 (although the interrupt flag goes live at 29830). This explains the 4-step frame, but the 5-step frame doesn't sync up exactly right (the first step of the second frame comes a little earlier than this would predict).


Top
  
 
 Post subject:
PostPosted: Tue Aug 02, 2005 1:12 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
The delay between steps is different for each step.

Write $00 to $4017 | 7459 delay | Step 1 | 7456 delay | Step 2 | 7458 delay | Step 3 | 7458 delay | Step 4 | 7458 delay | Step 1 | 7456 delay ...

Write $80 to $4017 | 1 delay | Step 0 | 7458 delay | Step 1 | 7456 delay | Step 2 | 7458 delay | Step 3 | 7456 delay | Step 4 (do nothing) | 7454 delay | Step 0 | 7458 delay ...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 17, 2005 1:05 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
There's something I really can't figure... -_-

1) By taking 29830 cycles DIV 4 = 7457.5 cycles per quarter. I can't figure a clock at 7456 cycle. Over 7457.5 is okay, but not lower than that.

2) You wrote that writes to 4017h changes the mode on EVEN apu cycles. On odd cycles, it's delayed by 1. I'm doing an stupid *apu_cycles AND 1* to reset the apu cycle counter = if TRUE, then it's 1; else, it's 0. It seems to work fine, but test #5 of 'clock jitter' fails. -_-

- Like I wrote, I have the logs of my tests documented. I'll post them here once I record to a CD and brings it to my father's home (no internet on my home).

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 17, 2005 2:19 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
1) The steps don't occur at a uniform interval, so you can't use a fixed delay between steps. I still don't have a clear idea of what approach you're taking and what the problem is. It would help if you described your design and the problem that's occurring.

2) As for handling even/odd APU clocks, you can just delay the first step by an extra clock when the write is on an odd clock. Be sure you keep track of odd/even independently of steps and delays, otherwise your code might reverse them occasionally. If your APU has a function that runs for N clocks, just toggle the even/odd at the end:

Code:
int odd_clock;

void run_apu( int count )
{
   // ...
   odd_clock ^= count & 1;
}


Then when you have a write to $4017, add odd_clock to the initial delay until the first step.

If you don't want to implement even/odd clocks, I think all the tests should pass except #5 of the clock jitter tests (I tried to rely on as little as possible in each test, so you could test things independently). As I've mentioned, I think a simplified model of the APU might be useful to work out for those who don't want to implement features that probably don't matter for virtually all NES software available.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 24, 2005 12:58 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
Thanks, it was fixed. :)

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 01, 2005 11:06 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
To avoid another topic open, here's another question:

- I rewrote my CPU core to work with cycle precision timing. This way, there's an issue (quite obvious?) with the APU: every step (if the APU runs for every single CPU cycle) will take EXACTLY 7458 cycles to output a clock (7457,5 to be exact), hence the other steps will ALWAYS be 7458 cycles, giving errors in the APU tests. Yes, the LDA (read) occurs before the last cycle. Any advice? ^_^;; That's why I can't see the first clocking occuring at 7459! >_<

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 01, 2005 8:26 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
I wrote a soundless APU from scratch in C++ a couple of days ago and tested it in my NES emulator. I'm still working on it, so it has some complex parts. All eleven APU test ROMs pass. Kind of humorous that it passes all the tests while being silent as a mouse. :)

http://www.slack.net/~ant/nes-tests/validated_apu.zip

Hopefully it'll help dispel the idea that you can run each step every 7457.5 clocks.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 05, 2005 5:15 am 
Offline
Formerly Fx3
User avatar

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

_________________
Zepper
RockNES developer


Last edited by Zepper on Wed Jul 14, 2010 4:33 am, edited 1 time in total.

Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  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