Help with apu test 5 [solved]

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Help with apu test 5 [solved]
by on (#64255)
- I'm getting an error running apu test 5-len_timing: "First length of mode 0 is too late". Is this related with 4017h? For mode 0, on 4017h write, the first apu step should run for 7459 cycles, +1 if in an odd cycle.

- All the apu reset tests have passed, without hacks. Any advice?
Re: Help with apu test 5
by on (#64257)
Zepper wrote:
- I'm getting an error running apu test 5-len_timing: "First length of mode 0 is too late". Is this related with 4017h? For mode 0, on 4017h write, the first apu step should run for 7459 cycles, +1 if in an odd cycle.

- All the apu reset tests have passed, without hacks. Any advice?


What about the clock jitter test, or the length timing test or the length table test? Those all pass?

Also where is your APU cycle executed in relation to your CPU cycle? [Do you run the CPU cycle then the APU cycle or the other way around?]

I implemented trace tags in my execution tracer that helped me figure out where things were occurring and then I could also match the code that was executing with the source provided and see if the APU event was occurring where the test wanted it to be or not.
Re: Help with apu test 5
by on (#64280)
NESICIDE wrote:
What about the clock jitter test, or the length timing test or the length table test? Those all pass?

Also where is your APU cycle executed in relation to your CPU cycle? [Do you run the CPU cycle then the APU cycle or the other way around?]

I implemented trace tags in my execution tracer that helped me figure out where things were occurring and then I could also match the code that was executing with the source provided and see if the APU event was occurring where the test wanted it to be or not.


-assuming NTSC-
- Yes, the previous tests pass ok. It doesn't matter if the APU is clocked before or after the PPU clock (=3 cycles). Anyway, I asked about 4017h register because setting 7456 cycles makes "too early" error; 7457 makes "too late" error. The default should be 7459, but Nintendulator uses a different value & increment on odd cycles, for example.

by on (#64281)
Does Nintendulator pass? If not, then it's not what you want to follow.

5-len_timing shouldn't be depending on jitter. Odd that you fail for either delay, since the test basically reads the length counter at 14915, then 14916, and ensures it's clocked between those.

What channel does it fail on when you use 7456 and 7457?

Hmmm, maybe you're assuming each step is exactly 7456 or 7457 apart. Not sure why this isn't in the Wiki. Here are the timings:

Code:
Mode 0: 4-step sequence

Action      Envelopes &     Length Counter& Interrupt   Delay to next
            Linear Counter  Sweep Units     Flag        NTSC     PAL
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
$4017=$00   -               -               -           7459    8315
Step 1      Clock           -               -           7456    8314
Step 2      Clock           Clock           -           7458    8312
Step 3      Clock           -               -           7458    8314
Step 4      Clock           Clock       Set if enabled  7458    8314


Mode 1: 5-step sequence

Action      Envelopes &     Length Counter& Interrupt   Delay to next
            Linear Counter  Sweep Units     Flag        NTSC     PAL
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
$4017=$80   -               -               -              1       1
Step 1      Clock           Clock           -           7458    8314
Step 2      Clock           -               -           7456    8314
Step 3      Clock           Clock           -           7458    8312
Step 4      Clock           -               -           7458    8314
Step 5      -               -               -           7452    8312


See how it's not exactly the same delay between each step.

by on (#64293)
- I'm aware of APU timings and ya, the wiki was missing such table. Anyway, the test reads $4015 two times. The first time, the APU is clocked in the 2nd cycle of the following AND instruction. The second time, the APU is clocked right after reading $4015. Both return 1 because the remaining length is still 1.
Re: Help with apu test 5
by on (#64299)
Zepper wrote:
-assuming NTSC-


Ok.

Zepper wrote:
- Yes, the previous tests pass ok. It doesn't matter if the APU is clocked before or after the PPU clock (=3 cycles).


I didn't say PPU clock I said CPU clock. In my implementation I run one APU cycle before one CPU cycle. I just tried it the other way around and I get failure 16 on test 7. Order must, therefore, matter. Make sure you're doing exactly as many APU cycles as you are doing CPU cycles and you don't overshoot or undershoot.

Zepper wrote:
Anyway, I asked about 4017h register because setting 7456 cycles makes "too early" error; 7457 makes "too late" error. The default should be 7459, but Nintendulator uses a different value & increment on odd cycles, for example.


Nintendulator doesn't pass test all of the tests, though.

I have to say, adding an "APU Sequence Tick" tag to my execution tracer absolutely helped me figure out things like this. I even went so far as to add a breakpoint event for Length Counter clocking, just so I could have my emulator's debugger stop right at the right moment.
Re: Help with apu test 5
by on (#64302)
NESICIDE wrote:
I didn't say PPU clock I said CPU clock. In my implementation I run one APU cycle before one CPU cycle.


- Yes, I said PPU clock. One CPU clock = one memory access (read/write). The PPU is clocked 3 times before accessing memory. Got it? ^_^;;

Quote:
Nintendulator doesn't pass test all of the tests, though.


- You're wrong. It does pass through all 8 tests.

by on (#64304)
...

by on (#64306)
Sorry, can you restate the question? Not sure what you're getting at.
Re: Help with apu test 5
by on (#64307)
Zepper wrote:
- Yes, I said PPU clock. One CPU clock = one memory access (read/write). The PPU is clocked 3 times before accessing memory. Got it? ^_^;;

Sure. So do you do one APU cycle for one CPU cycle?
Zepper wrote:
Quote:
Nintendulator doesn't pass test all of the tests, though.

- You're wrong. It does pass through all 8 tests.

Quite right there. I was using Nintendulator 0.965. All the tests pass on Nintendulator 0.975.

by on (#64308)
- Sorry, here's the discussion about the frame IRQ / last 3 cycles.

- Back to the topic, I need to understand the length counter test. Well, you set the length counter (channel 0) to 2 and reads $4015 twice. Is this the right path or am I wrong?

by on (#64310)
Zepper wrote:


Thanks for bringing that back up I'd been looking for that thread.

Zepper wrote:
- Back to the topic, I need to understand the length counter test. Well, you set the length counter (channel 0) to 2 and reads $4015 twice. Is this the right path or am I wrong?


That might be the case for 1-len_ctr.nes, but 5-len_timing.nes looks for the count to occur on specific APU/CPU cycles. In 1-len_ctr.nes he's expecting the length counter to expire (and he counts cycles until it does). In 5-len_timing.nes he's looking for specific length counter clocks, each of which are separated by a specific number of APU/CPU cycles. Did you look at the source code for the test?

by on (#64313)
Note how 5-len_timing tests 2 and 3 are loading 2 into the length counter, then clocking it once (by writing $C0 to $4017). This way, it will reach zero on the next length clock at 14915.

I'm still wondering what channel it prints for the two failures (when you use 7456 and 7457). You said for one it says too soon, the other too late. What channel does it list for each of these failures? That might shed some light on this.

by on (#64334)
- It prints "Channel: 0". Well, I have no clue what's up. Here's a copy of my emulator log.

- Let me know if you have some question.

by on (#64335)
Zepper wrote:
- It prints "Channel: 0". Well, I have no clue what's up. Here's a copy of my emulator log.

- Let me know if you have some question.


Line 52546: Shouldn't this be 7456 cycles elapsed, not 7458?

Code:
Mode 0:
Sequence step:     1        2       3        4       5         6
Cycles to next: 7459     7456    7458     7458    7458      7458
Next step:         2        3       4        5       6         2
Cycles elapsed:    0     7459   14915    22373   29831     37289


On cycle 37289, for mode 0, I reset the APU cycle counter to 7459 so that the next sequence tick will happen 7456 APU cycles later, as expected.

Line 55661: Confused how you get to APU cycle 7460?

In my thinking on this topic it helps and is easier to think of it in terms of an APU "frame" even though we're shy to use the word "frame" when talking about the APU because it implies alignment with something else, such as the PPU "frame" being aligned with the video signal. If you think of it as in mode 0 an APU frame is 37289 APU [or CPU] cycles long, and you write your APU to trigger the expected sequence of events at the "frame-relative" cycle numbers, instead of worrying about whether you need to count 7456, 7458, or 7459 cycles between, it makes things much easier. This is why, when I get to cycle 37289 in mode 0 I reset the APU cycle counter to 7459 and not 0...because then my mode 0 implementation doesn't need to concern itself with whether or not the sequence was reset and what that means for how many "inter-sequence" ticks I need to count before doing the next sequence tick.

by on (#64336)
- When a write to $4017 is done, the APU is clocked after 7459 cycles (or 7460 if in an odd cycle). After that, isn't step 2, of 7458 cycles?

by on (#64337)
Zepper wrote:
- When a write to $4017 is done, the APU is clocked after 7459 cycles (or 7460 if in an odd cycle). After that, isn't step 2, of 7458 cycles?


No. Step 2 is 7456...unless I drastically misunderstand blargg's writings on the topic. But yet, my APU passes all tests...so I think I've got it clear in my head. Sorry if the explanation isn't as clear.

This is why I suggested thinking of it as an "APU frame". Divorce the idea of even/odd cycle from how many APU cycles the first sequence takes. The first sequence step *always* takes 7459 APU cycles but doesn't start until 1 cycle after it's expected to if $4017 was written on an *odd* APU cycle.

EDIT: The last "APU cycle" was incorrectly "CPU cycle" in last sentence.

by on (#64338)
- Mode 0 uses a 4-Step Sequence, not 5... or does 4017h write counts as an extra step? I think that 4017h changes the step 1 time to 7459..?

by on (#64353)
Zepper wrote:
- Mode 0 uses a 4-Step Sequence, not 5... or does 4017h write counts as an extra step? I think that 4017h changes the step 1 time to 7459..?


This is directly from the readme.txt that come's with blargg's old set of APU tests (blargg_apu_2005.07.30):

Code:
Mode 0 Timing
-------------
-5    lda   #$00
-3    sta   $4017
0     (write occurs here)
1
2
3
...
      Step 1
7459  Clock linear
...
      Step 2
14915 Clock linear & length
...
      Step 3
22373 Clock linear
...
      Step 4
29830 Set frame irq
29831 Clock linear & length and set frame irq
29832 Set frame irq
...
      Step 1
37289 Clock linear
...
etc.


I never said mode 0 is five steps, I said on cycle 37289 I reset the APU's cycle counter to 7459 so that it starts in the appropriate place [Step 1]. Clearly, 7456 cycles after cycle 37289/7459, Step 2 will occur. Step 1 time is always 7456 cycles. Always...

There's a 7459 cycle *delay* before Step 1 immediately following a write to $4017 enabling mode 0.

Clear?

EDIT: Added clarity to last cycle.

by on (#64355)
- Unless I'm doing wrong calculations, but the timings don't match the latest ones:

Code:
$4017 write: 0 ~ 7458 [7459]
step 1......:  7459 + [7456] = 14915
step 2......: 14915 + [7458] = 22373
step 3......: 22373 + [7457] = 29830 [frame IRQ]
..........................+1 = 29831 [clock + frame IRQ]
..........................+1 = 29832 [clock + frame IRQ]
step 4......: 29832 + [7457] = 37289


- 7459 ($4017), then 7456, 7458, 7459, 7457.
- It should be 7456, 7458, 7458, 7458.

by on (#64356)
OK, I think I understand what's going on now. Zepper's emulator is doing the first length clock at the wrong time. When he changes its time, he's throwing off his APU frame length time. This is why changing it by one cycle causes it to toggle between too soon/too late, which makes it sound like there's no timing that's correct. This throws off his APU frame length, which means that the synchronization code fails. Hence NESICIDE's suggestion of basing timing relative to the APU frame, so that changes in the length clock timing won't throw off the timing of other length clocks or the frame length.

Zepper wrote:
Anyway, I asked about 4017h register because setting 7456 cycles makes "too early" error; 7457 makes "too late" error.

Zepper, please do the following and report the result. Set the timing to 7456 as you had before when you first posted. Run the first 5 APU tests. Which ones fail, and what are the results? Now, set the timing to 7457, and run the first 5 again. Which ones fail, and what are the results?

It is important that you run these tests I just described. They will provide further info and help me figure out what's going on. Please run them even if you think they won't help, or whatever. Thanks.

by on (#64358)
- I wasn't emulating the APU timing properly, since $4017 delay was okay, but it skipped step 1; instead, step *2* was performed. Well, I'm fixing the things, but I need to know about the APU timings firstly.

by on (#64359)
Zepper wrote:
- Unless I'm doing wrong calculations, but the timings don't match the latest ones:

Code:
$4017 write: 0 ~ 7458 [7459]
step 1......:  7459 + [7456] = 14915
step 2......: 14915 + [7458] = 22373
step 3......: 22373 + [7457] = 29830 [frame IRQ]
..........................+1 = 29831 [clock + frame IRQ]
..........................+1 = 29832 [clock + frame IRQ]
step 4......: 29832 + [7457] = 37289


- 7459 ($4017), then 7456, 7458, 7459, 7457.
- It should be 7456, 7458, 7458, 7458.


Everything you have looks correct and in agreement with what I wrote. However, the 29832 cycle should not be a "clock +" cycle it should just be a "frame IRQ" cycle. The difference between 22373 and 29831 is...7458. And, the difference between 29831 and 37289 is...7458.

Step 4 should be 29831 + 7458 = 37289.

I just have a series of if statements [pseudo-code]:

Code:
CAPU::EMULATE()
{
 if ( videoMode == NTSC )
 {
  if ( mode == 0 )
  {
   if ( cycle == 7459 ) seqTick(1);
   else if ( cycle == 14915 ) seqTick(2);
   else if ( cycle == 22373 ) seqTick(3);
   else if ( cycle == 29830 ) frameIRQ();
   else if ( cycle == 29831 ) { frameIRQ(); seqTick(4); }
   else if ( cycle == 29832 ) frameIRQ();
  }
  else...
 }
 else...

 cycle++;
 if ( videoMode == NTSC )
 {
  if ( mode == 0 )
  {
   if ( cycle >= 37289 ) cycle = 7459;
  }
  else...
 }
 else...
}

by on (#64405)
- I rewrote my code to include $4017 delay (7459) before step 1 (7456)... and still:
Code:
Channel: 0
First length of mode 0 is too soon
Failed #2


- By following blargg' suggestion, if I change the $4017 delay to 7460, the error changes to "too late". Running the previous tests, it fails 4-jitter as "Frame IRQ is set too late".

- I suspect about the frame IRQ raising at 29830,31 or 32.

by on (#64406)
OK, so it's exactly what I said: you need to adjust the time that the first length clock occurs, without affecting when the later APU events occur. Then you can take my lazy approach: adjust the time until the test passes, then move on to the next length clock.

You can take NESICIDE's approach of timing things relative to an APU frame. It seems your current approach is to have each step begin once the previous ends, so that if you increase the length of the first step, all the later ones occur later as well. With this approach, if you increase the length of the first step, you need to decrease the length of the second step by the same amount. If you're not passing tests 1-4, then you're messing something else up. That's your way of seeing whether you're only adjusting the time of the first length clock: tests 1-4 should pass regardless of when you have the first length clock occur.

by on (#64410)
blargg wrote:
I just stumbled onto a bit of confusion, myself...
Code:
Mode 1: 5-step sequence

Action      Envelopes &     Length Counter& Interrupt   Delay to next
            Linear Counter  Sweep Units     Flag        NTSC     PAL
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
$4017=$80   -               -               -              1       1
Step 1      Clock           Clock           -           7458    8314
Step 2      Clock           -               -           7456    8314
Step 3      Clock           Clock           -           7458    8312
Step 4      Clock           -               -           7458    8314
Step 5      -               -               -           7452    8312


From the above table, step 5 should occur on APU cycle 1+7458+7456+7458+7458=29831. However, in the readme.txt that comes with the old set of tests:
Code:
      Step 4
29829 (do nothing)

Here step 4 is the same as step 5 (one reference is zero-based, the other one-based). Unless I missed a "the old timings are wrong" post somewhere, shouldn't the readme.txt say cycle 29831 for step 5 of mode 1?

With either 29829 or 29831 as the cycle for step 5 I still pass the tests. :roll:

EDIT: Duh! Just realized step 5 is a "do nothing" step. My overall timing is still frame-correct, methink. :oops:

by on (#64411)
- I wasn't understanding $4017 effect on mode 0/1 timing. The bug in my emulator was taking $4017 delay (7459) as step 1, but it works like a step 0:
Code:
$4017, steps
0->1->2->3->4->1->2->3...

Instead, I was doing:
$4017 changes the time of step 1 from 7456 to 7459 (E).
E->2->3->4->1->2->3...


- Now I have rewritten the code, but it still gives the same error code. Well, I'll trace my logs a bit more. One question: in your diagram, you don't take cycles 29830/31/32 as checking the frame IRQ, only at 29831. So, what is the correct anyway?

EDIT: the length counter is clocked right on $4015 read (cycle 14915), so status does not change. In other words, 4015 is read before clocking the length counter. Looks like my suspect was correct: it applies to the triangle & noise channels too.

EDIT2: fixed the frame IRQ timings.