mirror of https://github.com/bsnes-emu/bsnes.git
Update to v094r33 release.
byuu says: Small WIP, just fixes the timings for GSU multiply. However, the actual product may still be wrong when CLSR and MS0 are both set. Since I wasn't 'corrupting' the value in said case before, then this behavior can only be better than before. Turned the (cache,memory)_access_timing into functions that compute the values; and pulled "clockspeed" into GSU. Also, I'm thinking it might be kind of pointless to have clockspeed at all. Supposedly even the Mario Chip can run at 21.48MHz anyway. Enforcing 10.74MHz mode seems kind of silly. If we change it to just be a "default value for CLSR", then we can just inline the memory access tests without the need for the access_timing functions (literally just clsr?2:1 then) Slight compilation bug: go to processor/gsu/registers.hpp:33 and add reg16_t() = default; I missed it due to a partial recompile. Too lazy to upload another WIP just for that. Probably not worth doing much SuperFX testing just yet, as it looks like they're doing some other tests at the moment on NESdev.
This commit is contained in:
parent
169e400437
commit
4c9266d18f
|
@ -8,7 +8,7 @@ using namespace nall;
|
||||||
|
|
||||||
namespace Emulator {
|
namespace Emulator {
|
||||||
static const string Name = "higan";
|
static const string Name = "higan";
|
||||||
static const string Version = "094.32";
|
static const string Version = "094.33";
|
||||||
static const string Author = "byuu";
|
static const string Author = "byuu";
|
||||||
static const string License = "GPLv3";
|
static const string License = "GPLv3";
|
||||||
static const string Website = "http://byuu.org/";
|
static const string Website = "http://byuu.org/";
|
||||||
|
|
|
@ -7,10 +7,25 @@ namespace Processor {
|
||||||
#include "table.cpp"
|
#include "table.cpp"
|
||||||
#include "serialization.cpp"
|
#include "serialization.cpp"
|
||||||
|
|
||||||
void GSU::power() {
|
//note: multiplication results *may* sometimes be invalid when both CLSR and MS0 are set
|
||||||
|
//the product of multiplication in this mode (21mhz + fast-multiply) has not been analyzed;
|
||||||
|
//however, the timing of this mode has been confirmed to work as specified below
|
||||||
|
auto GSU::cache_access_speed() -> unsigned {
|
||||||
|
if(clockmode == 1) return 2;
|
||||||
|
if(clockmode == 2) return 1;
|
||||||
|
return regs.clsr ? 1 : 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSU::reset() {
|
auto GSU::memory_access_speed() -> unsigned {
|
||||||
|
if(clockmode == 1) return 6;
|
||||||
|
if(clockmode == 2) return 5;
|
||||||
|
return regs.clsr ? 5 : 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto GSU::power() -> void {
|
||||||
|
}
|
||||||
|
|
||||||
|
auto GSU::reset() -> void {
|
||||||
for(auto& r : regs.r) r = 0x0000;
|
for(auto& r : regs.r) r = 0x0000;
|
||||||
regs.sfr = 0x0000;
|
regs.sfr = 0x0000;
|
||||||
regs.pbr = 0x00;
|
regs.pbr = 0x00;
|
||||||
|
|
|
@ -4,113 +4,120 @@
|
||||||
namespace Processor {
|
namespace Processor {
|
||||||
|
|
||||||
struct GSU {
|
struct GSU {
|
||||||
|
unsigned clockmode; //0 = selectable; 1 = force 10.74mhz; 2 = force 21.48mhz
|
||||||
#include "registers.hpp"
|
#include "registers.hpp"
|
||||||
|
|
||||||
virtual void step(unsigned clocks) = 0;
|
virtual auto step(unsigned clocks) -> void = 0;
|
||||||
|
|
||||||
virtual void stop() = 0;
|
virtual auto stop() -> void = 0;
|
||||||
virtual uint8 color(uint8 source) = 0;
|
virtual auto color(uint8 source) -> uint8 = 0;
|
||||||
virtual void plot(uint8 x, uint8 y) = 0;
|
virtual auto plot(uint8 x, uint8 y) -> void = 0;
|
||||||
virtual uint8 rpix(uint8 x, uint8 y) = 0;
|
virtual auto rpix(uint8 x, uint8 y) -> uint8 = 0;
|
||||||
|
|
||||||
virtual uint8 pipe() = 0;
|
virtual auto pipe() -> uint8 = 0;
|
||||||
virtual void rombuffer_sync() = 0;
|
virtual auto rombuffer_sync() -> void = 0;
|
||||||
virtual uint8 rombuffer_read() = 0;
|
virtual auto rombuffer_read() -> uint8 = 0;
|
||||||
virtual void rambuffer_sync() = 0;
|
virtual auto rambuffer_sync() -> void = 0;
|
||||||
virtual uint8 rambuffer_read(uint16 addr) = 0;
|
virtual auto rambuffer_read(uint16 addr) -> uint8 = 0;
|
||||||
virtual void rambuffer_write(uint16 addr, uint8 data) = 0;
|
virtual auto rambuffer_write(uint16 addr, uint8 data) -> void = 0;
|
||||||
virtual void cache_flush() = 0;
|
virtual auto cache_flush() -> void = 0;
|
||||||
|
|
||||||
void power();
|
//gsu.cpp
|
||||||
void reset();
|
auto cache_access_speed() -> unsigned;
|
||||||
void serialize(serializer&);
|
auto memory_access_speed() -> unsigned;
|
||||||
|
|
||||||
//table.cpp
|
auto power() -> void;
|
||||||
void (GSU::*opcode_table[1024])();
|
auto reset() -> void;
|
||||||
void initialize_opcode_table();
|
|
||||||
|
|
||||||
//instructions.cpp
|
//instructions.cpp
|
||||||
template<int> void op_adc_i();
|
template<int> auto op_adc_i();
|
||||||
template<int> void op_adc_r();
|
template<int> auto op_adc_r();
|
||||||
template<int> void op_add_i();
|
template<int> auto op_add_i();
|
||||||
template<int> void op_add_r();
|
template<int> auto op_add_r();
|
||||||
void op_alt1();
|
auto op_alt1();
|
||||||
void op_alt2();
|
auto op_alt2();
|
||||||
void op_alt3();
|
auto op_alt3();
|
||||||
template<int> void op_and_i();
|
template<int> auto op_and_i();
|
||||||
template<int> void op_and_r();
|
template<int> auto op_and_r();
|
||||||
void op_asr();
|
auto op_asr();
|
||||||
void op_bge();
|
auto op_bge();
|
||||||
void op_bcc();
|
auto op_bcc();
|
||||||
void op_bcs();
|
auto op_bcs();
|
||||||
void op_beq();
|
auto op_beq();
|
||||||
template<int> void op_bic_i();
|
template<int> auto op_bic_i();
|
||||||
template<int> void op_bic_r();
|
template<int> auto op_bic_r();
|
||||||
void op_blt();
|
auto op_blt();
|
||||||
void op_bmi();
|
auto op_bmi();
|
||||||
void op_bne();
|
auto op_bne();
|
||||||
void op_bpl();
|
auto op_bpl();
|
||||||
void op_bra();
|
auto op_bra();
|
||||||
void op_bvc();
|
auto op_bvc();
|
||||||
void op_bvs();
|
auto op_bvs();
|
||||||
void op_cache();
|
auto op_cache();
|
||||||
void op_cmode();
|
auto op_cmode();
|
||||||
template<int> void op_cmp_r();
|
template<int> auto op_cmp_r();
|
||||||
void op_color();
|
auto op_color();
|
||||||
template<int> void op_dec_r();
|
template<int> auto op_dec_r();
|
||||||
void op_div2();
|
auto op_div2();
|
||||||
void op_fmult();
|
auto op_fmult();
|
||||||
template<int> void op_from_r();
|
template<int> auto op_from_r();
|
||||||
void op_getb();
|
auto op_getb();
|
||||||
void op_getbl();
|
auto op_getbl();
|
||||||
void op_getbh();
|
auto op_getbh();
|
||||||
void op_getbs();
|
auto op_getbs();
|
||||||
void op_getc();
|
auto op_getc();
|
||||||
void op_hib();
|
auto op_hib();
|
||||||
template<int> void op_ibt_r();
|
template<int> auto op_ibt_r();
|
||||||
template<int> void op_inc_r();
|
template<int> auto op_inc_r();
|
||||||
template<int> void op_iwt_r();
|
template<int> auto op_iwt_r();
|
||||||
template<int> void op_jmp_r();
|
template<int> auto op_jmp_r();
|
||||||
template<int> void op_ldb_ir();
|
template<int> auto op_ldb_ir();
|
||||||
template<int> void op_ldw_ir();
|
template<int> auto op_ldw_ir();
|
||||||
template<int> void op_link();
|
template<int> auto op_link();
|
||||||
template<int> void op_ljmp_r();
|
template<int> auto op_ljmp_r();
|
||||||
template<int> void op_lm_r();
|
template<int> auto op_lm_r();
|
||||||
template<int> void op_lms_r();
|
template<int> auto op_lms_r();
|
||||||
void op_lmult();
|
auto op_lmult();
|
||||||
void op_lob();
|
auto op_lob();
|
||||||
void op_loop();
|
auto op_loop();
|
||||||
void op_lsr();
|
auto op_lsr();
|
||||||
void op_merge();
|
auto op_merge();
|
||||||
template<int> void op_mult_i();
|
template<int> auto op_mult_i();
|
||||||
template<int> void op_mult_r();
|
template<int> auto op_mult_r();
|
||||||
void op_nop();
|
auto op_nop();
|
||||||
void op_not();
|
auto op_not();
|
||||||
template<int> void op_or_i();
|
template<int> auto op_or_i();
|
||||||
template<int> void op_or_r();
|
template<int> auto op_or_r();
|
||||||
void op_plot();
|
auto op_plot();
|
||||||
void op_ramb();
|
auto op_ramb();
|
||||||
void op_rol();
|
auto op_rol();
|
||||||
void op_romb();
|
auto op_romb();
|
||||||
void op_ror();
|
auto op_ror();
|
||||||
void op_rpix();
|
auto op_rpix();
|
||||||
template<int> void op_sbc_r();
|
template<int> auto op_sbc_r();
|
||||||
void op_sbk();
|
auto op_sbk();
|
||||||
void op_sex();
|
auto op_sex();
|
||||||
template<int> void op_sm_r();
|
template<int> auto op_sm_r();
|
||||||
template<int> void op_sms_r();
|
template<int> auto op_sms_r();
|
||||||
template<int> void op_stb_ir();
|
template<int> auto op_stb_ir();
|
||||||
void op_stop();
|
auto op_stop();
|
||||||
template<int> void op_stw_ir();
|
template<int> auto op_stw_ir();
|
||||||
template<int> void op_sub_i();
|
template<int> auto op_sub_i();
|
||||||
template<int> void op_sub_r();
|
template<int> auto op_sub_r();
|
||||||
void op_swap();
|
auto op_swap();
|
||||||
template<int> void op_to_r();
|
template<int> auto op_to_r();
|
||||||
template<int> void op_umult_i();
|
template<int> auto op_umult_i();
|
||||||
template<int> void op_umult_r();
|
template<int> auto op_umult_r();
|
||||||
template<int> void op_with_r();
|
template<int> auto op_with_r();
|
||||||
template<int> void op_xor_i();
|
template<int> auto op_xor_i();
|
||||||
template<int> void op_xor_r();
|
template<int> auto op_xor_r();
|
||||||
|
|
||||||
|
//table.cpp
|
||||||
|
auto (GSU::*opcode_table[1024])() -> void;
|
||||||
|
auto initialize_opcode_table() -> void;
|
||||||
|
|
||||||
|
//serialization.cpp
|
||||||
|
auto serialize(serializer&) -> void;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//$00 stop
|
//$00 stop
|
||||||
void GSU::op_stop() {
|
auto GSU::op_stop() {
|
||||||
if(regs.cfgr.irq == 0) {
|
if(regs.cfgr.irq == 0) {
|
||||||
regs.sfr.irq = 1;
|
regs.sfr.irq = 1;
|
||||||
stop();
|
stop();
|
||||||
|
@ -11,12 +11,12 @@ void GSU::op_stop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$01 nop
|
//$01 nop
|
||||||
void GSU::op_nop() {
|
auto GSU::op_nop() {
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$02 cache
|
//$02 cache
|
||||||
void GSU::op_cache() {
|
auto GSU::op_cache() {
|
||||||
if(regs.cbr != (regs.r[15] & 0xfff0)) {
|
if(regs.cbr != (regs.r[15] & 0xfff0)) {
|
||||||
regs.cbr = regs.r[15] & 0xfff0;
|
regs.cbr = regs.r[15] & 0xfff0;
|
||||||
cache_flush();
|
cache_flush();
|
||||||
|
@ -25,7 +25,7 @@ void GSU::op_cache() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$03 lsr
|
//$03 lsr
|
||||||
void GSU::op_lsr() {
|
auto GSU::op_lsr() {
|
||||||
regs.sfr.cy = (regs.sr() & 1);
|
regs.sfr.cy = (regs.sr() & 1);
|
||||||
regs.dr() = regs.sr() >> 1;
|
regs.dr() = regs.sr() >> 1;
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
|
@ -34,7 +34,7 @@ void GSU::op_lsr() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$04 rol
|
//$04 rol
|
||||||
void GSU::op_rol() {
|
auto GSU::op_rol() {
|
||||||
bool carry = (regs.sr() & 0x8000);
|
bool carry = (regs.sr() & 0x8000);
|
||||||
regs.dr() = (regs.sr() << 1) | regs.sfr.cy;
|
regs.dr() = (regs.sr() << 1) | regs.sfr.cy;
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
|
@ -44,73 +44,74 @@ void GSU::op_rol() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$05 bra e
|
//$05 bra e
|
||||||
void GSU::op_bra() {
|
auto GSU::op_bra() {
|
||||||
regs.r[15] += (int8)pipe();
|
regs.r[15] += (int8)pipe();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$06 blt e
|
//$06 blt e
|
||||||
void GSU::op_blt() {
|
auto GSU::op_blt() {
|
||||||
int e = (int8)pipe();
|
int e = (int8)pipe();
|
||||||
if((regs.sfr.s ^ regs.sfr.ov) == 0) regs.r[15] += e;
|
if((regs.sfr.s ^ regs.sfr.ov) == 0) regs.r[15] += e;
|
||||||
}
|
}
|
||||||
|
|
||||||
//$07 bge e
|
//$07 bge e
|
||||||
void GSU::op_bge() {
|
auto GSU::op_bge() {
|
||||||
int e = (int8)pipe();
|
int e = (int8)pipe();
|
||||||
if((regs.sfr.s ^ regs.sfr.ov) == 1) regs.r[15] += e;
|
if((regs.sfr.s ^ regs.sfr.ov) == 1) regs.r[15] += e;
|
||||||
}
|
}
|
||||||
|
|
||||||
//$08 bne e
|
//$08 bne e
|
||||||
void GSU::op_bne() {
|
auto GSU::op_bne() {
|
||||||
int e = (int8)pipe();
|
int e = (int8)pipe();
|
||||||
if(regs.sfr.z == 0) regs.r[15] += e;
|
if(regs.sfr.z == 0) regs.r[15] += e;
|
||||||
}
|
}
|
||||||
|
|
||||||
//$09 beq e
|
//$09 beq e
|
||||||
void GSU::op_beq() {
|
auto GSU::op_beq() {
|
||||||
int e = (int8)pipe();
|
int e = (int8)pipe();
|
||||||
if(regs.sfr.z == 1) regs.r[15] += e;
|
if(regs.sfr.z == 1) regs.r[15] += e;
|
||||||
}
|
}
|
||||||
|
|
||||||
//$0a bpl e
|
//$0a bpl e
|
||||||
void GSU::op_bpl() {
|
auto GSU::op_bpl() {
|
||||||
int e = (int8)pipe();
|
int e = (int8)pipe();
|
||||||
if(regs.sfr.s == 0) regs.r[15] += e;
|
if(regs.sfr.s == 0) regs.r[15] += e;
|
||||||
}
|
}
|
||||||
|
|
||||||
//$0b bmi e
|
//$0b bmi e
|
||||||
void GSU::op_bmi() {
|
auto GSU::op_bmi() {
|
||||||
int e = (int8)pipe();
|
int e = (int8)pipe();
|
||||||
if(regs.sfr.s == 1) regs.r[15] += e;
|
if(regs.sfr.s == 1) regs.r[15] += e;
|
||||||
}
|
}
|
||||||
|
|
||||||
//$0c bcc e
|
//$0c bcc e
|
||||||
void GSU::op_bcc() {
|
auto GSU::op_bcc() {
|
||||||
int e = (int8)pipe();
|
int e = (int8)pipe();
|
||||||
if(regs.sfr.cy == 0) regs.r[15] += e;
|
if(regs.sfr.cy == 0) regs.r[15] += e;
|
||||||
}
|
}
|
||||||
|
|
||||||
//$0d bcs e
|
//$0d bcs e
|
||||||
void GSU::op_bcs() {
|
auto GSU::op_bcs() {
|
||||||
int e = (int8)pipe();
|
int e = (int8)pipe();
|
||||||
if(regs.sfr.cy == 1) regs.r[15] += e;
|
if(regs.sfr.cy == 1) regs.r[15] += e;
|
||||||
}
|
}
|
||||||
|
|
||||||
//$0e bvc e
|
//$0e bvc e
|
||||||
void GSU::op_bvc() {
|
auto GSU::op_bvc() {
|
||||||
int e = (int8)pipe();
|
int e = (int8)pipe();
|
||||||
if(regs.sfr.ov == 0) regs.r[15] += e;
|
if(regs.sfr.ov == 0) regs.r[15] += e;
|
||||||
}
|
}
|
||||||
|
|
||||||
//$0f bvs e
|
//$0f bvs e
|
||||||
void GSU::op_bvs() {
|
auto GSU::op_bvs() {
|
||||||
int e = (int8)pipe();
|
int e = (int8)pipe();
|
||||||
if(regs.sfr.ov == 1) regs.r[15] += e;
|
if(regs.sfr.ov == 1) regs.r[15] += e;
|
||||||
}
|
}
|
||||||
|
|
||||||
//$10-1f(b0): to rN
|
//$10-1f(b0): to rN
|
||||||
//$10-1f(b1): move rN
|
//$10-1f(b1): move rN
|
||||||
template<int n> void GSU::op_to_r() {
|
template<int n>
|
||||||
|
auto GSU::op_to_r() {
|
||||||
if(regs.sfr.b == 0) {
|
if(regs.sfr.b == 0) {
|
||||||
regs.dreg = n;
|
regs.dreg = n;
|
||||||
} else {
|
} else {
|
||||||
|
@ -120,14 +121,16 @@ template<int n> void GSU::op_to_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$20-2f: with rN
|
//$20-2f: with rN
|
||||||
template<int n> void GSU::op_with_r() {
|
template<int n>
|
||||||
|
auto GSU::op_with_r() {
|
||||||
regs.sreg = n;
|
regs.sreg = n;
|
||||||
regs.dreg = n;
|
regs.dreg = n;
|
||||||
regs.sfr.b = 1;
|
regs.sfr.b = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//$30-3b(alt0): stw (rN)
|
//$30-3b(alt0): stw (rN)
|
||||||
template<int n> void GSU::op_stw_ir() {
|
template<int n>
|
||||||
|
auto GSU::op_stw_ir() {
|
||||||
regs.ramaddr = regs.r[n];
|
regs.ramaddr = regs.r[n];
|
||||||
rambuffer_write(regs.ramaddr ^ 0, regs.sr() >> 0);
|
rambuffer_write(regs.ramaddr ^ 0, regs.sr() >> 0);
|
||||||
rambuffer_write(regs.ramaddr ^ 1, regs.sr() >> 8);
|
rambuffer_write(regs.ramaddr ^ 1, regs.sr() >> 8);
|
||||||
|
@ -135,14 +138,15 @@ template<int n> void GSU::op_stw_ir() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$30-3b(alt1): stb (rN)
|
//$30-3b(alt1): stb (rN)
|
||||||
template<int n> void GSU::op_stb_ir() {
|
template<int n>
|
||||||
|
auto GSU::op_stb_ir() {
|
||||||
regs.ramaddr = regs.r[n];
|
regs.ramaddr = regs.r[n];
|
||||||
rambuffer_write(regs.ramaddr, regs.sr());
|
rambuffer_write(regs.ramaddr, regs.sr());
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$3c loop
|
//$3c loop
|
||||||
void GSU::op_loop() {
|
auto GSU::op_loop() {
|
||||||
regs.r[12]--;
|
regs.r[12]--;
|
||||||
regs.sfr.s = (regs.r[12] & 0x8000);
|
regs.sfr.s = (regs.r[12] & 0x8000);
|
||||||
regs.sfr.z = (regs.r[12] == 0);
|
regs.sfr.z = (regs.r[12] == 0);
|
||||||
|
@ -151,26 +155,27 @@ void GSU::op_loop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$3d alt1
|
//$3d alt1
|
||||||
void GSU::op_alt1() {
|
auto GSU::op_alt1() {
|
||||||
regs.sfr.b = 0;
|
regs.sfr.b = 0;
|
||||||
regs.sfr.alt1 = 1;
|
regs.sfr.alt1 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//$3e alt2
|
//$3e alt2
|
||||||
void GSU::op_alt2() {
|
auto GSU::op_alt2() {
|
||||||
regs.sfr.b = 0;
|
regs.sfr.b = 0;
|
||||||
regs.sfr.alt2 = 1;
|
regs.sfr.alt2 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//$3f alt3
|
//$3f alt3
|
||||||
void GSU::op_alt3() {
|
auto GSU::op_alt3() {
|
||||||
regs.sfr.b = 0;
|
regs.sfr.b = 0;
|
||||||
regs.sfr.alt1 = 1;
|
regs.sfr.alt1 = 1;
|
||||||
regs.sfr.alt2 = 1;
|
regs.sfr.alt2 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//$40-4b(alt0): ldw (rN)
|
//$40-4b(alt0): ldw (rN)
|
||||||
template<int n> void GSU::op_ldw_ir() {
|
template<int n>
|
||||||
|
auto GSU::op_ldw_ir() {
|
||||||
regs.ramaddr = regs.r[n];
|
regs.ramaddr = regs.r[n];
|
||||||
uint16_t data;
|
uint16_t data;
|
||||||
data = rambuffer_read(regs.ramaddr ^ 0) << 0;
|
data = rambuffer_read(regs.ramaddr ^ 0) << 0;
|
||||||
|
@ -180,21 +185,22 @@ template<int n> void GSU::op_ldw_ir() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$40-4b(alt1): ldb (rN)
|
//$40-4b(alt1): ldb (rN)
|
||||||
template<int n> void GSU::op_ldb_ir() {
|
template<int n>
|
||||||
|
auto GSU::op_ldb_ir() {
|
||||||
regs.ramaddr = regs.r[n];
|
regs.ramaddr = regs.r[n];
|
||||||
regs.dr() = rambuffer_read(regs.ramaddr);
|
regs.dr() = rambuffer_read(regs.ramaddr);
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$4c(alt0): plot
|
//$4c(alt0): plot
|
||||||
void GSU::op_plot() {
|
auto GSU::op_plot() {
|
||||||
plot(regs.r[1], regs.r[2]);
|
plot(regs.r[1], regs.r[2]);
|
||||||
regs.r[1]++;
|
regs.r[1]++;
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$4c(alt1): rpix
|
//$4c(alt1): rpix
|
||||||
void GSU::op_rpix() {
|
auto GSU::op_rpix() {
|
||||||
regs.dr() = rpix(regs.r[1], regs.r[2]);
|
regs.dr() = rpix(regs.r[1], regs.r[2]);
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
|
@ -202,7 +208,7 @@ void GSU::op_rpix() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$4d: swap
|
//$4d: swap
|
||||||
void GSU::op_swap() {
|
auto GSU::op_swap() {
|
||||||
regs.dr() = (regs.sr() >> 8) | (regs.sr() << 8);
|
regs.dr() = (regs.sr() >> 8) | (regs.sr() << 8);
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
|
@ -210,19 +216,19 @@ void GSU::op_swap() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$4e(alt0): color
|
//$4e(alt0): color
|
||||||
void GSU::op_color() {
|
auto GSU::op_color() {
|
||||||
regs.colr = color(regs.sr());
|
regs.colr = color(regs.sr());
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$4e(alt1): cmode
|
//$4e(alt1): cmode
|
||||||
void GSU::op_cmode() {
|
auto GSU::op_cmode() {
|
||||||
regs.por = regs.sr();
|
regs.por = regs.sr();
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$4f: not
|
//$4f: not
|
||||||
void GSU::op_not() {
|
auto GSU::op_not() {
|
||||||
regs.dr() = ~regs.sr();
|
regs.dr() = ~regs.sr();
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
|
@ -230,7 +236,8 @@ void GSU::op_not() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$50-5f(alt0): add rN
|
//$50-5f(alt0): add rN
|
||||||
template<int n> void GSU::op_add_r() {
|
template<int n>
|
||||||
|
auto GSU::op_add_r() {
|
||||||
int r = regs.sr() + regs.r[n];
|
int r = regs.sr() + regs.r[n];
|
||||||
regs.sfr.ov = ~(regs.sr() ^ regs.r[n]) & (regs.r[n] ^ r) & 0x8000;
|
regs.sfr.ov = ~(regs.sr() ^ regs.r[n]) & (regs.r[n] ^ r) & 0x8000;
|
||||||
regs.sfr.s = (r & 0x8000);
|
regs.sfr.s = (r & 0x8000);
|
||||||
|
@ -241,7 +248,8 @@ template<int n> void GSU::op_add_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$50-5f(alt1): adc rN
|
//$50-5f(alt1): adc rN
|
||||||
template<int n> void GSU::op_adc_r() {
|
template<int n>
|
||||||
|
auto GSU::op_adc_r() {
|
||||||
int r = regs.sr() + regs.r[n] + regs.sfr.cy;
|
int r = regs.sr() + regs.r[n] + regs.sfr.cy;
|
||||||
regs.sfr.ov = ~(regs.sr() ^ regs.r[n]) & (regs.r[n] ^ r) & 0x8000;
|
regs.sfr.ov = ~(regs.sr() ^ regs.r[n]) & (regs.r[n] ^ r) & 0x8000;
|
||||||
regs.sfr.s = (r & 0x8000);
|
regs.sfr.s = (r & 0x8000);
|
||||||
|
@ -252,7 +260,8 @@ template<int n> void GSU::op_adc_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$50-5f(alt2): add #N
|
//$50-5f(alt2): add #N
|
||||||
template<int n> void GSU::op_add_i() {
|
template<int n>
|
||||||
|
auto GSU::op_add_i() {
|
||||||
int r = regs.sr() + n;
|
int r = regs.sr() + n;
|
||||||
regs.sfr.ov = ~(regs.sr() ^ n) & (n ^ r) & 0x8000;
|
regs.sfr.ov = ~(regs.sr() ^ n) & (n ^ r) & 0x8000;
|
||||||
regs.sfr.s = (r & 0x8000);
|
regs.sfr.s = (r & 0x8000);
|
||||||
|
@ -263,7 +272,8 @@ template<int n> void GSU::op_add_i() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$50-5f(alt3): adc #N
|
//$50-5f(alt3): adc #N
|
||||||
template<int n> void GSU::op_adc_i() {
|
template<int n>
|
||||||
|
auto GSU::op_adc_i() {
|
||||||
int r = regs.sr() + n + regs.sfr.cy;
|
int r = regs.sr() + n + regs.sfr.cy;
|
||||||
regs.sfr.ov = ~(regs.sr() ^ n) & (n ^ r) & 0x8000;
|
regs.sfr.ov = ~(regs.sr() ^ n) & (n ^ r) & 0x8000;
|
||||||
regs.sfr.s = (r & 0x8000);
|
regs.sfr.s = (r & 0x8000);
|
||||||
|
@ -274,7 +284,8 @@ template<int n> void GSU::op_adc_i() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$60-6f(alt0): sub rN
|
//$60-6f(alt0): sub rN
|
||||||
template<int n> void GSU::op_sub_r() {
|
template<int n>
|
||||||
|
auto GSU::op_sub_r() {
|
||||||
int r = regs.sr() - regs.r[n];
|
int r = regs.sr() - regs.r[n];
|
||||||
regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000;
|
regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000;
|
||||||
regs.sfr.s = (r & 0x8000);
|
regs.sfr.s = (r & 0x8000);
|
||||||
|
@ -285,7 +296,8 @@ template<int n> void GSU::op_sub_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$60-6f(alt1): sbc rN
|
//$60-6f(alt1): sbc rN
|
||||||
template<int n> void GSU::op_sbc_r() {
|
template<int n>
|
||||||
|
auto GSU::op_sbc_r() {
|
||||||
int r = regs.sr() - regs.r[n] - !regs.sfr.cy;
|
int r = regs.sr() - regs.r[n] - !regs.sfr.cy;
|
||||||
regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000;
|
regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000;
|
||||||
regs.sfr.s = (r & 0x8000);
|
regs.sfr.s = (r & 0x8000);
|
||||||
|
@ -296,7 +308,8 @@ template<int n> void GSU::op_sbc_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$60-6f(alt2): sub #N
|
//$60-6f(alt2): sub #N
|
||||||
template<int n> void GSU::op_sub_i() {
|
template<int n>
|
||||||
|
auto GSU::op_sub_i() {
|
||||||
int r = regs.sr() - n;
|
int r = regs.sr() - n;
|
||||||
regs.sfr.ov = (regs.sr() ^ n) & (regs.sr() ^ r) & 0x8000;
|
regs.sfr.ov = (regs.sr() ^ n) & (regs.sr() ^ r) & 0x8000;
|
||||||
regs.sfr.s = (r & 0x8000);
|
regs.sfr.s = (r & 0x8000);
|
||||||
|
@ -307,7 +320,8 @@ template<int n> void GSU::op_sub_i() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$60-6f(alt3): cmp rN
|
//$60-6f(alt3): cmp rN
|
||||||
template<int n> void GSU::op_cmp_r() {
|
template<int n>
|
||||||
|
auto GSU::op_cmp_r() {
|
||||||
int r = regs.sr() - regs.r[n];
|
int r = regs.sr() - regs.r[n];
|
||||||
regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000;
|
regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000;
|
||||||
regs.sfr.s = (r & 0x8000);
|
regs.sfr.s = (r & 0x8000);
|
||||||
|
@ -317,7 +331,7 @@ template<int n> void GSU::op_cmp_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$70: merge
|
//$70: merge
|
||||||
void GSU::op_merge() {
|
auto GSU::op_merge() {
|
||||||
regs.dr() = (regs.r[7] & 0xff00) | (regs.r[8] >> 8);
|
regs.dr() = (regs.r[7] & 0xff00) | (regs.r[8] >> 8);
|
||||||
regs.sfr.ov = (regs.dr() & 0xc0c0);
|
regs.sfr.ov = (regs.dr() & 0xc0c0);
|
||||||
regs.sfr.s = (regs.dr() & 0x8080);
|
regs.sfr.s = (regs.dr() & 0x8080);
|
||||||
|
@ -327,7 +341,8 @@ void GSU::op_merge() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$71-7f(alt0): and rN
|
//$71-7f(alt0): and rN
|
||||||
template<int n> void GSU::op_and_r() {
|
template<int n>
|
||||||
|
auto GSU::op_and_r() {
|
||||||
regs.dr() = regs.sr() & regs.r[n];
|
regs.dr() = regs.sr() & regs.r[n];
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
|
@ -335,7 +350,8 @@ template<int n> void GSU::op_and_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$71-7f(alt1): bic rN
|
//$71-7f(alt1): bic rN
|
||||||
template<int n> void GSU::op_bic_r() {
|
template<int n>
|
||||||
|
auto GSU::op_bic_r() {
|
||||||
regs.dr() = regs.sr() & ~regs.r[n];
|
regs.dr() = regs.sr() & ~regs.r[n];
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
|
@ -343,7 +359,8 @@ template<int n> void GSU::op_bic_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$71-7f(alt2): and #N
|
//$71-7f(alt2): and #N
|
||||||
template<int n> void GSU::op_and_i() {
|
template<int n>
|
||||||
|
auto GSU::op_and_i() {
|
||||||
regs.dr() = regs.sr() & n;
|
regs.dr() = regs.sr() & n;
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
|
@ -351,7 +368,8 @@ template<int n> void GSU::op_and_i() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$71-7f(alt3): bic #N
|
//$71-7f(alt3): bic #N
|
||||||
template<int n> void GSU::op_bic_i() {
|
template<int n>
|
||||||
|
auto GSU::op_bic_i() {
|
||||||
regs.dr() = regs.sr() & ~n;
|
regs.dr() = regs.sr() & ~n;
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
|
@ -359,56 +377,61 @@ template<int n> void GSU::op_bic_i() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$80-8f(alt0): mult rN
|
//$80-8f(alt0): mult rN
|
||||||
template<int n> void GSU::op_mult_r() {
|
template<int n>
|
||||||
|
auto GSU::op_mult_r() {
|
||||||
regs.dr() = (int8)regs.sr() * (int8)regs.r[n];
|
regs.dr() = (int8)regs.sr() * (int8)regs.r[n];
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
regs.reset();
|
regs.reset();
|
||||||
if(!regs.cfgr.ms0) step(2);
|
if(!regs.cfgr.ms0) step(cache_access_speed());
|
||||||
}
|
}
|
||||||
|
|
||||||
//$80-8f(alt1): umult rN
|
//$80-8f(alt1): umult rN
|
||||||
template<int n> void GSU::op_umult_r() {
|
template<int n>
|
||||||
|
auto GSU::op_umult_r() {
|
||||||
regs.dr() = (uint8)regs.sr() * (uint8)regs.r[n];
|
regs.dr() = (uint8)regs.sr() * (uint8)regs.r[n];
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
regs.reset();
|
regs.reset();
|
||||||
if(!regs.cfgr.ms0) step(2);
|
if(!regs.cfgr.ms0) step(cache_access_speed());
|
||||||
}
|
}
|
||||||
|
|
||||||
//$80-8f(alt2): mult #N
|
//$80-8f(alt2): mult #N
|
||||||
template<int n> void GSU::op_mult_i() {
|
template<int n>
|
||||||
|
auto GSU::op_mult_i() {
|
||||||
regs.dr() = (int8)regs.sr() * (int8)n;
|
regs.dr() = (int8)regs.sr() * (int8)n;
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
regs.reset();
|
regs.reset();
|
||||||
if(!regs.cfgr.ms0) step(2);
|
if(!regs.cfgr.ms0) step(cache_access_speed());
|
||||||
}
|
}
|
||||||
|
|
||||||
//$80-8f(alt3): umult #N
|
//$80-8f(alt3): umult #N
|
||||||
template<int n> void GSU::op_umult_i() {
|
template<int n>
|
||||||
|
auto GSU::op_umult_i() {
|
||||||
regs.dr() = (uint8)regs.sr() * (uint8)n;
|
regs.dr() = (uint8)regs.sr() * (uint8)n;
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
regs.reset();
|
regs.reset();
|
||||||
if(!regs.cfgr.ms0) step(2);
|
if(!regs.cfgr.ms0) step(cache_access_speed());
|
||||||
}
|
}
|
||||||
|
|
||||||
//$90: sbk
|
//$90: sbk
|
||||||
void GSU::op_sbk() {
|
auto GSU::op_sbk() {
|
||||||
rambuffer_write(regs.ramaddr ^ 0, regs.sr() >> 0);
|
rambuffer_write(regs.ramaddr ^ 0, regs.sr() >> 0);
|
||||||
rambuffer_write(regs.ramaddr ^ 1, regs.sr() >> 8);
|
rambuffer_write(regs.ramaddr ^ 1, regs.sr() >> 8);
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$91-94: link #N
|
//$91-94: link #N
|
||||||
template<int n> void GSU::op_link() {
|
template<int n>
|
||||||
|
auto GSU::op_link() {
|
||||||
regs.r[11] = regs.r[15] + n;
|
regs.r[11] = regs.r[15] + n;
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$95: sex
|
//$95: sex
|
||||||
void GSU::op_sex() {
|
auto GSU::op_sex() {
|
||||||
regs.dr() = (int8)regs.sr();
|
regs.dr() = (int8)regs.sr();
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
|
@ -416,7 +439,7 @@ void GSU::op_sex() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$96(alt0): asr
|
//$96(alt0): asr
|
||||||
void GSU::op_asr() {
|
auto GSU::op_asr() {
|
||||||
regs.sfr.cy = (regs.sr() & 1);
|
regs.sfr.cy = (regs.sr() & 1);
|
||||||
regs.dr() = (int16_t)regs.sr() >> 1;
|
regs.dr() = (int16_t)regs.sr() >> 1;
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
|
@ -425,7 +448,7 @@ void GSU::op_asr() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$96(alt1): div2
|
//$96(alt1): div2
|
||||||
void GSU::op_div2() {
|
auto GSU::op_div2() {
|
||||||
regs.sfr.cy = (regs.sr() & 1);
|
regs.sfr.cy = (regs.sr() & 1);
|
||||||
regs.dr() = ((int16_t)regs.sr() >> 1) + ((regs.sr() + 1) >> 16);
|
regs.dr() = ((int16_t)regs.sr() >> 1) + ((regs.sr() + 1) >> 16);
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
|
@ -434,7 +457,7 @@ void GSU::op_div2() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$97: ror
|
//$97: ror
|
||||||
void GSU::op_ror() {
|
auto GSU::op_ror() {
|
||||||
bool carry = (regs.sr() & 1);
|
bool carry = (regs.sr() & 1);
|
||||||
regs.dr() = (regs.sfr.cy << 15) | (regs.sr() >> 1);
|
regs.dr() = (regs.sfr.cy << 15) | (regs.sr() >> 1);
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
|
@ -444,13 +467,15 @@ void GSU::op_ror() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$98-9d(alt0): jmp rN
|
//$98-9d(alt0): jmp rN
|
||||||
template<int n> void GSU::op_jmp_r() {
|
template<int n>
|
||||||
|
auto GSU::op_jmp_r() {
|
||||||
regs.r[15] = regs.r[n];
|
regs.r[15] = regs.r[n];
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$98-9d(alt1): ljmp rN
|
//$98-9d(alt1): ljmp rN
|
||||||
template<int n> void GSU::op_ljmp_r() {
|
template<int n>
|
||||||
|
auto GSU::op_ljmp_r() {
|
||||||
regs.pbr = regs.r[n] & 0x7f;
|
regs.pbr = regs.r[n] & 0x7f;
|
||||||
regs.r[15] = regs.sr();
|
regs.r[15] = regs.sr();
|
||||||
regs.cbr = regs.r[15] & 0xfff0;
|
regs.cbr = regs.r[15] & 0xfff0;
|
||||||
|
@ -459,7 +484,7 @@ template<int n> void GSU::op_ljmp_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$9e: lob
|
//$9e: lob
|
||||||
void GSU::op_lob() {
|
auto GSU::op_lob() {
|
||||||
regs.dr() = regs.sr() & 0xff;
|
regs.dr() = regs.sr() & 0xff;
|
||||||
regs.sfr.s = (regs.dr() & 0x80);
|
regs.sfr.s = (regs.dr() & 0x80);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
|
@ -467,7 +492,7 @@ void GSU::op_lob() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$9f(alt0): fmult
|
//$9f(alt0): fmult
|
||||||
void GSU::op_fmult() {
|
auto GSU::op_fmult() {
|
||||||
uint32_t result = (int16_t)regs.sr() * (int16_t)regs.r[6];
|
uint32_t result = (int16_t)regs.sr() * (int16_t)regs.r[6];
|
||||||
regs.dr() = result >> 16;
|
regs.dr() = result >> 16;
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
|
@ -478,7 +503,7 @@ void GSU::op_fmult() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$9f(alt1): lmult
|
//$9f(alt1): lmult
|
||||||
void GSU::op_lmult() {
|
auto GSU::op_lmult() {
|
||||||
uint32_t result = (int16_t)regs.sr() * (int16_t)regs.r[6];
|
uint32_t result = (int16_t)regs.sr() * (int16_t)regs.r[6];
|
||||||
regs.r[4] = result;
|
regs.r[4] = result;
|
||||||
regs.dr() = result >> 16;
|
regs.dr() = result >> 16;
|
||||||
|
@ -490,13 +515,15 @@ void GSU::op_lmult() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$a0-af(alt0): ibt rN,#pp
|
//$a0-af(alt0): ibt rN,#pp
|
||||||
template<int n> void GSU::op_ibt_r() {
|
template<int n>
|
||||||
|
auto GSU::op_ibt_r() {
|
||||||
regs.r[n] = (int8)pipe();
|
regs.r[n] = (int8)pipe();
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$a0-af(alt1): lms rN,(yy)
|
//$a0-af(alt1): lms rN,(yy)
|
||||||
template<int n> void GSU::op_lms_r() {
|
template<int n>
|
||||||
|
auto GSU::op_lms_r() {
|
||||||
regs.ramaddr = pipe() << 1;
|
regs.ramaddr = pipe() << 1;
|
||||||
uint16_t data;
|
uint16_t data;
|
||||||
data = rambuffer_read(regs.ramaddr ^ 0) << 0;
|
data = rambuffer_read(regs.ramaddr ^ 0) << 0;
|
||||||
|
@ -506,7 +533,8 @@ template<int n> void GSU::op_lms_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$a0-af(alt2): sms (yy),rN
|
//$a0-af(alt2): sms (yy),rN
|
||||||
template<int n> void GSU::op_sms_r() {
|
template<int n>
|
||||||
|
auto GSU::op_sms_r() {
|
||||||
regs.ramaddr = pipe() << 1;
|
regs.ramaddr = pipe() << 1;
|
||||||
rambuffer_write(regs.ramaddr ^ 0, regs.r[n] >> 0);
|
rambuffer_write(regs.ramaddr ^ 0, regs.r[n] >> 0);
|
||||||
rambuffer_write(regs.ramaddr ^ 1, regs.r[n] >> 8);
|
rambuffer_write(regs.ramaddr ^ 1, regs.r[n] >> 8);
|
||||||
|
@ -515,7 +543,8 @@ template<int n> void GSU::op_sms_r() {
|
||||||
|
|
||||||
//$b0-bf(b0): from rN
|
//$b0-bf(b0): from rN
|
||||||
//$b0-bf(b1): moves rN
|
//$b0-bf(b1): moves rN
|
||||||
template<int n> void GSU::op_from_r() {
|
template<int n>
|
||||||
|
auto GSU::op_from_r() {
|
||||||
if(regs.sfr.b == 0) {
|
if(regs.sfr.b == 0) {
|
||||||
regs.sreg = n;
|
regs.sreg = n;
|
||||||
} else {
|
} else {
|
||||||
|
@ -528,7 +557,7 @@ template<int n> void GSU::op_from_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$c0: hib
|
//$c0: hib
|
||||||
void GSU::op_hib() {
|
auto GSU::op_hib() {
|
||||||
regs.dr() = regs.sr() >> 8;
|
regs.dr() = regs.sr() >> 8;
|
||||||
regs.sfr.s = (regs.dr() & 0x80);
|
regs.sfr.s = (regs.dr() & 0x80);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
|
@ -536,7 +565,8 @@ void GSU::op_hib() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$c1-cf(alt0): or rN
|
//$c1-cf(alt0): or rN
|
||||||
template<int n> void GSU::op_or_r() {
|
template<int n>
|
||||||
|
auto GSU::op_or_r() {
|
||||||
regs.dr() = regs.sr() | regs.r[n];
|
regs.dr() = regs.sr() | regs.r[n];
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
|
@ -544,7 +574,8 @@ template<int n> void GSU::op_or_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$c1-cf(alt1): xor rN
|
//$c1-cf(alt1): xor rN
|
||||||
template<int n> void GSU::op_xor_r() {
|
template<int n>
|
||||||
|
auto GSU::op_xor_r() {
|
||||||
regs.dr() = regs.sr() ^ regs.r[n];
|
regs.dr() = regs.sr() ^ regs.r[n];
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
|
@ -552,7 +583,8 @@ template<int n> void GSU::op_xor_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$c1-cf(alt2): or #N
|
//$c1-cf(alt2): or #N
|
||||||
template<int n> void GSU::op_or_i() {
|
template<int n>
|
||||||
|
auto GSU::op_or_i() {
|
||||||
regs.dr() = regs.sr() | n;
|
regs.dr() = regs.sr() | n;
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
|
@ -560,7 +592,8 @@ template<int n> void GSU::op_or_i() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$c1-cf(alt3): xor #N
|
//$c1-cf(alt3): xor #N
|
||||||
template<int n> void GSU::op_xor_i() {
|
template<int n>
|
||||||
|
auto GSU::op_xor_i() {
|
||||||
regs.dr() = regs.sr() ^ n;
|
regs.dr() = regs.sr() ^ n;
|
||||||
regs.sfr.s = (regs.dr() & 0x8000);
|
regs.sfr.s = (regs.dr() & 0x8000);
|
||||||
regs.sfr.z = (regs.dr() == 0);
|
regs.sfr.z = (regs.dr() == 0);
|
||||||
|
@ -568,7 +601,8 @@ template<int n> void GSU::op_xor_i() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$d0-de: inc rN
|
//$d0-de: inc rN
|
||||||
template<int n> void GSU::op_inc_r() {
|
template<int n>
|
||||||
|
auto GSU::op_inc_r() {
|
||||||
regs.r[n]++;
|
regs.r[n]++;
|
||||||
regs.sfr.s = (regs.r[n] & 0x8000);
|
regs.sfr.s = (regs.r[n] & 0x8000);
|
||||||
regs.sfr.z = (regs.r[n] == 0);
|
regs.sfr.z = (regs.r[n] == 0);
|
||||||
|
@ -576,27 +610,28 @@ template<int n> void GSU::op_inc_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$df(alt0): getc
|
//$df(alt0): getc
|
||||||
void GSU::op_getc() {
|
auto GSU::op_getc() {
|
||||||
regs.colr = color(rombuffer_read());
|
regs.colr = color(rombuffer_read());
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$df(alt2): ramb
|
//$df(alt2): ramb
|
||||||
void GSU::op_ramb() {
|
auto GSU::op_ramb() {
|
||||||
rambuffer_sync();
|
rambuffer_sync();
|
||||||
regs.rambr = regs.sr();
|
regs.rambr = regs.sr();
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$df(alt3): romb
|
//$df(alt3): romb
|
||||||
void GSU::op_romb() {
|
auto GSU::op_romb() {
|
||||||
rombuffer_sync();
|
rombuffer_sync();
|
||||||
regs.rombr = regs.sr() & 0x7f;
|
regs.rombr = regs.sr() & 0x7f;
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$e0-ee: dec rN
|
//$e0-ee: dec rN
|
||||||
template<int n> void GSU::op_dec_r() {
|
template<int n>
|
||||||
|
auto GSU::op_dec_r() {
|
||||||
regs.r[n]--;
|
regs.r[n]--;
|
||||||
regs.sfr.s = (regs.r[n] & 0x8000);
|
regs.sfr.s = (regs.r[n] & 0x8000);
|
||||||
regs.sfr.z = (regs.r[n] == 0);
|
regs.sfr.z = (regs.r[n] == 0);
|
||||||
|
@ -604,31 +639,32 @@ template<int n> void GSU::op_dec_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$ef(alt0): getb
|
//$ef(alt0): getb
|
||||||
void GSU::op_getb() {
|
auto GSU::op_getb() {
|
||||||
regs.dr() = rombuffer_read();
|
regs.dr() = rombuffer_read();
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$ef(alt1): getbh
|
//$ef(alt1): getbh
|
||||||
void GSU::op_getbh() {
|
auto GSU::op_getbh() {
|
||||||
regs.dr() = (rombuffer_read() << 8) | (regs.sr() & 0x00ff);
|
regs.dr() = (rombuffer_read() << 8) | (regs.sr() & 0x00ff);
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$ef(alt2): getbl
|
//$ef(alt2): getbl
|
||||||
void GSU::op_getbl() {
|
auto GSU::op_getbl() {
|
||||||
regs.dr() = (regs.sr() & 0xff00) | (rombuffer_read() << 0);
|
regs.dr() = (regs.sr() & 0xff00) | (rombuffer_read() << 0);
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$ef(alt3): getbs
|
//$ef(alt3): getbs
|
||||||
void GSU::op_getbs() {
|
auto GSU::op_getbs() {
|
||||||
regs.dr() = (int8)rombuffer_read();
|
regs.dr() = (int8)rombuffer_read();
|
||||||
regs.reset();
|
regs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//$f0-ff(alt0): iwt rN,#xx
|
//$f0-ff(alt0): iwt rN,#xx
|
||||||
template<int n> void GSU::op_iwt_r() {
|
template<int n>
|
||||||
|
auto GSU::op_iwt_r() {
|
||||||
uint16_t data;
|
uint16_t data;
|
||||||
data = pipe() << 0;
|
data = pipe() << 0;
|
||||||
data |= pipe() << 8;
|
data |= pipe() << 8;
|
||||||
|
@ -637,7 +673,8 @@ template<int n> void GSU::op_iwt_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$f0-ff(alt1): lm rN,(xx)
|
//$f0-ff(alt1): lm rN,(xx)
|
||||||
template<int n> void GSU::op_lm_r() {
|
template<int n>
|
||||||
|
auto GSU::op_lm_r() {
|
||||||
regs.ramaddr = pipe() << 0;
|
regs.ramaddr = pipe() << 0;
|
||||||
regs.ramaddr |= pipe() << 8;
|
regs.ramaddr |= pipe() << 8;
|
||||||
uint16_t data;
|
uint16_t data;
|
||||||
|
@ -648,7 +685,8 @@ template<int n> void GSU::op_lm_r() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//$f0-ff(alt2): sm (xx),rN
|
//$f0-ff(alt2): sm (xx),rN
|
||||||
template<int n> void GSU::op_sm_r() {
|
template<int n>
|
||||||
|
auto GSU::op_sm_r() {
|
||||||
regs.ramaddr = pipe() << 0;
|
regs.ramaddr = pipe() << 0;
|
||||||
regs.ramaddr |= pipe() << 8;
|
regs.ramaddr |= pipe() << 8;
|
||||||
rambuffer_write(regs.ramaddr ^ 0, regs.r[n] >> 0);
|
rambuffer_write(regs.ramaddr ^ 0, regs.r[n] >> 0);
|
||||||
|
|
|
@ -1,34 +1,36 @@
|
||||||
//accepts a callback binding so r14 writes can trigger ROM buffering transparently
|
//accepts a callback binding so r14 writes can trigger ROM buffering transparently
|
||||||
struct reg16_t {
|
struct reg16_t {
|
||||||
uint16 data;
|
uint16 data = 0;
|
||||||
function<void (uint16)> modify;
|
function<auto (uint16) -> void> modify;
|
||||||
|
|
||||||
inline operator unsigned() const { return data; }
|
inline operator unsigned() const {
|
||||||
inline uint16 assign(uint16 i) {
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto assign(uint16 i) -> uint16 {
|
||||||
if(modify) modify(i);
|
if(modify) modify(i);
|
||||||
else data = i;
|
else data = i;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned operator++() { return assign(data + 1); }
|
inline auto operator++() { return assign(data + 1); }
|
||||||
inline unsigned operator--() { return assign(data - 1); }
|
inline auto operator--() { return assign(data - 1); }
|
||||||
inline unsigned operator++(int) { unsigned r = data; assign(data + 1); return r; }
|
inline auto operator++(int) { unsigned r = data; assign(data + 1); return r; }
|
||||||
inline unsigned operator--(int) { unsigned r = data; assign(data - 1); return r; }
|
inline auto operator--(int) { unsigned r = data; assign(data - 1); return r; }
|
||||||
inline unsigned operator = (unsigned i) { return assign(i); }
|
inline auto operator = (unsigned i) { return assign(i); }
|
||||||
inline unsigned operator |= (unsigned i) { return assign(data | i); }
|
inline auto operator |= (unsigned i) { return assign(data | i); }
|
||||||
inline unsigned operator ^= (unsigned i) { return assign(data ^ i); }
|
inline auto operator ^= (unsigned i) { return assign(data ^ i); }
|
||||||
inline unsigned operator &= (unsigned i) { return assign(data & i); }
|
inline auto operator &= (unsigned i) { return assign(data & i); }
|
||||||
inline unsigned operator <<= (unsigned i) { return assign(data << i); }
|
inline auto operator <<= (unsigned i) { return assign(data << i); }
|
||||||
inline unsigned operator >>= (unsigned i) { return assign(data >> i); }
|
inline auto operator >>= (unsigned i) { return assign(data >> i); }
|
||||||
inline unsigned operator += (unsigned i) { return assign(data + i); }
|
inline auto operator += (unsigned i) { return assign(data + i); }
|
||||||
inline unsigned operator -= (unsigned i) { return assign(data - i); }
|
inline auto operator -= (unsigned i) { return assign(data - i); }
|
||||||
inline unsigned operator *= (unsigned i) { return assign(data * i); }
|
inline auto operator *= (unsigned i) { return assign(data * i); }
|
||||||
inline unsigned operator /= (unsigned i) { return assign(data / i); }
|
inline auto operator /= (unsigned i) { return assign(data / i); }
|
||||||
inline unsigned operator %= (unsigned i) { return assign(data % i); }
|
inline auto operator %= (unsigned i) { return assign(data % i); }
|
||||||
|
|
||||||
inline unsigned operator = (const reg16_t& i) { return assign(i); }
|
inline auto operator = (const reg16_t& i) { return assign(i); }
|
||||||
|
|
||||||
reg16_t() : data(0) {}
|
|
||||||
reg16_t(const reg16_t&) = delete;
|
reg16_t(const reg16_t&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,7 +53,7 @@ struct sfr_t {
|
||||||
| (r << 6) | (g << 5) | (ov << 4) | (s << 3) | (cy << 2) | (z << 1);
|
| (r << 6) | (g << 5) | (ov << 4) | (s << 3) | (cy << 2) | (z << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
sfr_t& operator=(uint16_t data) {
|
auto& operator=(uint16_t data) {
|
||||||
irq = data & 0x8000;
|
irq = data & 0x8000;
|
||||||
b = data & 0x1000;
|
b = data & 0x1000;
|
||||||
ih = data & 0x0800;
|
ih = data & 0x0800;
|
||||||
|
@ -78,7 +80,7 @@ struct scmr_t {
|
||||||
return ((ht >> 1) << 5) | (ron << 4) | (ran << 3) | ((ht & 1) << 2) | (md);
|
return ((ht >> 1) << 5) | (ron << 4) | (ran << 3) | ((ht & 1) << 2) | (md);
|
||||||
}
|
}
|
||||||
|
|
||||||
scmr_t& operator=(uint8 data) {
|
auto& operator=(uint8 data) {
|
||||||
ht = (bool)(data & 0x20) << 1;
|
ht = (bool)(data & 0x20) << 1;
|
||||||
ht |= (bool)(data & 0x04) << 0;
|
ht |= (bool)(data & 0x04) << 0;
|
||||||
ron = data & 0x10;
|
ron = data & 0x10;
|
||||||
|
@ -99,7 +101,7 @@ struct por_t {
|
||||||
return (obj << 4) | (freezehigh << 3) | (highnibble << 2) | (dither << 1) | (transparent);
|
return (obj << 4) | (freezehigh << 3) | (highnibble << 2) | (dither << 1) | (transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
por_t& operator=(uint8 data) {
|
auto& operator=(uint8 data) {
|
||||||
obj = data & 0x10;
|
obj = data & 0x10;
|
||||||
freezehigh = data & 0x08;
|
freezehigh = data & 0x08;
|
||||||
highnibble = data & 0x04;
|
highnibble = data & 0x04;
|
||||||
|
@ -117,7 +119,7 @@ struct cfgr_t {
|
||||||
return (irq << 7) | (ms0 << 5);
|
return (irq << 7) | (ms0 << 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
cfgr_t& operator=(uint8 data) {
|
auto& operator=(uint8 data) {
|
||||||
irq = data & 0x80;
|
irq = data & 0x80;
|
||||||
ms0 = data & 0x20;
|
ms0 = data & 0x20;
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -151,10 +153,10 @@ struct regs_t {
|
||||||
uint8 ramdr; //RAM buffer data register
|
uint8 ramdr; //RAM buffer data register
|
||||||
|
|
||||||
unsigned sreg, dreg;
|
unsigned sreg, dreg;
|
||||||
reg16_t& sr() { return r[sreg]; } //source register (from)
|
auto& sr() { return r[sreg]; } //source register (from)
|
||||||
reg16_t& dr() { return r[dreg]; } //destination register (to)
|
auto& dr() { return r[dreg]; } //destination register (to)
|
||||||
|
|
||||||
void reset() {
|
auto reset() -> void {
|
||||||
sfr.b = 0;
|
sfr.b = 0;
|
||||||
sfr.alt1 = 0;
|
sfr.alt1 = 0;
|
||||||
sfr.alt2 = 0;
|
sfr.alt2 = 0;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
void GSU::serialize(serializer& s) {
|
auto GSU::serialize(serializer& s) -> void {
|
||||||
|
s.integer(clockmode);
|
||||||
|
|
||||||
s.integer(regs.pipeline);
|
s.integer(regs.pipeline);
|
||||||
s.integer(regs.ramaddr);
|
s.integer(regs.ramaddr);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
void GSU::initialize_opcode_table() {
|
auto GSU::initialize_opcode_table() -> void {
|
||||||
#define op4(id, name) \
|
#define op4(id, name) \
|
||||||
op(id+ 0, name< 1>) op(id+ 1, name< 2>) op(id+ 2, name< 3>) op(id+ 3, name< 4>)
|
op(id+ 0, name< 1>) op(id+ 1, name< 2>) op(id+ 2, name< 3>) op(id+ 3, name< 4>)
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
//ROM / RAM access from the S-CPU
|
//ROM / RAM access from the S-CPU
|
||||||
|
|
||||||
unsigned SuperFX::CPUROM::size() const {
|
auto SuperFX::CPUROM::size() const -> unsigned {
|
||||||
return superfx.rom.size();
|
return superfx.rom.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SuperFX::CPUROM::read(unsigned addr) {
|
auto SuperFX::CPUROM::read(unsigned addr) -> uint8 {
|
||||||
if(superfx.regs.sfr.g && superfx.regs.scmr.ron) {
|
if(superfx.regs.sfr.g && superfx.regs.scmr.ron) {
|
||||||
static const uint8_t data[16] = {
|
static const uint8_t data[16] = {
|
||||||
0x00, 0x01, 0x00, 0x01, 0x04, 0x01, 0x00, 0x01,
|
0x00, 0x01, 0x00, 0x01, 0x04, 0x01, 0x00, 0x01,
|
||||||
|
@ -17,20 +17,20 @@ uint8 SuperFX::CPUROM::read(unsigned addr) {
|
||||||
return superfx.rom.read(addr);
|
return superfx.rom.read(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::CPUROM::write(unsigned addr, uint8 data) {
|
auto SuperFX::CPUROM::write(unsigned addr, uint8 data) -> void {
|
||||||
superfx.rom.write(addr, data);
|
superfx.rom.write(addr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned SuperFX::CPURAM::size() const {
|
auto SuperFX::CPURAM::size() const -> unsigned {
|
||||||
return superfx.ram.size();
|
return superfx.ram.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SuperFX::CPURAM::read(unsigned addr) {
|
auto SuperFX::CPURAM::read(unsigned addr) -> uint8 {
|
||||||
if(superfx.regs.sfr.g && superfx.regs.scmr.ran) return cpu.regs.mdr;
|
if(superfx.regs.sfr.g && superfx.regs.scmr.ran) return cpu.regs.mdr;
|
||||||
return superfx.ram.read(addr);
|
return superfx.ram.read(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::CPURAM::write(unsigned addr, uint8 data) {
|
auto SuperFX::CPURAM::write(unsigned addr, uint8 data) -> void {
|
||||||
superfx.ram.write(addr, data);
|
superfx.ram.write(addr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
struct CPUROM : Memory {
|
struct CPUROM : Memory {
|
||||||
unsigned size() const;
|
auto size() const -> unsigned;
|
||||||
uint8 read(unsigned);
|
auto read(unsigned) -> uint8;
|
||||||
void write(unsigned, uint8);
|
auto write(unsigned, uint8) -> void;
|
||||||
} cpurom;
|
} cpurom;
|
||||||
|
|
||||||
struct CPURAM : Memory {
|
struct CPURAM : Memory {
|
||||||
unsigned size() const;
|
auto size() const -> unsigned;
|
||||||
uint8 read(unsigned);
|
auto read(unsigned) -> uint8;
|
||||||
void write(unsigned, uint8);
|
auto write(unsigned, uint8) -> void;
|
||||||
} cpuram;
|
} cpuram;
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
#ifdef SUPERFX_CPP
|
#ifdef SUPERFX_CPP
|
||||||
|
|
||||||
void SuperFX::stop() {
|
auto SuperFX::stop() -> void {
|
||||||
cpu.regs.irq = 1;
|
cpu.regs.irq = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SuperFX::color(uint8 source) {
|
auto SuperFX::color(uint8 source) -> uint8 {
|
||||||
if(regs.por.highnibble) return (regs.colr & 0xf0) | (source >> 4);
|
if(regs.por.highnibble) return (regs.colr & 0xf0) | (source >> 4);
|
||||||
if(regs.por.freezehigh) return (regs.colr & 0xf0) | (source & 0x0f);
|
if(regs.por.freezehigh) return (regs.colr & 0xf0) | (source & 0x0f);
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::plot(uint8 x, uint8 y) {
|
auto SuperFX::plot(uint8 x, uint8 y) -> void {
|
||||||
uint8 color = regs.colr;
|
uint8 color = regs.colr;
|
||||||
|
|
||||||
if(regs.por.dither && regs.scmr.md != 3) {
|
if(regs.por.dither && regs.scmr.md != 3) {
|
||||||
|
@ -48,7 +48,7 @@ void SuperFX::plot(uint8 x, uint8 y) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SuperFX::rpix(uint8 x, uint8 y) {
|
auto SuperFX::rpix(uint8 x, uint8 y) -> uint8 {
|
||||||
pixelcache_flush(pixelcache[1]);
|
pixelcache_flush(pixelcache[1]);
|
||||||
pixelcache_flush(pixelcache[0]);
|
pixelcache_flush(pixelcache[0]);
|
||||||
|
|
||||||
|
@ -66,14 +66,14 @@ uint8 SuperFX::rpix(uint8 x, uint8 y) {
|
||||||
|
|
||||||
for(unsigned n = 0; n < bpp; n++) {
|
for(unsigned n = 0; n < bpp; n++) {
|
||||||
unsigned byte = ((n >> 1) << 4) + (n & 1); // = [n]{ 0, 1, 16, 17, 32, 33, 48, 49 };
|
unsigned byte = ((n >> 1) << 4) + (n & 1); // = [n]{ 0, 1, 16, 17, 32, 33, 48, 49 };
|
||||||
step(memory_access_speed);
|
step(memory_access_speed());
|
||||||
data |= ((bus_read(addr + byte) >> x) & 1) << n;
|
data |= ((bus_read(addr + byte) >> x) & 1) << n;
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::pixelcache_flush(pixelcache_t& cache) {
|
auto SuperFX::pixelcache_flush(pixelcache_t& cache) -> void {
|
||||||
if(cache.bitpend == 0x00) return;
|
if(cache.bitpend == 0x00) return;
|
||||||
|
|
||||||
uint8 x = cache.offset << 3;
|
uint8 x = cache.offset << 3;
|
||||||
|
@ -94,11 +94,11 @@ void SuperFX::pixelcache_flush(pixelcache_t& cache) {
|
||||||
uint8 data = 0x00;
|
uint8 data = 0x00;
|
||||||
for(unsigned x = 0; x < 8; x++) data |= ((cache.data[x] >> n) & 1) << x;
|
for(unsigned x = 0; x < 8; x++) data |= ((cache.data[x] >> n) & 1) << x;
|
||||||
if(cache.bitpend != 0xff) {
|
if(cache.bitpend != 0xff) {
|
||||||
step(memory_access_speed);
|
step(memory_access_speed());
|
||||||
data &= cache.bitpend;
|
data &= cache.bitpend;
|
||||||
data |= bus_read(addr + byte) & ~cache.bitpend;
|
data |= bus_read(addr + byte) & ~cache.bitpend;
|
||||||
}
|
}
|
||||||
step(memory_access_speed);
|
step(memory_access_speed());
|
||||||
bus_write(addr + byte, data);
|
bus_write(addr + byte, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
void stop();
|
auto stop() -> void;
|
||||||
uint8 color(uint8 source);
|
auto color(uint8 source) -> uint8;
|
||||||
void plot(uint8 x, uint8 y);
|
auto plot(uint8 x, uint8 y) -> void;
|
||||||
uint8 rpix(uint8 x, uint8 y);
|
auto rpix(uint8 x, uint8 y) -> uint8;
|
||||||
void pixelcache_flush(pixelcache_t& cache);
|
auto pixelcache_flush(pixelcache_t& cache) -> void;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
//TODO: this belongs in processor/gsu
|
//TODO: this belongs in processor/gsu
|
||||||
|
|
||||||
void SuperFX::disassemble_opcode(char* output) {
|
auto SuperFX::disassemble_opcode(char* output) -> void {
|
||||||
*output = 0;
|
*output = 0;
|
||||||
|
|
||||||
if(!regs.sfr.alt2) {
|
if(!regs.sfr.alt2) {
|
||||||
|
@ -41,7 +41,7 @@ void SuperFX::disassemble_opcode(char* output) {
|
||||||
#define op1 bus_read((regs.pbr << 16) + regs.r[15] + 0)
|
#define op1 bus_read((regs.pbr << 16) + regs.r[15] + 0)
|
||||||
#define op2 bus_read((regs.pbr << 16) + regs.r[15] + 1)
|
#define op2 bus_read((regs.pbr << 16) + regs.r[15] + 1)
|
||||||
|
|
||||||
void SuperFX::disassemble_alt0(char* output) {
|
auto SuperFX::disassemble_alt0(char* output) -> void {
|
||||||
char t[256] = "";
|
char t[256] = "";
|
||||||
switch(op0) {
|
switch(op0) {
|
||||||
case (0x00): sprintf(t, "stop"); break;
|
case (0x00): sprintf(t, "stop"); break;
|
||||||
|
@ -98,7 +98,7 @@ void SuperFX::disassemble_alt0(char* output) {
|
||||||
strcat(output, t);
|
strcat(output, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::disassemble_alt1(char* output) {
|
auto SuperFX::disassemble_alt1(char* output) -> void {
|
||||||
char t[256] = "";
|
char t[256] = "";
|
||||||
switch(op0) {
|
switch(op0) {
|
||||||
case (0x00): sprintf(t, "stop"); break;
|
case (0x00): sprintf(t, "stop"); break;
|
||||||
|
@ -155,7 +155,7 @@ void SuperFX::disassemble_alt1(char* output) {
|
||||||
strcat(output, t);
|
strcat(output, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::disassemble_alt2(char* output) {
|
auto SuperFX::disassemble_alt2(char* output) -> void {
|
||||||
char t[256] = "";
|
char t[256] = "";
|
||||||
switch(op0) {
|
switch(op0) {
|
||||||
case (0x00): sprintf(t, "stop"); break;
|
case (0x00): sprintf(t, "stop"); break;
|
||||||
|
@ -212,7 +212,7 @@ void SuperFX::disassemble_alt2(char* output) {
|
||||||
strcat(output, t);
|
strcat(output, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::disassemble_alt3(char* output) {
|
auto SuperFX::disassemble_alt3(char* output) -> void {
|
||||||
char t[256] = "";
|
char t[256] = "";
|
||||||
switch(op0) {
|
switch(op0) {
|
||||||
case (0x00): sprintf(t, "stop"); break;
|
case (0x00): sprintf(t, "stop"); break;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
void disassemble_opcode(char* output);
|
auto disassemble_opcode(char* output) -> void;
|
||||||
void disassemble_alt0(char* output);
|
auto disassemble_alt0(char* output) -> void;
|
||||||
void disassemble_alt1(char* output);
|
auto disassemble_alt1(char* output) -> void;
|
||||||
void disassemble_alt2(char* output);
|
auto disassemble_alt2(char* output) -> void;
|
||||||
void disassemble_alt3(char* output);
|
auto disassemble_alt3(char* output) -> void;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#ifdef SUPERFX_CPP
|
#ifdef SUPERFX_CPP
|
||||||
|
|
||||||
uint8 SuperFX::bus_read(unsigned addr) {
|
auto SuperFX::bus_read(unsigned addr) -> uint8 {
|
||||||
if((addr & 0xc00000) == 0x000000) { //$00-3f:0000-7fff, $00-3f:8000-ffff
|
if((addr & 0xc00000) == 0x000000) { //$00-3f:0000-7fff, $00-3f:8000-ffff
|
||||||
while(!regs.scmr.ron && scheduler.sync != Scheduler::SynchronizeMode::All) {
|
while(!regs.scmr.ron && scheduler.sync != Scheduler::SynchronizeMode::All) {
|
||||||
step(6);
|
step(6);
|
||||||
|
@ -26,7 +26,7 @@ uint8 SuperFX::bus_read(unsigned addr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::bus_write(unsigned addr, uint8 data) {
|
auto SuperFX::bus_write(unsigned addr, uint8 data) -> void {
|
||||||
if((addr & 0xe00000) == 0x600000) { //$60-7f:0000-ffff
|
if((addr & 0xe00000) == 0x600000) { //$60-7f:0000-ffff
|
||||||
while(!regs.scmr.ran && scheduler.sync != Scheduler::SynchronizeMode::All) {
|
while(!regs.scmr.ran && scheduler.sync != Scheduler::SynchronizeMode::All) {
|
||||||
step(6);
|
step(6);
|
||||||
|
@ -36,19 +36,19 @@ void SuperFX::bus_write(unsigned addr, uint8 data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SuperFX::op_read(uint16 addr) {
|
auto SuperFX::op_read(uint16 addr) -> uint8 {
|
||||||
uint16 offset = addr - regs.cbr;
|
uint16 offset = addr - regs.cbr;
|
||||||
if(offset < 512) {
|
if(offset < 512) {
|
||||||
if(cache.valid[offset >> 4] == false) {
|
if(cache.valid[offset >> 4] == false) {
|
||||||
unsigned dp = offset & 0xfff0;
|
unsigned dp = offset & 0xfff0;
|
||||||
unsigned sp = (regs.pbr << 16) + ((regs.cbr + dp) & 0xfff0);
|
unsigned sp = (regs.pbr << 16) + ((regs.cbr + dp) & 0xfff0);
|
||||||
for(unsigned n = 0; n < 16; n++) {
|
for(unsigned n = 0; n < 16; n++) {
|
||||||
step(memory_access_speed);
|
step(memory_access_speed());
|
||||||
cache.buffer[dp++] = bus_read(sp++);
|
cache.buffer[dp++] = bus_read(sp++);
|
||||||
}
|
}
|
||||||
cache.valid[offset >> 4] = true;
|
cache.valid[offset >> 4] = true;
|
||||||
} else {
|
} else {
|
||||||
step(cache_access_speed);
|
step(cache_access_speed());
|
||||||
}
|
}
|
||||||
return cache.buffer[offset];
|
return cache.buffer[offset];
|
||||||
}
|
}
|
||||||
|
@ -56,46 +56,46 @@ uint8 SuperFX::op_read(uint16 addr) {
|
||||||
if(regs.pbr <= 0x5f) {
|
if(regs.pbr <= 0x5f) {
|
||||||
//$[00-5f]:[0000-ffff] ROM
|
//$[00-5f]:[0000-ffff] ROM
|
||||||
rombuffer_sync();
|
rombuffer_sync();
|
||||||
step(memory_access_speed);
|
step(memory_access_speed());
|
||||||
return bus_read((regs.pbr << 16) + addr);
|
return bus_read((regs.pbr << 16) + addr);
|
||||||
} else {
|
} else {
|
||||||
//$[60-7f]:[0000-ffff] RAM
|
//$[60-7f]:[0000-ffff] RAM
|
||||||
rambuffer_sync();
|
rambuffer_sync();
|
||||||
step(memory_access_speed);
|
step(memory_access_speed());
|
||||||
return bus_read((regs.pbr << 16) + addr);
|
return bus_read((regs.pbr << 16) + addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SuperFX::peekpipe() {
|
auto SuperFX::peekpipe() -> uint8 {
|
||||||
uint8 result = regs.pipeline;
|
uint8 result = regs.pipeline;
|
||||||
regs.pipeline = op_read(regs.r[15]);
|
regs.pipeline = op_read(regs.r[15]);
|
||||||
r15_modified = false;
|
r15_modified = false;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SuperFX::pipe() {
|
auto SuperFX::pipe() -> uint8 {
|
||||||
uint8 result = regs.pipeline;
|
uint8 result = regs.pipeline;
|
||||||
regs.pipeline = op_read(++regs.r[15]);
|
regs.pipeline = op_read(++regs.r[15]);
|
||||||
r15_modified = false;
|
r15_modified = false;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::cache_flush() {
|
auto SuperFX::cache_flush() -> void {
|
||||||
for(unsigned n = 0; n < 32; n++) cache.valid[n] = false;
|
for(unsigned n = 0; n < 32; n++) cache.valid[n] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SuperFX::cache_mmio_read(uint16 addr) {
|
auto SuperFX::cache_mmio_read(uint16 addr) -> uint8 {
|
||||||
addr = (addr + regs.cbr) & 511;
|
addr = (addr + regs.cbr) & 511;
|
||||||
return cache.buffer[addr];
|
return cache.buffer[addr];
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::cache_mmio_write(uint16 addr, uint8 data) {
|
auto SuperFX::cache_mmio_write(uint16 addr, uint8 data) -> void {
|
||||||
addr = (addr + regs.cbr) & 511;
|
addr = (addr + regs.cbr) & 511;
|
||||||
cache.buffer[addr] = data;
|
cache.buffer[addr] = data;
|
||||||
if((addr & 15) == 15) cache.valid[addr >> 4] = true;
|
if((addr & 15) == 15) cache.valid[addr >> 4] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::memory_reset() {
|
auto SuperFX::memory_reset() -> void {
|
||||||
rom_mask = rom.size() - 1;
|
rom_mask = rom.size() - 1;
|
||||||
ram_mask = ram.size() - 1;
|
ram_mask = ram.size() - 1;
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
unsigned rom_mask; //rom_size - 1
|
unsigned rom_mask; //rom_size - 1
|
||||||
unsigned ram_mask; //ram_size - 1
|
unsigned ram_mask; //ram_size - 1
|
||||||
uint8 bus_read(unsigned addr);
|
|
||||||
void bus_write(unsigned addr, uint8 data);
|
|
||||||
|
|
||||||
uint8 op_read(uint16 addr);
|
auto bus_read(unsigned addr) -> uint8;
|
||||||
alwaysinline uint8 peekpipe();
|
auto bus_write(unsigned addr, uint8 data) -> void;
|
||||||
alwaysinline uint8 pipe();
|
|
||||||
|
|
||||||
void cache_flush();
|
auto op_read(uint16 addr) -> uint8;
|
||||||
uint8 cache_mmio_read(uint16 addr);
|
alwaysinline auto peekpipe() -> uint8;
|
||||||
void cache_mmio_write(uint16 addr, uint8 data);
|
alwaysinline auto pipe() -> uint8;
|
||||||
|
|
||||||
void memory_reset();
|
auto cache_flush() -> void;
|
||||||
|
auto cache_mmio_read(uint16 addr) -> uint8;
|
||||||
|
auto cache_mmio_write(uint16 addr, uint8 data) -> void;
|
||||||
|
|
||||||
|
auto memory_reset() -> void;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#ifdef SUPERFX_CPP
|
#ifdef SUPERFX_CPP
|
||||||
|
|
||||||
uint8 SuperFX::mmio_read(unsigned addr) {
|
auto SuperFX::mmio_read(unsigned addr) -> uint8 {
|
||||||
cpu.synchronize_coprocessors();
|
cpu.synchronize_coprocessors();
|
||||||
addr &= 0xffff;
|
addr &= 0xffff;
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ uint8 SuperFX::mmio_read(unsigned addr) {
|
||||||
return 0x00;
|
return 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::mmio_write(unsigned addr, uint8 data) {
|
auto SuperFX::mmio_write(unsigned addr, uint8 data) -> void {
|
||||||
cpu.synchronize_coprocessors();
|
cpu.synchronize_coprocessors();
|
||||||
addr &= 0xffff;
|
addr &= 0xffff;
|
||||||
|
|
||||||
|
@ -97,7 +97,6 @@ void SuperFX::mmio_write(unsigned addr, uint8 data) {
|
||||||
|
|
||||||
case 0x3037: {
|
case 0x3037: {
|
||||||
regs.cfgr = data;
|
regs.cfgr = data;
|
||||||
update_speed();
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 0x3038: {
|
case 0x3038: {
|
||||||
|
@ -106,7 +105,6 @@ void SuperFX::mmio_write(unsigned addr, uint8 data) {
|
||||||
|
|
||||||
case 0x3039: {
|
case 0x3039: {
|
||||||
regs.clsr = data;
|
regs.clsr = data;
|
||||||
update_speed();
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 0x303a: {
|
case 0x303a: {
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
uint8 mmio_read(unsigned addr);
|
auto mmio_read(unsigned addr) -> uint8;
|
||||||
void mmio_write(unsigned addr, uint8 data);
|
auto mmio_write(unsigned addr, uint8 data) -> void;
|
||||||
|
|
|
@ -1,16 +1,11 @@
|
||||||
#ifdef SUPERFX_CPP
|
#ifdef SUPERFX_CPP
|
||||||
|
|
||||||
void SuperFX::serialize(serializer& s) {
|
auto SuperFX::serialize(serializer& s) -> void {
|
||||||
GSU::serialize(s);
|
GSU::serialize(s);
|
||||||
Thread::serialize(s);
|
Thread::serialize(s);
|
||||||
|
|
||||||
s.array(ram.data(), ram.size());
|
s.array(ram.data(), ram.size());
|
||||||
|
|
||||||
s.integer(clockmode);
|
|
||||||
s.integer(instruction_counter);
|
s.integer(instruction_counter);
|
||||||
|
|
||||||
s.integer(cache_access_speed);
|
|
||||||
s.integer(memory_access_speed);
|
|
||||||
s.integer(r15_modified);
|
s.integer(r15_modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,11 @@ namespace SuperFamicom {
|
||||||
|
|
||||||
SuperFX superfx;
|
SuperFX superfx;
|
||||||
|
|
||||||
void SuperFX::Enter() { superfx.enter(); }
|
auto SuperFX::Enter() -> void {
|
||||||
|
superfx.enter();
|
||||||
|
}
|
||||||
|
|
||||||
void SuperFX::enter() {
|
auto SuperFX::enter() -> void {
|
||||||
while(true) {
|
while(true) {
|
||||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||||
|
@ -37,25 +39,25 @@ void SuperFX::enter() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::init() {
|
auto SuperFX::init() -> void {
|
||||||
initialize_opcode_table();
|
initialize_opcode_table();
|
||||||
regs.r[14].modify = {&SuperFX::r14_modify, this};
|
regs.r[14].modify = {&SuperFX::r14_modify, this};
|
||||||
regs.r[15].modify = {&SuperFX::r15_modify, this};
|
regs.r[15].modify = {&SuperFX::r15_modify, this};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::load() {
|
auto SuperFX::load() -> void {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::unload() {
|
auto SuperFX::unload() -> void {
|
||||||
rom.reset();
|
rom.reset();
|
||||||
ram.reset();
|
ram.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::power() {
|
auto SuperFX::power() -> void {
|
||||||
GSU::power();
|
GSU::power();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::reset() {
|
auto SuperFX::reset() -> void {
|
||||||
GSU::reset();
|
GSU::reset();
|
||||||
create(SuperFX::Enter, system.cpu_frequency());
|
create(SuperFX::Enter, system.cpu_frequency());
|
||||||
instruction_counter = 0;
|
instruction_counter = 0;
|
||||||
|
|
|
@ -9,18 +9,21 @@ struct SuperFX : Processor::GSU, Coprocessor {
|
||||||
#include "timing/timing.hpp"
|
#include "timing/timing.hpp"
|
||||||
#include "disassembler/disassembler.hpp"
|
#include "disassembler/disassembler.hpp"
|
||||||
|
|
||||||
static void Enter();
|
//superfx.cpp
|
||||||
void enter();
|
static auto Enter() -> void;
|
||||||
void init();
|
|
||||||
void load();
|
auto enter() -> void;
|
||||||
void unload();
|
auto init() -> void;
|
||||||
void power();
|
auto load() -> void;
|
||||||
void reset();
|
auto unload() -> void;
|
||||||
void serialize(serializer&);
|
auto power() -> void;
|
||||||
|
auto reset() -> void;
|
||||||
|
|
||||||
|
//serialization.cpp
|
||||||
|
auto serialize(serializer&) -> void;
|
||||||
|
|
||||||
privileged:
|
privileged:
|
||||||
unsigned clockmode = 0; //0 = selectable, 1 = force 10.74mhz, 2 = force 21.48mhz
|
unsigned instruction_counter = 0;
|
||||||
unsigned instruction_counter;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern SuperFX superfx;
|
extern SuperFX superfx;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#ifdef SUPERFX_CPP
|
#ifdef SUPERFX_CPP
|
||||||
|
|
||||||
void SuperFX::step(unsigned clocks) {
|
auto SuperFX::step(unsigned clocks) -> void {
|
||||||
if(regs.romcl) {
|
if(regs.romcl) {
|
||||||
regs.romcl -= min(clocks, regs.romcl);
|
regs.romcl -= min(clocks, regs.romcl);
|
||||||
if(regs.romcl == 0) {
|
if(regs.romcl == 0) {
|
||||||
|
@ -20,70 +20,47 @@ void SuperFX::step(unsigned clocks) {
|
||||||
synchronize_cpu();
|
synchronize_cpu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::rombuffer_sync() {
|
auto SuperFX::rombuffer_sync() -> void {
|
||||||
if(regs.romcl) step(regs.romcl);
|
if(regs.romcl) step(regs.romcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::rombuffer_update() {
|
auto SuperFX::rombuffer_update() -> void {
|
||||||
regs.sfr.r = 1;
|
regs.sfr.r = 1;
|
||||||
regs.romcl = memory_access_speed;
|
regs.romcl = memory_access_speed();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SuperFX::rombuffer_read() {
|
auto SuperFX::rombuffer_read() -> uint8 {
|
||||||
rombuffer_sync();
|
rombuffer_sync();
|
||||||
return regs.romdr;
|
return regs.romdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::rambuffer_sync() {
|
auto SuperFX::rambuffer_sync() -> void {
|
||||||
if(regs.ramcl) step(regs.ramcl);
|
if(regs.ramcl) step(regs.ramcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SuperFX::rambuffer_read(uint16 addr) {
|
auto SuperFX::rambuffer_read(uint16 addr) -> uint8 {
|
||||||
rambuffer_sync();
|
rambuffer_sync();
|
||||||
return bus_read(0x700000 + (regs.rambr << 16) + addr);
|
return bus_read(0x700000 + (regs.rambr << 16) + addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::rambuffer_write(uint16 addr, uint8 data) {
|
auto SuperFX::rambuffer_write(uint16 addr, uint8 data) -> void {
|
||||||
rambuffer_sync();
|
rambuffer_sync();
|
||||||
regs.ramcl = memory_access_speed;
|
regs.ramcl = memory_access_speed();
|
||||||
regs.ramar = addr;
|
regs.ramar = addr;
|
||||||
regs.ramdr = data;
|
regs.ramdr = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::r14_modify(uint16 data) {
|
auto SuperFX::r14_modify(uint16 data) -> void {
|
||||||
regs.r[14].data = data;
|
regs.r[14].data = data;
|
||||||
rombuffer_update();
|
rombuffer_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::r15_modify(uint16 data) {
|
auto SuperFX::r15_modify(uint16 data) -> void {
|
||||||
regs.r[15].data = data;
|
regs.r[15].data = data;
|
||||||
r15_modified = true;
|
r15_modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::update_speed() {
|
auto SuperFX::timing_reset() -> void {
|
||||||
//force SuperFX1 mode?
|
|
||||||
if(clockmode == 1) {
|
|
||||||
cache_access_speed = 2;
|
|
||||||
memory_access_speed = 6;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//force SuperFX2 mode?
|
|
||||||
if(clockmode == 2) {
|
|
||||||
cache_access_speed = 1;
|
|
||||||
memory_access_speed = 5;
|
|
||||||
regs.cfgr.ms0 = 0; //cannot use high-speed multiplication in 21MHz mode
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//default: allow S-CPU to select mode
|
|
||||||
cache_access_speed = (regs.clsr ? 1 : 2);
|
|
||||||
memory_access_speed = (regs.clsr ? 5 : 6);
|
|
||||||
if(regs.clsr) regs.cfgr.ms0 = 0; //cannot use high-speed multiplication in 21MHz mode
|
|
||||||
}
|
|
||||||
|
|
||||||
void SuperFX::timing_reset() {
|
|
||||||
update_speed();
|
|
||||||
r15_modified = false;
|
r15_modified = false;
|
||||||
|
|
||||||
regs.romcl = 0;
|
regs.romcl = 0;
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
unsigned cache_access_speed;
|
bool r15_modified = false;
|
||||||
unsigned memory_access_speed;
|
|
||||||
bool r15_modified;
|
|
||||||
|
|
||||||
void step(unsigned clocks);
|
auto step(unsigned clocks) -> void;
|
||||||
|
|
||||||
void rombuffer_sync();
|
auto rombuffer_sync() -> void;
|
||||||
void rombuffer_update();
|
auto rombuffer_update() -> void;
|
||||||
uint8 rombuffer_read();
|
auto rombuffer_read() -> uint8;
|
||||||
|
|
||||||
void rambuffer_sync();
|
auto rambuffer_sync() -> void;
|
||||||
uint8 rambuffer_read(uint16 addr);
|
auto rambuffer_read(uint16 addr) -> uint8;
|
||||||
void rambuffer_write(uint16 addr, uint8 data);
|
auto rambuffer_write(uint16 addr, uint8 data) -> void;
|
||||||
|
|
||||||
void r14_modify(uint16);
|
auto r14_modify(uint16) -> void;
|
||||||
void r15_modify(uint16);
|
auto r15_modify(uint16) -> void;
|
||||||
|
|
||||||
void update_speed();
|
auto timing_reset() -> void;
|
||||||
void timing_reset();
|
|
||||||
|
|
Loading…
Reference in New Issue