SPC700 Tracer

Strictly for discussing ZSNES development and for submitting code. You can also join us on IRC at irc.libera.chat in #zsnes.
Please, no requests here.

Moderator: ZSNES Mods

Post Reply
Albert
New Member
Posts: 8
Joined: Wed May 17, 2006 12:38 am

SPC700 Tracer

Post by Albert »

I'm trying to get my emulator to work with a (suposedly simple) demo (the one made by yoshi, the author of the docs) but I need to find out why both cpu's lock up in an infinite loop. So I would like to compare my data to one that's correct. I tried Super Sleuth but It doesn't trace SPC700 Data, I remember that zsnes dos did it once, but I don't remember how to activate it, if it does it now, and I just don't get how to use Geiger's Snes9x. So, any help would be great.

Regards
byuu

Post by byuu »

bsnes v0.013 (not any of the newer versions) traces SPC700 code. I don't know if it uses a trace mask or not though. I think it has one...

ZSNES doesn't log SPC700 commands even when SPC700 debug output is enabled, IIRC. Otherwise, 1 and 2 toggle output for CPU and APU (might have those reversed), and l logs the code to a file.
Albert
New Member
Posts: 8
Joined: Wed May 17, 2006 12:38 am

Post by Albert »

Hey thanks, I'll take a look at that. This thing is like looking for a needle in a haystack.

Edit: I have a question, do I have to step it through manually to trace the output to a file?
Last edited by Albert on Wed May 17, 2006 2:43 am, edited 1 time in total.
byuu

Post by byuu »

Heh, get used to it. It only gets harder and harder, with less and less games fixed for each bug you finally do track down. And then you end up getting to the point where your bug fix ends up breaking more than it fixed, even though it is a proper fix. More and more work for less and less reward, and yet the more you work on it, the more you want to continue working on it. Sound like anything else you know? ;)
Albert
New Member
Posts: 8
Joined: Wed May 17, 2006 12:38 am

Post by Albert »

Hey, I have one question, how many masterclock cycles pass between a spc700 cycle (at normal rate)? I guessed that they were like around 20-21.
byuu

Post by byuu »

None. They have separate timing crystals and run in parallel.

The SPC700 runs at ~24.576000mhz, the CPU runs at ~21.477272mhz (NTSC) and whatever for PAL, I forget. Each SPC700 opcode cycle is 24 master clocks on the SPC700 crystal. Each CPU opcode cycle is 6, 8 or 12 master clocks, depending on whether its read/write or i/o, whether fastrom is enabled and the ROM is fast enough, and which address is being read from/written to.

I guess the easiest way to sync the two is to do something like :

Code: Select all

void run() {
  if(cpu.cycles <= apu.cycles) {
    apu.cycles -= cpu.cycles;
  //cpu.cycles = 0;

    cpu.run();
  //yes, this should be backwards, cpu cycles * -a-pu speed...
    cpu.cycles = cpu.cycles_executed() * apu.clock_speed;
  } else {
    cpu.cycles -= apu.cycles;
  //apu.cycles = 0;

    apu.run();
  //...and vice versa
    apu.cycles = apu.cycles_executed() * cpu.clock_speed;
  }
}
or

Code: Select all

void run() {
  if(counter <= 0) {
    cpu.run();
    counter += cpu.cycles_executed() * apu.clock_speed;
  } else {
    apu.run();
    counter -= apu.cycles_executed() * cpu.clock_speed;
  }
}
You can get away with making the APU timing crystal run at 1.024mhz and adding one clock per APU cycle, but you won't be able to simulate bus hold delays that way. The CPU, because it runs 6, 8 or 12 clocks per cycle, means you can only really reduce that clock by 1/2 (the only common denominator between all three numbers).

You can enslave the PPU to the CPU's timing crystal, and the DSP to the APU's timing crystal. But if you want to add timing for anything else (SA-1, SuperFX/2, etc), you'll have to come up with something more complex.
Albert
New Member
Posts: 8
Joined: Wed May 17, 2006 12:38 am

Post by Albert »

I noticed my emulator was off in it's syncronization compared to bsnes, (opcode based interpreter). But tried your solution and it doesn't even finish the transfer of the program to the spc700 ram, so let me see if I get this. 'clock_speed' means the amount of cycles per the corresponding master clock (24 for the apu and 6/8/12 for the cpu), and cycles_executed() means the amount of cpu or apu cycles the opcode took. Is that correct?
byuu

Post by byuu »

The variable name means exactly what it says. clock_speed means the speed of the clock. 24576000 for apu.clock_speed, and 21477272 for cpu.clock_speed.

I really shouldn't have used cycles_executed. clocks_executed() would have been more correct. See, I used to call the clocks 'master cycles', hence the confusion.

So, say you execute the lda #$a9 opcode in SlowROM. 8 clocks + 8 clocks = 16 clock opcode.

counter += cpu.clocks_executed() * apu.clock_speed;
counter += 16 * 24576000;

Then you execute nop on the SPC700, 24 clocks + 24 clocks.
counter -= apu.clocks_executed() * cpu.clock_speed;
counter -= 48 * 21477272;
Albert
New Member
Posts: 8
Joined: Wed May 17, 2006 12:38 am

Post by Albert »

There, now it finishes the transfer, it just locks up in the transfered code. But there is an issue, it's still slightly off sync, so I think that's why it still gets locked in an endless loop. Is it correct to assume that if an instruction takes 7 cpu cycles then to the master clock it will be 7 * 6/8/12?
byuu

Post by byuu »

It's based on each cycle of the opcode how many clocks each cycle will take.
Albert
New Member
Posts: 8
Joined: Wed May 17, 2006 12:38 am

Post by Albert »

But that means that that the cpu does not have a constant frequecy... I would've never thought that... Well back to coding, thanks again :).

Edit: BTW how does an address from bus A translate to a ROM address?? either /cart or not, and what's the difference between LowROM and HiROM (I know the obvious difference, but is there another one besides a15 being high)?
Post Reply