mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-09-24 18:11:32 +02:00
Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6c59a2f1b4 | ||
|
a295c86c05 | ||
|
a539f2f578 | ||
|
e710259611 | ||
|
f1d1ab7ed1 | ||
|
1934197fb7 | ||
|
e1c8757a10 | ||
|
768e9b589d | ||
|
582f17b330 | ||
|
23866a348d | ||
|
d0de306546 | ||
|
2af60d0a13 | ||
|
a8263afc24 | ||
|
a9943ab4f4 | ||
|
46a1eb8cce | ||
|
4517c0249f | ||
|
b538c13aad | ||
|
d3d98f9f54 | ||
|
1d5e09ef07 |
BIN
QtCore4.dll
Normal file
BIN
QtCore4.dll
Normal file
Binary file not shown.
BIN
QtGui4.dll
Normal file
BIN
QtGui4.dll
Normal file
Binary file not shown.
BIN
bsnes-debugger.exe
Normal file
BIN
bsnes-debugger.exe
Normal file
Binary file not shown.
@@ -1,13 +1,15 @@
|
||||
include lib/nall/Makefile
|
||||
include lib/nall/Makefile-qt
|
||||
ui = ui_qt
|
||||
|
||||
ui := ui_qt
|
||||
qtlibs := $(strip QtCore QtGui $(if $(findstring osx,$(platform)),QtOpenGL))
|
||||
include lib/nall/qt/Makefile
|
||||
|
||||
################
|
||||
### compiler ###
|
||||
################
|
||||
|
||||
c := $(compiler)
|
||||
cpp := $(subst cc,++,$(compiler))
|
||||
c := $(compiler) --std=gnu99
|
||||
cpp := $(subst cc,++,$(compiler)) -std=gnu++0x
|
||||
flags := -O3 -fomit-frame-pointer -Ilib
|
||||
link :=
|
||||
|
||||
@@ -23,7 +25,7 @@ link :=
|
||||
################
|
||||
|
||||
ifeq ($(platform),x)
|
||||
link += -s
|
||||
link += -s -ldl -lX11 -lXext
|
||||
|
||||
ruby := video.glx video.xv video.qtraster video.sdl
|
||||
ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao
|
||||
@@ -56,21 +58,22 @@ endif
|
||||
### ruby ###
|
||||
############
|
||||
|
||||
rubyflags := $(call ifhas,.sdl,$(ruby),`sdl-config --cflags`)
|
||||
rubyflags += $(call ifhas,.qt,$(ruby),$(qtinc))
|
||||
rubyflags := $(if $(finstring .sdl,$(ruby)),`sdl-config --cflags`)
|
||||
rubyflags += $(if $(findstring .qt,$(ruby)),$(qtinc))
|
||||
|
||||
link += $(call ifhas,.sdl,$(ruby),`sdl-config --libs`)
|
||||
link += $(call ifhas,video.direct3d,$(ruby),-ld3d9)
|
||||
link += $(call ifhas,video.directdraw,$(ruby),-lddraw)
|
||||
link += $(call ifhas,video.glx,$(ruby),-lGL)
|
||||
link += $(call ifhas,video.wgl,$(ruby),-lopengl32)
|
||||
link += $(call ifhas,video.xv,$(ruby),-lXv)
|
||||
link += $(call ifhas,audio.alsa,$(ruby),-lasound)
|
||||
link += $(call ifhas,audio.ao,$(ruby),-lao)
|
||||
link += $(call ifhas,audio.directsound,$(ruby),-ldsound)
|
||||
link += $(call ifhas,audio.pulseaudio,$(ruby),-lpulse-simple)
|
||||
link += $(call ifhas,input.directinput,$(ruby),-ldinput8 -ldxguid)
|
||||
link += $(call ifhas,input.rawinput,$(ruby),-ldinput8 -ldxguid)
|
||||
link += $(if $(findstring .sdl,$(ruby)),`sdl-config --libs`)
|
||||
link += $(if $(findstring video.direct3d,$(ruby)),-ld3d9)
|
||||
link += $(if $(findstring video.directdraw,$(ruby)),-lddraw)
|
||||
link += $(if $(findstring video.glx,$(ruby)),-lGL)
|
||||
link += $(if $(findstring video.wgl,$(ruby)),-lopengl32)
|
||||
link += $(if $(findstring video.xv,$(ruby)),-lXv)
|
||||
link += $(if $(findstring audio.alsa,$(ruby)),-lasound)
|
||||
link += $(if $(findstring audio.ao,$(ruby)),-lao)
|
||||
link += $(if $(findstring audio.directsound,$(ruby)),-ldsound)
|
||||
link += $(if $(findstring audio.pulseaudio,$(ruby)),-lpulse)
|
||||
link += $(if $(findstring audio.pulseaudiosimple,$(ruby)),-lpulse-simple)
|
||||
link += $(if $(findstring input.directinput,$(ruby)),-ldinput8 -ldxguid)
|
||||
link += $(if $(findstring input.rawinput,$(ruby)),-ldinput8 -ldxguid)
|
||||
|
||||
###############
|
||||
### objects ###
|
||||
@@ -78,10 +81,10 @@ link += $(call ifhas,input.rawinput,$(ruby),-ldinput8 -ldxguid)
|
||||
|
||||
objects := libco ruby
|
||||
objects += system cartridge cheat
|
||||
objects += memory smemory cpu cpucore scpu smp smpcore ssmp sdsp ppu bppu
|
||||
objects += memory smemory cpu cpucore scpu smp smpcore ssmp dsp sdsp ppu bppu
|
||||
objects += supergameboy superfx sa1
|
||||
objects += bsx srtc sdd1 spc7110 cx4 dsp1 dsp2 dsp3 dsp4 obc1 st010 st011 st018
|
||||
objects += 21fx
|
||||
objects += bsx srtc sdd1 spc7110 cx4 dsp1 dsp2 dsp3 dsp4 obc1 st0010 st0011 st0018
|
||||
objects += msu1
|
||||
|
||||
######################
|
||||
### implicit rules ###
|
||||
@@ -147,6 +150,7 @@ obj/ssmp.o : smp/ssmp/ssmp.cpp $(call rwildcard,smp/ssmp/)
|
||||
### dsp ###
|
||||
###########
|
||||
|
||||
obj/dsp.o : dsp/dsp.cpp dsp/*
|
||||
obj/adsp.o: dsp/adsp/adsp.cpp dsp/adsp/*
|
||||
obj/sdsp.o: dsp/sdsp/sdsp.cpp dsp/sdsp/*
|
||||
|
||||
@@ -180,10 +184,10 @@ obj/dsp2.o : chip/dsp2/dsp2.cpp chip/dsp2/*
|
||||
obj/dsp3.o : chip/dsp3/dsp3.cpp chip/dsp3/*
|
||||
obj/dsp4.o : chip/dsp4/dsp4.cpp chip/dsp4/*
|
||||
obj/obc1.o : chip/obc1/obc1.cpp chip/obc1/*
|
||||
obj/st010.o : chip/st010/st010.cpp chip/st010/*
|
||||
obj/st011.o : chip/st011/st011.cpp chip/st011/*
|
||||
obj/st018.o : chip/st018/st018.cpp chip/st018/*
|
||||
obj/21fx.o : chip/21fx/21fx.cpp chip/21fx/*
|
||||
obj/st0010.o : chip/st0010/st0010.cpp chip/st0010/*
|
||||
obj/st0011.o : chip/st0011/st0011.cpp chip/st0011/*
|
||||
obj/st0018.o : chip/st0018/st0018.cpp chip/st0018/*
|
||||
obj/msu1.o : chip/msu1/msu1.cpp chip/msu1/*
|
||||
|
||||
###############
|
||||
### targets ###
|
@@ -1,6 +1,6 @@
|
||||
static const char bsnesVersion[] = "0.059";
|
||||
static const char bsnesVersion[] = "061";
|
||||
static const char bsnesTitle[] = "bsnes";
|
||||
static const unsigned bsnesSerializerVersion = 4;
|
||||
static const unsigned bsnesSerializerVersion = 5;
|
||||
|
||||
//S-DSP can be encapsulated into a state machine using #define magic
|
||||
//this avoids ~2.048m co_switch() calls per second (~5% speedup)
|
||||
@@ -22,6 +22,7 @@ static const unsigned bsnesSerializerVersion = 4;
|
||||
#include <nall/dl.hpp>
|
||||
#include <nall/endian.hpp>
|
||||
#include <nall/file.hpp>
|
||||
#include <nall/foreach.hpp>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/moduloarray.hpp>
|
||||
#include <nall/platform.hpp>
|
@@ -5,8 +5,7 @@
|
||||
#define CARTRIDGE_CPP
|
||||
namespace SNES {
|
||||
|
||||
#include "header.cpp"
|
||||
#include "gameboyheader.cpp"
|
||||
#include "xml.cpp"
|
||||
#include "serialization.cpp"
|
||||
|
||||
namespace memory {
|
||||
@@ -19,9 +18,32 @@ namespace memory {
|
||||
|
||||
Cartridge cartridge;
|
||||
|
||||
void Cartridge::load(Mode cartridge_mode) {
|
||||
void Cartridge::load(Mode cartridge_mode, const lstring &xml_list) {
|
||||
spc7110_data_rom_offset = 0x100000;
|
||||
supergameboy_version = SuperGameBoyVersion::Version1;
|
||||
supergameboy_ram_size = 0;
|
||||
supergameboy_rtc_size = 0;
|
||||
|
||||
has_bsx_slot = false;
|
||||
has_superfx = false;
|
||||
has_sa1 = false;
|
||||
has_srtc = false;
|
||||
has_sdd1 = false;
|
||||
has_spc7110 = false;
|
||||
has_spc7110rtc = false;
|
||||
has_cx4 = false;
|
||||
has_dsp1 = false;
|
||||
has_dsp2 = false;
|
||||
has_dsp3 = false;
|
||||
has_dsp4 = false;
|
||||
has_obc1 = false;
|
||||
has_st0010 = false;
|
||||
has_st0011 = false;
|
||||
has_st0018 = false;
|
||||
has_msu1 = false;
|
||||
|
||||
mode = cartridge_mode;
|
||||
read_header(memory::cartrom.data(), memory::cartrom.size());
|
||||
parse_xml(xml_list);
|
||||
|
||||
if(ram_size > 0) {
|
||||
memory::cartram.map(allocate<uint8_t>(ram_size, 0xff), ram_size);
|
||||
@@ -31,23 +53,20 @@ void Cartridge::load(Mode cartridge_mode) {
|
||||
memory::cartrtc.map(allocate<uint8_t>(20, 0xff), 20);
|
||||
}
|
||||
|
||||
if(mode == ModeBsx) {
|
||||
if(mode == Mode::Bsx) {
|
||||
memory::bsxram.map (allocate<uint8_t>( 32 * 1024, 0xff), 32 * 1024);
|
||||
memory::bsxpram.map(allocate<uint8_t>(512 * 1024, 0xff), 512 * 1024);
|
||||
}
|
||||
|
||||
if(mode == ModeSufamiTurbo) {
|
||||
if(mode == Mode::SufamiTurbo) {
|
||||
if(memory::stArom.data()) memory::stAram.map(allocate<uint8_t>(128 * 1024, 0xff), 128 * 1024);
|
||||
if(memory::stBrom.data()) memory::stBram.map(allocate<uint8_t>(128 * 1024, 0xff), 128 * 1024);
|
||||
}
|
||||
|
||||
if(mode == ModeSuperGameBoy) {
|
||||
if(mode == Mode::SuperGameBoy) {
|
||||
if(memory::gbrom.data()) {
|
||||
unsigned ram_size = gameboy_ram_size();
|
||||
unsigned rtc_size = gameboy_rtc_size();
|
||||
|
||||
if(ram_size) memory::gbram.map(allocate<uint8_t>(ram_size, 0xff), ram_size);
|
||||
if(rtc_size) memory::gbrtc.map(allocate<uint8_t>(rtc_size, 0x00), rtc_size);
|
||||
if(supergameboy_ram_size) memory::gbram.map(allocate<uint8_t>(supergameboy_ram_size, 0xff), supergameboy_ram_size);
|
||||
if(supergameboy_rtc_size) memory::gbrtc.map(allocate<uint8_t>(supergameboy_rtc_size, 0x00), supergameboy_rtc_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,21 +84,13 @@ void Cartridge::load(Mode cartridge_mode) {
|
||||
memory::gbram.write_protect(false);
|
||||
memory::gbrtc.write_protect(false);
|
||||
|
||||
unsigned checksum = ~0;
|
||||
for(unsigned n = 0; n < memory::cartrom.size(); n++) checksum = crc32_adjust(checksum, memory::cartrom[n]);
|
||||
if(memory::bsxflash.size() != 0 && memory::bsxflash.size() != ~0)
|
||||
for(unsigned n = 0; n < memory::bsxflash.size(); n++) checksum = crc32_adjust(checksum, memory::bsxflash[n]);
|
||||
if(memory::stArom.size() != 0 && memory::stArom.size() != ~0)
|
||||
for(unsigned n = 0; n < memory::stArom.size(); n++) checksum = crc32_adjust(checksum, memory::stArom[n]);
|
||||
if(memory::stBrom.size() != 0 && memory::stBrom.size() != ~0)
|
||||
for(unsigned n = 0; n < memory::stBrom.size(); n++) checksum = crc32_adjust(checksum, memory::stBrom[n]);
|
||||
if(memory::gbrom.size() != 0 && memory::gbrom.size() != ~0)
|
||||
for(unsigned n = 0; n < memory::gbrom.size(); n++) checksum = crc32_adjust(checksum, memory::gbrom[n]);
|
||||
unsigned checksum = ~0; foreach(n, memory::cartrom ) checksum = crc32_adjust(checksum, n);
|
||||
if(memory::bsxflash.size() != 0 && memory::bsxflash.size() != ~0) foreach(n, memory::bsxflash) checksum = crc32_adjust(checksum, n);
|
||||
if(memory::stArom.size() != 0 && memory::stArom.size() != ~0) foreach(n, memory::stArom ) checksum = crc32_adjust(checksum, n);
|
||||
if(memory::stBrom.size() != 0 && memory::stBrom.size() != ~0) foreach(n, memory::stBrom ) checksum = crc32_adjust(checksum, n);
|
||||
if(memory::gbrom.size() != 0 && memory::gbrom.size() != ~0) foreach(n, memory::gbrom ) checksum = crc32_adjust(checksum, n);
|
||||
crc32 = ~checksum;
|
||||
|
||||
#if 0
|
||||
fprintf(stdout, "crc32 = %.8x\n", (unsigned)crc32);
|
||||
|
||||
sha256_ctx sha;
|
||||
uint8_t shahash[32];
|
||||
sha256_init(&sha);
|
||||
@@ -87,10 +98,9 @@ void Cartridge::load(Mode cartridge_mode) {
|
||||
sha256_final(&sha);
|
||||
sha256_hash(&sha, shahash);
|
||||
|
||||
fprintf(stdout, "sha256 = ");
|
||||
for(unsigned i = 0; i < 32; i++) fprintf(stdout, "%.2x", shahash[i]);
|
||||
fprintf(stdout, "\n");
|
||||
#endif
|
||||
string hash;
|
||||
foreach(n, shahash) hash << strhex<2>(n);
|
||||
sha256 = hash;
|
||||
|
||||
bus.load_cart();
|
||||
system.serialize_init();
|
||||
@@ -117,10 +127,6 @@ void Cartridge::unload() {
|
||||
loaded = false;
|
||||
}
|
||||
|
||||
bool Cartridge::has_21fx() const {
|
||||
return s21fx.exists();
|
||||
}
|
||||
|
||||
Cartridge::Cartridge() {
|
||||
loaded = false;
|
||||
unload();
|
111
bsnes/cartridge/cartridge.hpp
Normal file
111
bsnes/cartridge/cartridge.hpp
Normal file
@@ -0,0 +1,111 @@
|
||||
class Cartridge : property<Cartridge> {
|
||||
public:
|
||||
enum class Mode : unsigned {
|
||||
Normal,
|
||||
BsxSlotted,
|
||||
Bsx,
|
||||
SufamiTurbo,
|
||||
SuperGameBoy,
|
||||
};
|
||||
|
||||
enum class Region : unsigned {
|
||||
NTSC,
|
||||
PAL,
|
||||
};
|
||||
|
||||
enum class SuperGameBoyVersion : unsigned {
|
||||
Version1,
|
||||
Version2,
|
||||
};
|
||||
|
||||
readonly<bool> loaded;
|
||||
readonly<unsigned> crc32;
|
||||
readonly<string> sha256;
|
||||
|
||||
readonly<Mode> mode;
|
||||
readonly<Region> region;
|
||||
readonly<unsigned> ram_size;
|
||||
readonly<unsigned> spc7110_data_rom_offset;
|
||||
readonly<SuperGameBoyVersion> supergameboy_version;
|
||||
readonly<unsigned> supergameboy_ram_size;
|
||||
readonly<unsigned> supergameboy_rtc_size;
|
||||
|
||||
readonly<bool> has_bsx_slot;
|
||||
readonly<bool> has_superfx;
|
||||
readonly<bool> has_sa1;
|
||||
readonly<bool> has_srtc;
|
||||
readonly<bool> has_sdd1;
|
||||
readonly<bool> has_spc7110;
|
||||
readonly<bool> has_spc7110rtc;
|
||||
readonly<bool> has_cx4;
|
||||
readonly<bool> has_dsp1;
|
||||
readonly<bool> has_dsp2;
|
||||
readonly<bool> has_dsp3;
|
||||
readonly<bool> has_dsp4;
|
||||
readonly<bool> has_obc1;
|
||||
readonly<bool> has_st0010;
|
||||
readonly<bool> has_st0011;
|
||||
readonly<bool> has_st0018;
|
||||
readonly<bool> has_msu1;
|
||||
|
||||
struct Mapping {
|
||||
Memory *memory;
|
||||
MMIO *mmio;
|
||||
Bus::MapMode mode;
|
||||
unsigned banklo;
|
||||
unsigned bankhi;
|
||||
unsigned addrlo;
|
||||
unsigned addrhi;
|
||||
unsigned offset;
|
||||
unsigned size;
|
||||
|
||||
Mapping();
|
||||
Mapping(Memory&);
|
||||
Mapping(MMIO&);
|
||||
};
|
||||
array<Mapping> mapping;
|
||||
|
||||
void load(Mode, const lstring&);
|
||||
void unload();
|
||||
|
||||
void serialize(serializer&);
|
||||
Cartridge();
|
||||
~Cartridge();
|
||||
|
||||
private:
|
||||
void parse_xml(const lstring&);
|
||||
void parse_xml_cartridge(const char*);
|
||||
void parse_xml_bsx(const char*);
|
||||
void parse_xml_sufami_turbo(const char*, bool);
|
||||
void parse_xml_gameboy(const char*);
|
||||
|
||||
void xml_parse_rom(xml_element*);
|
||||
void xml_parse_ram(xml_element*);
|
||||
void xml_parse_superfx(xml_element*);
|
||||
void xml_parse_sa1(xml_element*);
|
||||
void xml_parse_bsx(xml_element*);
|
||||
void xml_parse_sufamiturbo(xml_element*);
|
||||
void xml_parse_supergameboy(xml_element*);
|
||||
void xml_parse_srtc(xml_element*);
|
||||
void xml_parse_sdd1(xml_element*);
|
||||
void xml_parse_spc7110(xml_element*);
|
||||
void xml_parse_cx4(xml_element*);
|
||||
void xml_parse_necdsp(xml_element*);
|
||||
void xml_parse_obc1(xml_element*);
|
||||
void xml_parse_setadsp(xml_element*);
|
||||
void xml_parse_setarisc(xml_element*);
|
||||
void xml_parse_msu1(xml_element*);
|
||||
|
||||
void xml_parse_address(Mapping&, const string&);
|
||||
void xml_parse_mode(Mapping&, const string&);
|
||||
};
|
||||
|
||||
namespace memory {
|
||||
extern MappedRAM cartrom, cartram, cartrtc;
|
||||
extern MappedRAM bsxflash, bsxram, bsxpram;
|
||||
extern MappedRAM stArom, stAram;
|
||||
extern MappedRAM stBrom, stBram;
|
||||
extern MappedRAM gbrom, gbram, gbrtc;
|
||||
};
|
||||
|
||||
extern Cartridge cartridge;
|
655
bsnes/cartridge/xml.cpp
Normal file
655
bsnes/cartridge/xml.cpp
Normal file
@@ -0,0 +1,655 @@
|
||||
#ifdef CARTRIDGE_CPP
|
||||
|
||||
void Cartridge::parse_xml(const lstring &list) {
|
||||
parse_xml_cartridge(list[0]);
|
||||
|
||||
if(mode == Mode::BsxSlotted) {
|
||||
parse_xml_bsx(list[1]);
|
||||
} else if(mode == Mode::Bsx) {
|
||||
parse_xml_bsx(list[1]);
|
||||
} else if(mode == Mode::SufamiTurbo) {
|
||||
parse_xml_sufami_turbo(list[1], 0);
|
||||
parse_xml_sufami_turbo(list[2], 1);
|
||||
} else if(mode == Mode::SuperGameBoy) {
|
||||
parse_xml_gameboy(list[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::parse_xml_cartridge(const char *data) {
|
||||
xml_element *document = xml_parse(data);
|
||||
if(document == 0) return;
|
||||
|
||||
foreach(head, document->element) {
|
||||
if(head->name == "cartridge") {
|
||||
foreach(attr, head->attribute) {
|
||||
if(attr->name == "region") {
|
||||
if(attr->content == "NTSC") region = Region::NTSC;
|
||||
if(attr->content == "PAL") region = Region::PAL;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(node, head->element) {
|
||||
if(node->name == "rom") xml_parse_rom(node);
|
||||
if(node->name == "ram") xml_parse_ram(node);
|
||||
if(node->name == "superfx") xml_parse_superfx(node);
|
||||
if(node->name == "sa1") xml_parse_sa1(node);
|
||||
if(node->name == "bsx") xml_parse_bsx(node);
|
||||
if(node->name == "sufamiturbo") xml_parse_sufamiturbo(node);
|
||||
if(node->name == "supergameboy") xml_parse_supergameboy(node);
|
||||
if(node->name == "srtc") xml_parse_srtc(node);
|
||||
if(node->name == "sdd1") xml_parse_sdd1(node);
|
||||
if(node->name == "spc7110") xml_parse_spc7110(node);
|
||||
if(node->name == "cx4") xml_parse_cx4(node);
|
||||
if(node->name == "necdsp") xml_parse_necdsp(node);
|
||||
if(node->name == "obc1") xml_parse_obc1(node);
|
||||
if(node->name == "setadsp") xml_parse_setadsp(node);
|
||||
if(node->name == "setarisc") xml_parse_setarisc(node);
|
||||
if(node->name == "msu1") xml_parse_msu1(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::parse_xml_bsx(const char *data) {
|
||||
}
|
||||
|
||||
void Cartridge::parse_xml_sufami_turbo(const char *data, bool slot) {
|
||||
}
|
||||
|
||||
void Cartridge::parse_xml_gameboy(const char *data) {
|
||||
xml_element *document = xml_parse(data);
|
||||
if(document == 0) return;
|
||||
|
||||
foreach(head, document->element) {
|
||||
if(head->name == "cartridge") {
|
||||
foreach(attr, head->attribute) {
|
||||
if(attr->name == "rtc") {
|
||||
supergameboy_rtc_size = (attr->content == "true") ? 4 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(leaf, head->element) {
|
||||
if(leaf->name == "ram") {
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "size") {
|
||||
supergameboy_ram_size = strhex(attr->content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete document;
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_rom(xml_element *root) {
|
||||
foreach(leaf, root->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::cartrom);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_ram(xml_element *root) {
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "size") ram_size = strhex(attr->content);
|
||||
}
|
||||
|
||||
foreach(leaf, root->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::cartram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_superfx(xml_element *root) {
|
||||
has_superfx = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "rom") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::fxrom);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "ram") {
|
||||
foreach(attr, node->attribute) {
|
||||
if(attr->name == "size") ram_size = strhex(attr->content);
|
||||
}
|
||||
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::fxram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(superfx);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_sa1(xml_element *root) {
|
||||
has_sa1 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "rom") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::vsprom);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "iram") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::cpuiram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "bwram") {
|
||||
foreach(attr, node->attribute) {
|
||||
if(attr->name == "size") ram_size = strhex(attr->content);
|
||||
}
|
||||
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::cc1bwram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(sa1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_bsx(xml_element *root) {
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "slot") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::bsxflash);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(bsxcart);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_sufamiturbo(xml_element *root) {
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "slot") {
|
||||
bool slotid = 0;
|
||||
foreach(attr, node->attribute) {
|
||||
if(attr->name == "id") {
|
||||
if(attr->content == "A") slotid = 0;
|
||||
if(attr->content == "B") slotid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(slot, node->element) {
|
||||
if(slot->name == "rom") {
|
||||
foreach(leaf, slot->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(slotid == 0 ? memory::stArom : memory::stBrom);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
if(m.memory->size() > 0) mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(slot->name == "ram") {
|
||||
foreach(leaf, slot->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(slotid == 0 ? memory::stAram : memory::stBram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
if(m.memory->size() > 0) mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_supergameboy(xml_element *root) {
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "revision") {
|
||||
if(attr->content == "1") supergameboy_version = SuperGameBoyVersion::Version1;
|
||||
if(attr->content == "2") supergameboy_version = SuperGameBoyVersion::Version2;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m((Memory&)supergameboy);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_srtc(xml_element *root) {
|
||||
has_srtc = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(srtc);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_sdd1(xml_element *root) {
|
||||
has_sdd1 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mcu") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m((Memory&)sdd1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m((MMIO&)sdd1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_spc7110(xml_element *root) {
|
||||
has_spc7110 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "dcu") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(spc7110dcu);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mcu") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(spc7110mcu);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "offset") spc7110_data_rom_offset = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(spc7110);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "ram") {
|
||||
foreach(attr, node->attribute) {
|
||||
if(attr->name == "size") ram_size = strhex(attr->content);
|
||||
}
|
||||
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(spc7110ram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "rtc") {
|
||||
has_spc7110rtc = true;
|
||||
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(spc7110);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_cx4(xml_element *root) {
|
||||
has_cx4 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(cx4);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_necdsp(xml_element *root) {
|
||||
unsigned program = 0;
|
||||
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "program") {
|
||||
if(attr->content == "DSP-1" || attr->content == "DSP-1A" || attr->content == "DSP-1B") {
|
||||
program = 1;
|
||||
has_dsp1 = true;
|
||||
} else if(attr->content == "DSP-2") {
|
||||
program = 2;
|
||||
has_dsp2 = true;
|
||||
} else if(attr->content == "DSP-3") {
|
||||
program = 3;
|
||||
has_dsp3 = true;
|
||||
} else if(attr->content == "DSP-4") {
|
||||
program = 4;
|
||||
has_dsp4 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Memory *dr[5] = { 0, &dsp1dr, &dsp2, &dsp3, &dsp4 };
|
||||
Memory *sr[5] = { 0, &dsp1sr, &dsp2, &dsp3, &dsp4 };
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "dr" && dr[program]) {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(*dr[program]);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "sr" && sr[program]) {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(*sr[program]);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_obc1(xml_element *root) {
|
||||
has_obc1 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(obc1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_setadsp(xml_element *root) {
|
||||
unsigned program = 0;
|
||||
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "program") {
|
||||
if(attr->content == "ST-0010") {
|
||||
program = 1;
|
||||
has_st0010 = true;
|
||||
} else if(attr->content == "ST-0011") {
|
||||
program = 2;
|
||||
has_st0011 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Memory *map[3] = { 0, &st0010, 0 };
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio" && map[program]) {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(*map[program]);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_setarisc(xml_element *root) {
|
||||
unsigned program = 0;
|
||||
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "program") {
|
||||
if(attr->content == "ST-0018") {
|
||||
program = 1;
|
||||
has_st0018 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MMIO *map[2] = { 0, &st0018 };
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio" && map[program]) {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(*map[program]);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_msu1(xml_element *root) {
|
||||
has_msu1 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(msu1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_address(Mapping &m, const string &data) {
|
||||
lstring part;
|
||||
part.split(":", data);
|
||||
if(part.size() != 2) return;
|
||||
|
||||
lstring subpart;
|
||||
subpart.split("-", part[0]);
|
||||
if(subpart.size() == 1) {
|
||||
m.banklo = strhex(subpart[0]);
|
||||
m.bankhi = m.banklo;
|
||||
} else if(subpart.size() == 2) {
|
||||
m.banklo = strhex(subpart[0]);
|
||||
m.bankhi = strhex(subpart[1]);
|
||||
}
|
||||
|
||||
subpart.split("-", part[1]);
|
||||
if(subpart.size() == 1) {
|
||||
m.addrlo = strhex(subpart[0]);
|
||||
m.addrhi = m.addrlo;
|
||||
} else if(subpart.size() == 2) {
|
||||
m.addrlo = strhex(subpart[0]);
|
||||
m.addrhi = strhex(subpart[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_mode(Mapping &m, const string& data) {
|
||||
if(data == "direct") m.mode = Bus::MapMode::Direct;
|
||||
else if(data == "linear") m.mode = Bus::MapMode::Linear;
|
||||
else if(data == "shadow") m.mode = Bus::MapMode::Shadow;
|
||||
}
|
||||
|
||||
Cartridge::Mapping::Mapping() {
|
||||
memory = 0;
|
||||
mmio = 0;
|
||||
mode = Bus::MapMode::Direct;
|
||||
banklo = bankhi = addrlo = addrhi = offset = size = 0;
|
||||
}
|
||||
|
||||
Cartridge::Mapping::Mapping(Memory &memory_) {
|
||||
memory = &memory_;
|
||||
mmio = 0;
|
||||
mode = Bus::MapMode::Direct;
|
||||
banklo = bankhi = addrlo = addrhi = offset = size = 0;
|
||||
}
|
||||
|
||||
Cartridge::Mapping::Mapping(MMIO &mmio_) {
|
||||
memory = 0;
|
||||
mmio = &mmio_;
|
||||
mode = Bus::MapMode::Direct;
|
||||
banklo = bankhi = addrlo = addrhi = offset = size = 0;
|
||||
}
|
||||
|
||||
#endif
|
@@ -83,7 +83,7 @@ bool Cheat::decode(const char *s, unsigned &addr, uint8 &data, Type &type) {
|
||||
//validate input
|
||||
for(unsigned i = 0; i < 8; i++) if(!ischr(t[i])) return false;
|
||||
|
||||
type = ProActionReplay;
|
||||
type = Type::ProActionReplay;
|
||||
unsigned r = strhex((const char*)t);
|
||||
addr = r >> 8;
|
||||
data = r & 0xff;
|
||||
@@ -94,7 +94,7 @@ bool Cheat::decode(const char *s, unsigned &addr, uint8 &data, Type &type) {
|
||||
//validate input
|
||||
for(unsigned i = 0; i < 8; i++) if(!ischr(t[i])) return false;
|
||||
|
||||
type = GameGenie;
|
||||
type = Type::GameGenie;
|
||||
strtr(t, "df4709156bc8a23e", "0123456789abcdef");
|
||||
unsigned r = strhex((const char*)t);
|
||||
//8421 8421 8421 8421 8421 8421
|
||||
@@ -124,11 +124,10 @@ bool Cheat::decode(const char *s, unsigned &addr, uint8 &data, Type &type) {
|
||||
bool Cheat::encode(string &s, unsigned addr, uint8 data, Type type) {
|
||||
char t[16];
|
||||
|
||||
if(type == ProActionReplay) {
|
||||
sprintf(t, "%.6x%.2x", addr, data);
|
||||
s = t;
|
||||
if(type == Type::ProActionReplay) {
|
||||
s = sprint("$$", strhex<6>(addr), strhex<2>(data));
|
||||
return true;
|
||||
} else if(type == GameGenie) {
|
||||
} else if(type == Type::GameGenie) {
|
||||
unsigned r = addr;
|
||||
addr = (!!(r & 0x008000) << 23) | (!!(r & 0x004000) << 22)
|
||||
| (!!(r & 0x002000) << 21) | (!!(r & 0x001000) << 20)
|
||||
@@ -142,9 +141,8 @@ bool Cheat::encode(string &s, unsigned addr, uint8 data, Type type) {
|
||||
| (!!(r & 0x080000) << 5) | (!!(r & 0x040000) << 4)
|
||||
| (!!(r & 0x020000) << 3) | (!!(r & 0x010000) << 2)
|
||||
| (!!(r & 0x000800) << 1) | (!!(r & 0x000400) << 0);
|
||||
sprintf(t, "%.2x%.2x-%.4x", data, addr >> 16, addr & 0xffff);
|
||||
strtr(t, "0123456789abcdef", "df4709156bc8a23e");
|
||||
s = t;
|
||||
s = sprint("$$-$", strhex<2>(data), strhex<2>(addr >> 16), strhex<4>(addr & 0xffff));
|
||||
strtr(s, "0123456789abcdef", "df4709156bc8a23e");
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
@@ -7,9 +7,9 @@ struct CheatCode {
|
||||
CheatCode();
|
||||
};
|
||||
|
||||
class Cheat : public vector<CheatCode> {
|
||||
class Cheat : public linear_vector<CheatCode> {
|
||||
public:
|
||||
enum Type { ProActionReplay, GameGenie };
|
||||
enum class Type : unsigned { ProActionReplay, GameGenie };
|
||||
|
||||
bool enabled() const;
|
||||
void enable(bool);
|
@@ -6,7 +6,6 @@ void BSXCart::init() {
|
||||
}
|
||||
|
||||
void BSXCart::enable() {
|
||||
for(uint16 i = 0x5000; i <= 0x5fff; i++) memory::mmio.map(i, *this);
|
||||
}
|
||||
|
||||
void BSXCart::power() {
|
||||
@@ -26,39 +25,39 @@ void BSXCart::update_memory_map() {
|
||||
|
||||
if((regs.r[0x02] & 0x80) == 0x00) {
|
||||
//LoROM mapping
|
||||
bus.map(Bus::MapLinear, 0x00, 0x7d, 0x8000, 0xffff, cart);
|
||||
bus.map(Bus::MapLinear, 0x80, 0xff, 0x8000, 0xffff, cart);
|
||||
bus.map(Bus::MapMode::Linear, 0x00, 0x7d, 0x8000, 0xffff, cart);
|
||||
bus.map(Bus::MapMode::Linear, 0x80, 0xff, 0x8000, 0xffff, cart);
|
||||
} else {
|
||||
//HiROM mapping
|
||||
bus.map(Bus::MapShadow, 0x00, 0x3f, 0x8000, 0xffff, cart);
|
||||
bus.map(Bus::MapLinear, 0x40, 0x7d, 0x0000, 0xffff, cart);
|
||||
bus.map(Bus::MapShadow, 0x80, 0xbf, 0x8000, 0xffff, cart);
|
||||
bus.map(Bus::MapLinear, 0xc0, 0xff, 0x0000, 0xffff, cart);
|
||||
bus.map(Bus::MapMode::Shadow, 0x00, 0x3f, 0x8000, 0xffff, cart);
|
||||
bus.map(Bus::MapMode::Linear, 0x40, 0x7d, 0x0000, 0xffff, cart);
|
||||
bus.map(Bus::MapMode::Shadow, 0x80, 0xbf, 0x8000, 0xffff, cart);
|
||||
bus.map(Bus::MapMode::Linear, 0xc0, 0xff, 0x0000, 0xffff, cart);
|
||||
}
|
||||
|
||||
if(regs.r[0x03] & 0x80) {
|
||||
bus.map(Bus::MapLinear, 0x60, 0x6f, 0x0000, 0xffff, memory::bsxpram);
|
||||
//bus.map(Bus::MapLinear, 0x70, 0x77, 0x0000, 0xffff, memory::bsxpram);
|
||||
bus.map(Bus::MapMode::Linear, 0x60, 0x6f, 0x0000, 0xffff, memory::bsxpram);
|
||||
//bus.map(Bus::MapMode::Linear, 0x70, 0x77, 0x0000, 0xffff, memory::bsxpram);
|
||||
}
|
||||
|
||||
if((regs.r[0x05] & 0x80) == 0x00) {
|
||||
bus.map(Bus::MapLinear, 0x40, 0x4f, 0x0000, 0xffff, memory::bsxpram);
|
||||
bus.map(Bus::MapMode::Linear, 0x40, 0x4f, 0x0000, 0xffff, memory::bsxpram);
|
||||
}
|
||||
|
||||
if((regs.r[0x06] & 0x80) == 0x00) {
|
||||
bus.map(Bus::MapLinear, 0x50, 0x5f, 0x0000, 0xffff, memory::bsxpram);
|
||||
bus.map(Bus::MapMode::Linear, 0x50, 0x5f, 0x0000, 0xffff, memory::bsxpram);
|
||||
}
|
||||
|
||||
if(regs.r[0x07] & 0x80) {
|
||||
bus.map(Bus::MapLinear, 0x00, 0x1f, 0x8000, 0xffff, memory::cartrom);
|
||||
bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, memory::cartrom);
|
||||
}
|
||||
|
||||
if(regs.r[0x08] & 0x80) {
|
||||
bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom);
|
||||
bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom);
|
||||
}
|
||||
|
||||
bus.map(Bus::MapShadow, 0x20, 0x3f, 0x6000, 0x7fff, memory::bsxpram);
|
||||
bus.map(Bus::MapLinear, 0x70, 0x77, 0x0000, 0xffff, memory::bsxpram);
|
||||
bus.map(Bus::MapMode::Shadow, 0x20, 0x3f, 0x6000, 0x7fff, memory::bsxpram);
|
||||
bus.map(Bus::MapMode::Linear, 0x70, 0x77, 0x0000, 0xffff, memory::bsxpram);
|
||||
}
|
||||
|
||||
uint8 BSXCart::mmio_read(unsigned addr) {
|
@@ -60,7 +60,7 @@ void BSXFlash::write(unsigned addr, uint8 data) {
|
||||
//use read-write flashcarts, and HiROM-mapped BS-X carts always use
|
||||
//read-only flashcarts.
|
||||
//below is an unfortunately necessary workaround to this problem.
|
||||
if(cartridge.mapper() == Cartridge::BSCHiROM) return;
|
||||
//if(cartridge.mapper() == Cartridge::BSCHiROM) return;
|
||||
|
||||
if((addr & 0xff0000) == 0) {
|
||||
regs.write_old = regs.write_new;
|
@@ -11,7 +11,7 @@
|
||||
#include "dsp3/dsp3.hpp"
|
||||
#include "dsp4/dsp4.hpp"
|
||||
#include "obc1/obc1.hpp"
|
||||
#include "st010/st010.hpp"
|
||||
#include "st011/st011.hpp"
|
||||
#include "st018/st018.hpp"
|
||||
#include "21fx/21fx.hpp"
|
||||
#include "st0010/st0010.hpp"
|
||||
#include "st0011/st0011.hpp"
|
||||
#include "st0018/st0018.hpp"
|
||||
#include "msu1/msu1.hpp"
|
@@ -21,8 +21,6 @@ void Cx4::init() {
|
||||
}
|
||||
|
||||
void Cx4::enable() {
|
||||
bus.map(Bus::MapDirect, 0x00, 0x3f, 0x6000, 0x7fff, *this);
|
||||
bus.map(Bus::MapDirect, 0x80, 0xbf, 0x6000, 0x7fff, *this);
|
||||
}
|
||||
|
||||
uint32 Cx4::ldr(uint8 r) {
|
33
bsnes/chip/dsp1/dsp1.cpp
Normal file
33
bsnes/chip/dsp1/dsp1.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <../base.hpp>
|
||||
|
||||
#define DSP1_CPP
|
||||
namespace SNES {
|
||||
|
||||
DSP1 dsp1;
|
||||
DSP1DR dsp1dr;
|
||||
DSP1SR dsp1sr;
|
||||
|
||||
#include "serialization.cpp"
|
||||
#include "dsp1emu.cpp"
|
||||
|
||||
void DSP1::init() {
|
||||
}
|
||||
|
||||
void DSP1::enable() {
|
||||
}
|
||||
|
||||
void DSP1::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void DSP1::reset() {
|
||||
dsp1.reset();
|
||||
}
|
||||
|
||||
uint8 DSP1DR::read(unsigned addr) { return dsp1.dsp1.getDr(); }
|
||||
void DSP1DR::write(unsigned addr, uint8 data) { dsp1.dsp1.setDr(data); }
|
||||
|
||||
uint8 DSP1SR::read(unsigned addr) { return dsp1.dsp1.getSr(); }
|
||||
void DSP1SR::write(unsigned addr, uint8 data) {}
|
||||
|
||||
};
|
@@ -1,20 +1,30 @@
|
||||
#include "dsp1emu.hpp"
|
||||
|
||||
class DSP1 : public Memory {
|
||||
class DSP1 {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 read(unsigned addr);
|
||||
void write(unsigned addr, uint8 data);
|
||||
|
||||
void serialize(serializer&);
|
||||
|
||||
private:
|
||||
Dsp1 dsp1;
|
||||
bool addr_decode(uint16 addr);
|
||||
friend class DSP1DR;
|
||||
friend class DSP1SR;
|
||||
};
|
||||
|
||||
class DSP1DR : public Memory {
|
||||
uint8 read(unsigned addr);
|
||||
void write(unsigned addr, uint8 data);
|
||||
};
|
||||
|
||||
class DSP1SR : public Memory {
|
||||
uint8 read(unsigned addr);
|
||||
void write(unsigned addr, uint8 data);
|
||||
};
|
||||
|
||||
extern DSP1 dsp1;
|
||||
extern DSP1DR dsp1dr;
|
||||
extern DSP1SR dsp1sr;
|
@@ -12,10 +12,6 @@ void DSP2::init() {
|
||||
}
|
||||
|
||||
void DSP2::enable() {
|
||||
bus.map(Bus::MapDirect, 0x20, 0x3f, 0x6000, 0x6fff, *this);
|
||||
bus.map(Bus::MapDirect, 0x20, 0x3f, 0x8000, 0xbfff, *this);
|
||||
bus.map(Bus::MapDirect, 0xa0, 0xbf, 0x6000, 0x6fff, *this);
|
||||
bus.map(Bus::MapDirect, 0xa0, 0xbf, 0x8000, 0xbfff, *this);
|
||||
}
|
||||
|
||||
void DSP2::power() {
|
@@ -15,8 +15,6 @@ void DSP3::init() {
|
||||
}
|
||||
|
||||
void DSP3::enable() {
|
||||
bus.map(Bus::MapDirect, 0x20, 0x3f, 0x8000, 0xffff, *this);
|
||||
bus.map(Bus::MapDirect, 0xa0, 0xbf, 0x8000, 0xffff, *this);
|
||||
}
|
||||
|
||||
void DSP3::power() {
|
@@ -9,8 +9,6 @@ void DSP4::init() {
|
||||
}
|
||||
|
||||
void DSP4::enable() {
|
||||
bus.map(Bus::MapDirect, 0x30, 0x3f, 0x8000, 0xffff, *this);
|
||||
bus.map(Bus::MapDirect, 0xb0, 0xbf, 0x8000, 0xffff, *this);
|
||||
}
|
||||
|
||||
namespace DSP4i {
|
150
bsnes/chip/msu1/msu1.cpp
Normal file
150
bsnes/chip/msu1/msu1.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#include <../base.hpp>
|
||||
|
||||
#define MSU1_CPP
|
||||
namespace SNES {
|
||||
|
||||
MSU1 msu1;
|
||||
|
||||
#include "serialization.cpp"
|
||||
|
||||
void MSU1::enter() {
|
||||
scheduler.clock.cop_freq = 44100;
|
||||
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
int16 left = 0, right = 0;
|
||||
|
||||
if(mmio.audio_play) {
|
||||
if(audiofile.open()) {
|
||||
if(audiofile.end()) {
|
||||
if(!mmio.audio_repeat) mmio.audio_play = false;
|
||||
audiofile.seek(mmio.audio_offset = 58);
|
||||
} else {
|
||||
mmio.audio_offset += 4;
|
||||
left = audiofile.readl(2);
|
||||
right = audiofile.readl(2);
|
||||
}
|
||||
} else {
|
||||
mmio.audio_play = false;
|
||||
}
|
||||
}
|
||||
|
||||
left = sclamp<16>((double)left * (double)mmio.audio_volume / 255.0);
|
||||
right = sclamp<16>((double)right * (double)mmio.audio_volume / 255.0);
|
||||
|
||||
audio.coprocessor_sample(left, right);
|
||||
scheduler.addclocks_cop(1);
|
||||
scheduler.sync_copcpu();
|
||||
}
|
||||
}
|
||||
|
||||
void MSU1::init() {
|
||||
}
|
||||
|
||||
void MSU1::enable() {
|
||||
audio.coprocessor_enable(true);
|
||||
audio.coprocessor_frequency(44100.0);
|
||||
|
||||
if(datafile.open()) datafile.close();
|
||||
datafile.open(string() << basename << ".msu", file::mode_read);
|
||||
}
|
||||
|
||||
void MSU1::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void MSU1::reset() {
|
||||
mmio.data_offset = 0;
|
||||
mmio.audio_offset = 0;
|
||||
mmio.audio_track = 0;
|
||||
mmio.audio_volume = 255;
|
||||
mmio.data_busy = true;
|
||||
mmio.audio_busy = true;
|
||||
mmio.audio_repeat = false;
|
||||
mmio.audio_play = false;
|
||||
}
|
||||
|
||||
uint8 MSU1::mmio_read(unsigned addr) {
|
||||
addr &= 0xffff;
|
||||
|
||||
if(addr == 0x2000) {
|
||||
return (mmio.data_busy << 7)
|
||||
| (mmio.audio_busy << 6)
|
||||
| (mmio.audio_repeat << 5)
|
||||
| (mmio.audio_play << 4)
|
||||
| (Revision << 0);
|
||||
}
|
||||
|
||||
if(addr == 0x2001) {
|
||||
if(mmio.data_busy) return 0x00;
|
||||
mmio.data_offset++;
|
||||
if(datafile.open()) return datafile.read();
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
if(addr == 0x2002) return 'S';
|
||||
if(addr == 0x2003) return '-';
|
||||
if(addr == 0x2004) return 'M';
|
||||
if(addr == 0x2005) return 'S';
|
||||
if(addr == 0x2006) return 'U';
|
||||
if(addr == 0x2007) return '0' + Revision;
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void MSU1::mmio_write(unsigned addr, uint8 data) {
|
||||
addr &= 0xffff;
|
||||
|
||||
if(addr == 0x2000) {
|
||||
mmio.data_offset = (mmio.data_offset & 0xffffff00) | (data << 0);
|
||||
}
|
||||
|
||||
if(addr == 0x2001) {
|
||||
mmio.data_offset = (mmio.data_offset & 0xffff00ff) | (data << 8);
|
||||
}
|
||||
|
||||
if(addr == 0x2002) {
|
||||
mmio.data_offset = (mmio.data_offset & 0xff00ffff) | (data << 16);
|
||||
}
|
||||
|
||||
if(addr == 0x2003) {
|
||||
mmio.data_offset = (mmio.data_offset & 0x00ffffff) | (data << 24);
|
||||
if(datafile.open()) datafile.seek(mmio.data_offset);
|
||||
mmio.data_busy = false;
|
||||
}
|
||||
|
||||
if(addr == 0x2004) {
|
||||
mmio.audio_track = (mmio.audio_track & 0xff00) | (data << 0);
|
||||
}
|
||||
|
||||
if(addr == 0x2005) {
|
||||
mmio.audio_track = (mmio.audio_track & 0x00ff) | (data << 8);
|
||||
if(audiofile.open()) audiofile.close();
|
||||
char track[16];
|
||||
sprintf(track, "-%u", mmio.audio_track);
|
||||
if(audiofile.open(string() << basename << track << ".wav", file::mode_read)) {
|
||||
audiofile.seek(mmio.audio_offset = 58); //skip WAV header
|
||||
}
|
||||
mmio.audio_busy = false;
|
||||
mmio.audio_repeat = false;
|
||||
mmio.audio_play = false;
|
||||
}
|
||||
|
||||
if(addr == 0x2006) {
|
||||
mmio.audio_volume = data;
|
||||
}
|
||||
|
||||
if(addr == 0x2007) {
|
||||
mmio.audio_repeat = data & 2;
|
||||
mmio.audio_play = data & 1;
|
||||
}
|
||||
}
|
||||
|
||||
void MSU1::base(const string& name) {
|
||||
basename = name;
|
||||
}
|
||||
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
class S21fx : public MMIO {
|
||||
class MSU1 : public MMIO {
|
||||
public:
|
||||
void enter();
|
||||
|
||||
@@ -10,35 +10,32 @@ public:
|
||||
uint8 mmio_read(unsigned addr);
|
||||
void mmio_write(unsigned addr, uint8 data);
|
||||
|
||||
void base(const string &path);
|
||||
bool exists();
|
||||
|
||||
void base(const string &name);
|
||||
void serialize(serializer&);
|
||||
S21fx();
|
||||
|
||||
private:
|
||||
string basepath;
|
||||
string basename;
|
||||
file datafile;
|
||||
file audiofile;
|
||||
|
||||
enum Flag {
|
||||
DataPortBusy = 0x80,
|
||||
AudioBusy = 0x40,
|
||||
AudioPlaying = 0x20,
|
||||
DataBusy = 0x80,
|
||||
AudioBusy = 0x40,
|
||||
AudioRepeating = 0x20,
|
||||
AudioPlaying = 0x10,
|
||||
Revision = 0x01,
|
||||
};
|
||||
|
||||
struct MMIO {
|
||||
uint8 status;
|
||||
uint64 shift_register;
|
||||
|
||||
uint32 data_offset;
|
||||
uint32 audio_offset;
|
||||
uint16 audio_track;
|
||||
uint8 audio_volume_left;
|
||||
uint8 audio_volume_right;
|
||||
uint8 audio_volume;
|
||||
bool data_busy;
|
||||
bool audio_busy;
|
||||
bool audio_repeat;
|
||||
bool audio_pause;
|
||||
bool audio_play;
|
||||
} mmio;
|
||||
};
|
||||
|
||||
extern S21fx s21fx;
|
||||
extern MSU1 msu1;
|
26
bsnes/chip/msu1/serialization.cpp
Normal file
26
bsnes/chip/msu1/serialization.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifdef MSU1_CPP
|
||||
|
||||
void MSU1::serialize(serializer &s) {
|
||||
s.integer(mmio.data_offset);
|
||||
s.integer(mmio.audio_offset);
|
||||
s.integer(mmio.audio_track);
|
||||
s.integer(mmio.audio_volume);
|
||||
s.integer(mmio.data_busy);
|
||||
s.integer(mmio.audio_busy);
|
||||
s.integer(mmio.audio_repeat);
|
||||
s.integer(mmio.audio_play);
|
||||
|
||||
if(datafile.open()) datafile.close();
|
||||
if(datafile.open(string() << basename << ".msun", file::mode_read)) {
|
||||
datafile.seek(mmio.data_offset);
|
||||
}
|
||||
|
||||
if(audiofile.open()) audiofile.close();
|
||||
char track[16];
|
||||
sprintf(track, "-%u", mmio.audio_track);
|
||||
if(audiofile.open(string() << basename << track << ".wav", file::mode_read)) {
|
||||
audiofile.seek(mmio.audio_offset);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -11,8 +11,6 @@ void OBC1::init() {
|
||||
}
|
||||
|
||||
void OBC1::enable() {
|
||||
bus.map(Bus::MapDirect, 0x00, 0x3f, 0x6000, 0x7fff, *this);
|
||||
bus.map(Bus::MapDirect, 0x80, 0xbf, 0x6000, 0x7fff, *this);
|
||||
}
|
||||
|
||||
void OBC1::power() {
|
@@ -5,13 +5,13 @@ SA1Bus sa1bus;
|
||||
|
||||
namespace memory {
|
||||
StaticRAM iram(2048);
|
||||
//accessed by:
|
||||
VectorSelectionPage vectorsp; //S-CPU + SA-1
|
||||
CPUIRAM cpuiram; //S-CPU
|
||||
SA1IRAM sa1iram; //SA-1
|
||||
SA1BWRAM sa1bwram; //SA-1
|
||||
CC1BWRAM cc1bwram; //S-CPU
|
||||
BitmapRAM bitmapram; //SA-1
|
||||
//accessed by:
|
||||
VSPROM vsprom; //S-CPU + SA-1
|
||||
CPUIRAM cpuiram; //S-CPU
|
||||
SA1IRAM sa1iram; //SA-1
|
||||
SA1BWRAM sa1bwram; //SA-1
|
||||
CC1BWRAM cc1bwram; //S-CPU
|
||||
BitmapRAM bitmapram; //SA-1
|
||||
}
|
||||
|
||||
//$230c (VDPL), $230d (VDPH) use this bus to read variable-length data.
|
||||
@@ -20,53 +20,41 @@ namespace memory {
|
||||
//these ports.
|
||||
//(* eg, memory::cartram is used directly, as memory::sa1bwram syncs to the S-CPU)
|
||||
void VBRBus::init() {
|
||||
map(MapDirect, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped);
|
||||
map(MapMode::Direct, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped);
|
||||
|
||||
map(MapLinear, 0x00, 0x3f, 0x0000, 0x07ff, memory::iram);
|
||||
map(MapLinear, 0x00, 0x3f, 0x3000, 0x37ff, memory::iram);
|
||||
map(MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::cartram);
|
||||
map(MapLinear, 0x00, 0x3f, 0x8000, 0xffff, memory::cartrom);
|
||||
map(MapLinear, 0x40, 0x4f, 0x0000, 0xffff, memory::cartram);
|
||||
map(MapLinear, 0x80, 0xbf, 0x0000, 0x07ff, memory::iram);
|
||||
map(MapLinear, 0x80, 0xbf, 0x3000, 0x37ff, memory::iram);
|
||||
map(MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::cartram);
|
||||
map(MapLinear, 0x80, 0xbf, 0x8000, 0xffff, memory::cartrom);
|
||||
map(MapLinear, 0xc0, 0xff, 0x0000, 0xffff, memory::cartrom);
|
||||
map(MapMode::Linear, 0x00, 0x3f, 0x0000, 0x07ff, memory::iram);
|
||||
map(MapMode::Linear, 0x00, 0x3f, 0x3000, 0x37ff, memory::iram);
|
||||
map(MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::cartram);
|
||||
map(MapMode::Linear, 0x00, 0x3f, 0x8000, 0xffff, memory::vsprom);
|
||||
map(MapMode::Linear, 0x40, 0x4f, 0x0000, 0xffff, memory::cartram);
|
||||
map(MapMode::Linear, 0x80, 0xbf, 0x0000, 0x07ff, memory::iram);
|
||||
map(MapMode::Linear, 0x80, 0xbf, 0x3000, 0x37ff, memory::iram);
|
||||
map(MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::cartram);
|
||||
map(MapMode::Linear, 0x80, 0xbf, 0x8000, 0xffff, memory::vsprom);
|
||||
map(MapMode::Linear, 0xc0, 0xff, 0x0000, 0xffff, memory::vsprom);
|
||||
}
|
||||
|
||||
void SA1Bus::init() {
|
||||
map(MapDirect, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped);
|
||||
for(unsigned i = 0x2200; i <= 0x23ff; i++) memory::mmio.map(i, sa1);
|
||||
map(MapMode::Direct, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped);
|
||||
|
||||
map(MapLinear, 0x00, 0x3f, 0x0000, 0x07ff, memory::sa1iram);
|
||||
map(MapDirect, 0x00, 0x3f, 0x2200, 0x23ff, memory::mmio);
|
||||
map(MapLinear, 0x00, 0x3f, 0x3000, 0x37ff, memory::sa1iram);
|
||||
map(MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::sa1bwram);
|
||||
map(MapLinear, 0x00, 0x3f, 0x8000, 0xffff, memory::cartrom);
|
||||
map(MapLinear, 0x40, 0x4f, 0x0000, 0xffff, memory::sa1bwram);
|
||||
map(MapLinear, 0x60, 0x6f, 0x0000, 0xffff, memory::bitmapram);
|
||||
map(MapLinear, 0x80, 0xbf, 0x0000, 0x07ff, memory::sa1iram);
|
||||
map(MapDirect, 0x80, 0xbf, 0x2200, 0x23ff, memory::mmio);
|
||||
map(MapLinear, 0x80, 0xbf, 0x3000, 0x37ff, memory::sa1iram);
|
||||
map(MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::sa1bwram);
|
||||
map(MapLinear, 0x80, 0xbf, 0x8000, 0xffff, memory::cartrom);
|
||||
map(MapLinear, 0xc0, 0xff, 0x0000, 0xffff, memory::cartrom);
|
||||
|
||||
bus.map(MapLinear, 0x00, 0x3f, 0x3000, 0x37ff, memory::cpuiram);
|
||||
bus.map(MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::cc1bwram);
|
||||
bus.map(MapLinear, 0x00, 0x3f, 0x8000, 0xffff, memory::cartrom);
|
||||
bus.map(MapLinear, 0x40, 0x4f, 0x0000, 0xffff, memory::cc1bwram);
|
||||
bus.map(MapLinear, 0x80, 0xbf, 0x3000, 0x37ff, memory::cpuiram);
|
||||
bus.map(MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::cc1bwram);
|
||||
bus.map(MapLinear, 0x80, 0xbf, 0x8000, 0xffff, memory::cartrom);
|
||||
bus.map(MapLinear, 0xc0, 0xff, 0x0000, 0xffff, memory::cartrom);
|
||||
|
||||
memory::vectorsp.sync();
|
||||
map(MapMode::Linear, 0x00, 0x3f, 0x0000, 0x07ff, memory::sa1iram);
|
||||
map(MapMode::Direct, 0x00, 0x3f, 0x2200, 0x23ff, memory::mmio);
|
||||
map(MapMode::Linear, 0x00, 0x3f, 0x3000, 0x37ff, memory::sa1iram);
|
||||
map(MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::sa1bwram);
|
||||
map(MapMode::Linear, 0x00, 0x3f, 0x8000, 0xffff, memory::vsprom);
|
||||
map(MapMode::Linear, 0x40, 0x4f, 0x0000, 0xffff, memory::sa1bwram);
|
||||
map(MapMode::Linear, 0x60, 0x6f, 0x0000, 0xffff, memory::bitmapram);
|
||||
map(MapMode::Linear, 0x80, 0xbf, 0x0000, 0x07ff, memory::sa1iram);
|
||||
map(MapMode::Direct, 0x80, 0xbf, 0x2200, 0x23ff, memory::mmio);
|
||||
map(MapMode::Linear, 0x80, 0xbf, 0x3000, 0x37ff, memory::sa1iram);
|
||||
map(MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::sa1bwram);
|
||||
map(MapMode::Linear, 0x80, 0xbf, 0x8000, 0xffff, memory::vsprom);
|
||||
map(MapMode::Linear, 0xc0, 0xff, 0x0000, 0xffff, memory::vsprom);
|
||||
}
|
||||
|
||||
//===================
|
||||
//VectorSelectionPage
|
||||
//===================
|
||||
//======
|
||||
//VSPROM
|
||||
//======
|
||||
|
||||
//this class maps $00:[ff00-ffff] for the purpose of supporting:
|
||||
//$2209.d6 IVSW (S-CPU IRQ vector selection) (0 = cart, 1 = SA-1)
|
||||
@@ -78,35 +66,22 @@ void SA1Bus::init() {
|
||||
//$00:[ffea-ffeb|ffee-ffef] are special cased on read;
|
||||
//all other addresses return original mapped data.
|
||||
|
||||
uint8 VectorSelectionPage::read(unsigned addr) {
|
||||
switch(0xff00 | (addr & 0xff)) {
|
||||
case 0xffea: case 0xffeb: {
|
||||
if(sa1.mmio.cpu_nvsw == true) return (sa1.mmio.snv >> ((addr & 1) << 3));
|
||||
} break;
|
||||
|
||||
case 0xffee: case 0xffef: {
|
||||
if(sa1.mmio.cpu_ivsw == true) return (sa1.mmio.siv >> ((addr & 1) << 3));
|
||||
} break;
|
||||
}
|
||||
|
||||
return access->read(addr);
|
||||
unsigned VSPROM::size() const {
|
||||
return memory::cartrom.size();
|
||||
}
|
||||
|
||||
void VectorSelectionPage::write(unsigned addr, uint8 data) {
|
||||
return access->write(addr, data);
|
||||
uint8 VSPROM::read(unsigned addr) {
|
||||
//use $7fex instead of $ffex due to linear mapping of 32k granularity ROM data
|
||||
if((addr & 0xffffe0) == 0x007fe0) {
|
||||
if(addr == 0x7fea && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 0;
|
||||
if(addr == 0x7feb && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 8;
|
||||
if(addr == 0x7fee && sa1.mmio.cpu_ivsw) return sa1.mmio.siv >> 0;
|
||||
if(addr == 0x7fef && sa1.mmio.cpu_ivsw) return sa1.mmio.siv >> 8;
|
||||
}
|
||||
return memory::cartrom.read(addr);
|
||||
}
|
||||
|
||||
//call this whenever bus is remapped.
|
||||
//note: S-CPU and SA-1 bus always share $00:[ff00-ffff] as cartridge ROM data;
|
||||
//the SA-1 MMC does not allow mapping these independently between processors.
|
||||
//this allows this class to be shared for both, caching only ones' access class.
|
||||
void VectorSelectionPage::sync() {
|
||||
if(bus.page[0x00ff00 >> 8].access != this) {
|
||||
//bus was re-mapped, hook access routine
|
||||
access = bus.page[0x00ff00 >> 8].access;
|
||||
bus.page[0x00ff00 >> 8].access = this;
|
||||
sa1bus.page[0x00ff00 >> 8].access = this;
|
||||
}
|
||||
void VSPROM::write(unsigned addr, uint8 data) {
|
||||
}
|
||||
|
||||
//=======
|
@@ -6,11 +6,10 @@ struct SA1Bus : Bus {
|
||||
void init();
|
||||
};
|
||||
|
||||
struct VectorSelectionPage : Memory {
|
||||
struct VSPROM : Memory {
|
||||
unsigned size() const;
|
||||
alwaysinline uint8 read(unsigned);
|
||||
alwaysinline void write(unsigned, uint8);
|
||||
void sync();
|
||||
Memory *access;
|
||||
};
|
||||
|
||||
struct CPUIRAM : Memory {
|
||||
@@ -47,7 +46,7 @@ struct BitmapRAM : Memory {
|
||||
namespace memory {
|
||||
extern StaticRAM iram;
|
||||
|
||||
extern VectorSelectionPage vectorsp;
|
||||
extern VSPROM vsprom;
|
||||
extern CPUIRAM cpuiram;
|
||||
extern SA1IRAM sa1iram;
|
||||
extern SA1BWRAM sa1bwram;
|
@@ -2,8 +2,8 @@
|
||||
|
||||
//BS-X flash carts, when present, are mapped to 0x400000+
|
||||
Memory& SA1::mmio_access(unsigned &addr) {
|
||||
if(!memory::bsxflash.data()) return memory::cartrom;
|
||||
if(addr < 0x400000) return memory::cartrom;
|
||||
if(!memory::bsxflash.data()) return memory::vsprom;
|
||||
if(addr < 0x400000) return memory::vsprom;
|
||||
addr &= 0x3fffff;
|
||||
return bsxflash;
|
||||
}
|
||||
@@ -156,17 +156,15 @@ void SA1::mmio_w2220(uint8 data) {
|
||||
Memory &access = mmio_access(addr);
|
||||
|
||||
if(mmio.cbmode == 0) {
|
||||
bus.map(Bus::MapLinear, 0x00, 0x1f, 0x8000, 0xffff, memory::cartrom, 0x000000);
|
||||
sa1bus.map(Bus::MapLinear, 0x00, 0x1f, 0x8000, 0xffff, memory::cartrom, 0x000000);
|
||||
bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, memory::vsprom, 0x000000);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, memory::vsprom, 0x000000);
|
||||
} else {
|
||||
bus.map(Bus::MapLinear, 0x00, 0x1f, 0x8000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapLinear, 0x00, 0x1f, 0x8000, 0xffff, access, addr);
|
||||
bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, access, addr);
|
||||
}
|
||||
|
||||
bus.map(Bus::MapLinear, 0xc0, 0xcf, 0x0000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapLinear, 0xc0, 0xcf, 0x0000, 0xffff, access, addr);
|
||||
|
||||
memory::vectorsp.sync();
|
||||
bus.map(Bus::MapMode::Linear, 0xc0, 0xcf, 0x0000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0xc0, 0xcf, 0x0000, 0xffff, access, addr);
|
||||
}
|
||||
|
||||
//(DXB) Super MMC bank D
|
||||
@@ -178,15 +176,15 @@ void SA1::mmio_w2221(uint8 data) {
|
||||
Memory &access = mmio_access(addr);
|
||||
|
||||
if(mmio.dbmode == 0) {
|
||||
bus.map(Bus::MapLinear, 0x20, 0x3f, 0x8000, 0xffff, memory::cartrom, 0x100000);
|
||||
sa1bus.map(Bus::MapLinear, 0x20, 0x3f, 0x8000, 0xffff, memory::cartrom, 0x100000);
|
||||
bus.map(Bus::MapMode::Linear, 0x20, 0x3f, 0x8000, 0xffff, memory::vsprom, 0x100000);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0x20, 0x3f, 0x8000, 0xffff, memory::vsprom, 0x100000);
|
||||
} else {
|
||||
bus.map(Bus::MapLinear, 0x20, 0x3f, 0x8000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapLinear, 0x20, 0x3f, 0x8000, 0xffff, access, addr);
|
||||
bus.map(Bus::MapMode::Linear, 0x20, 0x3f, 0x8000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0x20, 0x3f, 0x8000, 0xffff, access, addr);
|
||||
}
|
||||
|
||||
bus.map(Bus::MapLinear, 0xd0, 0xdf, 0x0000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapLinear, 0xd0, 0xdf, 0x0000, 0xffff, access, addr);
|
||||
bus.map(Bus::MapMode::Linear, 0xd0, 0xdf, 0x0000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0xd0, 0xdf, 0x0000, 0xffff, access, addr);
|
||||
}
|
||||
|
||||
//(EXB) Super MMC bank E
|
||||
@@ -198,15 +196,15 @@ void SA1::mmio_w2222(uint8 data) {
|
||||
Memory &access = mmio_access(addr);
|
||||
|
||||
if(mmio.ebmode == 0) {
|
||||
bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom, 0x200000);
|
||||
sa1bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom, 0x200000);
|
||||
bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, memory::vsprom, 0x200000);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, memory::vsprom, 0x200000);
|
||||
} else {
|
||||
bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, access, addr);
|
||||
bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, access, addr);
|
||||
}
|
||||
|
||||
bus.map(Bus::MapLinear, 0xe0, 0xef, 0x0000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapLinear, 0xe0, 0xef, 0x0000, 0xffff, access, addr);
|
||||
bus.map(Bus::MapMode::Linear, 0xe0, 0xef, 0x0000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0xe0, 0xef, 0x0000, 0xffff, access, addr);
|
||||
}
|
||||
|
||||
//(FXB) Super MMC bank F
|
||||
@@ -218,23 +216,23 @@ void SA1::mmio_w2223(uint8 data) {
|
||||
Memory &access = mmio_access(addr);
|
||||
|
||||
if(mmio.fbmode == 0) {
|
||||
bus.map(Bus::MapLinear, 0xa0, 0xbf, 0x8000, 0xffff, memory::cartrom, 0x300000);
|
||||
sa1bus.map(Bus::MapLinear, 0xa0, 0xbf, 0x8000, 0xffff, memory::cartrom, 0x300000);
|
||||
bus.map(Bus::MapMode::Linear, 0xa0, 0xbf, 0x8000, 0xffff, memory::vsprom, 0x300000);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0xa0, 0xbf, 0x8000, 0xffff, memory::vsprom, 0x300000);
|
||||
} else {
|
||||
bus.map(Bus::MapLinear, 0xa0, 0xbf, 0x8000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapLinear, 0xa0, 0xbf, 0x8000, 0xffff, access, addr);
|
||||
bus.map(Bus::MapMode::Linear, 0xa0, 0xbf, 0x8000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0xa0, 0xbf, 0x8000, 0xffff, access, addr);
|
||||
}
|
||||
|
||||
bus.map(Bus::MapLinear, 0xf0, 0xff, 0x0000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapLinear, 0xf0, 0xff, 0x0000, 0xffff, access, addr);
|
||||
bus.map(Bus::MapMode::Linear, 0xf0, 0xff, 0x0000, 0xffff, access, addr);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0xf0, 0xff, 0x0000, 0xffff, access, addr);
|
||||
}
|
||||
|
||||
//(BMAPS) S-CPU BW-RAM address mapping
|
||||
void SA1::mmio_w2224(uint8 data) {
|
||||
mmio.sbm = (data & 0x1f);
|
||||
|
||||
bus.map(Bus::MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::cc1bwram, mmio.sbm * 0x2000, 0x2000);
|
||||
bus.map(Bus::MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::cc1bwram, mmio.sbm * 0x2000, 0x2000);
|
||||
bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::cc1bwram, mmio.sbm * 0x2000, 0x2000);
|
||||
bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::cc1bwram, mmio.sbm * 0x2000, 0x2000);
|
||||
}
|
||||
|
||||
//(BMAP) SA-1 BW-RAM address mapping
|
||||
@@ -244,12 +242,12 @@ void SA1::mmio_w2225(uint8 data) {
|
||||
|
||||
if(mmio.sw46 == 0) {
|
||||
//$[40-43]:[0000-ffff] x 32 projection
|
||||
sa1bus.map(Bus::MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::sa1bwram, (mmio.cbm & 0x1f) * 0x2000, 0x2000);
|
||||
sa1bus.map(Bus::MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::sa1bwram, (mmio.cbm & 0x1f) * 0x2000, 0x2000);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::sa1bwram, (mmio.cbm & 0x1f) * 0x2000, 0x2000);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::sa1bwram, (mmio.cbm & 0x1f) * 0x2000, 0x2000);
|
||||
} else {
|
||||
//$[60-6f]:[0000-ffff] x 128 projection
|
||||
sa1bus.map(Bus::MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::bitmapram, mmio.cbm * 0x2000, 0x2000);
|
||||
sa1bus.map(Bus::MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::bitmapram, mmio.cbm * 0x2000, 0x2000);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::bitmapram, mmio.cbm * 0x2000, 0x2000);
|
||||
sa1bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::bitmapram, mmio.cbm * 0x2000, 0x2000);
|
||||
}
|
||||
}
|
||||
|
@@ -13,8 +13,8 @@ SA1 sa1;
|
||||
|
||||
void SA1::enter() {
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SyncAll) {
|
||||
scheduler.exit(Scheduler::SynchronizeEvent);
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
if(mmio.sa1_rdyb || mmio.sa1_resb) {
|
||||
@@ -127,7 +127,6 @@ void SA1::power() {
|
||||
}
|
||||
|
||||
void SA1::reset() {
|
||||
memory::vectorsp.access = 0;
|
||||
memory::cc1bwram.dma = false;
|
||||
for(unsigned addr = 0; addr < memory::iram.size(); addr++) {
|
||||
memory::iram.write(addr, 0x00);
|
||||
@@ -152,7 +151,7 @@ void SA1::reset() {
|
||||
status.interrupt_pending = false;
|
||||
status.interrupt_vector = 0x0000;
|
||||
|
||||
status.scanlines = (system.region() == System::NTSC ? 262 : 312);
|
||||
status.scanlines = (system.region() == System::Region::NTSC ? 262 : 312);
|
||||
status.vcounter = 0;
|
||||
status.hcounter = 0;
|
||||
|
@@ -16,8 +16,6 @@ void SA1::serialize(serializer &s) {
|
||||
//bus/bus.hpp
|
||||
s.array(memory::iram.data(), memory::iram.size());
|
||||
|
||||
memory::vectorsp.sync();
|
||||
|
||||
s.integer(memory::cc1bwram.dma);
|
||||
|
||||
//dma/dma.hpp
|
@@ -17,11 +17,6 @@ void SDD1::enable() {
|
||||
cpu_mmio[i & 0x7f] = memory::mmio.mmio[i - 0x2000];
|
||||
memory::mmio.map(i, *this);
|
||||
}
|
||||
|
||||
//hook S-DD1 MMIO registers
|
||||
for(unsigned i = 0x4800; i <= 0x4807; i++) {
|
||||
memory::mmio.map(i, *this);
|
||||
}
|
||||
}
|
||||
|
||||
void SDD1::power() {
|
||||
@@ -43,8 +38,6 @@ void SDD1::reset() {
|
||||
}
|
||||
|
||||
buffer.ready = false;
|
||||
|
||||
bus.map(Bus::MapDirect, 0xc0, 0xff, 0x0000, 0xffff, *this);
|
||||
}
|
||||
|
||||
uint8 SDD1::mmio_read(unsigned addr) {
|
@@ -24,9 +24,9 @@ void SPC7110Decomp::write(uint8 data) {
|
||||
}
|
||||
|
||||
uint8 SPC7110Decomp::dataread() {
|
||||
unsigned size = memory::cartrom.size() - 0x100000;
|
||||
unsigned size = memory::cartrom.size() - cartridge.spc7110_data_rom_offset();
|
||||
while(decomp_offset >= size) decomp_offset -= size;
|
||||
return memory::cartrom.read(0x100000 + decomp_offset++);
|
||||
return memory::cartrom.read(cartridge.spc7110_data_rom_offset() + decomp_offset++);
|
||||
}
|
||||
|
||||
void SPC7110Decomp::init(unsigned mode, unsigned offset, unsigned index) {
|
@@ -4,6 +4,9 @@
|
||||
namespace SNES {
|
||||
|
||||
SPC7110 spc7110;
|
||||
SPC7110MCU spc7110mcu;
|
||||
SPC7110DCU spc7110dcu;
|
||||
SPC7110RAM spc7110ram;
|
||||
|
||||
#include "serialization.cpp"
|
||||
#include "decomp.cpp"
|
||||
@@ -11,11 +14,7 @@ SPC7110 spc7110;
|
||||
const unsigned SPC7110::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
void SPC7110::init() {}
|
||||
|
||||
void SPC7110::enable() {
|
||||
uint16_t limit = (cartridge.has_spc7110rtc() ? 0x4842 : 0x483f);
|
||||
for(uint16_t i = 0x4800; i <= limit; i++) memory::mmio.map(i, *this);
|
||||
}
|
||||
void SPC7110::enable() {}
|
||||
|
||||
void SPC7110::power() {
|
||||
reset();
|
||||
@@ -85,9 +84,9 @@ void SPC7110::reset() {
|
||||
}
|
||||
|
||||
unsigned SPC7110::datarom_addr(unsigned addr) {
|
||||
unsigned size = memory::cartrom.size() - 0x100000;
|
||||
unsigned size = memory::cartrom.size() - cartridge.spc7110_data_rom_offset();
|
||||
while(addr >= size) addr -= size;
|
||||
return addr + 0x100000;
|
||||
return cartridge.spc7110_data_rom_offset() + addr;
|
||||
}
|
||||
|
||||
unsigned SPC7110::data_pointer() { return r4811 + (r4812 << 8) + (r4813 << 16); }
|
||||
@@ -632,46 +631,52 @@ void SPC7110::mmio_write(unsigned addr, uint8 data) {
|
||||
}
|
||||
}
|
||||
|
||||
uint8 SPC7110::read(unsigned addr) {
|
||||
//$[00-0f|80-8f]:[8000-ffff], $[c0-cf]:[0000-ffff] mapped directly to memory::cartrom
|
||||
|
||||
if((addr & 0xffe000) == 0x006000 || (addr & 0xffe000) == 0x306000) {
|
||||
//$[00|30]:[6000-7fff]
|
||||
return memory::cartram.read(addr & 0x1fff);
|
||||
}
|
||||
|
||||
if((addr & 0xff0000) == 0x500000) {
|
||||
//$[50]:[0000-ffff]
|
||||
return mmio_read(0x4800);
|
||||
}
|
||||
|
||||
if((addr & 0xf00000) == 0xd00000) {
|
||||
//$[d0-df]:[0000-ffff]
|
||||
return memory::cartrom.read(dx_offset + (addr & 0x0fffff));
|
||||
}
|
||||
|
||||
if((addr & 0xf00000) == 0xe00000) {
|
||||
//$[e0-ef]:[0000-ffff]
|
||||
return memory::cartrom.read(ex_offset + (addr & 0x0fffff));
|
||||
}
|
||||
|
||||
if((addr & 0xf00000) == 0xf00000) {
|
||||
//$[f0-ff]:[0000-ffff]
|
||||
return memory::cartrom.read(fx_offset + (addr & 0x0fffff));
|
||||
}
|
||||
|
||||
return cpu.regs.mdr;
|
||||
}
|
||||
|
||||
void SPC7110::write(unsigned addr, uint8 data) {
|
||||
if((addr & 0xffe000) == 0x006000 || (addr & 0xffe000) == 0x306000) {
|
||||
//$[00|30]:[6000-7fff]
|
||||
if(r4830 & 0x80) memory::cartram.write(addr & 0x1fff, data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SPC7110::SPC7110() {
|
||||
}
|
||||
|
||||
//==========
|
||||
//SPC7110MCU
|
||||
//==========
|
||||
|
||||
unsigned SPC7110MCU::size() const {
|
||||
return 0x300000;
|
||||
}
|
||||
|
||||
uint8 SPC7110MCU::read(unsigned addr) {
|
||||
if(addr <= 0xdfffff) return memory::cartrom.read(spc7110.dx_offset + (addr & 0x0fffff));
|
||||
if(addr <= 0xefffff) return memory::cartrom.read(spc7110.ex_offset + (addr & 0x0fffff));
|
||||
if(addr <= 0xffffff) return memory::cartrom.read(spc7110.fx_offset + (addr & 0x0fffff));
|
||||
return cpu.regs.mdr;
|
||||
}
|
||||
|
||||
void SPC7110MCU::write(unsigned addr, uint8 data) {
|
||||
}
|
||||
|
||||
//==========
|
||||
//SPC7110DCU
|
||||
//==========
|
||||
|
||||
uint8 SPC7110DCU::read(unsigned) {
|
||||
return spc7110.mmio_read(0x4800);
|
||||
}
|
||||
|
||||
void SPC7110DCU::write(unsigned, uint8) {
|
||||
}
|
||||
|
||||
//==========
|
||||
//SPC7110RAM
|
||||
//==========
|
||||
|
||||
unsigned SPC7110RAM::size() const {
|
||||
return 0x2000;
|
||||
}
|
||||
|
||||
uint8 SPC7110RAM::read(unsigned addr) {
|
||||
return memory::cartram.read(addr & 0x1fff);
|
||||
}
|
||||
|
||||
void SPC7110RAM::write(unsigned addr, uint8 data) {
|
||||
if(spc7110.r4830 & 0x80) memory::cartram.write(addr & 0x1fff, data);
|
||||
}
|
||||
|
||||
};
|
@@ -1,6 +1,6 @@
|
||||
/*****
|
||||
* SPC7110 emulator - version 0.03 (2008-08-10)
|
||||
* Copyright (c) 2008, byuu and neviksti
|
||||
* SPC7110 emulator - version 0.04 (2010-02-14)
|
||||
* Copyright (c) 2008-2010, byuu and neviksti
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include "decomp.hpp"
|
||||
|
||||
class SPC7110 : public MMIO, public Memory {
|
||||
class SPC7110 : public MMIO {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
@@ -38,9 +38,6 @@ public:
|
||||
uint8 mmio_read(unsigned addr);
|
||||
void mmio_write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 read(unsigned addr);
|
||||
void write(unsigned addr, uint8 data);
|
||||
|
||||
//spc7110decomp
|
||||
void decomp_init();
|
||||
uint8 decomp_read();
|
||||
@@ -131,6 +128,32 @@ private:
|
||||
unsigned rtc_index;
|
||||
|
||||
static const unsigned months[12];
|
||||
friend class SPC7110MCU;
|
||||
friend class SPC7110DCU;
|
||||
friend class SPC7110RAM;
|
||||
};
|
||||
|
||||
class SPC7110MCU : public Memory {
|
||||
public:
|
||||
unsigned size() const;
|
||||
uint8 read(unsigned addr);
|
||||
void write(unsigned addr, uint8 data);
|
||||
};
|
||||
|
||||
class SPC7110DCU : public Memory {
|
||||
public:
|
||||
uint8 read(unsigned addr);
|
||||
void write(unsigned addr, uint8 data);
|
||||
};
|
||||
|
||||
class SPC7110RAM : public Memory {
|
||||
public:
|
||||
unsigned size() const;
|
||||
uint8 read(unsigned addr);
|
||||
void write(unsigned addr, uint8 data);
|
||||
};
|
||||
|
||||
extern SPC7110 spc7110;
|
||||
extern SPC7110MCU spc7110mcu;
|
||||
extern SPC7110DCU spc7110dcu;
|
||||
extern SPC7110RAM spc7110ram;
|
@@ -13,8 +13,6 @@ void SRTC::init() {
|
||||
}
|
||||
|
||||
void SRTC::enable() {
|
||||
memory::mmio.map(0x2800, *this);
|
||||
memory::mmio.map(0x2801, *this);
|
||||
}
|
||||
|
||||
void SRTC::power() {
|
@@ -1,4 +1,6 @@
|
||||
const int16 ST010::sin_table[256] = {
|
||||
#ifdef ST0010_CPP
|
||||
|
||||
const int16 ST0010::sin_table[256] = {
|
||||
0x0000, 0x0324, 0x0648, 0x096a, 0x0c8c, 0x0fab, 0x12c8, 0x15e2,
|
||||
0x18f9, 0x1c0b, 0x1f1a, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11,
|
||||
0x30fb, 0x33df, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a,
|
||||
@@ -33,7 +35,7 @@ const int16 ST010::sin_table[256] = {
|
||||
-0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324
|
||||
};
|
||||
|
||||
const int16 ST010::mode7_scale[176] = {
|
||||
const int16 ST0010::mode7_scale[176] = {
|
||||
0x0380, 0x0325, 0x02da, 0x029c, 0x0268, 0x023b, 0x0215, 0x01f3,
|
||||
0x01d5, 0x01bb, 0x01a3, 0x018e, 0x017b, 0x016a, 0x015a, 0x014b,
|
||||
0x013e, 0x0132, 0x0126, 0x011c, 0x0112, 0x0109, 0x0100, 0x00f8,
|
||||
@@ -58,7 +60,7 @@ const int16 ST010::mode7_scale[176] = {
|
||||
0x002d, 0x002c, 0x002c, 0x002c, 0x002c, 0x002b, 0x002b, 0x002b
|
||||
};
|
||||
|
||||
const uint8 ST010::arctan[32][32] = {
|
||||
const uint8 ST0010::arctan[32][32] = {
|
||||
{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 },
|
||||
{ 0x80, 0xa0, 0xad, 0xb3, 0xb6, 0xb8, 0xb9, 0xba, 0xbb, 0xbb, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd,
|
||||
@@ -124,3 +126,5 @@ const uint8 ST010::arctan[32][32] = {
|
||||
{ 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92,
|
||||
0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0 }
|
||||
};
|
||||
|
||||
#endif
|
@@ -1,9 +1,9 @@
|
||||
#ifdef ST010_CPP
|
||||
#ifdef ST0010_CPP
|
||||
|
||||
//ST-010 emulation code - Copyright (C) 2003 The Dumper, Matthew Kendora, Overload, Feather
|
||||
//ST-0010 emulation code - Copyright (C) 2003 The Dumper, Matthew Kendora, Overload, Feather
|
||||
//bsnes port - Copyright (C) 2007 byuu
|
||||
|
||||
void ST010::op_01(int16 x0, int16 y0, int16 &x1, int16 &y1, int16 &quadrant, int16 &theta) {
|
||||
void ST0010::op_01(int16 x0, int16 y0, int16 &x1, int16 &y1, int16 &quadrant, int16 &theta) {
|
||||
if((x0 < 0) && (y0 < 0)) {
|
||||
x1 = -x0;
|
||||
y1 = -y0;
|
||||
@@ -34,7 +34,7 @@ void ST010::op_01(int16 x0, int16 y0, int16 &x1, int16 &y1, int16 &quadrant, int
|
||||
|
||||
//
|
||||
|
||||
void ST010::op_01() {
|
||||
void ST0010::op_01() {
|
||||
int16 x0 = readw(0x0000);
|
||||
int16 y0 = readw(0x0002);
|
||||
int16 x1, y1, quadrant, theta;
|
||||
@@ -48,7 +48,7 @@ void ST010::op_01() {
|
||||
writew(0x0010, theta);
|
||||
}
|
||||
|
||||
void ST010::op_02() {
|
||||
void ST0010::op_02() {
|
||||
int16 positions = readw(0x0024);
|
||||
uint16 *places = (uint16*)(ram + 0x0040);
|
||||
uint16 *drivers = (uint16*)(ram + 0x0080);
|
||||
@@ -76,7 +76,7 @@ void ST010::op_02() {
|
||||
}
|
||||
}
|
||||
|
||||
void ST010::op_03() {
|
||||
void ST0010::op_03() {
|
||||
int16 x0 = readw(0x0000);
|
||||
int16 y0 = readw(0x0002);
|
||||
int16 multiplier = readw(0x0004);
|
||||
@@ -89,7 +89,7 @@ void ST010::op_03() {
|
||||
writed(0x0014, y1);
|
||||
}
|
||||
|
||||
void ST010::op_04() {
|
||||
void ST0010::op_04() {
|
||||
int16 x = readw(0x0000);
|
||||
int16 y = readw(0x0002);
|
||||
int16 square;
|
||||
@@ -99,7 +99,7 @@ void ST010::op_04() {
|
||||
writew(0x0010, square);
|
||||
}
|
||||
|
||||
void ST010::op_05() {
|
||||
void ST0010::op_05() {
|
||||
int32 dx, dy;
|
||||
int16 a1, b1, c1;
|
||||
uint16 o1;
|
||||
@@ -217,7 +217,7 @@ void ST010::op_05() {
|
||||
writew(0x00dc, flags);
|
||||
}
|
||||
|
||||
void ST010::op_06() {
|
||||
void ST0010::op_06() {
|
||||
int16 multiplicand = readw(0x0000);
|
||||
int16 multiplier = readw(0x0002);
|
||||
int32 product;
|
||||
@@ -227,7 +227,7 @@ void ST010::op_06() {
|
||||
writed(0x0010, product);
|
||||
}
|
||||
|
||||
void ST010::op_07() {
|
||||
void ST0010::op_07() {
|
||||
int16 theta = readw(0x0000);
|
||||
|
||||
int16 data;
|
||||
@@ -245,7 +245,7 @@ void ST010::op_07() {
|
||||
}
|
||||
}
|
||||
|
||||
void ST010::op_08() {
|
||||
void ST0010::op_08() {
|
||||
int16 x0 = readw(0x0000);
|
||||
int16 y0 = readw(0x0002);
|
||||
int16 theta = readw(0x0004);
|
7
bsnes/chip/st0010/serialization.cpp
Normal file
7
bsnes/chip/st0010/serialization.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifdef ST0010_CPP
|
||||
|
||||
void ST0010::serialize(serializer &s) {
|
||||
s.array(ram);
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,56 +1,54 @@
|
||||
#include <../base.hpp>
|
||||
|
||||
#define ST010_CPP
|
||||
#define ST0010_CPP
|
||||
namespace SNES {
|
||||
|
||||
ST010 st010;
|
||||
ST0010 st0010;
|
||||
|
||||
#include "st010_data.hpp"
|
||||
#include "data.hpp"
|
||||
#include "opcodes.cpp"
|
||||
#include "serialization.cpp"
|
||||
#include "st010_op.cpp"
|
||||
|
||||
void ST010::init() {
|
||||
void ST0010::init() {
|
||||
}
|
||||
|
||||
void ST010::enable() {
|
||||
bus.map(Bus::MapDirect, 0x68, 0x6f, 0x0000, 0x0fff, *this);
|
||||
bus.map(Bus::MapDirect, 0xe8, 0xef, 0x0000, 0x0fff, *this);
|
||||
void ST0010::enable() {
|
||||
}
|
||||
|
||||
int16 ST010::sin(int16 theta) {
|
||||
int16 ST0010::sin(int16 theta) {
|
||||
return sin_table[(theta >> 8) & 0xff];
|
||||
}
|
||||
|
||||
int16 ST010::cos(int16 theta) {
|
||||
int16 ST0010::cos(int16 theta) {
|
||||
return sin_table[((theta + 0x4000) >> 8) & 0xff];
|
||||
}
|
||||
|
||||
uint8 ST010::readb(uint16 addr) {
|
||||
uint8 ST0010::readb(uint16 addr) {
|
||||
return ram[addr & 0xfff];
|
||||
}
|
||||
|
||||
uint16 ST010::readw(uint16 addr) {
|
||||
uint16 ST0010::readw(uint16 addr) {
|
||||
return (readb(addr + 0) << 0) |
|
||||
(readb(addr + 1) << 8);
|
||||
}
|
||||
|
||||
uint32 ST010::readd(uint16 addr) {
|
||||
uint32 ST0010::readd(uint16 addr) {
|
||||
return (readb(addr + 0) << 0) |
|
||||
(readb(addr + 1) << 8) |
|
||||
(readb(addr + 2) << 16) |
|
||||
(readb(addr + 3) << 24);
|
||||
}
|
||||
|
||||
void ST010::writeb(uint16 addr, uint8 data) {
|
||||
void ST0010::writeb(uint16 addr, uint8 data) {
|
||||
ram[addr & 0xfff] = data;
|
||||
}
|
||||
|
||||
void ST010::writew(uint16 addr, uint16 data) {
|
||||
void ST0010::writew(uint16 addr, uint16 data) {
|
||||
writeb(addr + 0, data >> 0);
|
||||
writeb(addr + 1, data >> 8);
|
||||
}
|
||||
|
||||
void ST010::writed(uint16 addr, uint32 data) {
|
||||
void ST0010::writed(uint16 addr, uint32 data) {
|
||||
writeb(addr + 0, data >> 0);
|
||||
writeb(addr + 1, data >> 8);
|
||||
writeb(addr + 2, data >> 16);
|
||||
@@ -59,21 +57,21 @@ void ST010::writed(uint16 addr, uint32 data) {
|
||||
|
||||
//
|
||||
|
||||
void ST010::power() {
|
||||
void ST0010::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void ST010::reset() {
|
||||
void ST0010::reset() {
|
||||
memset(ram, 0x00, sizeof ram);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
uint8 ST010::read(unsigned addr) {
|
||||
uint8 ST0010::read(unsigned addr) {
|
||||
return readb(addr);
|
||||
}
|
||||
|
||||
void ST010::write(unsigned addr, uint8 data) {
|
||||
void ST0010::write(unsigned addr, uint8 data) {
|
||||
writeb(addr, data);
|
||||
|
||||
if((addr & 0xfff) == 0x0021 && (data & 0x80)) {
|
@@ -1,4 +1,4 @@
|
||||
class ST010 : public Memory {
|
||||
class ST0010 : public Memory {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
@@ -41,4 +41,4 @@ private:
|
||||
void op_01(int16 x0, int16 y0, int16 &x1, int16 &y1, int16 &quadrant, int16 &theta);
|
||||
};
|
||||
|
||||
extern ST010 st010;
|
||||
extern ST0010 st0010;
|
20
bsnes/chip/st0011/st0011.cpp
Normal file
20
bsnes/chip/st0011/st0011.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <../base.hpp>
|
||||
|
||||
#define ST0011_CPP
|
||||
namespace SNES {
|
||||
|
||||
ST0011 st0011;
|
||||
|
||||
void ST0011::init() {
|
||||
}
|
||||
|
||||
void ST0011::enable() {
|
||||
}
|
||||
|
||||
void ST0011::power() {
|
||||
}
|
||||
|
||||
void ST0011::reset() {
|
||||
}
|
||||
|
||||
};
|
@@ -1,4 +1,4 @@
|
||||
class ST011 {
|
||||
class ST0011 {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
@@ -6,4 +6,4 @@ public:
|
||||
void reset();
|
||||
};
|
||||
|
||||
extern ST011 st011;
|
||||
extern ST0011 st0011;
|
@@ -1,18 +1,18 @@
|
||||
#include <../base.hpp>
|
||||
|
||||
#define ST018_CPP
|
||||
#define ST0018_CPP
|
||||
namespace SNES {
|
||||
|
||||
ST018 st018;
|
||||
ST0018 st0018;
|
||||
|
||||
uint8 ST018::mmio_read(unsigned addr) {
|
||||
uint8 ST0018::mmio_read(unsigned addr) {
|
||||
addr &= 0xffff;
|
||||
if(addr == 0x3800) return regs.r3800;
|
||||
if(addr == 0x3804) return regs.r3804;
|
||||
return cpu.regs.mdr;
|
||||
}
|
||||
|
||||
void ST018::mmio_write(unsigned addr, uint8 data) {
|
||||
void ST0018::mmio_write(unsigned addr, uint8 data) {
|
||||
addr &= 0xffff;
|
||||
|
||||
if(addr == 0x3802) {
|
||||
@@ -45,18 +45,17 @@ void ST018::mmio_write(unsigned addr, uint8 data) {
|
||||
}
|
||||
}
|
||||
|
||||
void ST018::init() {
|
||||
void ST0018::init() {
|
||||
}
|
||||
|
||||
void ST018::enable() {
|
||||
for(unsigned i = 0x3800; i <= 0x38ff; i++) memory::mmio.map(i, *this);
|
||||
void ST0018::enable() {
|
||||
}
|
||||
|
||||
void ST018::power() {
|
||||
void ST0018::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void ST018::reset() {
|
||||
void ST0018::reset() {
|
||||
regs.mode = Waiting;
|
||||
regs.r3800 = 0x00;
|
||||
regs.r3804 = 0x85;
|
||||
@@ -64,17 +63,17 @@ void ST018::reset() {
|
||||
for(unsigned i = 0; i < 97; i++) board[i] = 0;
|
||||
}
|
||||
|
||||
//=============
|
||||
//ST018 opcodes
|
||||
//=============
|
||||
//===============
|
||||
//ST-0018 opcodes
|
||||
//===============
|
||||
|
||||
void ST018::op_board_upload() {
|
||||
void ST0018::op_board_upload() {
|
||||
regs.mode = BoardUpload;
|
||||
regs.counter = 0;
|
||||
regs.r3800 = 0xe0;
|
||||
}
|
||||
|
||||
void ST018::op_board_upload(uint8 data) {
|
||||
void ST0018::op_board_upload(uint8 data) {
|
||||
board[regs.counter] = data;
|
||||
regs.r3800 = 96 - regs.counter;
|
||||
regs.counter++;
|
||||
@@ -93,31 +92,31 @@ void ST018::op_board_upload(uint8 data) {
|
||||
}
|
||||
}
|
||||
|
||||
void ST018::op_b2() {
|
||||
void ST0018::op_b2() {
|
||||
fprintf(stdout, "* ST018 w3802::b2\n");
|
||||
regs.r3800 = 0xe0;
|
||||
regs.r3800_01 = 0; //unknown
|
||||
}
|
||||
|
||||
void ST018::op_b3() {
|
||||
void ST0018::op_b3() {
|
||||
fprintf(stdout, "* ST018 w3802::b3\n");
|
||||
regs.r3800 = 0xe0;
|
||||
regs.r3800_01 = 1; //0 = player lost?
|
||||
}
|
||||
|
||||
void ST018::op_b4() {
|
||||
void ST0018::op_b4() {
|
||||
fprintf(stdout, "* ST018 w3802::b4\n");
|
||||
regs.r3800 = 0xe0;
|
||||
regs.r3800_01 = 1; //0 = player won?
|
||||
}
|
||||
|
||||
void ST018::op_b5() {
|
||||
void ST0018::op_b5() {
|
||||
fprintf(stdout, "* ST018 w3802::b5\n");
|
||||
regs.r3800 = 0xe0;
|
||||
regs.r3800_01 = 0; //1 = move will result in checkmate?
|
||||
}
|
||||
|
||||
void ST018::op_query_chip() {
|
||||
void ST0018::op_query_chip() {
|
||||
regs.r3800 = 0x00;
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
class ST018 : public MMIO {
|
||||
class ST0018 : public MMIO {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
@@ -48,4 +48,4 @@ private:
|
||||
void op_query_chip();
|
||||
};
|
||||
|
||||
extern ST018 st018;
|
||||
extern ST0018 st0018;
|
@@ -10,21 +10,12 @@ namespace memory {
|
||||
}
|
||||
|
||||
void SuperFXBus::init() {
|
||||
map(MapDirect, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped);
|
||||
map(MapMode::Direct, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped);
|
||||
|
||||
map(MapLinear, 0x00, 0x3f, 0x0000, 0x7fff, memory::gsurom);
|
||||
map(MapLinear, 0x00, 0x3f, 0x8000, 0xffff, memory::gsurom);
|
||||
map(MapLinear, 0x40, 0x5f, 0x0000, 0xffff, memory::gsurom);
|
||||
map(MapLinear, 0x60, 0x7f, 0x0000, 0xffff, memory::gsuram);
|
||||
|
||||
bus.map(MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::fxram, 0x0000, 0x2000);
|
||||
bus.map(MapLinear, 0x00, 0x3f, 0x8000, 0xffff, memory::fxrom);
|
||||
bus.map(MapLinear, 0x40, 0x5f, 0x0000, 0xffff, memory::fxrom);
|
||||
bus.map(MapLinear, 0x60, 0x7d, 0x0000, 0xffff, memory::fxram);
|
||||
bus.map(MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::fxram, 0x0000, 0x2000);
|
||||
bus.map(MapLinear, 0x80, 0xbf, 0x8000, 0xffff, memory::fxrom);
|
||||
bus.map(MapLinear, 0xc0, 0xdf, 0x0000, 0xffff, memory::fxrom);
|
||||
bus.map(MapLinear, 0xe0, 0xff, 0x0000, 0xffff, memory::fxram);
|
||||
map(MapMode::Linear, 0x00, 0x3f, 0x0000, 0x7fff, memory::gsurom);
|
||||
map(MapMode::Linear, 0x00, 0x3f, 0x8000, 0xffff, memory::gsurom);
|
||||
map(MapMode::Linear, 0x40, 0x5f, 0x0000, 0xffff, memory::gsurom);
|
||||
map(MapMode::Linear, 0x60, 0x7f, 0x0000, 0xffff, memory::gsuram);
|
||||
}
|
||||
|
||||
//ROM / RAM access from the SuperFX CPU
|
||||
@@ -34,7 +25,7 @@ unsigned SuperFXGSUROM::size() const {
|
||||
}
|
||||
|
||||
uint8 SuperFXGSUROM::read(unsigned addr) {
|
||||
while(!superfx.regs.scmr.ron && scheduler.sync != Scheduler::SyncAll) {
|
||||
while(!superfx.regs.scmr.ron && scheduler.sync != Scheduler::SynchronizeMode::All) {
|
||||
superfx.add_clocks(6);
|
||||
scheduler.sync_copcpu();
|
||||
}
|
||||
@@ -42,7 +33,7 @@ uint8 SuperFXGSUROM::read(unsigned addr) {
|
||||
}
|
||||
|
||||
void SuperFXGSUROM::write(unsigned addr, uint8 data) {
|
||||
while(!superfx.regs.scmr.ron && scheduler.sync != Scheduler::SyncAll) {
|
||||
while(!superfx.regs.scmr.ron && scheduler.sync != Scheduler::SynchronizeMode::All) {
|
||||
superfx.add_clocks(6);
|
||||
scheduler.sync_copcpu();
|
||||
}
|
||||
@@ -54,7 +45,7 @@ unsigned SuperFXGSURAM::size() const {
|
||||
}
|
||||
|
||||
uint8 SuperFXGSURAM::read(unsigned addr) {
|
||||
while(!superfx.regs.scmr.ran && scheduler.sync != Scheduler::SyncAll) {
|
||||
while(!superfx.regs.scmr.ran && scheduler.sync != Scheduler::SynchronizeMode::All) {
|
||||
superfx.add_clocks(6);
|
||||
scheduler.sync_copcpu();
|
||||
}
|
||||
@@ -62,7 +53,7 @@ uint8 SuperFXGSURAM::read(unsigned addr) {
|
||||
}
|
||||
|
||||
void SuperFXGSURAM::write(unsigned addr, uint8 data) {
|
||||
while(!superfx.regs.scmr.ran && scheduler.sync != Scheduler::SyncAll) {
|
||||
while(!superfx.regs.scmr.ran && scheduler.sync != Scheduler::SynchronizeMode::All) {
|
||||
superfx.add_clocks(6);
|
||||
scheduler.sync_copcpu();
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
//accepts a callback binding so r14 writes can trigger ROM buffering transparently
|
||||
struct reg16_t : noncopyable {
|
||||
struct reg16_t {
|
||||
uint16 data;
|
||||
function<void (uint16)> on_modify;
|
||||
|
||||
@@ -29,6 +29,7 @@ struct reg16_t : noncopyable {
|
||||
inline unsigned operator = (const reg16_t& i) { return assign(i); }
|
||||
|
||||
reg16_t() : data(0) {}
|
||||
reg16_t(const reg16_t&) = delete;
|
||||
};
|
||||
|
||||
struct sfr_t {
|
@@ -15,8 +15,8 @@ SuperFX superfx;
|
||||
|
||||
void SuperFX::enter() {
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SyncAll) {
|
||||
scheduler.exit(Scheduler::SynchronizeEvent);
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
if(regs.sfr.g == 0) {
|
||||
@@ -42,7 +42,6 @@ void SuperFX::init() {
|
||||
}
|
||||
|
||||
void SuperFX::enable() {
|
||||
for(unsigned i = 0x3000; i <= 0x32ff; i++) memory::mmio.map(i, *this);
|
||||
}
|
||||
|
||||
void SuperFX::power() {
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user