mirror of https://github.com/bsnes-emu/bsnes.git
Update to v092r09 release.
byuu says: This will be another massive diff from the previous version. All of higan was updated to use the new foo& bar syntax, and I also updated switch statements to be consistent as well (but not in the disassemblers, was starting to get an RSI just from what I already did.) phoenix/{windows, cocoa, qt} need to be updated to use "string foo" instead of "const string& foo", and after that, the major diffs should be finished. This archive is the first time I'm posting my copy-on-write, size+capacity nall::string class, so any feedback on that is welcome as well.
This commit is contained in:
parent
75dab443b4
commit
29ea5bd599
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
namespace Emulator {
|
namespace Emulator {
|
||||||
static const char Name[] = "higan";
|
static const char Name[] = "higan";
|
||||||
static const char Version[] = "092.08";
|
static const char Version[] = "092.09";
|
||||||
static const char Author[] = "byuu";
|
static const char Author[] = "byuu";
|
||||||
static const char License[] = "GPLv3";
|
static const char License[] = "GPLv3";
|
||||||
static const char Website[] = "http://byuu.org/";
|
static const char Website[] = "http://byuu.org/";
|
||||||
|
|
|
@ -47,9 +47,9 @@ struct Interface {
|
||||||
vector<Port> port;
|
vector<Port> port;
|
||||||
|
|
||||||
struct Bind {
|
struct Bind {
|
||||||
virtual void loadRequest(unsigned, const string&, const string&) {}
|
virtual void loadRequest(unsigned, string, string) {}
|
||||||
virtual void loadRequest(unsigned, const string&) {}
|
virtual void loadRequest(unsigned, string) {}
|
||||||
virtual void saveRequest(unsigned, const string&) {}
|
virtual void saveRequest(unsigned, string) {}
|
||||||
virtual uint32_t videoColor(unsigned, uint16_t, uint16_t, uint16_t) { return 0u; }
|
virtual uint32_t videoColor(unsigned, uint16_t, uint16_t, uint16_t) { return 0u; }
|
||||||
virtual void videoRefresh(const uint32_t*, unsigned, unsigned, unsigned) {}
|
virtual void videoRefresh(const uint32_t*, unsigned, unsigned, unsigned) {}
|
||||||
virtual void audioSample(int16_t, int16_t) {}
|
virtual void audioSample(int16_t, int16_t) {}
|
||||||
|
@ -57,14 +57,14 @@ struct Interface {
|
||||||
virtual unsigned dipSettings(const Markup::Node&) { return 0; }
|
virtual unsigned dipSettings(const Markup::Node&) { return 0; }
|
||||||
virtual string path(unsigned) { return ""; }
|
virtual string path(unsigned) { return ""; }
|
||||||
virtual string server() { return ""; }
|
virtual string server() { return ""; }
|
||||||
virtual void notify(const string& text) { print(text, "\n"); }
|
virtual void notify(string text) { print(text, "\n"); }
|
||||||
};
|
};
|
||||||
Bind* bind = nullptr;
|
Bind* bind = nullptr;
|
||||||
|
|
||||||
//callback bindings (provided by user interface)
|
//callback bindings (provided by user interface)
|
||||||
void loadRequest(unsigned id, const string& name, const string& type) { return bind->loadRequest(id, name, type); }
|
void loadRequest(unsigned id, string name, string type) { return bind->loadRequest(id, name, type); }
|
||||||
void loadRequest(unsigned id, const string& path) { return bind->loadRequest(id, path); }
|
void loadRequest(unsigned id, string path) { return bind->loadRequest(id, path); }
|
||||||
void saveRequest(unsigned id, const string& path) { return bind->saveRequest(id, path); }
|
void saveRequest(unsigned id, string path) { return bind->saveRequest(id, path); }
|
||||||
uint32_t videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue) { return bind->videoColor(source, red, green, blue); }
|
uint32_t videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue) { return bind->videoColor(source, red, green, blue); }
|
||||||
void videoRefresh(const uint32_t* data, unsigned pitch, unsigned width, unsigned height) { return bind->videoRefresh(data, pitch, width, height); }
|
void videoRefresh(const uint32_t* data, unsigned pitch, unsigned width, unsigned height) { return bind->videoRefresh(data, pitch, width, height); }
|
||||||
void audioSample(int16_t lsample, int16_t rsample) { return bind->audioSample(lsample, rsample); }
|
void audioSample(int16_t lsample, int16_t rsample) { return bind->audioSample(lsample, rsample); }
|
||||||
|
|
|
@ -9,7 +9,7 @@ void APU::DMC::stop() {
|
||||||
length_counter = 0;
|
length_counter = 0;
|
||||||
dma_delay_counter = 0;
|
dma_delay_counter = 0;
|
||||||
cpu.set_rdy_line(1);
|
cpu.set_rdy_line(1);
|
||||||
cpu.set_rdy_addr({ false, 0u });
|
cpu.set_rdy_addr(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 APU::DMC::clock() {
|
uint8 APU::DMC::clock() {
|
||||||
|
@ -19,10 +19,10 @@ uint8 APU::DMC::clock() {
|
||||||
dma_delay_counter--;
|
dma_delay_counter--;
|
||||||
|
|
||||||
if(dma_delay_counter == 1) {
|
if(dma_delay_counter == 1) {
|
||||||
cpu.set_rdy_addr({ true, uint16(0x8000 | read_addr) });
|
cpu.set_rdy_addr(true, 0x8000 | read_addr);
|
||||||
} else if(dma_delay_counter == 0) {
|
} else if(dma_delay_counter == 0) {
|
||||||
cpu.set_rdy_line(1);
|
cpu.set_rdy_line(1);
|
||||||
cpu.set_rdy_addr({ false, 0u });
|
cpu.set_rdy_addr(false);
|
||||||
|
|
||||||
dma_buffer = cpu.mdr();
|
dma_buffer = cpu.mdr();
|
||||||
have_dma_buffer = true;
|
have_dma_buffer = true;
|
||||||
|
@ -91,7 +91,7 @@ void APU::DMC::reset() {
|
||||||
sample = 0;
|
sample = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::DMC::serialize(serializer &s) {
|
void APU::DMC::serialize(serializer& s) {
|
||||||
s.integer(length_counter);
|
s.integer(length_counter);
|
||||||
s.integer(irq_pending);
|
s.integer(irq_pending);
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ void APU::Envelope::reset() {
|
||||||
decay_volume = 0;
|
decay_volume = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Envelope::serialize(serializer &s) {
|
void APU::Envelope::serialize(serializer& s) {
|
||||||
s.integer(speed);
|
s.integer(speed);
|
||||||
s.integer(use_speed_as_volume);
|
s.integer(use_speed_as_volume);
|
||||||
s.integer(loop_mode);
|
s.integer(loop_mode);
|
||||||
|
|
|
@ -44,7 +44,7 @@ void APU::Noise::reset() {
|
||||||
lfsr = 1;
|
lfsr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Noise::serialize(serializer &s) {
|
void APU::Noise::serialize(serializer& s) {
|
||||||
s.integer(length_counter);
|
s.integer(length_counter);
|
||||||
|
|
||||||
envelope.serialize(s);
|
envelope.serialize(s);
|
||||||
|
|
|
@ -8,7 +8,7 @@ uint8 APU::Pulse::clock() {
|
||||||
if(sweep.check_period() == false) return 0;
|
if(sweep.check_period() == false) return 0;
|
||||||
if(length_counter == 0) return 0;
|
if(length_counter == 0) return 0;
|
||||||
|
|
||||||
static const unsigned duty_table[] = { 1, 2, 4, 6 };
|
static const unsigned duty_table[] = {1, 2, 4, 6};
|
||||||
uint8 result = (duty_counter < duty_table[duty]) ? envelope.volume() : 0;
|
uint8 result = (duty_counter < duty_table[duty]) ? envelope.volume() : 0;
|
||||||
if(sweep.pulse_period < 0x008) result = 0;
|
if(sweep.pulse_period < 0x008) result = 0;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ void APU::Pulse::reset() {
|
||||||
period_counter = 1;
|
period_counter = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Pulse::serialize(serializer &s) {
|
void APU::Pulse::serialize(serializer& s) {
|
||||||
s.integer(length_counter);
|
s.integer(length_counter);
|
||||||
|
|
||||||
envelope.serialize(s);
|
envelope.serialize(s);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
void APU::serialize(serializer &s) {
|
void APU::serialize(serializer& s) {
|
||||||
Thread::serialize(s);
|
Thread::serialize(s);
|
||||||
|
|
||||||
filter.serialize(s);
|
filter.serialize(s);
|
||||||
|
@ -13,13 +13,13 @@ void APU::serialize(serializer &s) {
|
||||||
s.integer(cartridge_sample);
|
s.integer(cartridge_sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Filter::serialize(serializer &s) {
|
void APU::Filter::serialize(serializer& s) {
|
||||||
s.integer(hipass_strong);
|
s.integer(hipass_strong);
|
||||||
s.integer(hipass_weak);
|
s.integer(hipass_weak);
|
||||||
s.integer(lopass);
|
s.integer(lopass);
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::FrameCounter::serialize(serializer &s) {
|
void APU::FrameCounter::serialize(serializer& s) {
|
||||||
s.integer(irq_pending);
|
s.integer(irq_pending);
|
||||||
|
|
||||||
s.integer(mode);
|
s.integer(mode);
|
||||||
|
|
|
@ -42,7 +42,7 @@ void APU::Sweep::power() {
|
||||||
void APU::Sweep::reset() {
|
void APU::Sweep::reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Sweep::serialize(serializer &s) {
|
void APU::Sweep::serialize(serializer& s) {
|
||||||
s.integer(shift);
|
s.integer(shift);
|
||||||
s.integer(decrement);
|
s.integer(decrement);
|
||||||
s.integer(period);
|
s.integer(period);
|
||||||
|
|
|
@ -43,7 +43,7 @@ void APU::Triangle::reset() {
|
||||||
reload_linear = 0;
|
reload_linear = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Triangle::serialize(serializer &s) {
|
void APU::Triangle::serialize(serializer& s) {
|
||||||
s.integer(length_counter);
|
s.integer(length_counter);
|
||||||
|
|
||||||
s.integer(linear_length);
|
s.integer(linear_length);
|
||||||
|
|
|
@ -100,7 +100,7 @@ void reset() {
|
||||||
irq_latch = 0;
|
irq_latch = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
|
|
||||||
s.array(chr_bank);
|
s.array(chr_bank);
|
||||||
|
@ -111,7 +111,7 @@ void serialize(serializer &s) {
|
||||||
s.integer(irq_latch);
|
s.integer(irq_latch);
|
||||||
}
|
}
|
||||||
|
|
||||||
BandaiFCG(Markup::Node &document) : Board(document) {
|
BandaiFCG(Markup::Node& document) : Board(document) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -77,12 +77,12 @@ void Board::power() {
|
||||||
void Board::reset() {
|
void Board::reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Board::serialize(serializer &s) {
|
void Board::serialize(serializer& s) {
|
||||||
if(prgram.size) s.array(prgram.data, prgram.size);
|
if(prgram.size) s.array(prgram.data, prgram.size);
|
||||||
if(chrram.size) s.array(chrram.data, chrram.size);
|
if(chrram.size) s.array(chrram.data, chrram.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Board::Board(Markup::Node &document) {
|
Board::Board(Markup::Node& document) {
|
||||||
cartridge.board = this;
|
cartridge.board = this;
|
||||||
auto cartridge = document["cartridge"];
|
auto cartridge = document["cartridge"];
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ Board::Board(Markup::Node &document) {
|
||||||
Board::~Board() {
|
Board::~Board() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Board* Board::load(const string &manifest) {
|
Board* Board::load(string manifest) {
|
||||||
auto document = Markup::Document(manifest);
|
auto document = Markup::Document(manifest);
|
||||||
cartridge.information.title = document["information/title"].text();
|
cartridge.information.title = document["information/title"].text();
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
struct Board {
|
struct Board {
|
||||||
struct Memory {
|
struct Memory {
|
||||||
uint8_t *data;
|
uint8_t* data;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
bool writable;
|
bool writable;
|
||||||
|
|
||||||
inline uint8 read(unsigned addr) const;
|
inline uint8 read(unsigned addr) const;
|
||||||
inline void write(unsigned addr, uint8 data);
|
inline void write(unsigned addr, uint8 data);
|
||||||
|
|
||||||
inline Memory(uint8_t *data, unsigned size) : data(data), size(size) {}
|
inline Memory(uint8_t* data, unsigned size) : data(data), size(size) {}
|
||||||
inline Memory() : data(nullptr), size(0u), writable(false) {}
|
inline Memory() : data(nullptr), size(0u), writable(false) {}
|
||||||
inline ~Memory() { if(data) delete[] data; }
|
inline ~Memory() { if(data) delete[] data; }
|
||||||
};
|
};
|
||||||
|
@ -29,10 +29,10 @@ struct Board {
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
|
|
||||||
virtual void serialize(serializer&);
|
virtual void serialize(serializer&);
|
||||||
Board(Markup::Node &document);
|
Board(Markup::Node& document);
|
||||||
virtual ~Board();
|
virtual ~Board();
|
||||||
|
|
||||||
static Board* load(const string &manifest);
|
static Board* load(string manifest);
|
||||||
|
|
||||||
struct Information {
|
struct Information {
|
||||||
string type;
|
string type;
|
||||||
|
|
|
@ -29,12 +29,12 @@ void reset() {
|
||||||
vrc1.reset();
|
vrc1.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
vrc1.serialize(s);
|
vrc1.serialize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
KonamiVRC1(Markup::Node &document) : Board(document), vrc1(*this) {
|
KonamiVRC1(Markup::Node& document) : Board(document), vrc1(*this) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,12 +44,12 @@ void reset() {
|
||||||
vrc2.reset();
|
vrc2.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
vrc2.serialize(s);
|
vrc2.serialize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
KonamiVRC2(Markup::Node &document) : Board(document), vrc2(*this) {
|
KonamiVRC2(Markup::Node& document) : Board(document), vrc2(*this) {
|
||||||
settings.pinout.a0 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a0"].data);
|
settings.pinout.a0 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a0"].data);
|
||||||
settings.pinout.a1 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a1"].data);
|
settings.pinout.a1 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a1"].data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,12 +45,12 @@ void reset() {
|
||||||
vrc3.reset();
|
vrc3.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
vrc3.serialize(s);
|
vrc3.serialize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
KonamiVRC3(Markup::Node &document) : Board(document), vrc3(*this) {
|
KonamiVRC3(Markup::Node& document) : Board(document), vrc3(*this) {
|
||||||
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,12 +48,12 @@ void reset() {
|
||||||
vrc4.reset();
|
vrc4.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
vrc4.serialize(s);
|
vrc4.serialize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
KonamiVRC4(Markup::Node &document) : Board(document), vrc4(*this) {
|
KonamiVRC4(Markup::Node& document) : Board(document), vrc4(*this) {
|
||||||
settings.pinout.a0 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a0"].data);
|
settings.pinout.a0 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a0"].data);
|
||||||
settings.pinout.a1 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a1"].data);
|
settings.pinout.a1 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a1"].data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ void chr_write(unsigned addr, uint8 data) {
|
||||||
return Board::chr_write(vrc6.chr_addr(addr), data);
|
return Board::chr_write(vrc6.chr_addr(addr), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
vrc6.serialize(s);
|
vrc6.serialize(s);
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ void main() { vrc6.main(); }
|
||||||
void power() { vrc6.power(); }
|
void power() { vrc6.power(); }
|
||||||
void reset() { vrc6.reset(); }
|
void reset() { vrc6.reset(); }
|
||||||
|
|
||||||
KonamiVRC6(Markup::Node &document) : Board(document), vrc6(*this) {
|
KonamiVRC6(Markup::Node& document) : Board(document), vrc6(*this) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,12 +36,12 @@ void reset() {
|
||||||
vrc7.reset();
|
vrc7.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
vrc7.serialize(s);
|
vrc7.serialize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
KonamiVRC7(Markup::Node &document) : Board(document), vrc7(*this) {
|
KonamiVRC7(Markup::Node& document) : Board(document), vrc7(*this) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,14 +38,14 @@ void reset() {
|
||||||
mirror_select = 0;
|
mirror_select = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
|
|
||||||
s.integer(prg_bank);
|
s.integer(prg_bank);
|
||||||
s.integer(mirror_select);
|
s.integer(mirror_select);
|
||||||
}
|
}
|
||||||
|
|
||||||
NES_AxROM(Markup::Node &document) : Board(document) {
|
NES_AxROM(Markup::Node& document) : Board(document) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,12 +40,12 @@ void reset() {
|
||||||
prg_bank = 0;
|
prg_bank = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
s.integer(prg_bank);
|
s.integer(prg_bank);
|
||||||
}
|
}
|
||||||
|
|
||||||
NES_BNROM(Markup::Node &document) : Board(document) {
|
NES_BNROM(Markup::Node& document) : Board(document) {
|
||||||
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,12 +42,12 @@ void reset() {
|
||||||
chr_bank = 0;
|
chr_bank = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
s.integer(chr_bank);
|
s.integer(chr_bank);
|
||||||
}
|
}
|
||||||
|
|
||||||
NES_CNROM(Markup::Node &document) : Board(document) {
|
NES_CNROM(Markup::Node& document) : Board(document) {
|
||||||
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,12 +41,12 @@ void reset() {
|
||||||
mmc5.reset();
|
mmc5.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
mmc5.serialize(s);
|
mmc5.serialize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
NES_ExROM(Markup::Node &document) : Board(document), mmc5(*this) {
|
NES_ExROM(Markup::Node& document) : Board(document), mmc5(*this) {
|
||||||
revision = Revision::ELROM;
|
revision = Revision::ELROM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ void reset() {
|
||||||
latch[1] = 0;
|
latch[1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
|
|
||||||
s.integer(prg_bank);
|
s.integer(prg_bank);
|
||||||
|
@ -84,7 +84,7 @@ void serialize(serializer &s) {
|
||||||
s.array(latch);
|
s.array(latch);
|
||||||
}
|
}
|
||||||
|
|
||||||
NES_FxROM(Markup::Node &document) : Board(document) {
|
NES_FxROM(Markup::Node& document) : Board(document) {
|
||||||
revision = Revision::FKROM;
|
revision = Revision::FKROM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,13 +48,13 @@ void reset() {
|
||||||
chr_bank = 0;
|
chr_bank = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
s.integer(prg_bank);
|
s.integer(prg_bank);
|
||||||
s.integer(chr_bank);
|
s.integer(chr_bank);
|
||||||
}
|
}
|
||||||
|
|
||||||
NES_GxROM(Markup::Node &document) : Board(document) {
|
NES_GxROM(Markup::Node& document) : Board(document) {
|
||||||
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,12 +37,12 @@ void reset() {
|
||||||
mmc6.reset();
|
mmc6.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
mmc6.serialize(s);
|
mmc6.serialize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
NES_HKROM(Markup::Node &document) : Board(document), mmc6(*this) {
|
NES_HKROM(Markup::Node& document) : Board(document), mmc6(*this) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,11 +32,11 @@ void chr_write(unsigned addr, uint8 data) {
|
||||||
if(chrram.size) return chrram.write(addr, data);
|
if(chrram.size) return chrram.write(addr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
NES_NROM(Markup::Node &document) : Board(document) {
|
NES_NROM(Markup::Node& document) : Board(document) {
|
||||||
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ void reset() {
|
||||||
latch[1] = 0;
|
latch[1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
|
|
||||||
s.integer(prg_bank);
|
s.integer(prg_bank);
|
||||||
|
@ -90,7 +90,7 @@ void serialize(serializer &s) {
|
||||||
s.array(latch);
|
s.array(latch);
|
||||||
}
|
}
|
||||||
|
|
||||||
NES_PxROM(Markup::Node &document) : Board(document) {
|
NES_PxROM(Markup::Node& document) : Board(document) {
|
||||||
revision = Revision::PNROM;
|
revision = Revision::PNROM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,12 +89,12 @@ void reset() {
|
||||||
mmc1.reset();
|
mmc1.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
mmc1.serialize(s);
|
mmc1.serialize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
NES_SxROM(Markup::Node &document) : Board(document), mmc1(*this) {
|
NES_SxROM(Markup::Node& document) : Board(document), mmc1(*this) {
|
||||||
revision = Revision::SXROM;
|
revision = Revision::SXROM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,12 +55,12 @@ void reset() {
|
||||||
mmc3.reset();
|
mmc3.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
mmc3.serialize(s);
|
mmc3.serialize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
NES_TxROM(Markup::Node &document) : Board(document), mmc3(*this) {
|
NES_TxROM(Markup::Node& document) : Board(document), mmc3(*this) {
|
||||||
revision = Revision::TLROM;
|
revision = Revision::TLROM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,13 +42,13 @@ void reset() {
|
||||||
prg_bank = 0;
|
prg_bank = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
|
|
||||||
s.integer(prg_bank);
|
s.integer(prg_bank);
|
||||||
}
|
}
|
||||||
|
|
||||||
NES_UxROM(Markup::Node &document) : Board(document) {
|
NES_UxROM(Markup::Node& document) : Board(document) {
|
||||||
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ struct Pulse {
|
||||||
output = 0;
|
output = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
s.integer(disable);
|
s.integer(disable);
|
||||||
s.integer(frequency);
|
s.integer(frequency);
|
||||||
s.integer(volume);
|
s.integer(volume);
|
||||||
|
@ -190,8 +190,8 @@ void reset() {
|
||||||
mmu_port = 0;
|
mmu_port = 0;
|
||||||
apu_port = 0;
|
apu_port = 0;
|
||||||
|
|
||||||
for(auto &n : prg_bank) n = 0;
|
for(auto& n : prg_bank) n = 0;
|
||||||
for(auto &n : chr_bank) n = 0;
|
for(auto& n : chr_bank) n = 0;
|
||||||
mirror = 0;
|
mirror = 0;
|
||||||
irq_enable = 0;
|
irq_enable = 0;
|
||||||
irq_counter_enable = 0;
|
irq_counter_enable = 0;
|
||||||
|
@ -202,7 +202,7 @@ void reset() {
|
||||||
pulse[2].reset();
|
pulse[2].reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
Board::serialize(s);
|
Board::serialize(s);
|
||||||
|
|
||||||
s.integer(mmu_port);
|
s.integer(mmu_port);
|
||||||
|
@ -220,7 +220,7 @@ void serialize(serializer &s) {
|
||||||
pulse[2].serialize(s);
|
pulse[2].serialize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sunsoft5B(Markup::Node &document) : Board(document) {
|
Sunsoft5B(Markup::Node& document) : Board(document) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,7 +32,7 @@ void Cartridge::load() {
|
||||||
sha256_final(&sha);
|
sha256_final(&sha);
|
||||||
sha256_hash(&sha, hash);
|
sha256_hash(&sha, hash);
|
||||||
string result;
|
string result;
|
||||||
for(auto &byte : hash) result.append(hex<2>(byte));
|
for(auto& byte : hash) result.append(hex<2>(byte));
|
||||||
sha256 = result;
|
sha256 = result;
|
||||||
|
|
||||||
system.load();
|
system.load();
|
||||||
|
@ -78,7 +78,7 @@ void Cartridge::scanline(unsigned y) {
|
||||||
return board->scanline(y);
|
return board->scanline(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cartridge::serialize(serializer &s) {
|
void Cartridge::serialize(serializer& s) {
|
||||||
Thread::serialize(s);
|
Thread::serialize(s);
|
||||||
return board->serialize(s);
|
return board->serialize(s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,5 +13,5 @@ void Chip::tick() {
|
||||||
board.tick();
|
board.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
Chip::Chip(Board &board) : board(board) {
|
Chip::Chip(Board& board) : board(board) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
struct Board;
|
struct Board;
|
||||||
|
|
||||||
struct Chip {
|
struct Chip {
|
||||||
Board &board;
|
Board& board;
|
||||||
void tick();
|
void tick();
|
||||||
Chip(Board &board);
|
Chip(Board& board);
|
||||||
};
|
};
|
||||||
|
|
|
@ -115,7 +115,7 @@ void reset() {
|
||||||
prg_bank = 0;
|
prg_bank = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
s.integer(writedelay);
|
s.integer(writedelay);
|
||||||
s.integer(shiftaddr);
|
s.integer(shiftaddr);
|
||||||
s.integer(shiftdata);
|
s.integer(shiftdata);
|
||||||
|
@ -129,7 +129,7 @@ void serialize(serializer &s) {
|
||||||
s.integer(prg_bank);
|
s.integer(prg_bank);
|
||||||
}
|
}
|
||||||
|
|
||||||
MMC1(Board &board) : Chip(board) {
|
MMC1(Board& board) : Chip(board) {
|
||||||
revision = Revision::MMC1B2;
|
revision = Revision::MMC1B2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ void reset() {
|
||||||
chr_abus = 0;
|
chr_abus = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
s.integer(chr_mode);
|
s.integer(chr_mode);
|
||||||
s.integer(prg_mode);
|
s.integer(prg_mode);
|
||||||
s.integer(bank_select);
|
s.integer(bank_select);
|
||||||
|
@ -183,7 +183,7 @@ void serialize(serializer &s) {
|
||||||
s.integer(chr_abus);
|
s.integer(chr_abus);
|
||||||
}
|
}
|
||||||
|
|
||||||
MMC3(Board &board) : Chip(board) {
|
MMC3(Board& board) : Chip(board) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -399,13 +399,13 @@ void power() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
for(auto &n : exram) n = 0xff;
|
for(auto& n : exram) n = 0xff;
|
||||||
|
|
||||||
prg_mode = 3;
|
prg_mode = 3;
|
||||||
chr_mode = 0;
|
chr_mode = 0;
|
||||||
for(auto &n : prgram_write_protect) n = 0;
|
for(auto& n : prgram_write_protect) n = 0;
|
||||||
exram_mode = 0;
|
exram_mode = 0;
|
||||||
for(auto &n : nametable_mode) n = 0;
|
for(auto& n : nametable_mode) n = 0;
|
||||||
fillmode_tile = 0;
|
fillmode_tile = 0;
|
||||||
fillmode_color = 0;
|
fillmode_color = 0;
|
||||||
ram_select = 0;
|
ram_select = 0;
|
||||||
|
@ -414,8 +414,8 @@ void reset() {
|
||||||
prg_bank[1] = 0x00;
|
prg_bank[1] = 0x00;
|
||||||
prg_bank[2] = 0x00;
|
prg_bank[2] = 0x00;
|
||||||
prg_bank[3] = 0xff;
|
prg_bank[3] = 0xff;
|
||||||
for(auto &n : chr_sprite_bank) n = 0;
|
for(auto& n : chr_sprite_bank) n = 0;
|
||||||
for(auto &n : chr_bg_bank) n = 0;
|
for(auto& n : chr_bg_bank) n = 0;
|
||||||
chr_bank_hi = 0;
|
chr_bank_hi = 0;
|
||||||
vs_enable = 0;
|
vs_enable = 0;
|
||||||
vs_side = 0;
|
vs_side = 0;
|
||||||
|
@ -433,7 +433,7 @@ void reset() {
|
||||||
in_frame = 0;
|
in_frame = 0;
|
||||||
vcounter = 0;
|
vcounter = 0;
|
||||||
hcounter = 0;
|
hcounter = 0;
|
||||||
for(auto &n : chr_access) n = 0;
|
for(auto& n : chr_access) n = 0;
|
||||||
chr_active = 0;
|
chr_active = 0;
|
||||||
sprite_8x16 = 0;
|
sprite_8x16 = 0;
|
||||||
|
|
||||||
|
@ -445,21 +445,21 @@ void reset() {
|
||||||
vs_hpos = 0;
|
vs_hpos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
s.array(exram);
|
s.array(exram);
|
||||||
|
|
||||||
s.integer(prg_mode);
|
s.integer(prg_mode);
|
||||||
s.integer(chr_mode);
|
s.integer(chr_mode);
|
||||||
for(auto &n : prgram_write_protect) s.integer(n);
|
for(auto& n : prgram_write_protect) s.integer(n);
|
||||||
s.integer(exram_mode);
|
s.integer(exram_mode);
|
||||||
for(auto &n : nametable_mode) s.integer(n);
|
for(auto& n : nametable_mode) s.integer(n);
|
||||||
s.integer(fillmode_tile);
|
s.integer(fillmode_tile);
|
||||||
s.integer(fillmode_color);
|
s.integer(fillmode_color);
|
||||||
s.integer(ram_select);
|
s.integer(ram_select);
|
||||||
s.integer(ram_bank);
|
s.integer(ram_bank);
|
||||||
for(auto &n : prg_bank) s.integer(n);
|
for(auto& n : prg_bank) s.integer(n);
|
||||||
for(auto &n : chr_sprite_bank) s.integer(n);
|
for(auto& n : chr_sprite_bank) s.integer(n);
|
||||||
for(auto &n : chr_bg_bank) s.integer(n);
|
for(auto& n : chr_bg_bank) s.integer(n);
|
||||||
s.integer(chr_bank_hi);
|
s.integer(chr_bank_hi);
|
||||||
s.integer(vs_enable);
|
s.integer(vs_enable);
|
||||||
s.integer(vs_side);
|
s.integer(vs_side);
|
||||||
|
@ -478,7 +478,7 @@ void serialize(serializer &s) {
|
||||||
|
|
||||||
s.integer(vcounter);
|
s.integer(vcounter);
|
||||||
s.integer(hcounter);
|
s.integer(hcounter);
|
||||||
for(auto &n : chr_access) s.integer(n);
|
for(auto& n : chr_access) s.integer(n);
|
||||||
s.integer(chr_active);
|
s.integer(chr_active);
|
||||||
s.integer(sprite_8x16);
|
s.integer(sprite_8x16);
|
||||||
|
|
||||||
|
@ -490,7 +490,7 @@ void serialize(serializer &s) {
|
||||||
s.integer(vs_hpos);
|
s.integer(vs_hpos);
|
||||||
}
|
}
|
||||||
|
|
||||||
MMC5(Board &board) : Chip(board) {
|
MMC5(Board& board) : Chip(board) {
|
||||||
revision = Revision::MMC5;
|
revision = Revision::MMC5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,11 +161,11 @@ void reset() {
|
||||||
prg_mode = 0;
|
prg_mode = 0;
|
||||||
ram_enable = 0;
|
ram_enable = 0;
|
||||||
bank_select = 0;
|
bank_select = 0;
|
||||||
for(auto &n : prg_bank) n = 0;
|
for(auto& n : prg_bank) n = 0;
|
||||||
for(auto &n : chr_bank) n = 0;
|
for(auto& n : chr_bank) n = 0;
|
||||||
mirror = 0;
|
mirror = 0;
|
||||||
for(auto &n : ram_readable) n = 0;
|
for(auto& n : ram_readable) n = 0;
|
||||||
for(auto &n : ram_writable) n = 0;
|
for(auto& n : ram_writable) n = 0;
|
||||||
irq_latch = 0;
|
irq_latch = 0;
|
||||||
irq_counter = 0;
|
irq_counter = 0;
|
||||||
irq_enable = 0;
|
irq_enable = 0;
|
||||||
|
@ -175,16 +175,16 @@ void reset() {
|
||||||
chr_abus = 0;
|
chr_abus = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
s.integer(chr_mode);
|
s.integer(chr_mode);
|
||||||
s.integer(prg_mode);
|
s.integer(prg_mode);
|
||||||
s.integer(ram_enable);
|
s.integer(ram_enable);
|
||||||
s.integer(bank_select);
|
s.integer(bank_select);
|
||||||
for(auto &n : prg_bank) s.integer(n);
|
for(auto& n : prg_bank) s.integer(n);
|
||||||
for(auto &n : chr_bank) s.integer(n);
|
for(auto& n : chr_bank) s.integer(n);
|
||||||
s.integer(mirror);
|
s.integer(mirror);
|
||||||
for(auto &n : ram_readable) s.integer(n);
|
for(auto& n : ram_readable) s.integer(n);
|
||||||
for(auto &n : ram_writable) s.integer(n);
|
for(auto& n : ram_writable) s.integer(n);
|
||||||
s.integer(irq_latch);
|
s.integer(irq_latch);
|
||||||
s.integer(irq_counter);
|
s.integer(irq_counter);
|
||||||
s.integer(irq_enable);
|
s.integer(irq_enable);
|
||||||
|
@ -194,7 +194,7 @@ void serialize(serializer &s) {
|
||||||
s.integer(chr_abus);
|
s.integer(chr_abus);
|
||||||
}
|
}
|
||||||
|
|
||||||
MMC6(Board &board) : Chip(board) {
|
MMC6(Board& board) : Chip(board) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -61,20 +61,20 @@ void power() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
for(auto &n : prg_bank) n = 0;
|
for(auto& n : prg_bank) n = 0;
|
||||||
for(auto &n : chr_banklo) n = 0;
|
for(auto& n : chr_banklo) n = 0;
|
||||||
for(auto &n : chr_bankhi) n = 0;
|
for(auto& n : chr_bankhi) n = 0;
|
||||||
mirror = 0;
|
mirror = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
for(auto &n : prg_bank) s.integer(n);
|
for(auto& n : prg_bank) s.integer(n);
|
||||||
for(auto &n : chr_banklo) s.integer(n);
|
for(auto& n : chr_banklo) s.integer(n);
|
||||||
for(auto &n : chr_bankhi) s.integer(n);
|
for(auto& n : chr_bankhi) s.integer(n);
|
||||||
s.integer(mirror);
|
s.integer(mirror);
|
||||||
}
|
}
|
||||||
|
|
||||||
VRC1(Board &board) : Chip(board) {
|
VRC1(Board& board) : Chip(board) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -91,20 +91,20 @@ void power() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
for(auto &n : prg_bank) n = 0;
|
for(auto& n : prg_bank) n = 0;
|
||||||
for(auto &n : chr_bank) n = 0;
|
for(auto& n : chr_bank) n = 0;
|
||||||
mirror = 0;
|
mirror = 0;
|
||||||
latch = 0;
|
latch = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
for(auto &n : prg_bank) s.integer(n);
|
for(auto& n : prg_bank) s.integer(n);
|
||||||
for(auto &n : chr_bank) s.integer(n);
|
for(auto& n : chr_bank) s.integer(n);
|
||||||
s.integer(mirror);
|
s.integer(mirror);
|
||||||
s.integer(latch);
|
s.integer(latch);
|
||||||
}
|
}
|
||||||
|
|
||||||
VRC2(Board &board) : Chip(board) {
|
VRC2(Board& board) : Chip(board) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -84,7 +84,7 @@ void reset() {
|
||||||
irq_line = 0;
|
irq_line = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
s.integer(prg_bank);
|
s.integer(prg_bank);
|
||||||
s.integer(irq_mode);
|
s.integer(irq_mode);
|
||||||
s.integer(irq_enable);
|
s.integer(irq_enable);
|
||||||
|
@ -94,7 +94,7 @@ void serialize(serializer &s) {
|
||||||
s.integer(irq_line);
|
s.integer(irq_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
VRC3(Board &board) : Chip(board) {
|
VRC3(Board& board) : Chip(board) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -148,9 +148,9 @@ void power() {
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
prg_mode = 0;
|
prg_mode = 0;
|
||||||
for(auto &n : prg_bank) n = 0;
|
for(auto& n : prg_bank) n = 0;
|
||||||
mirror = 0;
|
mirror = 0;
|
||||||
for(auto &n : chr_bank) n = 0;
|
for(auto& n : chr_bank) n = 0;
|
||||||
|
|
||||||
irq_latch = 0;
|
irq_latch = 0;
|
||||||
irq_mode = 0;
|
irq_mode = 0;
|
||||||
|
@ -162,11 +162,11 @@ void reset() {
|
||||||
irq_line = 0;
|
irq_line = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
s.integer(prg_mode);
|
s.integer(prg_mode);
|
||||||
for(auto &n : prg_bank) s.integer(n);
|
for(auto& n : prg_bank) s.integer(n);
|
||||||
s.integer(mirror);
|
s.integer(mirror);
|
||||||
for(auto &n : chr_bank) s.integer(n);
|
for(auto& n : chr_bank) s.integer(n);
|
||||||
|
|
||||||
s.integer(irq_latch);
|
s.integer(irq_latch);
|
||||||
s.integer(irq_mode);
|
s.integer(irq_mode);
|
||||||
|
@ -178,7 +178,7 @@ void serialize(serializer &s) {
|
||||||
s.integer(irq_line);
|
s.integer(irq_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
VRC4(Board &board) : Chip(board) {
|
VRC4(Board& board) : Chip(board) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,7 +33,7 @@ struct Pulse {
|
||||||
if(enable == false) output = 0;
|
if(enable == false) output = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
s.integer(mode);
|
s.integer(mode);
|
||||||
s.integer(duty);
|
s.integer(duty);
|
||||||
s.integer(volume);
|
s.integer(volume);
|
||||||
|
@ -73,7 +73,7 @@ struct Sawtooth {
|
||||||
if(enable == false) output = 0;
|
if(enable == false) output = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
s.integer(rate);
|
s.integer(rate);
|
||||||
s.integer(enable);
|
s.integer(enable);
|
||||||
s.integer(frequency);
|
s.integer(frequency);
|
||||||
|
@ -297,7 +297,7 @@ void reset() {
|
||||||
sawtooth.output = 0;
|
sawtooth.output = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
pulse1.serialize(s);
|
pulse1.serialize(s);
|
||||||
pulse2.serialize(s);
|
pulse2.serialize(s);
|
||||||
sawtooth.serialize(s);
|
sawtooth.serialize(s);
|
||||||
|
@ -315,7 +315,7 @@ void serialize(serializer &s) {
|
||||||
s.integer(irq_line);
|
s.integer(irq_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
VRC6(Board &board) : Chip(board) {
|
VRC6(Board& board) : Chip(board) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -119,8 +119,8 @@ void power() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
for(auto &n : prg_bank) n = 0;
|
for(auto& n : prg_bank) n = 0;
|
||||||
for(auto &n : chr_bank) n = 0;
|
for(auto& n : chr_bank) n = 0;
|
||||||
mirror = 0;
|
mirror = 0;
|
||||||
|
|
||||||
irq_latch = 0;
|
irq_latch = 0;
|
||||||
|
@ -133,7 +133,7 @@ void reset() {
|
||||||
irq_line = 0;
|
irq_line = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(serializer &s) {
|
void serialize(serializer& s) {
|
||||||
s.array(prg_bank);
|
s.array(prg_bank);
|
||||||
s.array(chr_bank);
|
s.array(chr_bank);
|
||||||
s.integer(mirror);
|
s.integer(mirror);
|
||||||
|
@ -148,7 +148,7 @@ void serialize(serializer &s) {
|
||||||
s.integer(irq_line);
|
s.integer(irq_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
VRC7(Board &board) : Chip(board) {
|
VRC7(Board& board) : Chip(board) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,20 +4,20 @@ namespace Famicom {
|
||||||
|
|
||||||
Cheat cheat;
|
Cheat cheat;
|
||||||
|
|
||||||
bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned &comp) {
|
bool Cheat::decode(string code_, unsigned& addr, unsigned& data, unsigned& comp) {
|
||||||
static bool initialize = false;
|
static bool initialize = false;
|
||||||
static uint8 mapProActionReplay[256], mapGameGenie[256];
|
static uint8 mapProActionReplay[256], mapGameGenie[256];
|
||||||
|
|
||||||
if(initialize == false) {
|
if(initialize == false) {
|
||||||
initialize = true;
|
initialize = true;
|
||||||
|
|
||||||
for(auto &n : mapProActionReplay) n = ~0;
|
for(auto& n : mapProActionReplay) n = ~0;
|
||||||
mapProActionReplay['0'] = 0; mapProActionReplay['1'] = 1; mapProActionReplay['2'] = 2; mapProActionReplay['3'] = 3;
|
mapProActionReplay['0'] = 0; mapProActionReplay['1'] = 1; mapProActionReplay['2'] = 2; mapProActionReplay['3'] = 3;
|
||||||
mapProActionReplay['4'] = 4; mapProActionReplay['5'] = 5; mapProActionReplay['6'] = 6; mapProActionReplay['7'] = 7;
|
mapProActionReplay['4'] = 4; mapProActionReplay['5'] = 5; mapProActionReplay['6'] = 6; mapProActionReplay['7'] = 7;
|
||||||
mapProActionReplay['8'] = 8; mapProActionReplay['9'] = 9; mapProActionReplay['A'] = 10; mapProActionReplay['B'] = 11;
|
mapProActionReplay['8'] = 8; mapProActionReplay['9'] = 9; mapProActionReplay['A'] = 10; mapProActionReplay['B'] = 11;
|
||||||
mapProActionReplay['C'] = 12; mapProActionReplay['D'] = 13; mapProActionReplay['E'] = 14; mapProActionReplay['F'] = 15;
|
mapProActionReplay['C'] = 12; mapProActionReplay['D'] = 13; mapProActionReplay['E'] = 14; mapProActionReplay['F'] = 15;
|
||||||
|
|
||||||
for(auto &n : mapGameGenie) n = ~0;
|
for(auto& n : mapGameGenie) n = ~0;
|
||||||
mapGameGenie['A'] = 0; mapGameGenie['P'] = 1; mapGameGenie['Z'] = 2; mapGameGenie['L'] = 3;
|
mapGameGenie['A'] = 0; mapGameGenie['P'] = 1; mapGameGenie['Z'] = 2; mapGameGenie['L'] = 3;
|
||||||
mapGameGenie['G'] = 4; mapGameGenie['I'] = 5; mapGameGenie['T'] = 6; mapGameGenie['Y'] = 7;
|
mapGameGenie['G'] = 4; mapGameGenie['I'] = 5; mapGameGenie['T'] = 6; mapGameGenie['Y'] = 7;
|
||||||
mapGameGenie['E'] = 8; mapGameGenie['O'] = 9; mapGameGenie['X'] = 10; mapGameGenie['U'] = 11;
|
mapGameGenie['E'] = 8; mapGameGenie['O'] = 9; mapGameGenie['X'] = 10; mapGameGenie['U'] = 11;
|
||||||
|
@ -29,7 +29,7 @@ bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned
|
||||||
unsigned length = code.length(), bits = 0;
|
unsigned length = code.length(), bits = 0;
|
||||||
|
|
||||||
if(code.wildcard("????:??")) {
|
if(code.wildcard("????:??")) {
|
||||||
code = { substr(code, 0, 4), substr(code, 5, 2) };
|
code = {substr(code, 0, 4), substr(code, 5, 2)};
|
||||||
for(unsigned n = 0; n < 6; n++) if(mapProActionReplay[code[n]] > 15) return false;
|
for(unsigned n = 0; n < 6; n++) if(mapProActionReplay[code[n]] > 15) return false;
|
||||||
bits = hex(code);
|
bits = hex(code);
|
||||||
addr = (bits >> 8) & 0xffff;
|
addr = (bits >> 8) & 0xffff;
|
||||||
|
@ -39,7 +39,7 @@ bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
if(code.wildcard("????:??:??")) {
|
if(code.wildcard("????:??:??")) {
|
||||||
code = { substr(code, 0, 4), substr(code, 5, 2), substr(code, 8, 2) };
|
code = {substr(code, 0, 4), substr(code, 5, 2), substr(code, 8, 2)};
|
||||||
for(unsigned n = 0; n < 8; n++) if(mapProActionReplay[code[n]] > 15) return false;
|
for(unsigned n = 0; n < 8; n++) if(mapProActionReplay[code[n]] > 15) return false;
|
||||||
bits = hex(code);
|
bits = hex(code);
|
||||||
addr = (bits >> 16) & 0xffff;
|
addr = (bits >> 16) & 0xffff;
|
||||||
|
@ -51,8 +51,8 @@ bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned
|
||||||
if(length == 6) {
|
if(length == 6) {
|
||||||
for(unsigned n = 0; n < 6; n++) if(mapGameGenie[code[n]] > 15) return false;
|
for(unsigned n = 0; n < 6; n++) if(mapGameGenie[code[n]] > 15) return false;
|
||||||
for(unsigned n = 0; n < 6; n++) bits |= mapGameGenie[code[n]] << (20 - n * 4);
|
for(unsigned n = 0; n < 6; n++) bits |= mapGameGenie[code[n]] << (20 - n * 4);
|
||||||
unsigned addrTable[] = { 10, 9, 8, 7, 2, 1, 0, 19, 14, 13, 12, 11, 6, 5, 4 };
|
unsigned addrTable[] = {10, 9, 8, 7, 2, 1, 0, 19, 14, 13, 12, 11, 6, 5, 4};
|
||||||
unsigned dataTable[] = { 23, 18, 17, 16, 3, 22, 21, 20 };
|
unsigned dataTable[] = {23, 18, 17, 16, 3, 22, 21, 20};
|
||||||
|
|
||||||
addr = 0x8000, data = 0x00, comp = ~0;
|
addr = 0x8000, data = 0x00, comp = ~0;
|
||||||
for(unsigned n = 0; n < 15; n++) addr |= bits & (1 << addrTable[n]) ? 0x4000 >> n : 0;
|
for(unsigned n = 0; n < 15; n++) addr |= bits & (1 << addrTable[n]) ? 0x4000 >> n : 0;
|
||||||
|
@ -63,9 +63,9 @@ bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned
|
||||||
if(length == 8) {
|
if(length == 8) {
|
||||||
for(unsigned n = 0; n < 8; n++) if(mapGameGenie[code[n]] > 15) return false;
|
for(unsigned n = 0; n < 8; n++) if(mapGameGenie[code[n]] > 15) return false;
|
||||||
for(unsigned n = 0; n < 8; n++) bits |= mapGameGenie[code[n]] << (28 - n * 4);
|
for(unsigned n = 0; n < 8; n++) bits |= mapGameGenie[code[n]] << (28 - n * 4);
|
||||||
unsigned addrTable[] = { 18, 17, 16, 15, 10, 9, 8, 27, 22, 21, 20, 19, 14, 13, 12 };
|
unsigned addrTable[] = {18, 17, 16, 15, 10, 9, 8, 27, 22, 21, 20, 19, 14, 13, 12};
|
||||||
unsigned dataTable[] = { 31, 26, 25, 24, 3, 30, 29, 28 };
|
unsigned dataTable[] = {31, 26, 25, 24, 3, 30, 29, 28};
|
||||||
unsigned compTable[] = { 7, 2, 1, 0, 11, 6, 5,4 };
|
unsigned compTable[] = {7, 2, 1, 0, 11, 6, 5, 4};
|
||||||
|
|
||||||
addr = 0x8000, data = 0x00, comp = 0x00;
|
addr = 0x8000, data = 0x00, comp = 0x00;
|
||||||
for(unsigned n = 0; n < 15; n++) addr |= bits & (1 << addrTable[n]) ? 0x4000 >> n : 0;
|
for(unsigned n = 0; n < 15; n++) addr |= bits & (1 << addrTable[n]) ? 0x4000 >> n : 0;
|
||||||
|
@ -78,7 +78,7 @@ bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cheat::synchronize() {
|
void Cheat::synchronize() {
|
||||||
for(auto &n : override) n = false;
|
for(auto& n : override) n = false;
|
||||||
|
|
||||||
for(unsigned n = 0; n < size(); n++) {
|
for(unsigned n = 0; n < size(); n++) {
|
||||||
override[operator[](n).addr] = true;
|
override[operator[](n).addr] = true;
|
||||||
|
|
|
@ -5,7 +5,7 @@ struct CheatCode {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Cheat : public vector<CheatCode> {
|
struct Cheat : public vector<CheatCode> {
|
||||||
static bool decode(const string &code, unsigned &addr, unsigned &data, unsigned &comp);
|
static bool decode(string code, unsigned& addr, unsigned& data, unsigned& comp);
|
||||||
|
|
||||||
void synchronize();
|
void synchronize();
|
||||||
bool override[65536];
|
bool override[65536];
|
||||||
|
|
|
@ -60,7 +60,8 @@ void CPU::reset() {
|
||||||
status.irq_apu_line = 0;
|
status.irq_apu_line = 0;
|
||||||
|
|
||||||
status.rdy_line = 1;
|
status.rdy_line = 1;
|
||||||
status.rdy_addr = { false, 0x0000 };
|
status.rdy_addr_valid = false;
|
||||||
|
status.rdy_addr_value = 0x0000;
|
||||||
|
|
||||||
status.oam_dma_pending = false;
|
status.oam_dma_pending = false;
|
||||||
status.oam_dma_page = 0x00;
|
status.oam_dma_page = 0x00;
|
||||||
|
|
|
@ -9,7 +9,8 @@ struct CPU : Processor::R6502, Thread {
|
||||||
bool irq_apu_line;
|
bool irq_apu_line;
|
||||||
|
|
||||||
bool rdy_line;
|
bool rdy_line;
|
||||||
optional<uint16> rdy_addr;
|
bool rdy_addr_valid;
|
||||||
|
uint16 rdy_addr_value;
|
||||||
|
|
||||||
bool oam_dma_pending;
|
bool oam_dma_pending;
|
||||||
uint8 oam_dma_page;
|
uint8 oam_dma_page;
|
||||||
|
@ -49,7 +50,7 @@ struct CPU : Processor::R6502, Thread {
|
||||||
void set_irq_apu_line(bool);
|
void set_irq_apu_line(bool);
|
||||||
|
|
||||||
void set_rdy_line(bool);
|
void set_rdy_line(bool);
|
||||||
void set_rdy_addr(optional<uint16>);
|
void set_rdy_addr(bool valid, uint16 value = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CPU cpu;
|
extern CPU cpu;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
void CPU::serialize(serializer &s) {
|
void CPU::serialize(serializer& s) {
|
||||||
R6502::serialize(s);
|
R6502::serialize(s);
|
||||||
Thread::serialize(s);
|
Thread::serialize(s);
|
||||||
|
|
||||||
|
@ -11,12 +11,8 @@ void CPU::serialize(serializer &s) {
|
||||||
s.integer(status.irq_apu_line);
|
s.integer(status.irq_apu_line);
|
||||||
|
|
||||||
s.integer(status.rdy_line);
|
s.integer(status.rdy_line);
|
||||||
bool rdy_addr_valid = status.rdy_addr;
|
s.integer(status.rdy_addr_valid);
|
||||||
unsigned rdy_addr_value = 0;
|
s.integer(status.rdy_addr_value);
|
||||||
if(rdy_addr_valid) rdy_addr_value = status.rdy_addr();
|
|
||||||
s.integer(rdy_addr_valid);
|
|
||||||
s.integer(rdy_addr_value);
|
|
||||||
if(rdy_addr_valid) status.rdy_addr = rdy_addr_value;
|
|
||||||
|
|
||||||
s.integer(status.oam_dma_pending);
|
s.integer(status.oam_dma_pending);
|
||||||
s.integer(status.oam_dma_page);
|
s.integer(status.oam_dma_page);
|
||||||
|
|
|
@ -6,7 +6,7 @@ uint8 CPU::op_read(uint16 addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
while(status.rdy_line == 0) {
|
while(status.rdy_line == 0) {
|
||||||
regs.mdr = bus.read(status.rdy_addr ? status.rdy_addr() : addr);
|
regs.mdr = bus.read(status.rdy_addr_valid ? status.rdy_addr_value : addr);
|
||||||
add_clocks(12);
|
add_clocks(12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ void CPU::set_rdy_line(bool line) {
|
||||||
status.rdy_line = line;
|
status.rdy_line = line;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::set_rdy_addr(optional<uint16> addr) {
|
void CPU::set_rdy_addr(bool valid, uint16 value) {
|
||||||
status.rdy_addr = addr;
|
status.rdy_addr_valid = valid;
|
||||||
|
status.rdy_addr_value = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace Famicom {
|
||||||
clock = 0;
|
clock = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void serialize(serializer &s) {
|
inline void serialize(serializer& s) {
|
||||||
s.integer(frequency);
|
s.integer(frequency);
|
||||||
s.integer(clock);
|
s.integer(clock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ struct Input {
|
||||||
void power();
|
void power();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
void serialize(serializer &s);
|
void serialize(serializer&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Device port1;
|
Device port1;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
void Input::serialize(serializer &s) {
|
void Input::serialize(serializer& s) {
|
||||||
s.integer((unsigned&)port1);
|
s.integer((unsigned&)port1);
|
||||||
s.integer((unsigned&)port2);
|
s.integer((unsigned&)port2);
|
||||||
|
|
||||||
|
|
|
@ -92,10 +92,10 @@ void PPU::reset() {
|
||||||
//$2003
|
//$2003
|
||||||
status.oam_addr = 0x00;
|
status.oam_addr = 0x00;
|
||||||
|
|
||||||
for(auto &n : buffer) n = 0;
|
for(auto& n : buffer) n = 0;
|
||||||
for(auto &n : ciram ) n = 0;
|
for(auto& n : ciram ) n = 0;
|
||||||
for(auto &n : cgram ) n = 0;
|
for(auto& n : cgram ) n = 0;
|
||||||
for(auto &n : oam ) n = 0;
|
for(auto& n : oam ) n = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 PPU::read(uint16 addr) {
|
uint8 PPU::read(uint16 addr) {
|
||||||
|
@ -281,7 +281,7 @@ void PPU::scrolly_increment() {
|
||||||
//
|
//
|
||||||
|
|
||||||
void PPU::raster_pixel() {
|
void PPU::raster_pixel() {
|
||||||
uint32 *output = buffer + status.ly * 256;
|
uint32* output = buffer + status.ly * 256;
|
||||||
|
|
||||||
unsigned mask = 0x8000 >> (status.xaddr + (status.lx & 7));
|
unsigned mask = 0x8000 >> (status.xaddr + (status.lx & 7));
|
||||||
unsigned palette = 0, object_palette = 0;
|
unsigned palette = 0, object_palette = 0;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
void PPU::serialize(serializer &s) {
|
void PPU::serialize(serializer& s) {
|
||||||
Thread::serialize(s);
|
Thread::serialize(s);
|
||||||
|
|
||||||
s.integer(status.mdr);
|
s.integer(status.mdr);
|
||||||
|
|
|
@ -15,7 +15,7 @@ serializer System::serialize() {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool System::unserialize(serializer &s) {
|
bool System::unserialize(serializer& s) {
|
||||||
unsigned signature, version;
|
unsigned signature, version;
|
||||||
char hash[64], description[512];
|
char hash[64], description[512];
|
||||||
|
|
||||||
|
@ -32,10 +32,10 @@ bool System::unserialize(serializer &s) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::serialize(serializer &s) {
|
void System::serialize(serializer& s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::serialize_all(serializer &s) {
|
void System::serialize_all(serializer& s) {
|
||||||
system.serialize(s);
|
system.serialize(s);
|
||||||
input.serialize(s);
|
input.serialize(s);
|
||||||
cartridge.serialize(s);
|
cartridge.serialize(s);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
struct Video {
|
struct Video {
|
||||||
unsigned *palette;
|
unsigned* palette = nullptr;
|
||||||
void generate_palette();
|
void generate_palette();
|
||||||
|
|
||||||
Video();
|
Video();
|
||||||
|
|
|
@ -57,7 +57,7 @@ void APU::power() {
|
||||||
create(Main, 4 * 1024 * 1024);
|
create(Main, 4 * 1024 * 1024);
|
||||||
for(unsigned n = 0xff10; n <= 0xff3f; n++) bus.mmio[n] = this;
|
for(unsigned n = 0xff10; n <= 0xff3f; n++) bus.mmio[n] = this;
|
||||||
|
|
||||||
for(auto &n : mmio_data) n = 0x00;
|
for(auto& n : mmio_data) n = 0x00;
|
||||||
sequencer_base = 0;
|
sequencer_base = 0;
|
||||||
sequencer_step = 0;
|
sequencer_step = 0;
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ void APU::Master::power() {
|
||||||
right = 0;
|
right = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Master::serialize(serializer &s) {
|
void APU::Master::serialize(serializer& s) {
|
||||||
s.integer(left_in_enable);
|
s.integer(left_in_enable);
|
||||||
s.integer(left_volume);
|
s.integer(left_volume);
|
||||||
s.integer(right_in_enable);
|
s.integer(right_in_enable);
|
||||||
|
|
|
@ -20,9 +20,6 @@ void APU::Noise::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Noise::clock_length() {
|
void APU::Noise::clock_length() {
|
||||||
//if(counter && length) {
|
|
||||||
// if(--length == 0) enable = false;
|
|
||||||
//}
|
|
||||||
if(enable && counter) {
|
if(enable && counter) {
|
||||||
if(++length == 0) enable = false;
|
if(++length == 0) enable = false;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +35,6 @@ void APU::Noise::clock_envelope() {
|
||||||
|
|
||||||
void APU::Noise::write(unsigned r, uint8 data) {
|
void APU::Noise::write(unsigned r, uint8 data) {
|
||||||
if(r == 1) { //$ff20 NR41
|
if(r == 1) { //$ff20 NR41
|
||||||
//length = 64 - (data & 0x3f);
|
|
||||||
length = data & 0x3f;
|
length = data & 0x3f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +62,6 @@ void APU::Noise::write(unsigned r, uint8 data) {
|
||||||
lfsr = ~0U;
|
lfsr = ~0U;
|
||||||
envelope_period = envelope_frequency;
|
envelope_period = envelope_frequency;
|
||||||
volume = envelope_volume;
|
volume = envelope_volume;
|
||||||
//if(length == 0) length = 64;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +85,7 @@ void APU::Noise::power() {
|
||||||
lfsr = 0;
|
lfsr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Noise::serialize(serializer &s) {
|
void APU::Noise::serialize(serializer& s) {
|
||||||
s.integer(enable);
|
s.integer(enable);
|
||||||
|
|
||||||
s.integer(envelope_volume);
|
s.integer(envelope_volume);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#ifdef APU_CPP
|
#ifdef APU_CPP
|
||||||
|
|
||||||
void APU::serialize(serializer &s) {
|
void APU::serialize(serializer& s) {
|
||||||
Thread::serialize(s);
|
Thread::serialize(s);
|
||||||
|
|
||||||
s.array(mmio_data);
|
s.array(mmio_data);
|
||||||
|
|
|
@ -9,10 +9,10 @@ void APU::Square1::run() {
|
||||||
period = 4 * (2048 - frequency);
|
period = 4 * (2048 - frequency);
|
||||||
phase++;
|
phase++;
|
||||||
switch(duty) {
|
switch(duty) {
|
||||||
case 0: duty_output = (phase == 6); break; //______-_
|
case 0: duty_output = (phase == 6); break; //______-_
|
||||||
case 1: duty_output = (phase >= 6); break; //______--
|
case 1: duty_output = (phase >= 6); break; //______--
|
||||||
case 2: duty_output = (phase >= 4); break; //____----
|
case 2: duty_output = (phase >= 4); break; //____----
|
||||||
case 3: duty_output = (phase <= 5); break; //------__
|
case 3: duty_output = (phase <= 5); break; //------__
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,10 +39,6 @@ void APU::Square1::sweep(bool update) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Square1::clock_length() {
|
void APU::Square1::clock_length() {
|
||||||
//if(counter && length) {
|
|
||||||
// if(--length == 0) enable = false;
|
|
||||||
//}
|
|
||||||
|
|
||||||
if(counter && enable) {
|
if(counter && enable) {
|
||||||
if(++length == 0) enable = false;
|
if(++length == 0) enable = false;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +70,6 @@ void APU::Square1::write(unsigned r, uint8 data) {
|
||||||
|
|
||||||
if(r == 1) { //$ff11 NR11
|
if(r == 1) { //$ff11 NR11
|
||||||
duty = data >> 6;
|
duty = data >> 6;
|
||||||
//length = 64 - (data & 0x3f);
|
|
||||||
length = data & 0x3f;
|
length = data & 0x3f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +99,6 @@ void APU::Square1::write(unsigned r, uint8 data) {
|
||||||
sweep_enable = sweep_period || sweep_shift;
|
sweep_enable = sweep_period || sweep_shift;
|
||||||
sweep_negate = false;
|
sweep_negate = false;
|
||||||
if(sweep_shift) sweep(0);
|
if(sweep_shift) sweep(0);
|
||||||
//if(length == 0) length = 64;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,7 +129,7 @@ void APU::Square1::power() {
|
||||||
volume = 0;
|
volume = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Square1::serialize(serializer &s) {
|
void APU::Square1::serialize(serializer& s) {
|
||||||
s.integer(enable);
|
s.integer(enable);
|
||||||
|
|
||||||
s.integer(sweep_frequency);
|
s.integer(sweep_frequency);
|
||||||
|
|
|
@ -9,10 +9,10 @@ void APU::Square2::run() {
|
||||||
period = 4 * (2048 - frequency);
|
period = 4 * (2048 - frequency);
|
||||||
phase++;
|
phase++;
|
||||||
switch(duty) {
|
switch(duty) {
|
||||||
case 0: duty_output = (phase == 6); break; //______-_
|
case 0: duty_output = (phase == 6); break; //______-_
|
||||||
case 1: duty_output = (phase >= 6); break; //______--
|
case 1: duty_output = (phase >= 6); break; //______--
|
||||||
case 2: duty_output = (phase >= 4); break; //____----
|
case 2: duty_output = (phase >= 4); break; //____----
|
||||||
case 3: duty_output = (phase <= 5); break; //------__
|
case 3: duty_output = (phase <= 5); break; //------__
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,10 +23,6 @@ void APU::Square2::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Square2::clock_length() {
|
void APU::Square2::clock_length() {
|
||||||
//if(counter && length) {
|
|
||||||
// if(--length == 0) enable = false;
|
|
||||||
//}
|
|
||||||
|
|
||||||
if(counter && enable) {
|
if(counter && enable) {
|
||||||
if(++length == 0) enable = false;
|
if(++length == 0) enable = false;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +39,6 @@ void APU::Square2::clock_envelope() {
|
||||||
void APU::Square2::write(unsigned r, uint8 data) {
|
void APU::Square2::write(unsigned r, uint8 data) {
|
||||||
if(r == 1) { //$ff16 NR21
|
if(r == 1) { //$ff16 NR21
|
||||||
duty = data >> 6;
|
duty = data >> 6;
|
||||||
//length = 64 - (data & 0x3f);
|
|
||||||
length = (data & 0x3f);
|
length = (data & 0x3f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +63,6 @@ void APU::Square2::write(unsigned r, uint8 data) {
|
||||||
period = 4 * (2048 - frequency);
|
period = 4 * (2048 - frequency);
|
||||||
envelope_period = envelope_frequency;
|
envelope_period = envelope_frequency;
|
||||||
volume = envelope_volume;
|
volume = envelope_volume;
|
||||||
//if(length == 0) length = 64;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,7 +86,7 @@ void APU::Square2::power() {
|
||||||
volume = 0;
|
volume = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Square2::serialize(serializer &s) {
|
void APU::Square2::serialize(serializer& s) {
|
||||||
s.integer(enable);
|
s.integer(enable);
|
||||||
|
|
||||||
s.integer(duty);
|
s.integer(duty);
|
||||||
|
|
|
@ -13,9 +13,6 @@ void APU::Wave::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Wave::clock_length() {
|
void APU::Wave::clock_length() {
|
||||||
//if(counter && length) {
|
|
||||||
// if(--length == 0) enable = false;
|
|
||||||
//}
|
|
||||||
if(enable && counter) {
|
if(enable && counter) {
|
||||||
if(++length == 0) enable = false;
|
if(++length == 0) enable = false;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +25,6 @@ void APU::Wave::write(unsigned r, uint8 data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(r == 1) { //$ff1b NR31
|
if(r == 1) { //$ff1b NR31
|
||||||
//length = 256 - data;
|
|
||||||
length = data;
|
length = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +50,6 @@ void APU::Wave::write(unsigned r, uint8 data) {
|
||||||
enable = dac_enable;
|
enable = dac_enable;
|
||||||
period = 2 * (2048 - frequency);
|
period = 2 * (2048 - frequency);
|
||||||
pattern_offset = 0;
|
pattern_offset = 0;
|
||||||
//if(length == 0) length = 256;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +69,7 @@ void APU::Wave::power() {
|
||||||
counter = 0;
|
counter = 0;
|
||||||
|
|
||||||
random_lfsr r;
|
random_lfsr r;
|
||||||
for(auto &n : pattern) n = r() & 15;
|
for(auto& n : pattern) n = r() & 15;
|
||||||
|
|
||||||
output = 0;
|
output = 0;
|
||||||
length = 0;
|
length = 0;
|
||||||
|
@ -83,7 +78,7 @@ void APU::Wave::power() {
|
||||||
pattern_sample = 0;
|
pattern_sample = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::Wave::serialize(serializer &s) {
|
void APU::Wave::serialize(serializer& s) {
|
||||||
s.integer(enable);
|
s.integer(enable);
|
||||||
|
|
||||||
s.integer(dac_enable);
|
s.integer(dac_enable);
|
||||||
|
|
|
@ -118,7 +118,7 @@ uint8 Cartridge::mmio_read(uint16 addr) {
|
||||||
if(addr == 0xff50) return 0x00;
|
if(addr == 0xff50) return 0x00;
|
||||||
|
|
||||||
if(bootrom_enable) {
|
if(bootrom_enable) {
|
||||||
const uint8 *data = nullptr;
|
const uint8* data = nullptr;
|
||||||
switch(system.revision()) { default:
|
switch(system.revision()) { default:
|
||||||
case System::Revision::GameBoy: data = system.bootROM.dmg; break;
|
case System::Revision::GameBoy: data = system.bootROM.dmg; break;
|
||||||
case System::Revision::SuperGameBoy: data = system.bootROM.sgb; break;
|
case System::Revision::SuperGameBoy: data = system.bootROM.sgb; break;
|
||||||
|
|
|
@ -45,13 +45,13 @@ struct Cartridge : MMIO, property<Cartridge> {
|
||||||
readonly<bool> loaded;
|
readonly<bool> loaded;
|
||||||
readonly<string> sha256;
|
readonly<string> sha256;
|
||||||
|
|
||||||
uint8_t *romdata;
|
uint8_t* romdata;
|
||||||
unsigned romsize;
|
unsigned romsize;
|
||||||
|
|
||||||
uint8_t *ramdata;
|
uint8_t* ramdata;
|
||||||
unsigned ramsize;
|
unsigned ramsize;
|
||||||
|
|
||||||
MMIO *mapper;
|
MMIO* mapper;
|
||||||
bool bootrom_enable;
|
bool bootrom_enable;
|
||||||
|
|
||||||
void load(System::Revision revision);
|
void load(System::Revision revision);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#ifdef CARTRIDGE_CPP
|
#ifdef CARTRIDGE_CPP
|
||||||
|
|
||||||
void Cartridge::serialize(serializer &s) {
|
void Cartridge::serialize(serializer& s) {
|
||||||
if(information.battery) s.array(ramdata, ramsize);
|
if(information.battery) s.array(ramdata, ramsize);
|
||||||
s.integer(bootrom_enable);
|
s.integer(bootrom_enable);
|
||||||
|
|
||||||
|
|
|
@ -4,20 +4,20 @@ namespace GameBoy {
|
||||||
|
|
||||||
Cheat cheat;
|
Cheat cheat;
|
||||||
|
|
||||||
bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned &comp) {
|
bool Cheat::decode(string code_, unsigned& addr, unsigned& data, unsigned& comp) {
|
||||||
static bool initialize = false;
|
static bool initialize = false;
|
||||||
static uint8 mapProActionReplay[256], mapGameGenie[256];
|
static uint8 mapProActionReplay[256], mapGameGenie[256];
|
||||||
|
|
||||||
if(initialize == false) {
|
if(initialize == false) {
|
||||||
initialize = true;
|
initialize = true;
|
||||||
|
|
||||||
for(auto &n : mapProActionReplay) n = ~0;
|
for(auto& n : mapProActionReplay) n = ~0;
|
||||||
mapProActionReplay['0'] = 0; mapProActionReplay['1'] = 1; mapProActionReplay['2'] = 2; mapProActionReplay['3'] = 3;
|
mapProActionReplay['0'] = 0; mapProActionReplay['1'] = 1; mapProActionReplay['2'] = 2; mapProActionReplay['3'] = 3;
|
||||||
mapProActionReplay['4'] = 4; mapProActionReplay['5'] = 5; mapProActionReplay['6'] = 6; mapProActionReplay['7'] = 7;
|
mapProActionReplay['4'] = 4; mapProActionReplay['5'] = 5; mapProActionReplay['6'] = 6; mapProActionReplay['7'] = 7;
|
||||||
mapProActionReplay['8'] = 8; mapProActionReplay['9'] = 9; mapProActionReplay['A'] = 10; mapProActionReplay['B'] = 11;
|
mapProActionReplay['8'] = 8; mapProActionReplay['9'] = 9; mapProActionReplay['A'] = 10; mapProActionReplay['B'] = 11;
|
||||||
mapProActionReplay['C'] = 12; mapProActionReplay['D'] = 13; mapProActionReplay['E'] = 14; mapProActionReplay['F'] = 15;
|
mapProActionReplay['C'] = 12; mapProActionReplay['D'] = 13; mapProActionReplay['E'] = 14; mapProActionReplay['F'] = 15;
|
||||||
|
|
||||||
for(auto &n : mapGameGenie) n = ~0;
|
for(auto& n : mapGameGenie) n = ~0;
|
||||||
mapGameGenie['0'] = 0; mapGameGenie['1'] = 1; mapGameGenie['2'] = 2; mapGameGenie['3'] = 3;
|
mapGameGenie['0'] = 0; mapGameGenie['1'] = 1; mapGameGenie['2'] = 2; mapGameGenie['3'] = 3;
|
||||||
mapGameGenie['4'] = 4; mapGameGenie['5'] = 5; mapGameGenie['6'] = 6; mapGameGenie['7'] = 7;
|
mapGameGenie['4'] = 4; mapGameGenie['5'] = 5; mapGameGenie['6'] = 6; mapGameGenie['7'] = 7;
|
||||||
mapGameGenie['8'] = 8; mapGameGenie['9'] = 9; mapGameGenie['A'] = 10; mapGameGenie['B'] = 11;
|
mapGameGenie['8'] = 8; mapGameGenie['9'] = 9; mapGameGenie['A'] = 10; mapGameGenie['B'] = 11;
|
||||||
|
@ -29,7 +29,7 @@ bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned
|
||||||
unsigned length = code.length(), bits = 0;
|
unsigned length = code.length(), bits = 0;
|
||||||
|
|
||||||
if(code.wildcard("????:??")) {
|
if(code.wildcard("????:??")) {
|
||||||
code = { substr(code, 0, 4), substr(code, 5, 2) };
|
code = {substr(code, 0, 4), substr(code, 5, 2)};
|
||||||
for(unsigned n = 0; n < 6; n++) if(mapProActionReplay[code[n]] > 15) return false;
|
for(unsigned n = 0; n < 6; n++) if(mapProActionReplay[code[n]] > 15) return false;
|
||||||
bits = hex(code);
|
bits = hex(code);
|
||||||
addr = (bits >> 8) & 0xffff;
|
addr = (bits >> 8) & 0xffff;
|
||||||
|
@ -39,7 +39,7 @@ bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
if(code.wildcard("????:??:??")) {
|
if(code.wildcard("????:??:??")) {
|
||||||
code = { substr(code, 0, 4), substr(code, 5, 2), substr(code, 8, 2) };
|
code = {substr(code, 0, 4), substr(code, 5, 2), substr(code, 8, 2)};
|
||||||
for(unsigned n = 0; n < 8; n++) if(mapProActionReplay[code[n]] > 15) return false;
|
for(unsigned n = 0; n < 8; n++) if(mapProActionReplay[code[n]] > 15) return false;
|
||||||
bits = hex(code);
|
bits = hex(code);
|
||||||
addr = (bits >> 16) & 0xffff;
|
addr = (bits >> 16) & 0xffff;
|
||||||
|
@ -49,7 +49,7 @@ bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
if(code.wildcard("???" "-" "???")) {
|
if(code.wildcard("???" "-" "???")) {
|
||||||
code = { substr(code, 0, 3), substr(code, 4, 3) };
|
code = {substr(code, 0, 3), substr(code, 4, 3)};
|
||||||
for(unsigned n = 0; n < 6; n++) if(mapGameGenie[code[n]] > 15) return false;
|
for(unsigned n = 0; n < 6; n++) if(mapGameGenie[code[n]] > 15) return false;
|
||||||
for(unsigned n = 0; n < 6; n++) bits |= mapGameGenie[code[n]] << (20 - n * 4);
|
for(unsigned n = 0; n < 6; n++) bits |= mapGameGenie[code[n]] << (20 - n * 4);
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
if(code.wildcard("???" "-" "???" "-" "???")) {
|
if(code.wildcard("???" "-" "???" "-" "???")) {
|
||||||
code = { substr(code, 0, 3), substr(code, 4, 3), substr(code, 8, 1), substr(code, 10, 1) };
|
code = {substr(code, 0, 3), substr(code, 4, 3), substr(code, 8, 1), substr(code, 10, 1)};
|
||||||
for(unsigned n = 0; n < 8; n++) if(mapGameGenie[code[n]] > 15) return false;
|
for(unsigned n = 0; n < 8; n++) if(mapGameGenie[code[n]] > 15) return false;
|
||||||
for(unsigned n = 0; n < 8; n++) bits |= mapGameGenie[code[n]] << (28 - n * 4);
|
for(unsigned n = 0; n < 8; n++) bits |= mapGameGenie[code[n]] << (28 - n * 4);
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cheat::synchronize() {
|
void Cheat::synchronize() {
|
||||||
for(auto &n : override) n = false;
|
for(auto& n : override) n = false;
|
||||||
|
|
||||||
for(unsigned n = 0; n < size(); n++) {
|
for(unsigned n = 0; n < size(); n++) {
|
||||||
override[operator[](n).addr] = true;
|
override[operator[](n).addr] = true;
|
||||||
|
|
|
@ -5,7 +5,7 @@ struct CheatCode {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Cheat : public vector<CheatCode> {
|
struct Cheat : public vector<CheatCode> {
|
||||||
static bool decode(const string &code, unsigned &addr, unsigned &data, unsigned &comp);
|
static bool decode(string code, unsigned& addr, unsigned& data, unsigned& comp);
|
||||||
|
|
||||||
void synchronize();
|
void synchronize();
|
||||||
bool override[65536];
|
bool override[65536];
|
||||||
|
|
|
@ -139,8 +139,8 @@ void CPU::power() {
|
||||||
bus.mmio[0xff77] = this; //???
|
bus.mmio[0xff77] = this; //???
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto &n : wram) n = 0x00;
|
for(auto& n : wram) n = 0x00;
|
||||||
for(auto &n : hram) n = 0x00;
|
for(auto& n : hram) n = 0x00;
|
||||||
|
|
||||||
r[PC] = 0x0000;
|
r[PC] = 0x0000;
|
||||||
r[SP] = 0x0000;
|
r[SP] = 0x0000;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#ifdef CPU_CPP
|
#ifdef CPU_CPP
|
||||||
|
|
||||||
void CPU::serialize(serializer &s) {
|
void CPU::serialize(serializer& s) {
|
||||||
LR35902::serialize(s);
|
LR35902::serialize(s);
|
||||||
Thread::serialize(s);
|
Thread::serialize(s);
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace GameBoy {
|
||||||
clock = 0;
|
clock = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void serialize(serializer &s) {
|
inline void serialize(serializer& s) {
|
||||||
s.integer(frequency);
|
s.integer(frequency);
|
||||||
s.integer(clock);
|
s.integer(clock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ void Interface::load(unsigned id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interface::save() {
|
void Interface::save() {
|
||||||
for(auto &memory : cartridge.memory) {
|
for(auto& memory : cartridge.memory) {
|
||||||
interface->saveRequest(memory.id, memory.name);
|
interface->saveRequest(memory.id, memory.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ void Memory::allocate(unsigned size_) {
|
||||||
data = new uint8_t[size]();
|
data = new uint8_t[size]();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::copy(const uint8_t *data_, unsigned size_) {
|
void Memory::copy(const uint8_t* data_, unsigned size_) {
|
||||||
free();
|
free();
|
||||||
size = size_;
|
size = size_;
|
||||||
data = new uint8_t[size];
|
data = new uint8_t[size];
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
struct Memory {
|
struct Memory {
|
||||||
uint8_t *data;
|
uint8_t* data;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
|
||||||
uint8_t& operator[](unsigned addr);
|
uint8_t& operator[](unsigned addr);
|
||||||
void allocate(unsigned size);
|
void allocate(unsigned size);
|
||||||
void copy(const uint8_t *data, unsigned size);
|
void copy(const uint8_t* data, unsigned size);
|
||||||
void free();
|
void free();
|
||||||
Memory();
|
Memory();
|
||||||
~Memory();
|
~Memory();
|
||||||
|
@ -21,7 +21,7 @@ struct Unmapped : MMIO {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Bus {
|
struct Bus {
|
||||||
MMIO *mmio[65536];
|
MMIO* mmio[65536];
|
||||||
uint8 read(uint16 addr);
|
uint8 read(uint16 addr);
|
||||||
void write(uint16 addr, uint8 data);
|
void write(uint16 addr, uint8 data);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ void PPU::cgb_render() {
|
||||||
if(status.ob_enable) cgb_render_ob();
|
if(status.ob_enable) cgb_render_ob();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 *output = screen + status.ly * 160;
|
uint32* output = screen + status.ly * 160;
|
||||||
for(unsigned n = 0; n < 160; n++) output[n] = video.palette[line[n]];
|
for(unsigned n = 0; n < 160; n++) output[n] = video.palette[line[n]];
|
||||||
interface->lcdScanline();
|
interface->lcdScanline();
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ void PPU::cgb_render() {
|
||||||
//0x20: horizontal flip
|
//0x20: horizontal flip
|
||||||
//0x08: VRAM bank#
|
//0x08: VRAM bank#
|
||||||
//0x07: palette#
|
//0x07: palette#
|
||||||
void PPU::cgb_read_tile(bool select, unsigned x, unsigned y, unsigned &tile, unsigned &attr, unsigned &data) {
|
void PPU::cgb_read_tile(bool select, unsigned x, unsigned y, unsigned& tile, unsigned& attr, unsigned& data) {
|
||||||
unsigned tmaddr = 0x1800 + (select << 10);
|
unsigned tmaddr = 0x1800 + (select << 10);
|
||||||
tmaddr += (((y >> 3) << 5) + (x >> 3)) & 0x03ff;
|
tmaddr += (((y >> 3) << 5) + (x >> 3)) & 0x03ff;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ void PPU::dmg_render() {
|
||||||
if(status.ob_enable) dmg_render_ob();
|
if(status.ob_enable) dmg_render_ob();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 *output = screen + status.ly * 160;
|
uint32* output = screen + status.ly * 160;
|
||||||
for(unsigned n = 0; n < 160; n++) output[n] = video.palette[line[n]];
|
for(unsigned n = 0; n < 160; n++) output[n] = video.palette[line[n]];
|
||||||
interface->lcdScanline();
|
interface->lcdScanline();
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,17 +106,17 @@ void PPU::power() {
|
||||||
bus.mmio[0xff6b] = this; //OBPD
|
bus.mmio[0xff6b] = this; //OBPD
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto &n : screen) n = 0x0000;
|
for(auto& n : screen) n = 0x0000;
|
||||||
for(auto &n : line) n = 0x0000;
|
for(auto& n : line) n = 0x0000;
|
||||||
for(auto &n : origin) n = Origin::None;
|
for(auto& n : origin) n = Origin::None;
|
||||||
|
|
||||||
for(auto &n : vram) n = 0x00;
|
for(auto& n : vram) n = 0x00;
|
||||||
for(auto &n : oam) n = 0x00;
|
for(auto& n : oam) n = 0x00;
|
||||||
for(auto &n : bgp) n = 0x00;
|
for(auto& n : bgp) n = 0x00;
|
||||||
for(auto &n : obp[0]) n = 0x00;
|
for(auto& n : obp[0]) n = 0x00;
|
||||||
for(auto &n : obp[1]) n = 0x00;
|
for(auto& n : obp[1]) n = 0x00;
|
||||||
for(auto &n : bgpd) n = 0x0000;
|
for(auto& n : bgpd) n = 0x0000;
|
||||||
for(auto &n : obpd) n = 0x0000;
|
for(auto& n : obpd) n = 0x0000;
|
||||||
|
|
||||||
status.lx = 0;
|
status.lx = 0;
|
||||||
status.wyc = 0;
|
status.wyc = 0;
|
||||||
|
|
|
@ -83,7 +83,7 @@ struct PPU : Thread, MMIO {
|
||||||
|
|
||||||
//cgb.cpp
|
//cgb.cpp
|
||||||
void cgb_render();
|
void cgb_render();
|
||||||
void cgb_read_tile(bool select, unsigned x, unsigned y, unsigned &tile, unsigned &attr, unsigned &data);
|
void cgb_read_tile(bool select, unsigned x, unsigned y, unsigned& tile, unsigned& attr, unsigned& data);
|
||||||
void cgb_render_bg();
|
void cgb_render_bg();
|
||||||
void cgb_render_window();
|
void cgb_render_window();
|
||||||
void cgb_render_ob();
|
void cgb_render_ob();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#ifdef PPU_CPP
|
#ifdef PPU_CPP
|
||||||
|
|
||||||
void PPU::serialize(serializer &s) {
|
void PPU::serialize(serializer& s) {
|
||||||
Thread::serialize(s);
|
Thread::serialize(s);
|
||||||
|
|
||||||
s.array(screen);
|
s.array(screen);
|
||||||
|
|
|
@ -23,8 +23,8 @@ void Scheduler::init() {
|
||||||
|
|
||||||
Scheduler::Scheduler() {
|
Scheduler::Scheduler() {
|
||||||
exit_reason = ExitReason::UnknownEvent;
|
exit_reason = ExitReason::UnknownEvent;
|
||||||
host_thread = 0;
|
host_thread = nullptr;
|
||||||
active_thread = 0;
|
active_thread = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ serializer System::serialize() {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool System::unserialize(serializer &s) {
|
bool System::unserialize(serializer& s) {
|
||||||
unsigned signature, version;
|
unsigned signature, version;
|
||||||
char hash[64], description[512];
|
char hash[64], description[512];
|
||||||
|
|
||||||
|
@ -34,11 +34,11 @@ bool System::unserialize(serializer &s) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::serialize(serializer &s) {
|
void System::serialize(serializer& s) {
|
||||||
s.integer(clocks_executed);
|
s.integer(clocks_executed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::serialize_all(serializer &s) {
|
void System::serialize_all(serializer& s) {
|
||||||
cartridge.serialize(s);
|
cartridge.serialize(s);
|
||||||
system.serialize(s);
|
system.serialize(s);
|
||||||
cpu.serialize(s);
|
cpu.serialize(s);
|
||||||
|
|
|
@ -73,9 +73,9 @@ void System::power() {
|
||||||
}
|
}
|
||||||
|
|
||||||
System::System() {
|
System::System() {
|
||||||
for(auto &byte : bootROM.dmg) byte = 0;
|
for(auto& byte : bootROM.dmg) byte = 0;
|
||||||
for(auto &byte : bootROM.sgb) byte = 0;
|
for(auto& byte : bootROM.sgb) byte = 0;
|
||||||
for(auto &byte : bootROM.cgb) byte = 0;
|
for(auto& byte : bootROM.cgb) byte = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,10 +56,10 @@ unsigned Video::palette_cgb(unsigned color) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
const double Video::monochrome[4][3] = {
|
const double Video::monochrome[4][3] = {
|
||||||
{ 0.605, 0.734, 0.059 },
|
{0.605, 0.734, 0.059},
|
||||||
{ 0.543, 0.672, 0.059 },
|
{0.543, 0.672, 0.059},
|
||||||
{ 0.188, 0.383, 0.188 },
|
{0.188, 0.383, 0.188},
|
||||||
{ 0.059, 0.219, 0.059 },
|
{0.059, 0.219, 0.059},
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
struct Video {
|
struct Video {
|
||||||
uint32_t *palette;
|
uint32_t* palette;
|
||||||
void generate_palette();
|
void generate_palette();
|
||||||
|
|
||||||
Video();
|
Video();
|
||||||
|
|
|
@ -11,7 +11,7 @@ void APU::FIFO::write(int8 byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::FIFO::reset() {
|
void APU::FIFO::reset() {
|
||||||
for(auto &byte : sample) byte = 0;
|
for(auto& byte : sample) byte = 0;
|
||||||
output = 0;
|
output = 0;
|
||||||
|
|
||||||
rdoffset = 0;
|
rdoffset = 0;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
void APU::runsequencer() {
|
void APU::runsequencer() {
|
||||||
auto &r = sequencer;
|
auto& r = sequencer;
|
||||||
|
|
||||||
if(r.base == 0) { //512hz
|
if(r.base == 0) { //512hz
|
||||||
if(r.step == 0 || r.step == 2 || r.step == 4 || r.step == 6) { //256hz
|
if(r.step == 0 || r.step == 2 || r.step == 4 || r.step == 6) { //256hz
|
||||||
|
@ -80,9 +80,9 @@ void APU::Sequencer::write(unsigned addr, uint8 byte) {
|
||||||
void APU::Sequencer::power() {
|
void APU::Sequencer::power() {
|
||||||
lvolume = 0;
|
lvolume = 0;
|
||||||
rvolume = 0;
|
rvolume = 0;
|
||||||
for(auto &n : lenable) n = 0;
|
for(auto& n : lenable) n = 0;
|
||||||
for(auto &n : renable) n = 0;
|
for(auto& n : renable) n = 0;
|
||||||
for(auto &n : enable) n = 0;
|
for(auto& n : enable) n = 0;
|
||||||
masterenable = 0;
|
masterenable = 0;
|
||||||
base = 0;
|
base = 0;
|
||||||
step = 0;
|
step = 0;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
void APU::serialize(serializer &s) {
|
void APU::serialize(serializer& s) {
|
||||||
Thread::serialize(s);
|
Thread::serialize(s);
|
||||||
|
|
||||||
s.integer(regs.bias.level);
|
s.integer(regs.bias.level);
|
||||||
|
@ -56,7 +56,7 @@ void APU::serialize(serializer &s) {
|
||||||
s.integer(wave.frequency);
|
s.integer(wave.frequency);
|
||||||
s.integer(wave.counter);
|
s.integer(wave.counter);
|
||||||
s.integer(wave.initialize);
|
s.integer(wave.initialize);
|
||||||
for(auto &value : wave.pattern) s.integer(value);
|
for(auto& value : wave.pattern) s.integer(value);
|
||||||
s.integer(wave.enable);
|
s.integer(wave.enable);
|
||||||
s.integer(wave.output);
|
s.integer(wave.output);
|
||||||
s.integer(wave.patternaddr);
|
s.integer(wave.patternaddr);
|
||||||
|
@ -84,17 +84,17 @@ void APU::serialize(serializer &s) {
|
||||||
s.integer(sequencer.volume);
|
s.integer(sequencer.volume);
|
||||||
s.integer(sequencer.lvolume);
|
s.integer(sequencer.lvolume);
|
||||||
s.integer(sequencer.rvolume);
|
s.integer(sequencer.rvolume);
|
||||||
for(auto &flag : sequencer.lenable) s.integer(flag);
|
for(auto& flag : sequencer.lenable) s.integer(flag);
|
||||||
for(auto &flag : sequencer.renable) s.integer(flag);
|
for(auto& flag : sequencer.renable) s.integer(flag);
|
||||||
for(auto &flag : sequencer.enable) s.integer(flag);
|
for(auto& flag : sequencer.enable) s.integer(flag);
|
||||||
s.integer(sequencer.masterenable);
|
s.integer(sequencer.masterenable);
|
||||||
s.integer(sequencer.base);
|
s.integer(sequencer.base);
|
||||||
s.integer(sequencer.step);
|
s.integer(sequencer.step);
|
||||||
s.integer(sequencer.lsample);
|
s.integer(sequencer.lsample);
|
||||||
s.integer(sequencer.rsample);
|
s.integer(sequencer.rsample);
|
||||||
|
|
||||||
for(auto &f : fifo) {
|
for(auto& f : fifo) {
|
||||||
for(auto &value : f.sample) s.integer(value);
|
for(auto& value : f.sample) s.integer(value);
|
||||||
s.integer(f.output);
|
s.integer(f.output);
|
||||||
s.integer(f.rdoffset);
|
s.integer(f.rdoffset);
|
||||||
s.integer(f.wroffset);
|
s.integer(f.wroffset);
|
||||||
|
|
|
@ -6,7 +6,7 @@ void APU::Wave::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
output = patternsample;
|
output = patternsample;
|
||||||
static unsigned multiplier[] = { 0, 4, 2, 1, 3, 3, 3, 3};
|
static unsigned multiplier[] = {0, 4, 2, 1, 3, 3, 3, 3};
|
||||||
output = (output * multiplier[volume]) / 4;
|
output = (output * multiplier[volume]) / 4;
|
||||||
if(enable == false) output = 0;
|
if(enable == false) output = 0;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ void APU::Wave::power() {
|
||||||
frequency = 0;
|
frequency = 0;
|
||||||
counter = 0;
|
counter = 0;
|
||||||
initialize = 0;
|
initialize = 0;
|
||||||
for(auto &sample : pattern) sample = 0;
|
for(auto& sample : pattern) sample = 0;
|
||||||
enable = 0;
|
enable = 0;
|
||||||
output = 0;
|
output = 0;
|
||||||
patternaddr = 0;
|
patternaddr = 0;
|
||||||
|
|
|
@ -28,8 +28,8 @@ struct Cartridge : property<Cartridge> {
|
||||||
uint8* ram_data();
|
uint8* ram_data();
|
||||||
unsigned ram_size();
|
unsigned ram_size();
|
||||||
|
|
||||||
uint32 read(uint8 *data, uint32 addr, uint32 size);
|
uint32 read(uint8* data, uint32 addr, uint32 size);
|
||||||
void write(uint8 *data, uint32 addr, uint32 size, uint32 word);
|
void write(uint8* data, uint32 addr, uint32 size, uint32 word);
|
||||||
|
|
||||||
uint32 read(uint32 addr, uint32 size);
|
uint32 read(uint32 addr, uint32 size);
|
||||||
void write(uint32 addr, uint32 size, uint32 word);
|
void write(uint32 addr, uint32 size, uint32 word);
|
||||||
|
|
|
@ -82,7 +82,7 @@ void Cartridge::EEPROM::power() {
|
||||||
address = 0;
|
address = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cartridge::EEPROM::serialize(serializer &s) {
|
void Cartridge::EEPROM::serialize(serializer& s) {
|
||||||
s.array(data, size);
|
s.array(data, size);
|
||||||
s.integer(size);
|
s.integer(size);
|
||||||
s.integer(mask);
|
s.integer(mask);
|
||||||
|
|
|
@ -86,7 +86,7 @@ void Cartridge::FlashROM::power() {
|
||||||
bank = 0;
|
bank = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cartridge::FlashROM::serialize(serializer &s) {
|
void Cartridge::FlashROM::serialize(serializer& s) {
|
||||||
s.array(data, size);
|
s.array(data, size);
|
||||||
s.integer(size);
|
s.integer(size);
|
||||||
s.integer(id);
|
s.integer(id);
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
struct Memory {
|
struct Memory {
|
||||||
uint8 *data;
|
uint8* data;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
unsigned mask;
|
unsigned mask;
|
||||||
} rom, ram;
|
} rom, ram;
|
||||||
|
|
||||||
struct EEPROM {
|
struct EEPROM {
|
||||||
uint8 *data;
|
uint8* data;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
unsigned mask;
|
unsigned mask;
|
||||||
unsigned test;
|
unsigned test;
|
||||||
|
@ -26,7 +26,7 @@ struct EEPROM {
|
||||||
} eeprom;
|
} eeprom;
|
||||||
|
|
||||||
struct FlashROM {
|
struct FlashROM {
|
||||||
uint8 *data;
|
uint8* data;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
uint16 id;
|
uint16 id;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
void Cartridge::serialize(serializer &s) {
|
void Cartridge::serialize(serializer& s) {
|
||||||
if(has_sram) s.array(ram.data, ram.size);
|
if(has_sram) s.array(ram.data, ram.size);
|
||||||
if(has_eeprom) eeprom.serialize(s);
|
if(has_eeprom) eeprom.serialize(s);
|
||||||
if(has_flashrom) flashrom.serialize(s);
|
if(has_flashrom) flashrom.serialize(s);
|
||||||
|
|
|
@ -105,7 +105,7 @@ void CPU::power() {
|
||||||
for(unsigned n = 0; n < 32 * 1024; n++) iwram[n] = 0;
|
for(unsigned n = 0; n < 32 * 1024; n++) iwram[n] = 0;
|
||||||
for(unsigned n = 0; n < 256 * 1024; n++) ewram[n] = 0;
|
for(unsigned n = 0; n < 256 * 1024; n++) ewram[n] = 0;
|
||||||
|
|
||||||
for(auto &dma : regs.dma) {
|
for(auto& dma : regs.dma) {
|
||||||
dma.source = 0;
|
dma.source = 0;
|
||||||
dma.target = 0;
|
dma.target = 0;
|
||||||
dma.length = 0;
|
dma.length = 0;
|
||||||
|
@ -115,7 +115,7 @@ void CPU::power() {
|
||||||
dma.run.source = 0;
|
dma.run.source = 0;
|
||||||
dma.run.length = 0;
|
dma.run.length = 0;
|
||||||
}
|
}
|
||||||
for(auto &timer : regs.timer) {
|
for(auto& timer : regs.timer) {
|
||||||
timer.period = 0;
|
timer.period = 0;
|
||||||
timer.reload = 0;
|
timer.reload = 0;
|
||||||
timer.control = 0;
|
timer.control = 0;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
struct CPU : Processor::ARM, Thread, MMIO {
|
struct CPU : Processor::ARM, Thread, MMIO {
|
||||||
uint8 *iwram;
|
uint8* iwram;
|
||||||
uint8 *ewram;
|
uint8* ewram;
|
||||||
#include "registers.hpp"
|
#include "registers.hpp"
|
||||||
#include "state.hpp"
|
#include "state.hpp"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
void CPU::dma_run() {
|
void CPU::dma_run() {
|
||||||
for(unsigned n = 0; n < 4; n++) {
|
for(unsigned n = 0; n < 4; n++) {
|
||||||
auto &dma = regs.dma[n];
|
auto& dma = regs.dma[n];
|
||||||
if(dma.pending) {
|
if(dma.pending) {
|
||||||
dma.pending = false;
|
dma.pending = false;
|
||||||
dma_transfer(dma);
|
dma_transfer(dma);
|
||||||
|
@ -10,7 +10,7 @@ void CPU::dma_run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::dma_transfer(Registers::DMA &dma) {
|
void CPU::dma_transfer(Registers::DMA& dma) {
|
||||||
unsigned size = dma.control.size ? Word : Half;
|
unsigned size = dma.control.size ? Word : Half;
|
||||||
unsigned seek = dma.control.size ? 4 : 2;
|
unsigned seek = dma.control.size ? 4 : 2;
|
||||||
|
|
||||||
|
@ -43,18 +43,18 @@ void CPU::dma_transfer(Registers::DMA &dma) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::dma_vblank() {
|
void CPU::dma_vblank() {
|
||||||
for(auto &dma : regs.dma) {
|
for(auto& dma : regs.dma) {
|
||||||
if(dma.control.enable && dma.control.timingmode == 1) dma.pending = true;
|
if(dma.control.enable && dma.control.timingmode == 1) dma.pending = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::dma_hblank() {
|
void CPU::dma_hblank() {
|
||||||
for(auto &dma : regs.dma) {
|
for(auto& dma : regs.dma) {
|
||||||
if(dma.control.enable && dma.control.timingmode == 2) dma.pending = true;
|
if(dma.control.enable && dma.control.timingmode == 2) dma.pending = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::dma_hdma() {
|
void CPU::dma_hdma() {
|
||||||
auto &dma = regs.dma[3];
|
auto& dma = regs.dma[3];
|
||||||
if(dma.control.enable && dma.control.timingmode == 3) dma.pending = true;
|
if(dma.control.enable && dma.control.timingmode == 3) dma.pending = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ uint8 CPU::read(uint32 addr) {
|
||||||
case 0x040000c6: case 0x040000c7:
|
case 0x040000c6: case 0x040000c7:
|
||||||
case 0x040000d2: case 0x040000d3:
|
case 0x040000d2: case 0x040000d3:
|
||||||
case 0x040000de: case 0x040000df: {
|
case 0x040000de: case 0x040000df: {
|
||||||
auto &dma = regs.dma[(addr - 0x040000ba) / 12];
|
auto& dma = regs.dma[(addr - 0x040000ba) / 12];
|
||||||
unsigned shift = (addr & 1) * 8;
|
unsigned shift = (addr & 1) * 8;
|
||||||
return dma.control >> shift;
|
return dma.control >> shift;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ uint8 CPU::read(uint32 addr) {
|
||||||
case 0x04000104: case 0x04000105:
|
case 0x04000104: case 0x04000105:
|
||||||
case 0x04000108: case 0x04000109:
|
case 0x04000108: case 0x04000109:
|
||||||
case 0x0400010c: case 0x0400010d: {
|
case 0x0400010c: case 0x0400010d: {
|
||||||
auto &timer = regs.timer[(addr >> 2) & 3];
|
auto& timer = regs.timer[(addr >> 2) & 3];
|
||||||
unsigned shift = (addr & 1) * 8;
|
unsigned shift = (addr & 1) * 8;
|
||||||
return timer.period >> shift;
|
return timer.period >> shift;
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ uint8 CPU::read(uint32 addr) {
|
||||||
case 0x04000106: case 0x04000107:
|
case 0x04000106: case 0x04000107:
|
||||||
case 0x0400010a: case 0x0400010b:
|
case 0x0400010a: case 0x0400010b:
|
||||||
case 0x0400010e: case 0x0400010f: {
|
case 0x0400010e: case 0x0400010f: {
|
||||||
auto &timer = regs.timer[(addr >> 2) & 3];
|
auto& timer = regs.timer[(addr >> 2) & 3];
|
||||||
unsigned shift = (addr & 1) * 8;
|
unsigned shift = (addr & 1) * 8;
|
||||||
return timer.control >> shift;
|
return timer.control >> shift;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ uint8 CPU::read(uint32 addr) {
|
||||||
case 0x04000122: case 0x04000123:
|
case 0x04000122: case 0x04000123:
|
||||||
case 0x04000124: case 0x04000125:
|
case 0x04000124: case 0x04000125:
|
||||||
case 0x04000126: case 0x04000127: {
|
case 0x04000126: case 0x04000127: {
|
||||||
auto &data = regs.serial.data[(addr >> 1) & 3];
|
auto& data = regs.serial.data[(addr >> 1) & 3];
|
||||||
unsigned shift = (addr & 1) * 8;
|
unsigned shift = (addr & 1) * 8;
|
||||||
return data >> shift;
|
return data >> shift;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ void CPU::write(uint32 addr, uint8 byte) {
|
||||||
case 0x040000bc: case 0x040000bd: case 0x040000be: case 0x040000bf:
|
case 0x040000bc: case 0x040000bd: case 0x040000be: case 0x040000bf:
|
||||||
case 0x040000c8: case 0x040000c9: case 0x040000ca: case 0x040000cb:
|
case 0x040000c8: case 0x040000c9: case 0x040000ca: case 0x040000cb:
|
||||||
case 0x040000d4: case 0x040000d5: case 0x040000d6: case 0x040000d7: {
|
case 0x040000d4: case 0x040000d5: case 0x040000d6: case 0x040000d7: {
|
||||||
auto &dma = regs.dma[(addr - 0x040000b0) / 12];
|
auto& dma = regs.dma[(addr - 0x040000b0) / 12];
|
||||||
unsigned shift = (addr & 3) * 8;
|
unsigned shift = (addr & 3) * 8;
|
||||||
dma.source = (dma.source & ~(255 << shift)) | (byte << shift);
|
dma.source = (dma.source & ~(255 << shift)) | (byte << shift);
|
||||||
return;
|
return;
|
||||||
|
@ -159,7 +159,7 @@ void CPU::write(uint32 addr, uint8 byte) {
|
||||||
case 0x040000c0: case 0x040000c1: case 0x040000c2: case 0x040000c3:
|
case 0x040000c0: case 0x040000c1: case 0x040000c2: case 0x040000c3:
|
||||||
case 0x040000cc: case 0x040000cd: case 0x040000ce: case 0x040000cf:
|
case 0x040000cc: case 0x040000cd: case 0x040000ce: case 0x040000cf:
|
||||||
case 0x040000d8: case 0x040000d9: case 0x040000da: case 0x040000db: {
|
case 0x040000d8: case 0x040000d9: case 0x040000da: case 0x040000db: {
|
||||||
auto &dma = regs.dma[(addr - 0x040000b4) / 12];
|
auto& dma = regs.dma[(addr - 0x040000b4) / 12];
|
||||||
unsigned shift = (addr & 3) * 8;
|
unsigned shift = (addr & 3) * 8;
|
||||||
dma.target = (dma.target & ~(255 << shift)) | (byte << shift);
|
dma.target = (dma.target & ~(255 << shift)) | (byte << shift);
|
||||||
return;
|
return;
|
||||||
|
@ -173,7 +173,7 @@ void CPU::write(uint32 addr, uint8 byte) {
|
||||||
case 0x040000c4: case 0x040000c5:
|
case 0x040000c4: case 0x040000c5:
|
||||||
case 0x040000d0: case 0x040000d1:
|
case 0x040000d0: case 0x040000d1:
|
||||||
case 0x040000dc: case 0x040000dd: {
|
case 0x040000dc: case 0x040000dd: {
|
||||||
auto &dma = regs.dma[(addr - 0x040000b8) / 12];
|
auto& dma = regs.dma[(addr - 0x040000b8) / 12];
|
||||||
unsigned shift = (addr & 1) * 8;
|
unsigned shift = (addr & 1) * 8;
|
||||||
dma.length = (dma.length & ~(255 << shift)) | (byte << shift);
|
dma.length = (dma.length & ~(255 << shift)) | (byte << shift);
|
||||||
return;
|
return;
|
||||||
|
@ -187,7 +187,7 @@ void CPU::write(uint32 addr, uint8 byte) {
|
||||||
case 0x040000c6: case 0x040000c7:
|
case 0x040000c6: case 0x040000c7:
|
||||||
case 0x040000d2: case 0x040000d3:
|
case 0x040000d2: case 0x040000d3:
|
||||||
case 0x040000de: case 0x040000df: {
|
case 0x040000de: case 0x040000df: {
|
||||||
auto &dma = regs.dma[(addr - 0x040000ba) / 12];
|
auto& dma = regs.dma[(addr - 0x040000ba) / 12];
|
||||||
unsigned shift = (addr & 1) * 8;
|
unsigned shift = (addr & 1) * 8;
|
||||||
bool enable = dma.control.enable;
|
bool enable = dma.control.enable;
|
||||||
dma.control = (dma.control & ~(255 << shift)) | (byte << shift);
|
dma.control = (dma.control & ~(255 << shift)) | (byte << shift);
|
||||||
|
@ -210,7 +210,7 @@ void CPU::write(uint32 addr, uint8 byte) {
|
||||||
case 0x04000104: case 0x04000105:
|
case 0x04000104: case 0x04000105:
|
||||||
case 0x04000108: case 0x04000109:
|
case 0x04000108: case 0x04000109:
|
||||||
case 0x0400010c: case 0x0400010d: {
|
case 0x0400010c: case 0x0400010d: {
|
||||||
auto &timer = regs.timer[(addr >> 2) & 3];
|
auto& timer = regs.timer[(addr >> 2) & 3];
|
||||||
unsigned shift = (addr & 1) * 8;
|
unsigned shift = (addr & 1) * 8;
|
||||||
timer.reload = (timer.reload & ~(255 << shift)) | (byte << shift);
|
timer.reload = (timer.reload & ~(255 << shift)) | (byte << shift);
|
||||||
return;
|
return;
|
||||||
|
@ -224,7 +224,7 @@ void CPU::write(uint32 addr, uint8 byte) {
|
||||||
case 0x04000106:
|
case 0x04000106:
|
||||||
case 0x0400010a:
|
case 0x0400010a:
|
||||||
case 0x0400010e: {
|
case 0x0400010e: {
|
||||||
auto &timer = regs.timer[(addr >> 2) & 3];
|
auto& timer = regs.timer[(addr >> 2) & 3];
|
||||||
bool enable = timer.control.enable;
|
bool enable = timer.control.enable;
|
||||||
timer.control = byte;
|
timer.control = byte;
|
||||||
if(enable == 0 && timer.control.enable == 1) {
|
if(enable == 0 && timer.control.enable == 1) {
|
||||||
|
@ -241,7 +241,7 @@ void CPU::write(uint32 addr, uint8 byte) {
|
||||||
case 0x04000122: case 0x04000123:
|
case 0x04000122: case 0x04000123:
|
||||||
case 0x04000124: case 0x04000125:
|
case 0x04000124: case 0x04000125:
|
||||||
case 0x04000126: case 0x04000127: {
|
case 0x04000126: case 0x04000127: {
|
||||||
auto &data = regs.serial.data[(addr >> 1) & 3];
|
auto& data = regs.serial.data[(addr >> 1) & 3];
|
||||||
unsigned shift = (addr & 1) * 8;
|
unsigned shift = (addr & 1) * 8;
|
||||||
data = (data & ~(255 << shift)) | (byte << shift);
|
data = (data & ~(255 << shift)) | (byte << shift);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
void CPU::serialize(serializer &s) {
|
void CPU::serialize(serializer& s) {
|
||||||
ARM::serialize(s);
|
ARM::serialize(s);
|
||||||
Thread::serialize(s);
|
Thread::serialize(s);
|
||||||
|
|
||||||
s.array(iwram, 32 * 1024);
|
s.array(iwram, 32 * 1024);
|
||||||
s.array(ewram, 256 * 1024);
|
s.array(ewram, 256 * 1024);
|
||||||
|
|
||||||
for(auto &dma : regs.dma) {
|
for(auto& dma : regs.dma) {
|
||||||
s.integer(dma.source);
|
s.integer(dma.source);
|
||||||
s.integer(dma.target);
|
s.integer(dma.target);
|
||||||
s.integer(dma.length);
|
s.integer(dma.length);
|
||||||
|
@ -22,7 +22,7 @@ void CPU::serialize(serializer &s) {
|
||||||
s.integer(dma.run.length);
|
s.integer(dma.run.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto &timer : regs.timer) {
|
for(auto& timer : regs.timer) {
|
||||||
s.integer(timer.period);
|
s.integer(timer.period);
|
||||||
s.integer(timer.reload);
|
s.integer(timer.reload);
|
||||||
s.integer(timer.control.frequency);
|
s.integer(timer.control.frequency);
|
||||||
|
@ -31,7 +31,7 @@ void CPU::serialize(serializer &s) {
|
||||||
s.integer(timer.control.enable);
|
s.integer(timer.control.enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto &value : regs.serial.data) s.integer(value);
|
for(auto& value : regs.serial.data) s.integer(value);
|
||||||
s.integer(regs.serial.control.shiftclockselect);
|
s.integer(regs.serial.control.shiftclockselect);
|
||||||
s.integer(regs.serial.control.shiftclockfrequency);
|
s.integer(regs.serial.control.shiftclockfrequency);
|
||||||
s.integer(regs.serial.control.transferenablereceive);
|
s.integer(regs.serial.control.transferenablereceive);
|
||||||
|
@ -41,7 +41,7 @@ void CPU::serialize(serializer &s) {
|
||||||
s.integer(regs.serial.control.irqenable);
|
s.integer(regs.serial.control.irqenable);
|
||||||
s.integer(regs.serial.data8);
|
s.integer(regs.serial.data8);
|
||||||
|
|
||||||
for(auto &flag : regs.keypad.control.flag) s.integer(flag);
|
for(auto& flag : regs.keypad.control.flag) s.integer(flag);
|
||||||
s.integer(regs.keypad.control.enable);
|
s.integer(regs.keypad.control.enable);
|
||||||
s.integer(regs.keypad.control.condition);
|
s.integer(regs.keypad.control.condition);
|
||||||
|
|
||||||
|
@ -73,23 +73,23 @@ void CPU::serialize(serializer &s) {
|
||||||
s.integer(regs.irq.enable.vblank);
|
s.integer(regs.irq.enable.vblank);
|
||||||
s.integer(regs.irq.enable.hblank);
|
s.integer(regs.irq.enable.hblank);
|
||||||
s.integer(regs.irq.enable.vcoincidence);
|
s.integer(regs.irq.enable.vcoincidence);
|
||||||
for(auto &flag : regs.irq.enable.timer) s.integer(flag);
|
for(auto& flag : regs.irq.enable.timer) s.integer(flag);
|
||||||
s.integer(regs.irq.enable.serial);
|
s.integer(regs.irq.enable.serial);
|
||||||
for(auto &flag : regs.irq.enable.dma) s.integer(flag);
|
for(auto& flag : regs.irq.enable.dma) s.integer(flag);
|
||||||
s.integer(regs.irq.enable.keypad);
|
s.integer(regs.irq.enable.keypad);
|
||||||
s.integer(regs.irq.enable.cartridge);
|
s.integer(regs.irq.enable.cartridge);
|
||||||
|
|
||||||
s.integer(regs.irq.flag.vblank);
|
s.integer(regs.irq.flag.vblank);
|
||||||
s.integer(regs.irq.flag.hblank);
|
s.integer(regs.irq.flag.hblank);
|
||||||
s.integer(regs.irq.flag.vcoincidence);
|
s.integer(regs.irq.flag.vcoincidence);
|
||||||
for(auto &flag : regs.irq.flag.timer) s.integer(flag);
|
for(auto& flag : regs.irq.flag.timer) s.integer(flag);
|
||||||
s.integer(regs.irq.flag.serial);
|
s.integer(regs.irq.flag.serial);
|
||||||
for(auto &flag : regs.irq.flag.dma) s.integer(flag);
|
for(auto& flag : regs.irq.flag.dma) s.integer(flag);
|
||||||
s.integer(regs.irq.flag.keypad);
|
s.integer(regs.irq.flag.keypad);
|
||||||
s.integer(regs.irq.flag.cartridge);
|
s.integer(regs.irq.flag.cartridge);
|
||||||
|
|
||||||
for(auto &flag : regs.wait.control.nwait) s.integer(flag);
|
for(auto& flag : regs.wait.control.nwait) s.integer(flag);
|
||||||
for(auto &flag : regs.wait.control.swait) s.integer(flag);
|
for(auto& flag : regs.wait.control.swait) s.integer(flag);
|
||||||
s.integer(regs.wait.control.phi);
|
s.integer(regs.wait.control.phi);
|
||||||
s.integer(regs.wait.control.prefetch);
|
s.integer(regs.wait.control.prefetch);
|
||||||
s.integer(regs.wait.control.gametype);
|
s.integer(regs.wait.control.gametype);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
void CPU::timer_step(unsigned clocks) {
|
void CPU::timer_step(unsigned clocks) {
|
||||||
for(unsigned c = 0; c < clocks; c++) {
|
for(unsigned c = 0; c < clocks; c++) {
|
||||||
for(unsigned n = 0; n < 4; n++) {
|
for(unsigned n = 0; n < 4; n++) {
|
||||||
auto &timer = regs.timer[n];
|
auto& timer = regs.timer[n];
|
||||||
if(timer.control.enable == false || timer.control.cascade == true) continue;
|
if(timer.control.enable == false || timer.control.cascade == true) continue;
|
||||||
|
|
||||||
static unsigned mask[] = { 0, 63, 255, 1023 };
|
static unsigned mask[] = {0, 63, 255, 1023};
|
||||||
if((regs.clock & mask[timer.control.frequency]) == 0) {
|
if((regs.clock & mask[timer.control.frequency]) == 0) {
|
||||||
timer_increment(n);
|
timer_increment(n);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ void CPU::timer_step(unsigned clocks) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::timer_increment(unsigned n) {
|
void CPU::timer_increment(unsigned n) {
|
||||||
auto &timer = regs.timer[n];
|
auto& timer = regs.timer[n];
|
||||||
if(++timer.period == 0) {
|
if(++timer.period == 0) {
|
||||||
timer.period = timer.reload;
|
timer.period = timer.reload;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ void CPU::timer_fifo_run(unsigned n) {
|
||||||
apu.fifo[n].read();
|
apu.fifo[n].read();
|
||||||
if(apu.fifo[n].size > 16) return;
|
if(apu.fifo[n].size > 16) return;
|
||||||
|
|
||||||
auto &dma = regs.dma[1 + n];
|
auto& dma = regs.dma[1 + n];
|
||||||
if(dma.control.enable && dma.control.timingmode == 3) {
|
if(dma.control.enable && dma.control.timingmode == 3) {
|
||||||
dma.pending = true;
|
dma.pending = true;
|
||||||
dma.control.targetmode = 2;
|
dma.control.targetmode = 2;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue