mirror of
https://github.com/Michael-Prince-Sharpe/bsnes-classic.git
synced 2025-04-02 10:21:42 -04:00
Compare commits
6 commits
Author | SHA1 | Date | |
---|---|---|---|
|
8b547f1c5d | ||
|
e93c847785 | ||
|
57d813f20e | ||
|
a47e32ce96 | ||
|
994b35cd30 | ||
|
04c29e5279 |
8 changed files with 42 additions and 53 deletions
|
@ -100,6 +100,7 @@ void NECDSP::exec_op(uint24 opcode) {
|
||||||
|
|
||||||
flag.s0 = (r & 0x8000);
|
flag.s0 = (r & 0x8000);
|
||||||
flag.z = (r == 0);
|
flag.z = (r == 0);
|
||||||
|
if (!flag.ov1) flag.s1 = flag.s0;
|
||||||
|
|
||||||
switch(alu) {
|
switch(alu) {
|
||||||
case 1: case 2: case 3: case 10: case 13: case 14: case 15: {
|
case 1: case 2: case 3: case 10: case 13: case 14: case 15: {
|
||||||
|
@ -111,17 +112,14 @@ void NECDSP::exec_op(uint24 opcode) {
|
||||||
case 4: case 5: case 6: case 7: case 8: case 9: {
|
case 4: case 5: case 6: case 7: case 8: case 9: {
|
||||||
if(alu & 1) {
|
if(alu & 1) {
|
||||||
//addition
|
//addition
|
||||||
flag.ov0 = (q ^ r) & ~(q ^ p) & 0x8000;
|
flag.ov0 = (q ^ r) & (p ^ r) & 0x8000;
|
||||||
flag.c = (r < q);
|
flag.c = (r < q);
|
||||||
} else {
|
} else {
|
||||||
//subtraction
|
//subtraction
|
||||||
flag.ov0 = (q ^ r) & (q ^ p) & 0x8000;
|
flag.ov0 = (q ^ r) & (q ^ p) & 0x8000;
|
||||||
flag.c = (r > q);
|
flag.c = (r > q);
|
||||||
}
|
}
|
||||||
if(flag.ov0) {
|
flag.ov1 = (flag.ov0 & flag.ov1) ? (flag.s1 == flag.s0) : (flag.ov0 | flag.ov1);
|
||||||
flag.s1 = flag.ov1 ^ !(r & 0x8000);
|
|
||||||
flag.ov1 = !flag.ov1;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 11: {
|
case 11: {
|
||||||
|
@ -146,15 +144,16 @@ void NECDSP::exec_op(uint24 opcode) {
|
||||||
|
|
||||||
exec_ld((idb << 6) + dst);
|
exec_ld((idb << 6) + dst);
|
||||||
|
|
||||||
|
if (dst != 4) {
|
||||||
switch(dpl) {
|
switch(dpl) {
|
||||||
case 1: regs.dp = (regs.dp & 0xf0) + ((regs.dp + 1) & 0x0f); break; //DPINC
|
case 1: regs.dp = (regs.dp & 0xf0) + ((regs.dp + 1) & 0x0f); break; //DPINC
|
||||||
case 2: regs.dp = (regs.dp & 0xf0) + ((regs.dp - 1) & 0x0f); break; //DPDEC
|
case 2: regs.dp = (regs.dp & 0xf0) + ((regs.dp - 1) & 0x0f); break; //DPDEC
|
||||||
case 3: regs.dp = (regs.dp & 0xf0); break; //DPCLR
|
case 3: regs.dp = (regs.dp & 0xf0); break; //DPCLR
|
||||||
}
|
}
|
||||||
|
|
||||||
regs.dp ^= dphm << 4;
|
regs.dp ^= dphm << 4;
|
||||||
|
}
|
||||||
|
|
||||||
if(rpdcr) regs.rp--;
|
if(rpdcr && dst != 5) regs.rp--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NECDSP::exec_rt(uint24 opcode) {
|
void NECDSP::exec_rt(uint24 opcode) {
|
||||||
|
|
|
@ -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
|
if(regs.p.p) break; //writes only valid when P flag is clear
|
||||||
|
|
||||||
status.clock_speed = (data >> 6) & 3;
|
status.clock_speed = (data >> 6) & 3;
|
||||||
status.timer_speed = (data >> 4) & 3;
|
status.ram_speed = (data >> 4) & 3;
|
||||||
status.timers_enabled = data & 0x08;
|
status.timers_enabled = data & 0x08;
|
||||||
status.ram_disabled = data & 0x04;
|
status.ram_disabled = data & 0x04;
|
||||||
status.ram_writable = data & 0x02;
|
status.ram_writable = data & 0x02;
|
||||||
status.timers_disabled = data & 0x01;
|
status.timers_disabled = data & 0x01;
|
||||||
|
|
||||||
status.timer_step = (1 << status.clock_speed) + (2 << status.timer_speed);
|
|
||||||
|
|
||||||
t0.sync_stage1();
|
t0.sync_stage1();
|
||||||
t1.sync_stage1();
|
t1.sync_stage1();
|
||||||
t2.sync_stage1();
|
t2.sync_stage1();
|
||||||
|
@ -176,23 +174,29 @@ alwaysinline void SMP::op_buswrite(uint16 addr, uint8 data) {
|
||||||
ram_write(addr, 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() {
|
void SMP::op_io() {
|
||||||
add_clocks(24);
|
add_clocks(24);
|
||||||
cycle_edge();
|
cycle_edge(status.clock_speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SMP::op_read(uint16 addr) {
|
uint8 SMP::op_read(uint16 addr) {
|
||||||
add_clocks(12);
|
add_clocks(12);
|
||||||
uint8 r = op_busread(addr);
|
uint8 r = op_busread(addr);
|
||||||
add_clocks(12);
|
add_clocks(12);
|
||||||
cycle_edge();
|
cycle_edge(speed(addr));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMP::op_write(uint16 addr, uint8 data) {
|
void SMP::op_write(uint16 addr, uint8 data) {
|
||||||
add_clocks(24);
|
add_clocks(24);
|
||||||
op_buswrite(addr, data);
|
op_buswrite(addr, data);
|
||||||
cycle_edge();
|
cycle_edge(speed(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,6 +4,8 @@ void ram_write(uint16 addr, uint8 data);
|
||||||
uint8 op_busread(uint16 addr);
|
uint8 op_busread(uint16 addr);
|
||||||
void op_buswrite(uint16 addr, uint8 data);
|
void op_buswrite(uint16 addr, uint8 data);
|
||||||
|
|
||||||
|
alwaysinline unsigned speed(uint16 addr) const;
|
||||||
|
|
||||||
void op_io();
|
void op_io();
|
||||||
debugvirtual uint8 op_read(uint16 addr);
|
debugvirtual uint8 op_read(uint16 addr);
|
||||||
debugvirtual void op_write(uint16 addr, uint8 data);
|
debugvirtual void op_write(uint16 addr, uint8 data);
|
||||||
|
|
|
@ -4,12 +4,8 @@ void SMP::serialize(serializer &s) {
|
||||||
Processor::serialize(s);
|
Processor::serialize(s);
|
||||||
SMPcore::core_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.clock_speed);
|
||||||
s.integer(status.timer_speed);
|
s.integer(status.ram_speed);
|
||||||
s.integer(status.timers_enabled);
|
s.integer(status.timers_enabled);
|
||||||
s.integer(status.ram_disabled);
|
s.integer(status.ram_disabled);
|
||||||
s.integer(status.ram_writable);
|
s.integer(status.ram_writable);
|
||||||
|
|
|
@ -76,13 +76,9 @@ void SMP::reset() {
|
||||||
memory::apuram.write(i, 0x00);
|
memory::apuram.write(i, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
status.clock_counter = 0;
|
|
||||||
status.dsp_counter = 0;
|
|
||||||
status.timer_step = 3;
|
|
||||||
|
|
||||||
//$00f0
|
//$00f0
|
||||||
status.clock_speed = 0;
|
status.clock_speed = 0;
|
||||||
status.timer_speed = 0;
|
status.ram_speed = 0;
|
||||||
status.timers_enabled = true;
|
status.timers_enabled = true;
|
||||||
status.ram_disabled = false;
|
status.ram_disabled = false;
|
||||||
status.ram_writable = true;
|
status.ram_writable = true;
|
||||||
|
|
|
@ -21,14 +21,9 @@ private:
|
||||||
#include "timing/timing.hpp"
|
#include "timing/timing.hpp"
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
//timing
|
|
||||||
unsigned clock_counter;
|
|
||||||
unsigned dsp_counter;
|
|
||||||
unsigned timer_step;
|
|
||||||
|
|
||||||
//$00f0
|
//$00f0
|
||||||
uint8 clock_speed;
|
uint8 clock_speed;
|
||||||
uint8 timer_speed;
|
uint8 ram_speed;
|
||||||
bool timers_enabled;
|
bool timers_enabled;
|
||||||
bool ram_disabled;
|
bool ram_disabled;
|
||||||
bool ram_writable;
|
bool ram_writable;
|
||||||
|
|
|
@ -9,25 +9,22 @@ void SMP::add_clocks(unsigned clocks) {
|
||||||
if(clock > +(768 * 24 * (int64)24000000)) synchronize_cpu();
|
if(clock > +(768 * 24 * (int64)24000000)) synchronize_cpu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMP::cycle_edge() {
|
void SMP::cycle_edge(unsigned speed) {
|
||||||
t0.tick();
|
static const uint8 wait_states[] = {0, 24*1, 24*4, 24*9};
|
||||||
t1.tick();
|
|
||||||
t2.tick();
|
unsigned ticks = 1 << 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
|
//24 clocks have already been added for this cycle at this point
|
||||||
switch(status.clock_speed) {
|
if(speed) add_clocks(wait_states[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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<unsigned timer_frequency>
|
template<unsigned timer_frequency>
|
||||||
void SMP::sSMPTimer<timer_frequency>::tick() {
|
void SMP::sSMPTimer<timer_frequency>::tick(unsigned step) {
|
||||||
//stage 0 increment
|
//stage 0 increment
|
||||||
stage0_ticks += smp.status.timer_step;
|
stage0_ticks += step;
|
||||||
if(stage0_ticks < timer_frequency) return;
|
if(stage0_ticks < timer_frequency) return;
|
||||||
stage0_ticks -= timer_frequency;
|
stage0_ticks -= timer_frequency;
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,13 @@ public:
|
||||||
bool enabled;
|
bool enabled;
|
||||||
uint8 target;
|
uint8 target;
|
||||||
|
|
||||||
void tick();
|
void tick(unsigned step);
|
||||||
void sync_stage1();
|
void sync_stage1();
|
||||||
};
|
};
|
||||||
|
|
||||||
sSMPTimer<192> t0;
|
sSMPTimer<64> t0;
|
||||||
sSMPTimer<192> t1;
|
sSMPTimer<64> t1;
|
||||||
sSMPTimer< 24> t2;
|
sSMPTimer< 8> t2;
|
||||||
|
|
||||||
alwaysinline void add_clocks(unsigned clocks);
|
alwaysinline void add_clocks(unsigned clocks);
|
||||||
alwaysinline void cycle_edge();
|
alwaysinline void cycle_edge(unsigned speed);
|
||||||
|
|
Loading…
Add table
Reference in a new issue