It is currently Mon Oct 23, 2017 7:20 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Quick 4017 question
PostPosted: Sat Mar 05, 2005 8:36 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
Still inside the recent 4017h discussion, is the following code correct?

Code:
case 4017:
   cpu_irqcancel(TIRQ_FRA);
   frameIRQ = value;
   frameCNT = 0; //APU step 0..3 or 4 [reset]
   if(value & 0x80) {
      atl_index = 5; //Max steps=5
      psg_step_run(); //APU clock [sweep unit]
   } else {
      atl_index = 4; //Max steps=4
   }
   frameCYC = 0; //APU divider (1/4th of frame_cycles) [reset]
   break;


It means the APU step as '1' (by counting from zero) after an immediate clock on 4017h:80h = 1.

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 05, 2005 10:07 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
AFAIK, writing to 4017 only clears the frame IRQ flag if bit 6 is on. Otherwise, if an IRQ is pending, it stays pending until disabled (4017 with bit 6 on) or acknowledged (4015 read)

The rest (as I understand it), looks right... although:
Code:
   frameCYC = 0;  //APU divider (1/4th of frame_cycles) [reset]


Is that the number of cycles until the next step through the frame sequencer? That looks like it will clock it immediately -- which isn't what you want (unless you're doing a count-up system instead of a count-down -- in which case it looks right)

Here's my code which has served me well:

Code:
case 0x4017:
  RunAPU(nCPUCycle);
  bAPUFrameMode =           (v & 0x80) ? 1 : 0; // 4/5 step sequence selection
  bFrameIRQEnabled =        !(v & 0x40);

  if(!bFrameIRQEnabled)     bFrameIRQPending = 0;  //if IRQs are disabled, clear IRQ flag

  if(bAPUFrameMode)         nAPUFrameTicks = 0;  //in 5-step mode, clock frame sequencer asap
  else                      nAPUFrameTicks = (bPALMode ? NES_APUFRAME_PAL : NES_APUFRAME_NTSC);  // else, reset to 1/4 frame of time

  nAPUFrameCur = 0;  //restart at step 0
  if(!flgI)                 FindNextIRQ();
  break;


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 05, 2005 10:59 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
I've just found some new information about $4017 handling while writing a ROM to test it, but haven't updated the NesDevWiki yet. Disch's code looks correct based on this new information. Here's a test ROM and source to verify $4017 length counter clocking and frame interrupt operation (see asm source for operation):

it's now http://h1.ripway.com/blargg/temp/test_apu_4017.zip

By the look of it, frame handling might also be incorrect, unless you clock the units differently based on atl_index (or bAPUFrameMode in Disch's code), as follows:

Code:
if ( frameCNT < 4 )
    clock_envelopes_and_linear_counter(); // clock on 0, 1, 2, 3

if ( atl_index == 4 && (frameCNT & 1) ) // clock on 1 and 3
    clock_length_and_sweep();

if ( atl_index == 5 && !(frameCNT & 1) ) // clock on 0 and 2
    clock_length_and_sweep();

frameCNT++;
if ( frameCNT >= atl_index )
    frameCNT = 0;


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 06, 2005 7:29 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
Disch wrote:
AFAIK, writing to 4017 only clears the frame IRQ flag if bit 6 is on. Otherwise, if an IRQ is pending, it stays pending until disabled (4017 with bit 6 on) or acknowledged (4015 read)


Well, frame-IRQs don't work yet... I hope to get it fixed, thanks.

Disch wrote:
The rest (as I understand it), looks right... although:
Code:
   frameCYC = 0;  //APU divider (1/4th of frame_cycles) [reset]


Is that the number of cycles until the next step through the frame sequencer? That looks like it will clock it immediately -- which isn't what you want (unless you're doing a count-up system instead of a count-down -- in which case it looks right)


frameCYC += cpu clock cycles (basically), count-up, yes.

Disch wrote:
Code:
if(bAPUFrameMode)         nAPUFrameTicks = 0;  //in 5-step mode, clock frame sequencer asap
  else                      nAPUFrameTicks = (bPALMode ? NES_APUFRAME_PAL : NES_APUFRAME_NTSC);  // else, reset to 1/4 frame of time

  nAPUFrameCur = 0;  //restart at step 0
  if(!flgI)                 FindNextIRQ();
  break;


If I'm using a count-up system, then the values (for nAPUFrameTicks on yours) must be reversed (?) here (for frameCYC on mine).

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 06, 2005 7:35 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
You make a 'nAPUFrameTicks=0' to force an immediate clock, but 'immediate' AFAIK would be 'immediate' on 4017 write, not later... Am I wrong? :| A way to check the correctness is to play SMB3: the dash & cracking block sounds must be audible and clean; otherwise, with distortion.

edit-- well, it worked in both ways. :)

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 06, 2005 12:15 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Fx3 wrote:
frameCYC += cpu clock cycles (basically), count-up, yes.


Okay... then what you're doing would be right.

Fx3 wrote:
If I'm using a count-up system, then the values (for nAPUFrameTicks on yours) must be reversed (?) here (for frameCYC on mine).


The way you have it set up looks right for a count up system.

Fx3 wrote:
You make a 'nAPUFrameTicks=0' to force an immediate clock, but 'immediate' AFAIK would be 'immediate' on 4017 write, not later... Am I wrong?


No, you're right. By setting nAPUFrameTicks to 0, I'm signalling that the frame sequencer will be clocked at the very start of the next call to RunAPU (My function which does all the APU stuff and produces samples). It has the exact same effect as clocking the sequencer inside my $4017 code, only this way I don't have to copy/paste anything or do an extra function call.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 06, 2005 5:24 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
blargg wrote:
By the look of it, frame handling might also be incorrect, unless you clock the units differently based on atl_index (or bAPUFrameMode in Disch's code), as follows:


That's it, except I use a CASE statement (very smart). ;)

_________________
Zepper
RockNES developer


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 1 guest


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