Skip to content

Commit

Permalink
smp: apply recent TEST findings
Browse files Browse the repository at this point in the history
  • Loading branch information
awjackson committed Jul 1, 2017
1 parent c583f8e commit 04c29e5
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 37 deletions.
16 changes: 10 additions & 6 deletions bsnes/snes/smp/memory/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,12 @@ alwaysinline void SMP::op_buswrite(uint16 addr, uint8 data) {
if(regs.p.p) break; //writes only valid when P flag is clear

status.clock_speed = (data >> 6) & 3;
status.timer_speed = (data >> 4) & 3;
status.ram_speed = (data >> 4) & 3;
status.timers_enabled = data & 0x08;
status.ram_disabled = data & 0x04;
status.ram_writable = data & 0x02;
status.timers_disabled = data & 0x01;

status.timer_step = (1 << status.clock_speed) + (2 << status.timer_speed);

t0.sync_stage1();
t1.sync_stage1();
t2.sync_stage1();
Expand Down Expand Up @@ -176,23 +174,29 @@ alwaysinline void SMP::op_buswrite(uint16 addr, uint8 data) {
ram_write(addr, data);
}

unsigned SMP::speed(uint16 addr) const {
if((addr & 0xfff0) == 0x00f0) return status.clock_speed;
if(addr >= 0xffc0 && status.iplrom_enabled) return status.clock_speed;
return status.ram_speed;
}

void SMP::op_io() {
add_clocks(24);
cycle_edge();
cycle_edge(status.clock_speed);
}

uint8 SMP::op_read(uint16 addr) {
add_clocks(12);
uint8 r = op_busread(addr);
add_clocks(12);
cycle_edge();
cycle_edge(speed(addr));
return r;
}

void SMP::op_write(uint16 addr, uint8 data) {
add_clocks(24);
op_buswrite(addr, data);
cycle_edge();
cycle_edge(speed(addr));
}

#endif
2 changes: 2 additions & 0 deletions bsnes/snes/smp/memory/memory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ void ram_write(uint16 addr, uint8 data);
uint8 op_busread(uint16 addr);
void op_buswrite(uint16 addr, uint8 data);

alwaysinline unsigned speed(uint16 addr) const;

void op_io();
debugvirtual uint8 op_read(uint16 addr);
debugvirtual void op_write(uint16 addr, uint8 data);
6 changes: 1 addition & 5 deletions bsnes/snes/smp/serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@ void SMP::serialize(serializer &s) {
Processor::serialize(s);
SMPcore::core_serialize(s);

s.integer(status.clock_counter);
s.integer(status.dsp_counter);
s.integer(status.timer_step);

s.integer(status.clock_speed);
s.integer(status.timer_speed);
s.integer(status.ram_speed);
s.integer(status.timers_enabled);
s.integer(status.ram_disabled);
s.integer(status.ram_writable);
Expand Down
6 changes: 1 addition & 5 deletions bsnes/snes/smp/smp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,9 @@ void SMP::reset() {
memory::apuram.write(i, 0x00);
}

status.clock_counter = 0;
status.dsp_counter = 0;
status.timer_step = 3;

//$00f0
status.clock_speed = 0;
status.timer_speed = 0;
status.ram_speed = 0;
status.timers_enabled = true;
status.ram_disabled = false;
status.ram_writable = true;
Expand Down
7 changes: 1 addition & 6 deletions bsnes/snes/smp/smp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,9 @@ class SMP : public Processor, public SMPcore, public MMIO {
#include "timing/timing.hpp"

struct {
//timing
unsigned clock_counter;
unsigned dsp_counter;
unsigned timer_step;

//$00f0
uint8 clock_speed;
uint8 timer_speed;
uint8 ram_speed;
bool timers_enabled;
bool ram_disabled;
bool ram_writable;
Expand Down
24 changes: 11 additions & 13 deletions bsnes/snes/smp/timing/timing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,23 @@ void SMP::add_clocks(unsigned clocks) {
if(clock > +(768 * 24 * (int64)24000000)) synchronize_cpu();
}

void SMP::cycle_edge() {
t0.tick();
t1.tick();
t2.tick();
void SMP::cycle_edge(unsigned speed) {
static const uint8 wait_states[] = {0, 24*1, 24*4, 24*9};
static const uint8 timer_ticks[] = {3*1, 3*2, 3*4, 3*8};

unsigned ticks = timer_ticks[speed];
t0.tick(ticks);
t1.tick(ticks);
t2.tick(ticks);

//TEST register S-SMP speed control
//24 clocks have already been added for this cycle at this point
switch(status.clock_speed) {
case 0: break; //100% speed
case 1: add_clocks(24); break; // 50% speed
case 2: while(true) add_clocks(24); // 0% speed -- locks S-SMP
case 3: add_clocks(24 * 9); break; // 10% speed
}
if(speed) add_clocks(wait_states[speed]);
}

template<unsigned timer_frequency>
void SMP::sSMPTimer<timer_frequency>::tick() {
void SMP::sSMPTimer<timer_frequency>::tick(unsigned step) {
//stage 0 increment
stage0_ticks += smp.status.timer_step;
stage0_ticks += step;
if(stage0_ticks < timer_frequency) return;
stage0_ticks -= timer_frequency;

Expand Down
4 changes: 2 additions & 2 deletions bsnes/snes/smp/timing/timing.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class sSMPTimer {
bool enabled;
uint8 target;

void tick();
void tick(unsigned step);
void sync_stage1();
};

Expand All @@ -18,4 +18,4 @@ sSMPTimer<192> t1;
sSMPTimer< 24> t2;

alwaysinline void add_clocks(unsigned clocks);
alwaysinline void cycle_edge();
alwaysinline void cycle_edge(unsigned speed);

0 comments on commit 04c29e5

Please sign in to comment.