Update to v089r09 release.

byuu says:

Changelog:
- SPC7110 data port emulation greatly improved
- SPC7110 $480b.d1 emulated (but $4805-4806 does not work right for mode
  2 decompression yet)
- MSU1 audio output will be muted when the S-DSP FLG ($6c).d6 (mute)
  flag is set
- MSU1 will read filenames from manifest now (defaults to msu1.rom and
  track-#.pcm if missing ... for now)
- bugfixes with MSU1 load state and track seek (and $4804 was wrapping
  into $4805 to change the track#)
- Link coprocessor removed (it was meant for ST018 HLE, which never
  happened)

Notes for things I forgot but need to address:
- $4813 needs to be uint7 for the set_data_offset() to not allow reading
  A23 as set ever (or we can mask)
- AbsoluteInput when window doesn't have focus should return -32768, not
  0
- need to support input ID lists that aren't linear (0-7), but arbitrary
  (0,1,6,7 or whatever)
This commit is contained in:
Tim Allen 2012-05-29 22:20:46 +10:00
parent 189e707594
commit 3302398907
22 changed files with 168 additions and 258 deletions

View File

@ -3,7 +3,7 @@
namespace Emulator {
static const char Name[] = "bsnes";
static const char Version[] = "089.08";
static const char Version[] = "089.09";
static const char Author[] = "byuu";
static const char License[] = "GPLv3";
}

View File

@ -6,7 +6,7 @@ sfc_objects += sfc-sa1 sfc-superfx
sfc_objects += sfc-armdsp sfc-hitachidsp sfc-necdsp
sfc_objects += sfc-epsonrtc sfc-sharprtc
sfc_objects += sfc-spc7110 sfc-sdd1 sfc-obc1
sfc_objects += sfc-msu1 sfc-link
sfc_objects += sfc-msu1
objects += $(sfc_objects)
ifeq ($(profile),accuracy)
@ -60,4 +60,3 @@ obj/sfc-sdd1.o : $(sfc)/chip/sdd1/sdd1.cpp $(sfc)/chip/sdd1/*
obj/sfc-obc1.o : $(sfc)/chip/obc1/obc1.cpp $(sfc)/chip/obc1/*
obj/sfc-msu1.o : $(sfc)/chip/msu1/msu1.cpp $(sfc)/chip/msu1/*
obj/sfc-link.o : $(sfc)/chip/link/link.cpp $(sfc)/chip/link/*

View File

@ -231,6 +231,9 @@ private:
void echo_30();
void soft_reset_common();
public:
bool mute() { return m.regs[r_flg] & 0x40; }
};
#include <assert.h>

View File

@ -31,6 +31,10 @@ void DSP::enter() {
}
}
bool DSP::mute() {
return spc_dsp.mute();
}
uint8 DSP::read(uint8 addr) {
return spc_dsp.read(addr);
}

View File

@ -5,6 +5,7 @@ struct DSP : Thread {
alwaysinline void step(unsigned clocks);
alwaysinline void synchronize_smp();
bool mute();
uint8 read(uint8 addr);
void write(uint8 addr, uint8 data);

View File

@ -26,8 +26,8 @@ void Cartridge::load(const string &manifest) {
has_sdd1 = false;
has_obc1 = false;
has_msu1 = false;
has_link = false;
this->manifest = manifest;
parse_markup(manifest);
//print(manifest, "\n\n");

View File

@ -18,6 +18,7 @@ struct Cartridge : property<Cartridge> {
readonly<bool> loaded;
readonly<string> sha256;
readonly<string> manifest;
readonly<Region> region;
@ -37,7 +38,6 @@ struct Cartridge : property<Cartridge> {
readonly<bool> has_sdd1;
readonly<bool> has_obc1;
readonly<bool> has_msu1;
readonly<bool> has_link;
struct Mapping {
function<uint8 (unsigned)> read;
@ -95,7 +95,6 @@ private:
void parse_markup_sdd1(XML::Node&);
void parse_markup_obc1(XML::Node&);
void parse_markup_msu1(XML::Node&);
void parse_markup_link(XML::Node&);
};
extern Cartridge cartridge;

View File

@ -24,7 +24,6 @@ void Cartridge::parse_markup(const char *markup) {
parse_markup_sdd1(cartridge["sdd1"]);
parse_markup_obc1(cartridge["obc1"]);
parse_markup_msu1(cartridge["msu1"]);
parse_markup_link(cartridge["link"]);
}
//
@ -294,7 +293,7 @@ void Cartridge::parse_markup_armdsp(XML::Node &root) {
for(auto &node : root) {
if(node.name != "map") continue;
Mapping m({ &ArmDSP::mmio_read, &armdsp }, { &ArmDSP::mmio_write, &armdsp });
Mapping m({&ArmDSP::mmio_read, &armdsp}, {&ArmDSP::mmio_write, &armdsp});
parse_markup_map(m, node);
mapping.append(m);
}
@ -317,14 +316,14 @@ void Cartridge::parse_markup_hitachidsp(XML::Node &root) {
if(node.name == "rom") {
for(auto &leaf : node) {
if(leaf.name != "map") continue;
Mapping m({ &HitachiDSP::rom_read, &hitachidsp }, { &HitachiDSP::rom_write, &hitachidsp });
Mapping m({&HitachiDSP::rom_read, &hitachidsp}, {&HitachiDSP::rom_write, &hitachidsp});
parse_markup_map(m, leaf);
mapping.append(m);
}
}
if(node.name == "mmio") {
for(auto &leaf : node) {
Mapping m({ &HitachiDSP::dsp_read, &hitachidsp }, { &HitachiDSP::dsp_write, &hitachidsp });
Mapping m({&HitachiDSP::dsp_read, &hitachidsp}, {&HitachiDSP::dsp_write, &hitachidsp});
parse_markup_map(m, leaf);
mapping.append(m);
}
@ -362,21 +361,21 @@ void Cartridge::parse_markup_necdsp(XML::Node &root) {
for(auto &node : root) {
if(node.name == "dr") {
for(auto &leaf : node) {
Mapping m({ &NECDSP::dr_read, &necdsp }, { &NECDSP::dr_write, &necdsp });
Mapping m({&NECDSP::dr_read, &necdsp}, {&NECDSP::dr_write, &necdsp});
parse_markup_map(m, leaf);
mapping.append(m);
}
}
if(node.name == "sr") {
for(auto &leaf : node) {
Mapping m({ &NECDSP::sr_read, &necdsp }, { &NECDSP::sr_write, &necdsp });
Mapping m({&NECDSP::sr_read, &necdsp}, {&NECDSP::sr_write, &necdsp});
parse_markup_map(m, leaf);
mapping.append(m);
}
}
if(node.name == "dp") {
for(auto &leaf : node) {
Mapping m({ &NECDSP::dp_read, &necdsp }, { &NECDSP::dp_write, &necdsp });
Mapping m({&NECDSP::dp_read, &necdsp}, {&NECDSP::dp_write, &necdsp});
parse_markup_map(m, leaf);
mapping.append(m);
}
@ -466,14 +465,14 @@ void Cartridge::parse_markup_sdd1(XML::Node &root) {
for(auto &node : root["mmio"]) {
if(node.name != "map") continue;
Mapping m({ &SDD1::mmio_read, &sdd1 }, { &SDD1::mmio_write, &sdd1 });
Mapping m({&SDD1::mmio_read, &sdd1}, {&SDD1::mmio_write, &sdd1});
parse_markup_map(m, node);
mapping.append(m);
}
for(auto &node : root["mcu"]) {
if(node.name != "map") continue;
Mapping m({ &SDD1::mcu_read, &sdd1 }, { &SDD1::mcu_write, &sdd1 });
Mapping m({&SDD1::mcu_read, &sdd1}, {&SDD1::mcu_write, &sdd1});
parse_markup_map(m, node);
mapping.append(m);
}
@ -485,45 +484,19 @@ void Cartridge::parse_markup_obc1(XML::Node &root) {
for(auto &node : root) {
if(node.name != "map") continue;
Mapping m({ &OBC1::read, &obc1 }, { &OBC1::write, &obc1 });
Mapping m({&OBC1::read, &obc1}, {&OBC1::write, &obc1});
parse_markup_map(m, node);
mapping.append(m);
}
}
void Cartridge::parse_markup_msu1(XML::Node &root) {
if(root.exists() == false) {
has_msu1 = file::exists({interface->path(0), "msu1.rom"});
if(has_msu1) {
Mapping m({ &MSU1::mmio_read, &msu1 }, { &MSU1::mmio_write, &msu1 });
m.banklo = 0x00, m.bankhi = 0x3f, m.addrlo = 0x2000, m.addrhi = 0x2007;
mapping.append(m);
m.banklo = 0x80, m.bankhi = 0xbf, m.addrlo = 0x2000, m.addrhi = 0x2007;
mapping.append(m);
}
return;
}
if(root.exists() == false) return;
has_msu1 = true;
for(auto &node : root) {
if(node.name != "map") continue;
Mapping m({ &MSU1::mmio_read, &msu1 }, { &MSU1::mmio_write, &msu1 });
parse_markup_map(m, node);
mapping.append(m);
}
}
void Cartridge::parse_markup_link(XML::Node &root) {
if(root.exists() == false) return;
has_link = true;
link.frequency = max(1, numeral(root["frequency"].data));
link.program = root["program"].data;
for(auto &node : root) {
if(node.name != "map") continue;
Mapping m({ &Link::read, &link }, { &Link::write, &link });
Mapping m({&MSU1::mmio_read, &msu1}, {&MSU1::mmio_write, &msu1});
parse_markup_map(m, node);
mapping.append(m);
}

View File

@ -23,7 +23,6 @@ struct Coprocessor : Thread {
#include <sfc/chip/obc1/obc1.hpp>
#include <sfc/chip/msu1/msu1.hpp>
#include <sfc/chip/link/link.hpp>
void Coprocessor::step(unsigned clocks) {
clock += clocks * (uint64)cpu.frequency;

View File

@ -1,56 +0,0 @@
#include <sfc/sfc.hpp>
#define LINK_HPP
namespace SuperFamicom {
Link link;
void Link::Enter() { link.enter(); }
void Link::enter() {
while(true) {
cpu.synchronize_coprocessors();
unsigned clocks = 1;
if(link_run) clocks = link_run();
step(clocks);
synchronize_cpu();
}
}
void Link::init() {
}
void Link::load() {
if(opened()) close();
if(open("link.so", interface->path(0))) {
link_power = sym("link_power");
link_reset = sym("link_reset");
link_run = sym("link_run" );
link_read = sym("link_read" );
link_write = sym("link_write");
}
}
void Link::unload() {
if(opened()) close();
}
void Link::power() {
if(link_power) link_power();
}
void Link::reset() {
if(link_reset) link_reset();
create(Link::Enter, frequency);
}
uint8 Link::read(unsigned addr) {
if(link_read) return link_read(addr);
return cpu.regs.mdr;
}
void Link::write(unsigned addr, uint8 data) {
if(link_write) return link_write(addr, data);
}
}

View File

@ -1,23 +0,0 @@
struct Link : Coprocessor, library {
string program;
static void Enter();
void enter();
void init();
void load();
void unload();
void power();
void reset();
uint8 read(unsigned addr);
void write(unsigned addr, uint8 data);
private:
function<void ()> link_power;
function<void ()> link_reset;
function<unsigned ()> link_run;
function<uint8 (unsigned)> link_read;
function<void (unsigned, uint8)> link_write;
};
extern Link link;

View File

@ -10,7 +10,10 @@ MSU1 msu1;
void MSU1::Enter() { msu1.enter(); }
void MSU1::enter() {
for(unsigned addr = 0; addr <= 7; addr++) mmio_write(addr, 0x00);
if(boot == true) {
boot = false;
for(unsigned addr = 0x2000; addr <= 0x2007; addr++) mmio_write(addr, 0x00);
}
while(true) {
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
@ -42,6 +45,7 @@ void MSU1::enter() {
signed rchannel = (double)right * (double)mmio.audio_volume / 255.0;
left = sclamp<16>(lchannel);
right = sclamp<16>(rchannel);
if(dsp.mute()) left = 0, right = 0;
audio.coprocessor_sample(left, right);
step(1);
@ -53,12 +57,12 @@ void MSU1::init() {
}
void MSU1::load() {
if(datafile.open()) datafile.close();
datafile.open({interface->path(0), "msu1.rom"}, file::mode::read);
data_open();
}
void MSU1::unload() {
if(datafile.open()) datafile.close();
if(audiofile.open()) audiofile.close();
}
void MSU1::power() {
@ -68,6 +72,7 @@ void MSU1::power() {
void MSU1::reset() {
create(MSU1::Enter, 44100);
boot = true;
mmio.data_offset = 0;
mmio.audio_offset = 0;
@ -80,52 +85,80 @@ void MSU1::reset() {
mmio.audio_error = false;
}
void MSU1::data_open() {
if(datafile.open()) datafile.close();
XML::Document document(cartridge.manifest());
string name = document["cartridge"]["msu1"]["rom"]["name"].data;
if(name.empty()) name = "msu1.rom";
if(datafile.open({interface->path(0), name}, file::mode::read)) {
datafile.seek(mmio.data_offset);
}
}
void MSU1::audio_open() {
if(audiofile.open()) audiofile.close();
XML::Document document(cartridge.manifest());
string name = {"track-", mmio.audio_track, ".pcm"};
for(auto &track : document["cartridge"]["msu1"]) {
if(track.name != "track") continue;
if(numeral(track["number"].data) != mmio.audio_track) continue;
name = track["name"].data;
break;
}
if(audiofile.open({interface->path(0), name}, file::mode::read)) {
audiofile.seek(mmio.audio_offset);
}
}
uint8 MSU1::mmio_read(unsigned addr) {
cpu.synchronize_coprocessors();
addr = 0x2000 | (addr & 7);
switch(addr & 7) {
case 0:
switch(addr) {
case 0x2000:
return (mmio.data_busy << 7)
| (mmio.audio_busy << 6)
| (mmio.audio_repeat << 5)
| (mmio.audio_play << 4)
| (mmio.audio_error << 3)
| (Revision << 0);
case 1:
case 0x2001:
if(mmio.data_busy) return 0x00;
mmio.data_offset++;
if(datafile.open()) return datafile.read();
return 0x00;
case 2: return 'S';
case 3: return '-';
case 4: return 'M';
case 5: return 'S';
case 6: return 'U';
case 7: return '1';
case 0x2002: return 'S';
case 0x2003: return '-';
case 0x2004: return 'M';
case 0x2005: return 'S';
case 0x2006: return 'U';
case 0x2007: return '1';
}
}
void MSU1::mmio_write(unsigned addr, uint8 data) {
cpu.synchronize_coprocessors();
addr = 0x2000 | (addr & 7);
switch(addr & 7) {
case 0: mmio.data_offset = (mmio.data_offset & 0xffffff00) | (data << 0); break;
case 1: mmio.data_offset = (mmio.data_offset & 0xffff00ff) | (data << 8); break;
case 2: mmio.data_offset = (mmio.data_offset & 0xff00ffff) | (data << 16); break;
case 3: mmio.data_offset = (mmio.data_offset & 0x00ffffff) | (data << 24);
switch(addr) {
case 0x2000: mmio.data_offset = (mmio.data_offset & 0xffffff00) | (data << 0); break;
case 0x2001: mmio.data_offset = (mmio.data_offset & 0xffff00ff) | (data << 8); break;
case 0x2002: mmio.data_offset = (mmio.data_offset & 0xff00ffff) | (data << 16); break;
case 0x2003: mmio.data_offset = (mmio.data_offset & 0x00ffffff) | (data << 24);
if(datafile.open()) datafile.seek(mmio.data_offset);
mmio.data_busy = false;
break;
case 4: mmio.audio_track = (mmio.audio_track & 0xff00) | (data << 0);
case 5: mmio.audio_track = (mmio.audio_track & 0x00ff) | (data << 8);
if(audiofile.open()) audiofile.close();
if(audiofile.open({interface->path(0), "track-", mmio.audio_track, ".pcm"}, file::mode::read)) {
case 0x2004: mmio.audio_track = (mmio.audio_track & 0xff00) | (data << 0); break;
case 0x2005: mmio.audio_track = (mmio.audio_track & 0x00ff) | (data << 8);
mmio.audio_offset = 0;
audio_open();
if(audiofile.open()) {
uint32 header = audiofile.readm(4);
if(header != 0x4d535531) { //verify 'MSU1' header
audiofile.close();
} else {
mmio.audio_offset = 8;
mmio.audio_loop_offset = 8 + audiofile.readl(4) * 4;
mmio.audio_offset = 8;
}
}
mmio.audio_busy = false;
@ -133,10 +166,10 @@ void MSU1::mmio_write(unsigned addr, uint8 data) {
mmio.audio_play = false;
mmio.audio_error = !audiofile.open();
break;
case 6:
case 0x2006:
mmio.audio_volume = data;
break;
case 7:
case 0x2007:
mmio.audio_repeat = data & 2;
mmio.audio_play = data & 1;
break;

View File

@ -7,12 +7,16 @@ struct MSU1 : Coprocessor {
void power();
void reset();
void data_open();
void audio_open();
uint8 mmio_read(unsigned addr);
void mmio_write(unsigned addr, uint8 data);
void serialize(serializer&);
private:
bool boot;
file datafile;
file audiofile;

View File

@ -3,6 +3,8 @@
void MSU1::serialize(serializer &s) {
Thread::serialize(s);
s.integer(boot);
s.integer(mmio.data_offset);
s.integer(mmio.audio_offset);
s.integer(mmio.audio_loop_offset);
@ -16,15 +18,8 @@ void MSU1::serialize(serializer &s) {
s.integer(mmio.audio_play);
s.integer(mmio.audio_error);
if(datafile.open()) datafile.close();
if(datafile.open({interface->path(0), "msu1.rom"}, file::mode::read)) {
datafile.seek(mmio.data_offset);
}
if(audiofile.open()) audiofile.close();
if(audiofile.open({interface->path(0), "track-", mmio.audio_track, ".pcm"}, file::mode::read)) {
audiofile.seek(mmio.audio_offset);
}
data_open();
audio_open();
}
#endif

View File

@ -12,58 +12,51 @@ uint8 SPC7110::datarom_read(unsigned addr) {
return cartridge.rom.read(drom_base + Bus::mirror(offset, drom_size));
}
unsigned SPC7110::data_offset() { return r4811 | r4812 << 8 | r4813 << 16; }
unsigned SPC7110::data_adjust() { return r4814 | r4815 << 8; }
unsigned SPC7110::data_increment() { return r4816 | r4817 << 8; }
unsigned SPC7110::data_offset() { return r4811 | r4812 << 8 | r4813 << 16; }
unsigned SPC7110::data_adjust() { return r4814 | r4815 << 8; }
unsigned SPC7110::data_stride() { return r4816 | r4817 << 8; }
void SPC7110::set_data_offset(unsigned addr) { r4811 = addr; r4812 = addr >> 8; r4813 = addr >> 16; }
void SPC7110::set_data_adjust(unsigned addr) { r4814 = addr; r4815 = addr >> 8; }
void SPC7110::data_port_read() {
unsigned offset = data_offset();
unsigned adjust = data_adjust();
unsigned adjust = r4818 & 2 ? data_adjust() : 0;
if(r4818 & 8) adjust = (int16)adjust;
if(r4818 & 2) offset += adjust;
r4810 = datarom_read(offset);
r4810 = datarom_read(offset + adjust);
}
void SPC7110::data_port_increment_a() {
void SPC7110::data_port_increment_4810() {
unsigned offset = data_offset();
unsigned stride = r4818 & 1 ? data_stride() : 1;
unsigned adjust = data_adjust();
if(r4818 & 4) stride = (int16)stride;
if(r4818 & 8) adjust = (int16)adjust;
if(r4818 & 2) return set_data_adjust(adjust + 1);
unsigned increment = r4818 & 1 ? data_increment() : 1u;
if(r4818 & 4) increment = (int16)increment;
if((r4818 & 16) == 0) set_data_offset(data_offset() + increment);
if((r4818 & 16) != 0) set_data_adjust(adjust + increment);
if((r4818 & 16) == 0) set_data_offset(offset + stride);
if((r4818 & 16) != 0) set_data_adjust(adjust + stride);
}
void SPC7110::data_port_increment_b() {
if(r4818 >> 5 != 3) return;
void SPC7110::data_port_increment_4814() {
if(r4818 >> 5 != 1) return;
unsigned offset = data_offset();
unsigned adjust = data_adjust();
if(r4818 & 8) adjust = (int16)adjust;
if((r4818 & 16) == 0) set_data_offset(offset + adjust);
if((r4818 & 16) != 0) set_data_adjust(adjust + adjust);
set_data_offset(offset + adjust);
}
void SPC7110::data_port_increment_c() {
if((r4818 & 2) == 0) return;
if(r4818 & 16) return;
void SPC7110::data_port_increment_4815() {
if(r4818 >> 5 != 2) return;
unsigned offset = data_offset();
unsigned adjust = data_adjust();
if(r4818 & 8) adjust = (int16)adjust;
set_data_offset(offset + adjust);
}
if(r4818 >> 5 == 1) {
unsigned increment = data_adjust() & 0xff;
if(r4818 & 8) increment = (int8)increment;
set_data_offset(data_offset() + increment);
}
if(r4818 >> 5 == 2) {
unsigned increment = data_adjust();
if(r4818 & 8) increment = (int16)increment;
set_data_offset(data_offset() + increment);
}
void SPC7110::data_port_increment_481a() {
if(r4818 >> 5 != 3) return;
unsigned offset = data_offset();
unsigned adjust = data_adjust();
if(r4818 & 8) adjust = (int16)adjust;
set_data_offset(offset + adjust);
}
#endif

View File

@ -26,8 +26,10 @@ void SPC7110::dcu_begin_transfer() {
ctx.invert = 0;
}
unsigned seek = (r4805 | r4806 << 8) << dcu_mode;
while(seek--) dcu_read();
if(r480b & 2) {
unsigned seek = (r4805 | r4806 << 8) << dcu_mode;
while(seek--) dcu_read();
}
}
uint8 SPC7110::dcu_read() {

View File

@ -36,9 +36,6 @@ void SPC7110::serialize(serializer &s) {
s.integer(r4818);
s.integer(r481a);
s.integer(r4814_latch);
s.integer(r4815_latch);
s.integer(r4820);
s.integer(r4821);
s.integer(r4822);

View File

@ -68,9 +68,6 @@ void SPC7110::reset() {
r4818 = 0x00;
r481a = 0x00;
r4814_latch = false;
r4815_latch = false;
r4820 = 0x00;
r4821 = 0x00;
r4822 = 0x00;
@ -100,7 +97,7 @@ void SPC7110::reset() {
uint8 SPC7110::mmio_read(unsigned addr) {
cpu.synchronize_coprocessors();
addr &= 0xffff;
addr = 0x4800 | (addr & 0x3f);
switch(addr) {
@ -138,7 +135,7 @@ uint8 SPC7110::mmio_read(unsigned addr) {
case 0x4810: {
uint8 data = r4810;
data_port_increment_a();
data_port_increment_4810();
data_port_read();
return data;
}
@ -151,13 +148,13 @@ uint8 SPC7110::mmio_read(unsigned addr) {
case 0x4817: return r4817;
case 0x4818: return r4818;
case 0x481a: {
data_port_increment_b();
data_port_increment_481a();
return 0x00;
}
//=========
//math unit
//=========
//=====================
//arithmetic logic unit
//=====================
case 0x4820: return r4820;
case 0x4821: return r4821;
@ -177,7 +174,7 @@ uint8 SPC7110::mmio_read(unsigned addr) {
case 0x482f: return r482f;
//===================
//memory mapping unit
//memory control unit
//===================
case 0x4830: return r4830;
@ -193,7 +190,7 @@ uint8 SPC7110::mmio_read(unsigned addr) {
void SPC7110::mmio_write(unsigned addr, uint8 data) {
cpu.synchronize_coprocessors();
addr &= 0xffff;
addr = 0x4800 | (addr & 0x3f);
switch(addr) {
@ -220,22 +217,15 @@ void SPC7110::mmio_write(unsigned addr, uint8 data) {
case 0x4811: r4811 = data; break;
case 0x4812: r4812 = data; break;
case 0x4813: r4813 = data & 0x7f; data_port_read(); break;
case 0x4814:
case 0x4815: {
if((addr & 1) == 0) r4814 = data, r4814_latch = true;
if((addr & 1) == 1) r4815 = data, r4815_latch = true;
if(r4814_latch && r4815_latch) data_port_increment_c();
} break;
case 0x4814: r4814 = data; data_port_increment_4814(); break;
case 0x4815: r4815 = data; data_port_increment_4815(); break;
case 0x4816: r4816 = data; break;
case 0x4817: r4817 = data; break;
case 0x4818: r4818 = data & 0x7f; {
r4814_latch = r4815_latch = false;
data_port_read();
} break;
case 0x4818: r4818 = data & 0x7f; data_port_read(); break;
//=========
//math unit
//=========
//=====================
//arithmetic logic unit
//=====================
case 0x4820: r4820 = data; break;
case 0x4821: r4821 = data; break;
@ -248,7 +238,7 @@ void SPC7110::mmio_write(unsigned addr, uint8 data) {
case 0x482e: r482e = data & 0x01; break;
//===================
//memory mapping unit
//memory control unit
//===================
case 0x4830: r4830 = data & 0x87; break;

View File

@ -59,16 +59,17 @@ struct SPC7110 : Coprocessor {
unsigned data_offset();
unsigned data_adjust();
unsigned data_increment();
unsigned data_stride();
void set_data_offset(unsigned addr);
void set_data_adjust(unsigned addr);
void data_port_read();
void data_port_increment_a();
void data_port_increment_b();
void data_port_increment_c();
void data_port_increment_4810();
void data_port_increment_4814();
void data_port_increment_4815();
void data_port_increment_481a();
//alu.cpp
void alu_multiply();
@ -78,16 +79,16 @@ private:
//==================
//decompression unit
//==================
uint8 r4801; //compression table low
uint8 r4802; //compression table high
uint8 r4803; //compression table bank
uint8 r4801; //compression table B0
uint8 r4802; //compression table B1
uint8 r4803; //compression table B2
uint8 r4804; //compression table index
uint8 r4805; //decompression buffer index low
uint8 r4806; //decompression buffer index high
uint8 r4805; //decompression buffer index B0
uint8 r4806; //decompression buffer index B1
uint8 r4807; //deinterleave length
uint8 r4809; //compression length low
uint8 r480a; //compression length high
uint8 r480b; //deinterleave enable
uint8 r4809; //compression counter B0
uint8 r480a; //compression counter B1
uint8 r480b; //decompression settings
uint8 r480c; //decompression status
uint2 dcu_mode;
@ -109,23 +110,20 @@ private:
//==============
//data port unit
//==============
uint8 r4810; //data port A
uint8 r4811; //data offset low
uint8 r4812; //data offset high
uint8 r4813; //data offset bank
uint8 r4814; //data adjust low
uint8 r4815; //data adjust high
uint8 r4816; //data increment low
uint8 r4817; //data increment high
uint8 r4818; //data port control register
uint8 r481a; //data port B
uint8 r4810; //data port read + seek
uint8 r4811; //data offset B0
uint8 r4812; //data offset B1
uint8 r4813; //data offset B2
uint8 r4814; //data adjust B0
uint8 r4815; //data adjust B1
uint8 r4816; //data stride B0
uint8 r4817; //data stride B1
uint8 r4818; //data port settings
uint8 r481a; //data port seek
bool r4814_latch;
bool r4815_latch;
//=========
//math unit
//=========
//=====================
//arithmetic logic unit
//=====================
uint8 r4820; //16-bit multiplicand B0, 32-bit dividend B0
uint8 r4821; //16-bit multiplicand B1, 32-bit dividend B1
uint8 r4822; //32-bit dividend B2
@ -140,20 +138,20 @@ private:
uint8 r482b; //32-bit product B3, 32-bit quotient B3
uint8 r482c; //16-bit remainder B0
uint8 r482d; //16-bit remainder B1
uint8 r482e; //math sign extend mode
uint8 r482e; //math settings
uint8 r482f; //math status
unsigned mul_wait;
unsigned div_wait;
//===================
//memory mapping unit
//memory control unit
//===================
uint8 r4830; //bank 0 mapping + SRAM write enable
uint8 r4831; //bank 1 mapping
uint8 r4832; //bank 2 mapping
uint8 r4833; //bank 3 mapping
uint8 r4834; //bank mapping control
uint8 r4834; //bank mapping settings
};
extern SPC7110 spc7110;

View File

@ -199,6 +199,10 @@ void DSP::tick() {
/* register interface for S-SMP $00f2,$00f3 */
bool DSP::mute() {
return state.regs[r_flg] & 0x40;
}
uint8 DSP::read(uint8 addr) {
return state.regs[addr];
}

View File

@ -3,6 +3,7 @@ struct DSP : Thread {
alwaysinline void step(unsigned clocks);
alwaysinline void synchronize_smp();
bool mute();
uint8 read(uint8 addr);
void write(uint8 addr, uint8 data);

View File

@ -80,7 +80,6 @@ void System::init() {
sdd1.init();
obc1.init();
msu1.init();
link.init();
video.init();
audio.init();
@ -127,7 +126,6 @@ void System::load() {
if(cartridge.has_sdd1()) sdd1.load();
if(cartridge.has_obc1()) obc1.load();
if(cartridge.has_msu1()) msu1.load();
if(cartridge.has_link()) link.load();
serialize_init();
cheat.init();
@ -151,7 +149,6 @@ void System::unload() {
if(cartridge.has_sdd1()) sdd1.unload();
if(cartridge.has_obc1()) obc1.unload();
if(cartridge.has_msu1()) msu1.unload();
if(cartridge.has_link()) link.unload();
}
void System::power() {
@ -178,7 +175,6 @@ void System::power() {
if(cartridge.has_sdd1()) sdd1.power();
if(cartridge.has_obc1()) obc1.power();
if(cartridge.has_msu1()) msu1.power();
if(cartridge.has_link()) link.power();
reset();
}
@ -205,7 +201,6 @@ void System::reset() {
if(cartridge.has_sdd1()) sdd1.reset();
if(cartridge.has_obc1()) obc1.reset();
if(cartridge.has_msu1()) msu1.reset();
if(cartridge.has_link()) link.reset();
if(cartridge.has_gb_slot()) cpu.coprocessors.append(&icd2);
if(cartridge.has_sa1()) cpu.coprocessors.append(&sa1);
@ -217,7 +212,6 @@ void System::reset() {
if(cartridge.has_sharprtc()) cpu.coprocessors.append(&sharprtc);
if(cartridge.has_spc7110()) cpu.coprocessors.append(&spc7110);
if(cartridge.has_msu1()) cpu.coprocessors.append(&msu1);
if(cartridge.has_link()) cpu.coprocessors.append(&link);
scheduler.init();
input.connect(0, config.controller_port1);