diff --git a/emulator/emulator.hpp b/emulator/emulator.hpp index 97cdaf05..d78825ab 100644 --- a/emulator/emulator.hpp +++ b/emulator/emulator.hpp @@ -7,7 +7,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "095.07"; + static const string Version = "095.08"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/gb/apu/apu.cpp b/gb/apu/apu.cpp index 9ba2b7ff..451cd655 100644 --- a/gb/apu/apu.cpp +++ b/gb/apu/apu.cpp @@ -1,6 +1,5 @@ #include -#define APU_CPP namespace GameBoy { #include "square1/square1.cpp" @@ -11,11 +10,11 @@ namespace GameBoy { #include "serialization.cpp" APU apu; -void APU::Main() { +auto APU::Main() -> void { apu.main(); } -void APU::main() { +auto APU::main() -> void { while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::All) { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); @@ -57,14 +56,14 @@ void APU::main() { } } -void APU::hipass(int16& sample, int64& bias) { +auto APU::hipass(int16& sample, int64& bias) -> void { bias += ((((int64)sample << 16) - (bias >> 16)) * 57593) >> 16; sample = sclamp<16>(sample - (bias >> 32)); } -void APU::power() { +auto APU::power() -> void { create(Main, 2 * 1024 * 1024); - for(unsigned n = 0xff10; n <= 0xff3f; n++) bus.mmio[n] = this; + for(uint n = 0xff10; n <= 0xff3f; n++) bus.mmio[n] = this; for(auto& n : mmio_data) n = 0x00; sequencer_base = 0; @@ -77,7 +76,7 @@ void APU::power() { master.power(); } -uint8 APU::mmio_read(uint16 addr) { +auto APU::mmio_read(uint16 addr) -> uint8 { static const uint8 table[48] = { 0x80, 0x3f, 0x00, 0xff, 0xbf, //square1 0xff, 0x3f, 0x00, 0xff, 0xbf, //square2 @@ -102,7 +101,7 @@ uint8 APU::mmio_read(uint16 addr) { return 0xff; } -void APU::mmio_write(uint16 addr, uint8 data) { +auto APU::mmio_write(uint16 addr, uint8 data) -> void { if(addr >= 0xff10 && addr <= 0xff3f) mmio_data[addr - 0xff10] = data; if(addr >= 0xff10 && addr <= 0xff14) return square1.write (addr - 0xff10, data); diff --git a/gb/apu/apu.hpp b/gb/apu/apu.hpp index 14a01434..043aff75 100644 --- a/gb/apu/apu.hpp +++ b/gb/apu/apu.hpp @@ -1,4 +1,14 @@ struct APU : Thread, MMIO { + static auto Main() -> void; + auto main() -> void; + auto hipass(int16& sample, int64& bias) -> void; + auto power() -> void; + + auto mmio_read(uint16 addr) -> uint8; + auto mmio_write(uint16 addr, uint8 data) -> void; + + auto serialize(serializer&) -> void; + #include "square1/square1.hpp" #include "square2/square2.hpp" #include "wave/wave.hpp" @@ -14,16 +24,6 @@ struct APU : Thread, MMIO { Wave wave; Noise noise; Master master; - - static void Main(); - void main(); - void hipass(int16& sample, int64& bias); - void power(); - - uint8 mmio_read(uint16 addr); - void mmio_write(uint16 addr, uint8 data); - - void serialize(serializer&); }; extern APU apu; diff --git a/gb/apu/master/master.cpp b/gb/apu/master/master.cpp index 9b601f44..201a8ebc 100644 --- a/gb/apu/master/master.cpp +++ b/gb/apu/master/master.cpp @@ -1,16 +1,14 @@ -#ifdef APU_CPP - -void APU::Master::run() { +auto APU::Master::run() -> void { if(enable == false) { center = 0; left = 0; right = 0; -center_bias = left_bias = right_bias = 0; + center_bias = left_bias = right_bias = 0; return; } - signed sample = 0; + int sample = 0; sample += apu.square1.output; sample += apu.square2.output; sample += apu.wave.output; @@ -41,7 +39,7 @@ center_bias = left_bias = right_bias = 0; right >>= 1; } -void APU::Master::write(unsigned r, uint8 data) { +auto APU::Master::write(uint r, uint8 data) -> void { if(r == 0) { //$ff24 NR50 left_in_enable = data & 0x80; left_volume = (data >> 4) & 7; @@ -65,7 +63,7 @@ void APU::Master::write(unsigned r, uint8 data) { } } -void APU::Master::power() { +auto APU::Master::power() -> void { left_in_enable = 0; left_volume = 0; right_in_enable = 0; @@ -89,7 +87,7 @@ void APU::Master::power() { right_bias = 0; } -void APU::Master::serialize(serializer& s) { +auto APU::Master::serialize(serializer& s) -> void { s.integer(left_in_enable); s.integer(left_volume); s.integer(right_in_enable); @@ -112,5 +110,3 @@ void APU::Master::serialize(serializer& s) { s.integer(left_bias); s.integer(right_bias); } - -#endif diff --git a/gb/apu/master/master.hpp b/gb/apu/master/master.hpp index 8b4be76a..c3c0e493 100644 --- a/gb/apu/master/master.hpp +++ b/gb/apu/master/master.hpp @@ -1,4 +1,10 @@ struct Master { + auto run() -> void; + auto write(uint r, uint8 data) -> void; + auto power() -> void; + + auto serialize(serializer&) -> void; + bool left_in_enable; uint3 left_volume; bool right_in_enable; @@ -20,9 +26,4 @@ struct Master { int64 center_bias; int64 left_bias; int64 right_bias; - - void run(); - void write(unsigned r, uint8 data); - void power(); - void serialize(serializer&); }; diff --git a/gb/apu/noise/noise.cpp b/gb/apu/noise/noise.cpp index c1566ba9..27cf3138 100644 --- a/gb/apu/noise/noise.cpp +++ b/gb/apu/noise/noise.cpp @@ -1,10 +1,8 @@ -#ifdef APU_CPP - -bool APU::Noise::dac_enable() { +auto APU::Noise::dac_enable() const -> bool { return (envelope_volume || envelope_direction); } -void APU::Noise::run() { +auto APU::Noise::run() -> void { if(period && --period == 0) { period = divisor << frequency; if(frequency < 14) { @@ -19,13 +17,13 @@ void APU::Noise::run() { output = sample; } -void APU::Noise::clock_length() { +auto APU::Noise::clock_length() -> void { if(enable && counter) { if(++length == 0) enable = false; } } -void APU::Noise::clock_envelope() { +auto APU::Noise::clock_envelope() -> void { if(enable && envelope_frequency && --envelope_period == 0) { envelope_period = envelope_frequency; if(envelope_direction == 0 && volume > 0) volume--; @@ -33,7 +31,7 @@ void APU::Noise::clock_envelope() { } } -void APU::Noise::write(unsigned r, uint8 data) { +auto APU::Noise::write(uint r, uint8 data) -> void { if(r == 1) { //$ff20 NR41 length = data & 0x3f; } @@ -66,7 +64,7 @@ void APU::Noise::write(unsigned r, uint8 data) { } } -void APU::Noise::power() { +auto APU::Noise::power() -> void { enable = 0; envelope_volume = 0; @@ -85,7 +83,7 @@ void APU::Noise::power() { lfsr = 0; } -void APU::Noise::serialize(serializer& s) { +auto APU::Noise::serialize(serializer& s) -> void { s.integer(enable); s.integer(envelope_volume); @@ -103,5 +101,3 @@ void APU::Noise::serialize(serializer& s) { s.integer(period); s.integer(lfsr); } - -#endif diff --git a/gb/apu/noise/noise.hpp b/gb/apu/noise/noise.hpp index 0f512610..3f3f8797 100644 --- a/gb/apu/noise/noise.hpp +++ b/gb/apu/noise/noise.hpp @@ -1,4 +1,14 @@ struct Noise { + auto dac_enable() const -> bool; + + auto run() -> void; + auto clock_length() -> void; + auto clock_envelope() -> void; + auto write(uint r, uint8 data) -> void; + auto power() -> void; + + auto serialize(serializer&) -> void; + bool enable; uint4 envelope_volume; @@ -6,22 +16,13 @@ struct Noise { uint3 envelope_frequency; uint4 frequency; bool narrow_lfsr; - unsigned divisor; + uint divisor; bool counter; int16 output; uint6 length; uint3 envelope_period; uint4 volume; - unsigned period; + uint period; uint15 lfsr; - - bool dac_enable(); - - void run(); - void clock_length(); - void clock_envelope(); - void write(unsigned r, uint8 data); - void power(); - void serialize(serializer&); }; diff --git a/gb/apu/serialization.cpp b/gb/apu/serialization.cpp index a9891838..037273dc 100644 --- a/gb/apu/serialization.cpp +++ b/gb/apu/serialization.cpp @@ -1,6 +1,4 @@ -#ifdef APU_CPP - -void APU::serialize(serializer& s) { +auto APU::serialize(serializer& s) -> void { Thread::serialize(s); s.array(mmio_data); @@ -13,5 +11,3 @@ void APU::serialize(serializer& s) { noise.serialize(s); master.serialize(s); } - -#endif diff --git a/gb/apu/square1/square1.cpp b/gb/apu/square1/square1.cpp index 88b7cf51..f6d07ad5 100644 --- a/gb/apu/square1/square1.cpp +++ b/gb/apu/square1/square1.cpp @@ -1,10 +1,8 @@ -#ifdef APU_CPP - -bool APU::Square1::dac_enable() { +auto APU::Square1::dac_enable() const -> bool { return (envelope_volume || envelope_direction); } -void APU::Square1::run() { +auto APU::Square1::run() -> void { if(period && --period == 0) { period = 2 * (2048 - frequency); phase++; @@ -22,12 +20,12 @@ void APU::Square1::run() { output = sample; } -void APU::Square1::sweep(bool update) { +auto APU::Square1::sweep(bool update) -> void { if(sweep_enable == false) return; sweep_negate = sweep_direction; - unsigned delta = frequency_shadow >> sweep_shift; - signed freq = frequency_shadow + (sweep_negate ? -delta : delta); + uint delta = frequency_shadow >> sweep_shift; + int freq = frequency_shadow + (sweep_negate ? -delta : delta); if(freq > 2047) { enable = false; @@ -38,13 +36,13 @@ void APU::Square1::sweep(bool update) { } } -void APU::Square1::clock_length() { +auto APU::Square1::clock_length() -> void { if(counter && enable) { if(++length == 0) enable = false; } } -void APU::Square1::clock_sweep() { +auto APU::Square1::clock_sweep() -> void { if(enable && sweep_frequency && --sweep_period == 0) { sweep_period = sweep_frequency; sweep(1); @@ -52,7 +50,7 @@ void APU::Square1::clock_sweep() { } } -void APU::Square1::clock_envelope() { +auto APU::Square1::clock_envelope() -> void { if(enable && envelope_frequency && --envelope_period == 0) { envelope_period = envelope_frequency; if(envelope_direction == 0 && volume > 0) volume--; @@ -60,7 +58,7 @@ void APU::Square1::clock_envelope() { } } -void APU::Square1::write(unsigned r, uint8 data) { +auto APU::Square1::write(uint r, uint8 data) -> void { if(r == 0) { //$ff10 NR10 if(sweep_negate && sweep_direction && !(data & 0x08)) enable = false; sweep_frequency = (data >> 4) & 7; @@ -103,7 +101,7 @@ void APU::Square1::write(unsigned r, uint8 data) { } } -void APU::Square1::power() { +auto APU::Square1::power() -> void { enable = 0; sweep_frequency = 0; @@ -129,7 +127,7 @@ void APU::Square1::power() { volume = 0; } -void APU::Square1::serialize(serializer& s) { +auto APU::Square1::serialize(serializer& s) -> void { s.integer(enable); s.integer(sweep_frequency); @@ -154,5 +152,3 @@ void APU::Square1::serialize(serializer& s) { s.integer(sweep_enable); s.integer(volume); } - -#endif diff --git a/gb/apu/square1/square1.hpp b/gb/apu/square1/square1.hpp index 50007f2c..eb975653 100644 --- a/gb/apu/square1/square1.hpp +++ b/gb/apu/square1/square1.hpp @@ -1,4 +1,16 @@ struct Square1 { + auto dac_enable() const -> bool; + + auto run() -> void; + auto sweep(bool update) -> void; + auto clock_length() -> void; + auto clock_sweep() -> void; + auto clock_envelope() -> void; + auto write(uint r, uint8 data) -> void; + auto power() -> void; + + auto serialize(serializer&) -> void; + bool enable; uint3 sweep_frequency; @@ -16,21 +28,10 @@ struct Square1 { int16 output; bool duty_output; uint3 phase; - unsigned period; + uint period; uint3 envelope_period; uint3 sweep_period; - signed frequency_shadow; + int frequency_shadow; bool sweep_enable; uint4 volume; - - bool dac_enable(); - - void run(); - void sweep(bool update); - void clock_length(); - void clock_sweep(); - void clock_envelope(); - void write(unsigned r, uint8 data); - void power(); - void serialize(serializer&); }; diff --git a/gb/apu/square2/square2.cpp b/gb/apu/square2/square2.cpp index 1c7282c9..02be430a 100644 --- a/gb/apu/square2/square2.cpp +++ b/gb/apu/square2/square2.cpp @@ -1,10 +1,8 @@ -#ifdef APU_CPP - -bool APU::Square2::dac_enable() { +auto APU::Square2::dac_enable() const -> bool { return (envelope_volume || envelope_direction); } -void APU::Square2::run() { +auto APU::Square2::run() -> void { if(period && --period == 0) { period = 2 * (2048 - frequency); phase++; @@ -22,13 +20,13 @@ void APU::Square2::run() { output = sample; } -void APU::Square2::clock_length() { +auto APU::Square2::clock_length() -> void { if(counter && enable) { if(++length == 0) enable = false; } } -void APU::Square2::clock_envelope() { +auto APU::Square2::clock_envelope() -> void { if(enable && envelope_frequency && --envelope_period == 0) { envelope_period = envelope_frequency; if(envelope_direction == 0 && volume > 0) volume--; @@ -36,7 +34,7 @@ void APU::Square2::clock_envelope() { } } -void APU::Square2::write(unsigned r, uint8 data) { +auto APU::Square2::write(uint r, uint8 data) -> void { if(r == 1) { //$ff16 NR21 duty = data >> 6; length = (data & 0x3f); @@ -67,7 +65,7 @@ void APU::Square2::write(unsigned r, uint8 data) { } } -void APU::Square2::power() { +auto APU::Square2::power() -> void { enable = 0; duty = 0; @@ -86,7 +84,7 @@ void APU::Square2::power() { volume = 0; } -void APU::Square2::serialize(serializer& s) { +auto APU::Square2::serialize(serializer& s) -> void { s.integer(enable); s.integer(duty); @@ -104,5 +102,3 @@ void APU::Square2::serialize(serializer& s) { s.integer(envelope_period); s.integer(volume); } - -#endif diff --git a/gb/apu/square2/square2.hpp b/gb/apu/square2/square2.hpp index c8923ebd..9655f641 100644 --- a/gb/apu/square2/square2.hpp +++ b/gb/apu/square2/square2.hpp @@ -1,4 +1,14 @@ struct Square2 { + auto dac_enable() const -> bool; + + auto run() -> void; + auto clock_length() -> void; + auto clock_envelope() -> void; + auto write(uint r, uint8 data) -> void; + auto power() -> void; + + auto serialize(serializer&) -> void; + bool enable; uint2 duty; @@ -12,16 +22,7 @@ struct Square2 { int16 output; bool duty_output; uint3 phase; - unsigned period; + uint period; uint3 envelope_period; uint4 volume; - - bool dac_enable(); - - void run(); - void clock_length(); - void clock_envelope(); - void write(unsigned r, uint8 data); - void power(); - void serialize(serializer&); }; diff --git a/gb/apu/wave/wave.cpp b/gb/apu/wave/wave.cpp index ce62c108..c2fc4326 100644 --- a/gb/apu/wave/wave.cpp +++ b/gb/apu/wave/wave.cpp @@ -1,6 +1,4 @@ -#ifdef APU_CPP - -void APU::Wave::run() { +auto APU::Wave::run() -> void { if(period && --period == 0) { period = 1 * (2048 - frequency); pattern_sample = pattern[++pattern_offset]; @@ -12,13 +10,13 @@ void APU::Wave::run() { output = sample; } -void APU::Wave::clock_length() { +auto APU::Wave::clock_length() -> void { if(enable && counter) { if(++length == 0) enable = false; } } -void APU::Wave::write(unsigned r, uint8 data) { +auto APU::Wave::write(uint r, uint8 data) -> void { if(r == 0) { //$ff1a NR30 dac_enable = data & 0x80; if(dac_enable == false) enable = false; @@ -54,13 +52,13 @@ void APU::Wave::write(unsigned r, uint8 data) { } } -void APU::Wave::write_pattern(unsigned p, uint8 data) { +auto APU::Wave::write_pattern(uint p, uint8 data) -> void { p <<= 1; pattern[p + 0] = (data >> 4) & 15; pattern[p + 1] = (data >> 0) & 15; } -void APU::Wave::power() { +auto APU::Wave::power() -> void { enable = 0; dac_enable = 0; @@ -78,7 +76,7 @@ void APU::Wave::power() { pattern_sample = 0; } -void APU::Wave::serialize(serializer& s) { +auto APU::Wave::serialize(serializer& s) -> void { s.integer(enable); s.integer(dac_enable); @@ -93,5 +91,3 @@ void APU::Wave::serialize(serializer& s) { s.integer(pattern_offset); s.integer(pattern_sample); } - -#endif diff --git a/gb/apu/wave/wave.hpp b/gb/apu/wave/wave.hpp index edeaa278..7d215721 100644 --- a/gb/apu/wave/wave.hpp +++ b/gb/apu/wave/wave.hpp @@ -1,22 +1,23 @@ struct Wave { + auto run() -> void; + auto clock_length() -> void; + auto write(uint r, uint8 data) -> void; + auto write_pattern(uint p, uint8 data) -> void; + auto power() -> void; + + auto serialize(serializer&) -> void; + bool enable; bool dac_enable; - unsigned volume_shift; + uint volume_shift; uint11 frequency; bool counter; uint8 pattern[32]; int16 output; uint8 length; - unsigned period; + uint period; uint5 pattern_offset; uint4 pattern_sample; - - void run(); - void clock_length(); - void write(unsigned r, uint8 data); - void write_pattern(unsigned p, uint8 data); - void power(); - void serialize(serializer&); }; diff --git a/gb/cartridge/cartridge.cpp b/gb/cartridge/cartridge.cpp index c1e3d21b..de464d4e 100644 --- a/gb/cartridge/cartridge.cpp +++ b/gb/cartridge/cartridge.cpp @@ -1,6 +1,5 @@ #include -#define CARTRIDGE_CPP namespace GameBoy { #include "mbc0/mbc0.cpp" @@ -14,12 +13,21 @@ namespace GameBoy { #include "serialization.cpp" Cartridge cartridge; -string Cartridge::title() { +Cartridge::Cartridge() { + loaded = false; + sha256 = ""; +} + +Cartridge::~Cartridge() { + unload(); +} + +auto Cartridge::title() -> string { return information.title; } //intended for use with Super Game Boy for when no Game Boy cartridge is inserted -void Cartridge::load_empty(System::Revision revision) { +auto Cartridge::load_empty(System::Revision revision) -> void { unload(); romsize = 32768; romdata = allocate(romsize, 0xff); @@ -30,7 +38,7 @@ void Cartridge::load_empty(System::Revision revision) { system.load(revision); } -void Cartridge::load(System::Revision revision) { +auto Cartridge::load(System::Revision revision) -> void { unload(); system.revision = revision; //needed for ID::Manifest to return correct group ID @@ -99,35 +107,35 @@ void Cartridge::load(System::Revision revision) { system.load(revision); } -void Cartridge::unload() { +auto Cartridge::unload() -> void { if(romdata) { delete[] romdata; romdata = nullptr; romsize = 0; } if(ramdata) { delete[] ramdata; ramdata = nullptr; ramsize = 0; } loaded = false; } -uint8 Cartridge::rom_read(unsigned addr) { +auto Cartridge::rom_read(uint addr) -> uint8 { if(addr >= romsize) addr %= romsize; return romdata[addr]; } -void Cartridge::rom_write(unsigned addr, uint8 data) { +auto Cartridge::rom_write(uint addr, uint8 data) -> void { if(addr >= romsize) addr %= romsize; romdata[addr] = data; } -uint8 Cartridge::ram_read(unsigned addr) { +auto Cartridge::ram_read(uint addr) -> uint8 { if(ramsize == 0) return 0x00; if(addr >= ramsize) addr %= ramsize; return ramdata[addr]; } -void Cartridge::ram_write(unsigned addr, uint8 data) { +auto Cartridge::ram_write(uint addr, uint8 data) -> void { if(ramsize == 0) return; if(addr >= ramsize) addr %= ramsize; ramdata[addr] = data; } -uint8 Cartridge::mmio_read(uint16 addr) { +auto Cartridge::mmio_read(uint16 addr) -> uint8 { if(addr == 0xff50) return 0x00; if(bootrom_enable) { @@ -144,7 +152,7 @@ uint8 Cartridge::mmio_read(uint16 addr) { return mapper->mmio_read(addr); } -void Cartridge::mmio_write(uint16 addr, uint8 data) { +auto Cartridge::mmio_write(uint16 addr, uint8 data) -> void { if(bootrom_enable && addr == 0xff50) { bootrom_enable = false; return; @@ -153,7 +161,7 @@ void Cartridge::mmio_write(uint16 addr, uint8 data) { mapper->mmio_write(addr, data); } -void Cartridge::power() { +auto Cartridge::power() -> void { bootrom_enable = true; mbc0.power(); @@ -165,18 +173,9 @@ void Cartridge::power() { huc1.power(); huc3.power(); - for(unsigned n = 0x0000; n <= 0x7fff; n++) bus.mmio[n] = this; - for(unsigned n = 0xa000; n <= 0xbfff; n++) bus.mmio[n] = this; + for(uint n = 0x0000; n <= 0x7fff; n++) bus.mmio[n] = this; + for(uint n = 0xa000; n <= 0xbfff; n++) bus.mmio[n] = this; bus.mmio[0xff50] = this; } -Cartridge::Cartridge() { - loaded = false; - sha256 = ""; -} - -Cartridge::~Cartridge() { - unload(); -} - } diff --git a/gb/cartridge/cartridge.hpp b/gb/cartridge/cartridge.hpp index 66b445d9..a5175226 100644 --- a/gb/cartridge/cartridge.hpp +++ b/gb/cartridge/cartridge.hpp @@ -1,4 +1,23 @@ struct Cartridge : MMIO, property { + Cartridge(); + ~Cartridge(); + + auto load_empty(System::Revision revision) -> void; + auto load(System::Revision revision) -> void; + auto unload() -> void; + + auto rom_read(uint addr) -> uint8; + auto rom_write(uint addr, uint8 data) -> void; + auto ram_read(uint addr) -> uint8; + auto ram_write(uint addr, uint8 data) -> void; + + auto mmio_read(uint16 addr) -> uint8; + auto mmio_write(uint16 addr, uint8 data) -> void; + + auto power() -> void; + + auto serialize(serializer&) -> void; + #include "mbc0/mbc0.hpp" #include "mbc1/mbc1.hpp" #include "mbc2/mbc2.hpp" @@ -8,7 +27,7 @@ struct Cartridge : MMIO, property { #include "huc1/huc1.hpp" #include "huc3/huc3.hpp" - enum Mapper : unsigned { + enum Mapper : uint { MBC0, MBC1, MBC2, @@ -30,14 +49,14 @@ struct Cartridge : MMIO, property { bool rtc; bool rumble; - unsigned romsize; - unsigned ramsize; + uint romsize; + uint ramsize; } information; string title(); struct Memory { - unsigned id; + uint id; string name; }; vector memory; @@ -45,32 +64,14 @@ struct Cartridge : MMIO, property { readonly loaded; readonly sha256; - uint8_t* romdata = nullptr; - unsigned romsize = 0; + uint8* romdata = nullptr; + uint romsize = 0; - uint8_t* ramdata = nullptr; - unsigned ramsize = 0; + uint8* ramdata = nullptr; + uint ramsize = 0; MMIO* mapper = nullptr; bool bootrom_enable = true; - - void load_empty(System::Revision revision); - void load(System::Revision revision); - void unload(); - - uint8 rom_read(unsigned addr); - void rom_write(unsigned addr, uint8 data); - uint8 ram_read(unsigned addr); - void ram_write(unsigned addr, uint8 data); - - uint8 mmio_read(uint16 addr); - void mmio_write(uint16 addr, uint8 data); - - void power(); - - void serialize(serializer&); - Cartridge(); - ~Cartridge(); }; extern Cartridge cartridge; diff --git a/gb/cartridge/huc1/huc1.cpp b/gb/cartridge/huc1/huc1.cpp index b8fb1101..efc2cc84 100644 --- a/gb/cartridge/huc1/huc1.cpp +++ b/gb/cartridge/huc1/huc1.cpp @@ -1,6 +1,4 @@ -#ifdef CARTRIDGE_CPP - -uint8 Cartridge::HuC1::mmio_read(uint16 addr) { +auto Cartridge::HuC1::mmio_read(uint16 addr) -> uint8 { if((addr & 0xc000) == 0x0000) { //$0000-3fff return cartridge.rom_read(addr); } @@ -16,7 +14,7 @@ uint8 Cartridge::HuC1::mmio_read(uint16 addr) { return 0x00; } -void Cartridge::HuC1::mmio_write(uint16 addr, uint8 data) { +auto Cartridge::HuC1::mmio_write(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x0000) { //$0000-1fff ram_writable = (data & 0x0f) == 0x0a; return; @@ -44,11 +42,9 @@ void Cartridge::HuC1::mmio_write(uint16 addr, uint8 data) { } } -void Cartridge::HuC1::power() { +auto Cartridge::HuC1::power() -> void { ram_writable = false; rom_select = 0x01; ram_select = 0x00; model = 0; } - -#endif diff --git a/gb/cartridge/huc1/huc1.hpp b/gb/cartridge/huc1/huc1.hpp index f0f60d8f..13daff56 100644 --- a/gb/cartridge/huc1/huc1.hpp +++ b/gb/cartridge/huc1/huc1.hpp @@ -1,10 +1,10 @@ struct HuC1 : MMIO { + auto mmio_read(uint16 addr) -> uint8; + auto mmio_write(uint16 addr, uint8 data) -> void; + auto power() -> void; + bool ram_writable; //$0000-1fff uint8 rom_select; //$2000-3fff uint8 ram_select; //$4000-5fff bool model; //$6000-7fff - - uint8 mmio_read(uint16 addr); - void mmio_write(uint16 addr, uint8 data); - void power(); } huc1; diff --git a/gb/cartridge/huc3/huc3.cpp b/gb/cartridge/huc3/huc3.cpp index c2bdcda4..9d9500e9 100644 --- a/gb/cartridge/huc3/huc3.cpp +++ b/gb/cartridge/huc3/huc3.cpp @@ -1,6 +1,4 @@ -#ifdef CARTRIDGE_CPP - -uint8 Cartridge::HuC3::mmio_read(uint16 addr) { +auto Cartridge::HuC3::mmio_read(uint16 addr) -> uint8 { if((addr & 0xc000) == 0x0000) { //$0000-3fff return cartridge.rom_read(addr); } @@ -17,7 +15,7 @@ uint8 Cartridge::HuC3::mmio_read(uint16 addr) { return 0x00; } -void Cartridge::HuC3::mmio_write(uint16 addr, uint8 data) { +auto Cartridge::HuC3::mmio_write(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x0000) { //$0000-1fff ram_enable = (data & 0x0f) == 0x0a; return; @@ -44,10 +42,8 @@ void Cartridge::HuC3::mmio_write(uint16 addr, uint8 data) { } } -void Cartridge::HuC3::power() { +auto Cartridge::HuC3::power() -> void { ram_enable = false; rom_select = 0x01; ram_select = 0x00; } - -#endif diff --git a/gb/cartridge/huc3/huc3.hpp b/gb/cartridge/huc3/huc3.hpp index 61d4aa61..4e793eb0 100644 --- a/gb/cartridge/huc3/huc3.hpp +++ b/gb/cartridge/huc3/huc3.hpp @@ -1,9 +1,9 @@ struct HuC3 : MMIO { + auto mmio_read(uint16 addr) -> uint8; + auto mmio_write(uint16 addr, uint8 data) -> void; + auto power() -> void; + bool ram_enable; //$0000-1fff uint8 rom_select; //$2000-3fff uint8 ram_select; //$4000-5fff - - uint8 mmio_read(uint16 addr); - void mmio_write(uint16 addr, uint8 data); - void power(); } huc3; diff --git a/gb/cartridge/mbc0/mbc0.cpp b/gb/cartridge/mbc0/mbc0.cpp index 2312f572..9e214a1e 100644 --- a/gb/cartridge/mbc0/mbc0.cpp +++ b/gb/cartridge/mbc0/mbc0.cpp @@ -1,6 +1,4 @@ -#ifdef CARTRIDGE_CPP - -uint8 Cartridge::MBC0::mmio_read(uint16 addr) { +auto Cartridge::MBC0::mmio_read(uint16 addr) -> uint8 { if((addr & 0x8000) == 0x0000) { //$0000-7fff return cartridge.rom_read(addr); } @@ -12,14 +10,12 @@ uint8 Cartridge::MBC0::mmio_read(uint16 addr) { return 0x00; } -void Cartridge::MBC0::mmio_write(uint16 addr, uint8 data) { +auto Cartridge::MBC0::mmio_write(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0xa000) { //$a000-bfff cartridge.ram_write(addr & 0x1fff, data); return; } } -void Cartridge::MBC0::power() { +auto Cartridge::MBC0::power() -> void { } - -#endif diff --git a/gb/cartridge/mbc0/mbc0.hpp b/gb/cartridge/mbc0/mbc0.hpp index da7390ea..ccc60070 100644 --- a/gb/cartridge/mbc0/mbc0.hpp +++ b/gb/cartridge/mbc0/mbc0.hpp @@ -1,5 +1,5 @@ struct MBC0 : MMIO { - uint8 mmio_read(uint16 addr); - void mmio_write(uint16 addr, uint8 data); - void power(); + auto mmio_read(uint16 addr) -> uint8; + auto mmio_write(uint16 addr, uint8 data) -> void; + auto power() -> void; } mbc0; diff --git a/gb/cartridge/mbc1/mbc1.cpp b/gb/cartridge/mbc1/mbc1.cpp index 7e15c135..499e05fe 100644 --- a/gb/cartridge/mbc1/mbc1.cpp +++ b/gb/cartridge/mbc1/mbc1.cpp @@ -1,6 +1,4 @@ -#ifdef CARTRIDGE_CPP - -uint8 Cartridge::MBC1::mmio_read(uint16 addr) { +auto Cartridge::MBC1::mmio_read(uint16 addr) -> uint8 { if((addr & 0xc000) == 0x0000) { //$0000-3fff return cartridge.rom_read(addr); } @@ -27,7 +25,7 @@ uint8 Cartridge::MBC1::mmio_read(uint16 addr) { return 0x00; } -void Cartridge::MBC1::mmio_write(uint16 addr, uint8 data) { +auto Cartridge::MBC1::mmio_write(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x0000) { //$0000-1fff ram_enable = (data & 0x0f) == 0x0a; return; @@ -60,11 +58,9 @@ void Cartridge::MBC1::mmio_write(uint16 addr, uint8 data) { } } -void Cartridge::MBC1::power() { +auto Cartridge::MBC1::power() -> void { ram_enable = false; rom_select = 0x01; ram_select = 0x00; mode_select = 0; } - -#endif diff --git a/gb/cartridge/mbc1/mbc1.hpp b/gb/cartridge/mbc1/mbc1.hpp index 19f8b75b..7cde13eb 100644 --- a/gb/cartridge/mbc1/mbc1.hpp +++ b/gb/cartridge/mbc1/mbc1.hpp @@ -1,10 +1,10 @@ struct MBC1 : MMIO { + auto mmio_read(uint16 addr) -> uint8; + auto mmio_write(uint16 addr, uint8 data) -> void; + auto power() -> void; + bool ram_enable; //$0000-1fff uint8 rom_select; //$2000-3fff uint8 ram_select; //$4000-5fff bool mode_select; //$6000-7fff - - uint8 mmio_read(uint16 addr); - void mmio_write(uint16 addr, uint8 data); - void power(); } mbc1; diff --git a/gb/cartridge/mbc2/mbc2.cpp b/gb/cartridge/mbc2/mbc2.cpp index 0e0825f8..ec25e50a 100644 --- a/gb/cartridge/mbc2/mbc2.cpp +++ b/gb/cartridge/mbc2/mbc2.cpp @@ -1,6 +1,4 @@ -#ifdef CARTRIDGE_CPP - -uint8 Cartridge::MBC2::mmio_read(uint16 addr) { +auto Cartridge::MBC2::mmio_read(uint16 addr) -> uint8 { if((addr & 0xc000) == 0x0000) { //$0000-3fff return cartridge.rom_read(addr); } @@ -17,7 +15,7 @@ uint8 Cartridge::MBC2::mmio_read(uint16 addr) { return 0x00; } -void Cartridge::MBC2::mmio_write(uint16 addr, uint8 data) { +auto Cartridge::MBC2::mmio_write(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x0000) { //$0000-1fff if(!(addr & 0x0100)) ram_enable = (data & 0x0f) == 0x0a; return; @@ -34,9 +32,7 @@ void Cartridge::MBC2::mmio_write(uint16 addr, uint8 data) { } } -void Cartridge::MBC2::power() { +auto Cartridge::MBC2::power() -> void { ram_enable = false; rom_select = 0x01; } - -#endif diff --git a/gb/cartridge/mbc2/mbc2.hpp b/gb/cartridge/mbc2/mbc2.hpp index c22a652a..d7ba7932 100644 --- a/gb/cartridge/mbc2/mbc2.hpp +++ b/gb/cartridge/mbc2/mbc2.hpp @@ -1,8 +1,8 @@ struct MBC2 : MMIO { + auto mmio_read(uint16 addr) -> uint8; + auto mmio_write(uint16 addr, uint8 data) -> void; + auto power() -> void; + bool ram_enable; //$0000-1fff uint8 rom_select; //$2000-3fff - - uint8 mmio_read(uint16 addr); - void mmio_write(uint16 addr, uint8 data); - void power(); } mbc2; diff --git a/gb/cartridge/mbc3/mbc3.cpp b/gb/cartridge/mbc3/mbc3.cpp index 595ac1d9..a90ce03f 100644 --- a/gb/cartridge/mbc3/mbc3.cpp +++ b/gb/cartridge/mbc3/mbc3.cpp @@ -1,6 +1,4 @@ -#ifdef CARTRIDGE_CPP - -void Cartridge::MBC3::second() { +auto Cartridge::MBC3::second() -> void { if(rtc_halt == false) { if(++rtc_second >= 60) { rtc_second = 0; @@ -18,7 +16,7 @@ void Cartridge::MBC3::second() { } } -uint8 Cartridge::MBC3::mmio_read(uint16 addr) { +auto Cartridge::MBC3::mmio_read(uint16 addr) -> uint8 { if((addr & 0xc000) == 0x0000) { //$0000-3fff return cartridge.rom_read(addr); } @@ -44,7 +42,7 @@ uint8 Cartridge::MBC3::mmio_read(uint16 addr) { return 0x00; } -void Cartridge::MBC3::mmio_write(uint16 addr, uint8 data) { +auto Cartridge::MBC3::mmio_write(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x0000) { //$0000-1fff ram_enable = (data & 0x0f) == 0x0a; return; @@ -97,7 +95,7 @@ void Cartridge::MBC3::mmio_write(uint16 addr, uint8 data) { } } -void Cartridge::MBC3::power() { +auto Cartridge::MBC3::power() -> void { ram_enable = false; rom_select = 0x01; ram_select = 0x00; @@ -116,5 +114,3 @@ void Cartridge::MBC3::power() { rtc_latch_day = 0; rtc_latch_day_carry = false; } - -#endif diff --git a/gb/cartridge/mbc3/mbc3.hpp b/gb/cartridge/mbc3/mbc3.hpp index fbd7775d..57057ec5 100644 --- a/gb/cartridge/mbc3/mbc3.hpp +++ b/gb/cartridge/mbc3/mbc3.hpp @@ -1,24 +1,24 @@ struct MBC3 : MMIO { + auto second() -> void; + auto mmio_read(uint16 addr) -> uint8; + auto mmio_write(uint16 addr, uint8 data) -> void; + auto power() -> void; + bool ram_enable; //$0000-1fff uint8 rom_select; //$2000-3fff uint8 ram_select; //$4000-5fff bool rtc_latch; //$6000-7fff bool rtc_halt; - unsigned rtc_second; - unsigned rtc_minute; - unsigned rtc_hour; - unsigned rtc_day; + uint rtc_second; + uint rtc_minute; + uint rtc_hour; + uint rtc_day; bool rtc_day_carry; - unsigned rtc_latch_second; - unsigned rtc_latch_minute; - unsigned rtc_latch_hour; - unsigned rtc_latch_day; - unsigned rtc_latch_day_carry; - - void second(); - uint8 mmio_read(uint16 addr); - void mmio_write(uint16 addr, uint8 data); - void power(); + uint rtc_latch_second; + uint rtc_latch_minute; + uint rtc_latch_hour; + uint rtc_latch_day; + uint rtc_latch_day_carry; } mbc3; diff --git a/gb/cartridge/mbc5/mbc5.cpp b/gb/cartridge/mbc5/mbc5.cpp index 52f3223b..3793bbd6 100644 --- a/gb/cartridge/mbc5/mbc5.cpp +++ b/gb/cartridge/mbc5/mbc5.cpp @@ -1,6 +1,4 @@ -#ifdef CARTRIDGE_CPP - -uint8 Cartridge::MBC5::mmio_read(uint16 addr) { +auto Cartridge::MBC5::mmio_read(uint16 addr) -> uint8 { if((addr & 0xc000) == 0x0000) { //$0000-3fff return cartridge.rom_read(addr); } @@ -17,7 +15,7 @@ uint8 Cartridge::MBC5::mmio_read(uint16 addr) { return 0x00; } -void Cartridge::MBC5::mmio_write(uint16 addr, uint8 data) { +auto Cartridge::MBC5::mmio_write(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x0000) { //$0000-1fff ram_enable = (data & 0x0f) == 0x0a; return; @@ -44,10 +42,8 @@ void Cartridge::MBC5::mmio_write(uint16 addr, uint8 data) { } } -void Cartridge::MBC5::power() { +auto Cartridge::MBC5::power() -> void { ram_enable = false; rom_select = 0x001; ram_select = 0x00; } - -#endif diff --git a/gb/cartridge/mbc5/mbc5.hpp b/gb/cartridge/mbc5/mbc5.hpp index 0ec3abb0..f920fd0d 100644 --- a/gb/cartridge/mbc5/mbc5.hpp +++ b/gb/cartridge/mbc5/mbc5.hpp @@ -1,9 +1,9 @@ struct MBC5 : MMIO { + auto mmio_read(uint16 addr) -> uint8; + auto mmio_write(uint16 addr, uint8 data) -> void; + auto power() -> void; + bool ram_enable; //$0000-1fff uint16 rom_select; //$2000-2fff + $3000-3fff uint8 ram_select; //$4000-5fff - - uint8 mmio_read(uint16 addr); - void mmio_write(uint16 addr, uint8 data); - void power(); } mbc5; diff --git a/gb/cartridge/mmm01/mmm01.cpp b/gb/cartridge/mmm01/mmm01.cpp index b690b8cf..5fa2d359 100644 --- a/gb/cartridge/mmm01/mmm01.cpp +++ b/gb/cartridge/mmm01/mmm01.cpp @@ -1,6 +1,4 @@ -#ifdef CARTRIDGE_CPP - -uint8 Cartridge::MMM01::mmio_read(uint16 addr) { +auto Cartridge::MMM01::mmio_read(uint16 addr) -> uint8 { if((addr & 0x8000) == 0x0000) { //$0000-7fff if(rom_mode == 0) return cartridge.rom_read(addr); } @@ -21,7 +19,7 @@ uint8 Cartridge::MMM01::mmio_read(uint16 addr) { return 0x00; } -void Cartridge::MMM01::mmio_write(uint16 addr, uint8 data) { +auto Cartridge::MMM01::mmio_write(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x0000) { //$0000-1fff if(rom_mode == 0) { rom_mode = 1; @@ -53,7 +51,7 @@ void Cartridge::MMM01::mmio_write(uint16 addr, uint8 data) { } } -void Cartridge::MMM01::power() { +auto Cartridge::MMM01::power() -> void { rom_mode = 0; rom_base = 0; @@ -61,5 +59,3 @@ void Cartridge::MMM01::power() { rom_select = 0x01; ram_select = 0x00; } - -#endif diff --git a/gb/cartridge/mmm01/mmm01.hpp b/gb/cartridge/mmm01/mmm01.hpp index 3474b062..94b50011 100644 --- a/gb/cartridge/mmm01/mmm01.hpp +++ b/gb/cartridge/mmm01/mmm01.hpp @@ -1,12 +1,12 @@ struct MMM01 : MMIO { + auto mmio_read(uint16 addr) -> uint8; + auto mmio_write(uint16 addr, uint8 data) -> void; + auto power() -> void; + bool rom_mode; uint8 rom_base; bool ram_enable; uint8 rom_select; uint8 ram_select; - - uint8 mmio_read(uint16 addr); - void mmio_write(uint16 addr, uint8 data); - void power(); } mmm01; diff --git a/gb/cartridge/serialization.cpp b/gb/cartridge/serialization.cpp index 39498e4d..a2465182 100644 --- a/gb/cartridge/serialization.cpp +++ b/gb/cartridge/serialization.cpp @@ -1,6 +1,4 @@ -#ifdef CARTRIDGE_CPP - -void Cartridge::serialize(serializer& s) { +auto Cartridge::serialize(serializer& s) -> void { if(information.battery) s.array(ramdata, ramsize); s.integer(bootrom_enable); @@ -50,5 +48,3 @@ void Cartridge::serialize(serializer& s) { s.integer(huc3.rom_select); s.integer(huc3.ram_select); } - -#endif diff --git a/gb/cheat/cheat.cpp b/gb/cheat/cheat.cpp index 7b45725b..4792c867 100644 --- a/gb/cheat/cheat.cpp +++ b/gb/cheat/cheat.cpp @@ -4,19 +4,19 @@ namespace GameBoy { Cheat cheat; -void Cheat::reset() { +auto Cheat::reset() -> void { codes.reset(); } -void Cheat::append(unsigned addr, unsigned data) { +auto Cheat::append(uint addr, uint data) -> void { codes.append({addr, Unused, data}); } -void Cheat::append(unsigned addr, unsigned comp, unsigned data) { +auto Cheat::append(uint addr, uint comp, uint data) -> void { codes.append({addr, comp, data}); } -maybe Cheat::find(unsigned addr, unsigned comp) { +auto Cheat::find(uint addr, uint comp) -> maybe { for(auto& code : codes) { if(code.addr == addr && (code.comp == Unused || code.comp == comp)) { return code.data; diff --git a/gb/cheat/cheat.hpp b/gb/cheat/cheat.hpp index 43f2d05c..ee8c1004 100644 --- a/gb/cheat/cheat.hpp +++ b/gb/cheat/cheat.hpp @@ -1,17 +1,18 @@ struct Cheat { struct Code { - unsigned addr; - unsigned comp; - unsigned data; + uint addr; + uint comp; + uint data; }; vector codes; - enum : unsigned { Unused = ~0u }; + enum : uint { Unused = ~0u }; - alwaysinline bool enable() const { return codes.size() > 0; } - void reset(); - void append(unsigned addr, unsigned data); - void append(unsigned addr, unsigned comp, unsigned data); - maybe find(unsigned addr, unsigned comp); + alwaysinline auto enable() const -> bool { return codes.size() > 0; } + + auto reset() -> void; + auto append(uint addr, uint data) -> void; + auto append(uint addr, uint comp, uint data) -> void; + auto find(uint addr, uint comp) -> maybe; }; extern Cheat cheat; diff --git a/gb/cpu/cpu.cpp b/gb/cpu/cpu.cpp index 782815a5..99e9b4da 100644 --- a/gb/cpu/cpu.cpp +++ b/gb/cpu/cpu.cpp @@ -1,6 +1,5 @@ #include -#define CPU_CPP namespace GameBoy { #include "mmio.cpp" @@ -9,11 +8,11 @@ namespace GameBoy { #include "serialization.cpp" CPU cpu; -void CPU::Main() { +auto CPU::Main() -> void { cpu.main(); } -void CPU::main() { +auto CPU::main() -> void { while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::CPU) { scheduler.sync = Scheduler::SynchronizeMode::All; @@ -25,7 +24,7 @@ void CPU::main() { } } -void CPU::interrupt_raise(CPU::Interrupt id) { +auto CPU::interrupt_raise(CPU::Interrupt id) -> void { if(id == Interrupt::Vblank) { status.interrupt_request_vblank = 1; if(status.interrupt_enable_vblank) r.halt = false; @@ -52,7 +51,7 @@ void CPU::interrupt_raise(CPU::Interrupt id) { } } -void CPU::interrupt_test() { +auto CPU::interrupt_test() -> void { if(r.ime) { if(status.interrupt_request_vblank && status.interrupt_enable_vblank) { status.interrupt_request_vblank = 0; @@ -81,7 +80,7 @@ void CPU::interrupt_test() { } } -void CPU::interrupt_exec(uint16 pc) { +auto CPU::interrupt_exec(uint16 pc) -> void { r.ime = 0; op_write(--r[SP], r[PC] >> 8); op_write(--r[SP], r[PC] >> 0); @@ -91,7 +90,7 @@ void CPU::interrupt_exec(uint16 pc) { op_io(); } -bool CPU::stop() { +auto CPU::stop() -> bool { if(status.speed_switch) { status.speed_switch = 0; status.speed_double ^= 1; @@ -102,13 +101,13 @@ bool CPU::stop() { return false; } -void CPU::power() { +auto CPU::power() -> void { create(Main, 4 * 1024 * 1024); LR35902::power(); - for(unsigned n = 0xc000; n <= 0xdfff; n++) bus.mmio[n] = this; //WRAM - for(unsigned n = 0xe000; n <= 0xfdff; n++) bus.mmio[n] = this; //WRAM (mirror) - for(unsigned n = 0xff80; n <= 0xfffe; n++) bus.mmio[n] = this; //HRAM + for(uint n = 0xc000; n <= 0xdfff; n++) bus.mmio[n] = this; //WRAM + for(uint n = 0xe000; n <= 0xfdff; n++) bus.mmio[n] = this; //WRAM (mirror) + for(uint n = 0xff80; n <= 0xfffe; n++) bus.mmio[n] = this; //HRAM bus.mmio[0xff00] = this; //JOYP bus.mmio[0xff01] = this; //SB diff --git a/gb/cpu/cpu.hpp b/gb/cpu/cpu.hpp index 5d492361..1fe4a373 100644 --- a/gb/cpu/cpu.hpp +++ b/gb/cpu/cpu.hpp @@ -1,14 +1,42 @@ struct CPU : Processor::LR35902, Thread, MMIO { - enum class Interrupt : unsigned { - Vblank, - Stat, - Timer, - Serial, - Joypad, - }; + enum class Interrupt : uint { Vblank, Stat, Timer, Serial, Joypad }; + + static auto Main() -> void; + auto main() -> void; + auto interrupt_raise(Interrupt id) -> void; + auto interrupt_test() -> void; + auto interrupt_exec(uint16 pc) -> void; + auto stop() -> bool; + auto power() -> void; + + auto serialize(serializer&) -> void; + + //mmio.cpp + auto wram_addr(uint16 addr) const -> uint; + auto mmio_joyp_poll() -> void; + auto mmio_read(uint16 addr) -> uint8; + auto mmio_write(uint16 addr, uint8 data) -> void; + + //memory.cpp + auto op_io() -> void; + auto op_read(uint16 addr) -> uint8; + auto op_write(uint16 addr, uint8 data) -> void; + auto cycle_edge() -> void; + auto dma_read(uint16 addr) -> uint8; + auto dma_write(uint16 addr, uint8 data) -> void; + auto debugger_read(uint16 addr) -> uint8; + + //timing.cpp + auto add_clocks(uint clocks) -> void; + auto timer_262144hz() -> void; + auto timer_65536hz() -> void; + auto timer_16384hz() -> void; + auto timer_8192hz() -> void; + auto timer_4096hz() -> void; + auto hblank() -> void; struct Status { - unsigned clock; + uint clock; //$ff00 JOYP bool p15; @@ -18,7 +46,7 @@ struct CPU : Processor::LR35902, Thread, MMIO { //$ff01 SB uint8 serial_data; - unsigned serial_bits; + uint serial_bits; //$ff02 SC bool serial_transfer; @@ -35,7 +63,7 @@ struct CPU : Processor::LR35902, Thread, MMIO { //$ff07 TAC bool timer_enable; - unsigned timer_clock; + uint timer_clock; //$ff0f IF bool interrupt_request_joypad; @@ -87,40 +115,6 @@ struct CPU : Processor::LR35902, Thread, MMIO { uint8 wram[32768]; //GB=8192, GBC=32768 uint8 hram[128]; - - static void Main(); - void main(); - void interrupt_raise(Interrupt id); - void interrupt_test(); - void interrupt_exec(uint16 pc); - bool stop(); - void power(); - - void serialize(serializer&); - - //mmio.cpp - unsigned wram_addr(uint16 addr) const; - void mmio_joyp_poll(); - uint8 mmio_read(uint16 addr); - void mmio_write(uint16 addr, uint8 data); - - //memory.cpp - void op_io(); - uint8 op_read(uint16 addr); - void op_write(uint16 addr, uint8 data); - void cycle_edge(); - uint8 dma_read(uint16 addr); - void dma_write(uint16 addr, uint8 data); - uint8 debugger_read(uint16 addr); - - //timing.cpp - void add_clocks(unsigned clocks); - void timer_262144hz(); - void timer_65536hz(); - void timer_16384hz(); - void timer_8192hz(); - void timer_4096hz(); - void hblank(); }; extern CPU cpu; diff --git a/gb/cpu/memory.cpp b/gb/cpu/memory.cpp index bee64757..a699cbca 100644 --- a/gb/cpu/memory.cpp +++ b/gb/cpu/memory.cpp @@ -1,25 +1,23 @@ -#ifdef CPU_CPP - -void CPU::op_io() { +auto CPU::op_io() -> void { cycle_edge(); add_clocks(4); } -uint8 CPU::op_read(uint16 addr) { +auto CPU::op_read(uint16 addr) -> uint8 { cycle_edge(); add_clocks(4); if(oamdma.active && (addr < 0xff80 || addr == 0xffff)) return 0x00; return bus.read(addr); } -void CPU::op_write(uint16 addr, uint8 data) { +auto CPU::op_write(uint16 addr, uint8 data) -> void { cycle_edge(); add_clocks(4); if(oamdma.active && (addr < 0xff80 || addr == 0xffff)) return; bus.write(addr, data); } -void CPU::cycle_edge() { +auto CPU::cycle_edge() -> void { if(r.ei) { r.ei = false; r.ime = 1; @@ -27,7 +25,7 @@ void CPU::cycle_edge() { } //VRAM DMA source can only be ROM or RAM -uint8 CPU::dma_read(uint16 addr) { +auto CPU::dma_read(uint16 addr) -> uint8 { if(addr < 0x8000) return bus.read(addr); //0000-7fff if(addr < 0xa000) return 0x00; //8000-9fff if(addr < 0xe000) return bus.read(addr); //a000-dfff @@ -35,13 +33,11 @@ uint8 CPU::dma_read(uint16 addr) { } //VRAM DMA target is always VRAM -void CPU::dma_write(uint16 addr, uint8 data) { +auto CPU::dma_write(uint16 addr, uint8 data) -> void { addr = 0x8000 | (addr & 0x1fff); //8000-9fff return bus.write(addr, data); } -uint8 CPU::debugger_read(uint16 addr) { +auto CPU::debugger_read(uint16 addr) -> uint8 { return bus.read(addr); } - -#endif diff --git a/gb/cpu/mmio.cpp b/gb/cpu/mmio.cpp index 1eba8ad4..cbb9b381 100644 --- a/gb/cpu/mmio.cpp +++ b/gb/cpu/mmio.cpp @@ -1,24 +1,22 @@ -#ifdef CPU_CPP - -unsigned CPU::wram_addr(uint16 addr) const { +auto CPU::wram_addr(uint16 addr) const -> uint { addr &= 0x1fff; if(addr < 0x1000) return addr; auto bank = status.wram_bank + (status.wram_bank == 0); return (bank * 0x1000) + (addr & 0x0fff); } -void CPU::mmio_joyp_poll() { - unsigned button = 0, dpad = 0; +auto CPU::mmio_joyp_poll() -> void { + uint button = 0, dpad = 0; - button |= interface->inputPoll(0, 0, (unsigned)Input::Start) << 3; - button |= interface->inputPoll(0, 0, (unsigned)Input::Select) << 2; - button |= interface->inputPoll(0, 0, (unsigned)Input::B) << 1; - button |= interface->inputPoll(0, 0, (unsigned)Input::A) << 0; + button |= interface->inputPoll(0, 0, (uint)Input::Start) << 3; + button |= interface->inputPoll(0, 0, (uint)Input::Select) << 2; + button |= interface->inputPoll(0, 0, (uint)Input::B) << 1; + button |= interface->inputPoll(0, 0, (uint)Input::A) << 0; - dpad |= interface->inputPoll(0, 0, (unsigned)Input::Down) << 3; - dpad |= interface->inputPoll(0, 0, (unsigned)Input::Up) << 2; - dpad |= interface->inputPoll(0, 0, (unsigned)Input::Left) << 1; - dpad |= interface->inputPoll(0, 0, (unsigned)Input::Right) << 0; + dpad |= interface->inputPoll(0, 0, (uint)Input::Down) << 3; + dpad |= interface->inputPoll(0, 0, (uint)Input::Up) << 2; + dpad |= interface->inputPoll(0, 0, (uint)Input::Left) << 1; + dpad |= interface->inputPoll(0, 0, (uint)Input::Right) << 0; if(system.revision != System::Revision::SuperGameBoy) { //D-pad pivot makes it impossible to press opposing directions at the same time @@ -34,7 +32,7 @@ void CPU::mmio_joyp_poll() { if(status.joyp != 0x0f) interrupt_raise(Interrupt::Joypad); } -uint8 CPU::mmio_read(uint16 addr) { +auto CPU::mmio_read(uint16 addr) -> uint8 { if(addr >= 0xc000 && addr <= 0xfdff) return wram[wram_addr(addr)]; if(addr >= 0xff80 && addr <= 0xfffe) return hram[addr & 0x7f]; @@ -135,7 +133,7 @@ uint8 CPU::mmio_read(uint16 addr) { return 0x00; } -void CPU::mmio_write(uint16 addr, uint8 data) { +auto CPU::mmio_write(uint16 addr, uint8 data) -> void { if(addr >= 0xc000 && addr <= 0xfdff) { wram[wram_addr(addr)] = data; return; } if(addr >= 0xff80 && addr <= 0xfffe) { hram[addr & 0x7f] = data; return; } @@ -280,5 +278,3 @@ void CPU::mmio_write(uint16 addr, uint8 data) { return; } } - -#endif diff --git a/gb/cpu/serialization.cpp b/gb/cpu/serialization.cpp index 465b41cf..a1a0df75 100644 --- a/gb/cpu/serialization.cpp +++ b/gb/cpu/serialization.cpp @@ -1,6 +1,4 @@ -#ifdef CPU_CPP - -void CPU::serialize(serializer& s) { +auto CPU::serialize(serializer& s) -> void { LR35902::serialize(s); Thread::serialize(s); @@ -60,5 +58,3 @@ void CPU::serialize(serializer& s) { s.integer(oamdma.bank); s.integer(oamdma.offset); } - -#endif diff --git a/gb/cpu/timing.cpp b/gb/cpu/timing.cpp index d07b7062..eaeb1654 100644 --- a/gb/cpu/timing.cpp +++ b/gb/cpu/timing.cpp @@ -2,11 +2,9 @@ // 456 clocks/scanline // 154 scanlines/frame -#ifdef CPU_CPP - -void CPU::add_clocks(unsigned clocks) { +auto CPU::add_clocks(uint clocks) -> void { if(oamdma.active) { - for(unsigned n = 0; n < 4 * clocks; n++) { + for(uint n = 0; n < 4 * clocks; n++) { bus.write(0xfe00 + oamdma.offset, bus.read((oamdma.bank << 8) + oamdma.offset)); if(++oamdma.offset == 160) { oamdma.active = false; @@ -38,7 +36,7 @@ void CPU::add_clocks(unsigned clocks) { if(apu.clock < 0) co_switch(scheduler.active_thread = apu.thread); } -void CPU::timer_262144hz() { +auto CPU::timer_262144hz() -> void { if(status.timer_enable && status.timer_clock == 1) { if(++status.tima == 0) { status.tima = status.tma; @@ -47,7 +45,7 @@ void CPU::timer_262144hz() { } } -void CPU::timer_65536hz() { +auto CPU::timer_65536hz() -> void { if(status.timer_enable && status.timer_clock == 2) { if(++status.tima == 0) { status.tima = status.tma; @@ -56,7 +54,7 @@ void CPU::timer_65536hz() { } } -void CPU::timer_16384hz() { +auto CPU::timer_16384hz() -> void { if(status.timer_enable && status.timer_clock == 3) { if(++status.tima == 0) { status.tima = status.tma; @@ -67,7 +65,7 @@ void CPU::timer_16384hz() { status.div++; } -void CPU::timer_8192hz() { +auto CPU::timer_8192hz() -> void { if(status.serial_transfer && status.serial_clock) { if(--status.serial_bits == 0) { status.serial_transfer = 0; @@ -76,7 +74,7 @@ void CPU::timer_8192hz() { } } -void CPU::timer_4096hz() { +auto CPU::timer_4096hz() -> void { if(status.timer_enable && status.timer_clock == 0) { if(++status.tima == 0) { status.tima = status.tma; @@ -85,14 +83,12 @@ void CPU::timer_4096hz() { } } -void CPU::hblank() { +auto CPU::hblank() -> void { if(status.dma_mode == 1 && status.dma_length && ppu.status.ly < 144) { - for(unsigned n = 0; n < 16; n++) { + for(auto n : range(16)) { dma_write(status.dma_target++, dma_read(status.dma_source++)); } add_clocks(8 << status.speed_double); status.dma_length -= 16; } } - -#endif diff --git a/gb/interface/interface.cpp b/gb/interface/interface.cpp index 0f8f3775..2f20a541 100644 --- a/gb/interface/interface.cpp +++ b/gb/interface/interface.cpp @@ -4,148 +4,6 @@ namespace GameBoy { Interface* interface = nullptr; -void Interface::lcdScanline() { - if(hook) hook->lcdScanline(); -} - -void Interface::lcdOutput(uint2 color) { - if(hook) hook->lcdOutput(color); -} - -void Interface::joypWrite(bool p15, bool p14) { - if(hook) hook->joypWrite(p15, p14); -} - -string Interface::title() { - return cartridge.title(); -} - -double Interface::videoFrequency() { - return 4194304.0 / (154.0 * 456.0); -} - -double Interface::audioFrequency() { - return 4194304.0 / 2.0; -} - -bool Interface::loaded() { - return cartridge.loaded(); -} - -string Interface::sha256() { - return cartridge.sha256(); -} - -unsigned Interface::group(unsigned id) { - switch(id) { - case ID::SystemManifest: - case ID::GameBoyBootROM: - case ID::SuperGameBoyBootROM: - case ID::GameBoyColorBootROM: - return 0; - case ID::Manifest: - case ID::ROM: - case ID::RAM: - switch(system.revision) { - case System::Revision::GameBoy: return ID::GameBoy; - case System::Revision::SuperGameBoy: return ID::SuperGameBoy; - case System::Revision::GameBoyColor: return ID::GameBoyColor; - } - throw; - } - throw; -} - -void Interface::load(unsigned id) { - if(id == ID::GameBoy) cartridge.load(System::Revision::GameBoy); - if(id == ID::SuperGameBoy) cartridge.load(System::Revision::SuperGameBoy); - if(id == ID::GameBoyColor) cartridge.load(System::Revision::GameBoyColor); -} - -void Interface::save() { - for(auto& memory : cartridge.memory) { - interface->saveRequest(memory.id, memory.name); - } -} - -void Interface::load(unsigned id, const stream& stream) { - if(id == ID::SystemManifest) { - system.information.manifest = stream.text(); - } - - if(id == ID::GameBoyBootROM) { - stream.read(system.bootROM.dmg, min( 256u, stream.size())); - } - - if(id == ID::SuperGameBoyBootROM) { - stream.read(system.bootROM.sgb, min( 256u, stream.size())); - } - - if(id == ID::GameBoyColorBootROM) { - stream.read(system.bootROM.cgb, min(2048u, stream.size())); - } - - if(id == ID::Manifest) { - cartridge.information.markup = stream.text(); - } - - if(id == ID::ROM) { - stream.read(cartridge.romdata, min(cartridge.romsize, stream.size())); - } - - if(id == ID::RAM) { - stream.read(cartridge.ramdata, min(stream.size(), cartridge.ramsize)); - } -} - -void Interface::save(unsigned id, const stream& stream) { - if(id == ID::RAM) { - stream.write(cartridge.ramdata, cartridge.ramsize); - } -} - -void Interface::unload() { - save(); - cartridge.unload(); -} - -void Interface::power() { - system.power(); -} - -void Interface::reset() { - system.power(); -} - -void Interface::run() { - system.run(); -} - -serializer Interface::serialize() { - system.runtosave(); - return system.serialize(); -} - -bool Interface::unserialize(serializer& s) { - return system.unserialize(s); -} - -void Interface::cheatSet(const lstring& list) { - cheat.reset(); - for(auto& codeset : list) { - lstring codes = codeset.split("+"); - for(auto& code : codes) { - lstring part = code.split("/"); - if(part.size() == 2) cheat.append(hex(part[0]), hex(part[1])); - if(part.size() == 3) cheat.append(hex(part[0]), hex(part[1]), hex(part[2])); - } - } -} - -void Interface::paletteUpdate(PaletteMode mode) { - video.generate_palette(mode); -} - Interface::Interface() { interface = this; hook = nullptr; @@ -179,4 +37,146 @@ Interface::Interface() { port.append({0, "Device", {device[0]}}); } +auto Interface::title() -> string { + return cartridge.title(); +} + +auto Interface::videoFrequency() -> double { + return 4194304.0 / (154.0 * 456.0); +} + +auto Interface::audioFrequency() -> double { + return 4194304.0 / 2.0; +} + +auto Interface::loaded() -> bool { + return cartridge.loaded(); +} + +auto Interface::sha256() -> string { + return cartridge.sha256(); +} + +auto Interface::group(uint id) -> uint { + switch(id) { + case ID::SystemManifest: + case ID::GameBoyBootROM: + case ID::SuperGameBoyBootROM: + case ID::GameBoyColorBootROM: + return 0; + case ID::Manifest: + case ID::ROM: + case ID::RAM: + switch(system.revision) { + case System::Revision::GameBoy: return ID::GameBoy; + case System::Revision::SuperGameBoy: return ID::SuperGameBoy; + case System::Revision::GameBoyColor: return ID::GameBoyColor; + } + throw; + } + throw; +} + +auto Interface::load(uint id) -> void { + if(id == ID::GameBoy) cartridge.load(System::Revision::GameBoy); + if(id == ID::SuperGameBoy) cartridge.load(System::Revision::SuperGameBoy); + if(id == ID::GameBoyColor) cartridge.load(System::Revision::GameBoyColor); +} + +auto Interface::save() -> void { + for(auto& memory : cartridge.memory) { + interface->saveRequest(memory.id, memory.name); + } +} + +auto Interface::load(uint id, const stream& stream) -> void { + if(id == ID::SystemManifest) { + system.information.manifest = stream.text(); + } + + if(id == ID::GameBoyBootROM) { + stream.read(system.bootROM.dmg, min( 256u, stream.size())); + } + + if(id == ID::SuperGameBoyBootROM) { + stream.read(system.bootROM.sgb, min( 256u, stream.size())); + } + + if(id == ID::GameBoyColorBootROM) { + stream.read(system.bootROM.cgb, min(2048u, stream.size())); + } + + if(id == ID::Manifest) { + cartridge.information.markup = stream.text(); + } + + if(id == ID::ROM) { + stream.read(cartridge.romdata, min(cartridge.romsize, stream.size())); + } + + if(id == ID::RAM) { + stream.read(cartridge.ramdata, min(stream.size(), cartridge.ramsize)); + } +} + +auto Interface::save(uint id, const stream& stream) -> void { + if(id == ID::RAM) { + stream.write(cartridge.ramdata, cartridge.ramsize); + } +} + +auto Interface::unload() -> void { + save(); + cartridge.unload(); +} + +auto Interface::power() -> void { + system.power(); +} + +auto Interface::reset() -> void { + system.power(); +} + +auto Interface::run() -> void { + system.run(); +} + +auto Interface::serialize() -> serializer { + system.runtosave(); + return system.serialize(); +} + +auto Interface::unserialize(serializer& s) -> bool { + return system.unserialize(s); +} + +auto Interface::cheatSet(const lstring& list) -> void { + cheat.reset(); + for(auto& codeset : list) { + lstring codes = codeset.split("+"); + for(auto& code : codes) { + lstring part = code.split("/"); + if(part.size() == 2) cheat.append(hex(part[0]), hex(part[1])); + if(part.size() == 3) cheat.append(hex(part[0]), hex(part[1]), hex(part[2])); + } + } +} + +auto Interface::paletteUpdate(PaletteMode mode) -> void { + video.generate_palette(mode); +} + +auto Interface::lcdScanline() -> void { + if(hook) hook->lcdScanline(); +} + +auto Interface::lcdOutput(uint2 color) -> void { + if(hook) hook->lcdOutput(color); +} + +auto Interface::joypWrite(bool p15, bool p14) -> void { + if(hook) hook->joypWrite(p15, p14); +} + } diff --git a/gb/interface/interface.hpp b/gb/interface/interface.hpp index 54159ec0..103245e1 100644 --- a/gb/interface/interface.hpp +++ b/gb/interface/interface.hpp @@ -3,14 +3,14 @@ namespace GameBoy { #endif struct ID { - enum : unsigned { + enum : uint { System, GameBoy, SuperGameBoy, GameBoyColor, }; - enum : unsigned { + enum : uint { SystemManifest, GameBoyBootROM, SuperGameBoyBootROM, @@ -21,49 +21,49 @@ struct ID { RAM, }; - enum : unsigned { + enum : uint { Device = 1, }; }; struct Interface : Emulator::Interface { + Interface(); + + auto title() -> string; + auto videoFrequency() -> double; + auto audioFrequency() -> double; + + auto loaded() -> bool; + auto sha256() -> string; + auto group(uint id) -> uint; + auto load(uint id) -> void; + auto save() -> void; + auto load(uint id, const stream& stream) -> void; + auto save(uint id, const stream& stream) -> void; + auto unload() -> void; + + auto power() -> void; + auto reset() -> void; + auto run() -> void; + + auto serialize() -> serializer; + auto unserialize(serializer&) -> bool; + + auto cheatSet(const lstring&) -> void; + + auto paletteUpdate(PaletteMode mode) -> void; + //Super Game Boy bindings struct Hook { - virtual void lcdScanline() {} - virtual void lcdOutput(uint2 color) {} - virtual void joypWrite(bool p15, bool p14) {} + virtual auto lcdScanline() -> void {} + virtual auto lcdOutput(uint2 color) -> void {} + virtual auto joypWrite(bool p15, bool p14) -> void {} }; Hook* hook = nullptr; - void lcdScanline(); - void lcdOutput(uint2 color); - void joypWrite(bool p15, bool p14); - - string title(); - double videoFrequency(); - double audioFrequency(); - - bool loaded(); - string sha256(); - unsigned group(unsigned id); - void load(unsigned id); - void save(); - void load(unsigned id, const stream& stream); - void save(unsigned id, const stream& stream); - void unload(); - - void power(); - void reset(); - void run(); - - serializer serialize(); - bool unserialize(serializer&); - - void cheatSet(const lstring&); - - void paletteUpdate(PaletteMode mode); - - Interface(); + auto lcdScanline() -> void; + auto lcdOutput(uint2 color) -> void; + auto joypWrite(bool p15, bool p14) -> void; private: vector device; diff --git a/gb/memory/memory.cpp b/gb/memory/memory.cpp index abcbce22..31634bee 100644 --- a/gb/memory/memory.cpp +++ b/gb/memory/memory.cpp @@ -1,47 +1,41 @@ #include -#define MEMORY_CPP namespace GameBoy { Unmapped unmapped; Bus bus; -uint8_t& Memory::operator[](unsigned addr) { +Memory::~Memory() { + free(); +} + +auto Memory::operator[](uint addr) -> uint8& { return data[addr]; } -void Memory::allocate(unsigned size_) { +auto Memory::allocate(uint size_) -> void { free(); size = size_; data = new uint8_t[size](); } -void Memory::copy(const uint8_t* data_, unsigned size_) { +auto Memory::copy(const uint8_t* data_, unsigned size_) -> void { free(); size = size_; data = new uint8_t[size]; memcpy(data, data_, size); } -void Memory::free() { +auto Memory::free() -> void { if(data) { delete[] data; - data = 0; + data = nullptr; } } -Memory::Memory() { - data = 0; - size = 0; -} - -Memory::~Memory() { - free(); -} - // -uint8 Bus::read(uint16 addr) { +auto Bus::read(uint16 addr) -> uint8 { uint8 data = mmio[addr]->mmio_read(addr); if(cheat.enable()) { @@ -51,12 +45,12 @@ uint8 Bus::read(uint16 addr) { return data; } -void Bus::write(uint16 addr, uint8 data) { +auto Bus::write(uint16 addr, uint8 data) -> void { mmio[addr]->mmio_write(addr, data); } -void Bus::power() { - for(unsigned n = 0x0000; n <= 0xffff; n++) mmio[n] = &unmapped; +auto Bus::power() -> void { + for(auto n : range(65536)) mmio[n] = &unmapped; } } diff --git a/gb/memory/memory.hpp b/gb/memory/memory.hpp index 464c3045..6165930d 100644 --- a/gb/memory/memory.hpp +++ b/gb/memory/memory.hpp @@ -1,31 +1,31 @@ struct Memory { - uint8_t* data; - unsigned size; - - uint8_t& operator[](unsigned addr); - void allocate(unsigned size); - void copy(const uint8_t* data, unsigned size); - void free(); - Memory(); ~Memory(); + + auto operator[](uint addr) -> uint8&; + auto allocate(uint size) -> void; + auto copy(const uint8* data, uint size) -> void; + auto free() -> void; + + uint8* data = nullptr; + uint size = 0; }; struct MMIO { - virtual uint8 mmio_read(uint16 addr) = 0; - virtual void mmio_write(uint16 addr, uint8 data) = 0; + virtual auto mmio_read(uint16 addr) -> uint8 = 0; + virtual auto mmio_write(uint16 addr, uint8 data) -> void = 0; }; struct Unmapped : MMIO { - uint8 mmio_read(uint16) { return 0x00; } - void mmio_write(uint16, uint8) {} + auto mmio_read(uint16) -> uint8 { return 0x00; } + auto mmio_write(uint16, uint8) -> void {} }; struct Bus { - MMIO* mmio[65536]; - uint8 read(uint16 addr); - void write(uint16 addr, uint8 data); + auto read(uint16 addr) -> uint8; + auto write(uint16 addr, uint8 data) -> void; + auto power() -> void; - void power(); + MMIO* mmio[65536]; }; extern Unmapped unmapped; diff --git a/gb/ppu/cgb.cpp b/gb/ppu/cgb.cpp index 9d04aa3a..8d8c0ec6 100644 --- a/gb/ppu/cgb.cpp +++ b/gb/ppu/cgb.cpp @@ -1,5 +1,3 @@ -#ifdef PPU_CPP - //BG attributes: //0x80: 0 = OAM priority, 1 = BG priority //0x40: vertical flip @@ -14,14 +12,14 @@ //0x08: VRAM bank# //0x07: palette# -void PPU::cgb_read_tile(bool select, unsigned x, unsigned y, unsigned& attr, unsigned& data) { - unsigned tmaddr = 0x1800 + (select << 10); +auto PPU::cgb_read_tile(bool select, uint x, uint y, uint& attr, uint& data) -> void { + uint tmaddr = 0x1800 + (select << 10); tmaddr += (((y >> 3) << 5) + (x >> 3)) & 0x03ff; - unsigned tile = vram[0x0000 + tmaddr]; + uint tile = vram[0x0000 + tmaddr]; attr = vram[0x2000 + tmaddr]; - unsigned tdaddr = attr & 0x08 ? 0x2000 : 0x0000; + uint tdaddr = attr & 0x08 ? 0x2000 : 0x0000; if(status.bg_tiledata_select == 0) { tdaddr += 0x1000 + ((int8)tile << 4); } else { @@ -37,14 +35,14 @@ void PPU::cgb_read_tile(bool select, unsigned x, unsigned y, unsigned& attr, uns if(attr & 0x20) data = hflip(data); } -void PPU::cgb_scanline() { +auto PPU::cgb_scanline() -> void { px = 0; - const unsigned Height = (status.ob_size == 0 ? 8 : 16); + const uint Height = (status.ob_size == 0 ? 8 : 16); sprites = 0; //find first ten sprites on this scanline - for(unsigned n = 0; n < 40 * 4; n += 4) { + for(uint n = 0; n < 40 * 4; n += 4) { Sprite& s = sprite[sprites]; s.y = oam[n + 0] - 16; s.x = oam[n + 1] - 8; @@ -55,7 +53,7 @@ void PPU::cgb_scanline() { if(s.y >= Height) continue; if(s.attr & 0x40) s.y ^= (Height - 1); - unsigned tdaddr = (s.attr & 0x08 ? 0x2000 : 0x0000) + (s.tile << 4) + (s.y << 1); + uint tdaddr = (s.attr & 0x08 ? 0x2000 : 0x0000) + (s.tile << 4) + (s.y << 1); s.data = vram[tdaddr + 0] << 0; s.data |= vram[tdaddr + 1] << 8; if(s.attr & 0x20) s.data = hflip(s.data); @@ -64,12 +62,12 @@ void PPU::cgb_scanline() { } } -void PPU::cgb_run() { +auto PPU::cgb_run() -> void { ob.color = 0; ob.palette = 0; ob.priority = 0; - unsigned color = 0x7fff; + uint color = 0x7fff; if(status.display_enable) { cgb_run_bg(); if(status.window_display_enable) cgb_run_window(); @@ -94,17 +92,17 @@ void PPU::cgb_run() { *output = color; } -void PPU::cgb_run_bg() { - unsigned scrolly = (status.ly + status.scy) & 255; - unsigned scrollx = (px + status.scx) & 255; - unsigned tx = scrollx & 7; +auto PPU::cgb_run_bg() -> void { + uint scrolly = (status.ly + status.scy) & 255; + uint scrollx = (px + status.scx) & 255; + uint tx = scrollx & 7; if(tx == 0 || px == 0) cgb_read_tile(status.bg_tilemap_select, scrollx, scrolly, background.attr, background.data); - unsigned index = 0; + uint index = 0; index |= (background.data & (0x0080 >> tx)) ? 1 : 0; index |= (background.data & (0x8000 >> tx)) ? 2 : 0; - unsigned palette = ((background.attr & 0x07) << 2) + index; - unsigned color = 0; + uint palette = ((background.attr & 0x07) << 2) + index; + uint color = 0; color |= bgpd[(palette << 1) + 0] << 0; color |= bgpd[(palette << 1) + 1] << 8; color &= 0x7fff; @@ -114,19 +112,19 @@ void PPU::cgb_run_bg() { bg.priority = background.attr & 0x80; } -void PPU::cgb_run_window() { - unsigned scrolly = status.ly - status.wy; - unsigned scrollx = px + 7 - status.wx; +auto PPU::cgb_run_window() -> void { + uint scrolly = status.ly - status.wy; + uint scrollx = px + 7 - status.wx; if(scrolly >= 144u) return; //also matches underflow (scrolly < 0) if(scrollx >= 160u) return; //also matches underflow (scrollx < 0) - unsigned tx = scrollx & 7; + uint tx = scrollx & 7; if(tx == 0 || px == 0) cgb_read_tile(status.window_tilemap_select, scrollx, scrolly, window.attr, window.data); - unsigned index = 0; + uint index = 0; index |= (window.data & (0x0080 >> tx)) ? 1 : 0; index |= (window.data & (0x8000 >> tx)) ? 2 : 0; - unsigned palette = ((window.attr & 0x07) << 2) + index; - unsigned color = 0; + uint palette = ((window.attr & 0x07) << 2) + index; + uint color = 0; color |= bgpd[(palette << 1) + 0] << 0; color |= bgpd[(palette << 1) + 1] << 8; color &= 0x7fff; @@ -136,21 +134,21 @@ void PPU::cgb_run_window() { bg.priority = window.attr & 0x80; } -void PPU::cgb_run_ob() { +auto PPU::cgb_run_ob() -> void { //render backwards, so that first sprite has priority - for(signed n = sprites - 1; n >= 0; n--) { + for(int n = sprites - 1; n >= 0; n--) { Sprite& s = sprite[n]; - signed tx = px - s.x; + int tx = px - s.x; if(tx < 0 || tx > 7) continue; - unsigned index = 0; + uint index = 0; index |= (s.data & (0x0080 >> tx)) ? 1 : 0; index |= (s.data & (0x8000 >> tx)) ? 2 : 0; if(index == 0) continue; - unsigned palette = ((s.attr & 0x07) << 2) + index; - unsigned color = 0; + uint palette = ((s.attr & 0x07) << 2) + index; + uint color = 0; color |= obpd[(palette << 1) + 0] << 0; color |= obpd[(palette << 1) + 1] << 8; color &= 0x7fff; @@ -160,5 +158,3 @@ void PPU::cgb_run_ob() { ob.priority = !(s.attr & 0x80); } } - -#endif diff --git a/gb/ppu/dmg.cpp b/gb/ppu/dmg.cpp index 2d9b39b2..6b239f7f 100644 --- a/gb/ppu/dmg.cpp +++ b/gb/ppu/dmg.cpp @@ -1,13 +1,11 @@ -#ifdef PPU_CPP - //OB attributes: //0x80: 0 = OBJ above BG, 1 = BG above OBJ //0x40: vertical flip //0x20: horizontal flip //0x10: palette# -void PPU::dmg_read_tile(bool select, unsigned x, unsigned y, unsigned& data) { - unsigned tmaddr = 0x1800 + (select << 10), tdaddr; +auto PPU::dmg_read_tile(bool select, uint x, uint y, uint& data) -> void { + uint tmaddr = 0x1800 + (select << 10), tdaddr; tmaddr += (((y >> 3) << 5) + (x >> 3)) & 0x03ff; if(status.bg_tiledata_select == 0) { tdaddr = 0x1000 + ((int8)vram[tmaddr] << 4); @@ -19,14 +17,14 @@ void PPU::dmg_read_tile(bool select, unsigned x, unsigned y, unsigned& data) { data |= vram[tdaddr + 1] << 8; } -void PPU::dmg_scanline() { +auto PPU::dmg_scanline() -> void { px = 0; - const unsigned Height = (status.ob_size == 0 ? 8 : 16); + const uint Height = (status.ob_size == 0 ? 8 : 16); sprites = 0; //find first ten sprites on this scanline - for(unsigned n = 0; n < 40 * 4; n += 4) { + for(uint n = 0; n < 40 * 4; n += 4) { Sprite& s = sprite[sprites]; s.y = oam[n + 0] - 16; s.x = oam[n + 1] - 8; @@ -37,7 +35,7 @@ void PPU::dmg_scanline() { if(s.y >= Height) continue; if(s.attr & 0x40) s.y ^= (Height - 1); - unsigned tdaddr = (s.tile << 4) + (s.y << 1); + uint tdaddr = (s.tile << 4) + (s.y << 1); s.data = vram[tdaddr + 0] << 0; s.data |= vram[tdaddr + 1] << 8; if(s.attr & 0x20) s.data = hflip(s.data); @@ -46,21 +44,21 @@ void PPU::dmg_scanline() { } //sort by X-coordinate - for(unsigned lo = 0; lo < sprites; lo++) { - for(unsigned hi = lo + 1; hi < sprites; hi++) { - if(sprite[hi].x < sprite[lo].x) std::swap(sprite[lo], sprite[hi]); + for(uint lo = 0; lo < sprites; lo++) { + for(uint hi = lo + 1; hi < sprites; hi++) { + if(sprite[hi].x < sprite[lo].x) swap(sprite[lo], sprite[hi]); } } } -void PPU::dmg_run() { +auto PPU::dmg_run() -> void { bg.color = 0; bg.palette = 0; ob.color = 0; ob.palette = 0; - unsigned color = 0; + uint color = 0; if(status.display_enable) { if(status.bg_enable) dmg_run_bg(); if(status.window_display_enable) dmg_run_window(); @@ -82,13 +80,13 @@ void PPU::dmg_run() { interface->lcdOutput(color); //Super Game Boy notification } -void PPU::dmg_run_bg() { - unsigned scrolly = (status.ly + status.scy) & 255; - unsigned scrollx = (px + status.scx) & 255; - unsigned tx = scrollx & 7; +auto PPU::dmg_run_bg() -> void { + uint scrolly = (status.ly + status.scy) & 255; + uint scrollx = (px + status.scx) & 255; + uint tx = scrollx & 7; if(tx == 0 || px == 0) dmg_read_tile(status.bg_tilemap_select, scrollx, scrolly, background.data); - unsigned index = 0; + uint index = 0; index |= (background.data & (0x0080 >> tx)) ? 1 : 0; index |= (background.data & (0x8000 >> tx)) ? 2 : 0; @@ -96,15 +94,15 @@ void PPU::dmg_run_bg() { bg.palette = index; } -void PPU::dmg_run_window() { - unsigned scrolly = status.ly - status.wy; - unsigned scrollx = px + 7 - status.wx; +auto PPU::dmg_run_window() -> void { + uint scrolly = status.ly - status.wy; + uint scrollx = px + 7 - status.wx; if(scrolly >= 144u) return; //also matches underflow (scrolly < 0) if(scrollx >= 160u) return; //also matches underflow (scrollx < 0) - unsigned tx = scrollx & 7; + uint tx = scrollx & 7; if(tx == 0 || px == 0) dmg_read_tile(status.window_tilemap_select, scrollx, scrolly, window.data); - unsigned index = 0; + uint index = 0; index |= (window.data & (0x0080 >> tx)) ? 1 : 0; index |= (window.data & (0x8000 >> tx)) ? 2 : 0; @@ -112,15 +110,15 @@ void PPU::dmg_run_window() { bg.palette = index; } -void PPU::dmg_run_ob() { +auto PPU::dmg_run_ob() -> void { //render backwards, so that first sprite has priority - for(signed n = sprites - 1; n >= 0; n--) { + for(int n = sprites - 1; n >= 0; n--) { Sprite& s = sprite[n]; - signed tx = px - s.x; + int tx = px - s.x; if(tx < 0 || tx > 7) continue; - unsigned index = 0; + uint index = 0; index |= (s.data & (0x0080 >> tx)) ? 1 : 0; index |= (s.data & (0x8000 >> tx)) ? 2 : 0; if(index == 0) continue; @@ -130,5 +128,3 @@ void PPU::dmg_run_ob() { ob.priority = !(s.attr & 0x80); } } - -#endif diff --git a/gb/ppu/mmio.cpp b/gb/ppu/mmio.cpp index af33162c..ed2c0da5 100644 --- a/gb/ppu/mmio.cpp +++ b/gb/ppu/mmio.cpp @@ -1,10 +1,8 @@ -#ifdef PPU_CPP - -unsigned PPU::vram_addr(uint16 addr) const { +auto PPU::vram_addr(uint16 addr) const -> uint { return (status.vram_bank * 0x2000) + (addr & 0x1fff); } -uint8 PPU::mmio_read(uint16 addr) { +auto PPU::mmio_read(uint16 addr) -> uint8 { if(addr >= 0x8000 && addr <= 0x9fff) return vram[vram_addr(addr)]; if(addr >= 0xfe00 && addr <= 0xfe9f) return oam[addr & 0xff]; @@ -20,7 +18,7 @@ uint8 PPU::mmio_read(uint16 addr) { } if(addr == 0xff41) { //STAT - unsigned mode; + uint mode; if(status.ly >= 144) mode = 1; //Vblank else if(status.lx < 80) mode = 2; //OAM else if(status.lx < 252) mode = 3; //LCD @@ -90,7 +88,7 @@ uint8 PPU::mmio_read(uint16 addr) { return 0x00; } -void PPU::mmio_write(uint16 addr, uint8 data) { +auto PPU::mmio_write(uint16 addr, uint8 data) -> void { if(addr >= 0x8000 && addr <= 0x9fff) { vram[vram_addr(addr)] = data; return; } if(addr >= 0xfe00 && addr <= 0xfe9f) { oam[addr & 0xff] = data; return; } @@ -199,5 +197,3 @@ void PPU::mmio_write(uint16 addr, uint8 data) { if(status.obpi_increment) status.obpi++; } } - -#endif diff --git a/gb/ppu/ppu.cpp b/gb/ppu/ppu.cpp index ecba6e82..5caa160b 100644 --- a/gb/ppu/ppu.cpp +++ b/gb/ppu/ppu.cpp @@ -6,7 +6,6 @@ //LX = 0-455 -#define PPU_CPP namespace GameBoy { #include "mmio.cpp" @@ -15,11 +14,11 @@ namespace GameBoy { #include "serialization.cpp" PPU ppu; -void PPU::Main() { +auto PPU::Main() -> void { ppu.main(); } -void PPU::main() { +auto PPU::main() -> void { while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::All) { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); @@ -30,7 +29,7 @@ void PPU::main() { if(status.display_enable && status.ly < 144) { if(status.interrupt_oam) cpu.interrupt_raise(CPU::Interrupt::Stat); add_clocks(92); - for(unsigned n = 0; n < 160; n++) { + for(auto n : range(160)) { system.cgb() ? cgb_run() : dmg_run(); add_clocks(1); } @@ -45,7 +44,7 @@ void PPU::main() { } } -void PPU::add_clocks(unsigned clocks) { +auto PPU::add_clocks(uint clocks) -> void { status.lx += clocks; clock += clocks * cpu.frequency; if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) { @@ -53,7 +52,7 @@ void PPU::add_clocks(unsigned clocks) { } } -void PPU::scanline() { +auto PPU::scanline() -> void { status.lx = 0; if(++status.ly == 154) frame(); @@ -71,23 +70,23 @@ void PPU::scanline() { } } -void PPU::frame() { +auto PPU::frame() -> void { status.ly = 0; scheduler.exit(Scheduler::ExitReason::FrameEvent); } -unsigned PPU::hflip(unsigned data) const { +auto PPU::hflip(uint data) const -> uint { return ((data & 0x8080) >> 7) | ((data & 0x4040) >> 5) | ((data & 0x2020) >> 3) | ((data & 0x1010) >> 1) | ((data & 0x0808) << 1) | ((data & 0x0404) << 3) | ((data & 0x0202) << 5) | ((data & 0x0101) << 7); } -void PPU::power() { +auto PPU::power() -> void { create(Main, 4 * 1024 * 1024); - for(unsigned n = 0x8000; n <= 0x9fff; n++) bus.mmio[n] = this; //VRAM - for(unsigned n = 0xfe00; n <= 0xfe9f; n++) bus.mmio[n] = this; //OAM + for(uint n = 0x8000; n <= 0x9fff; n++) bus.mmio[n] = this; //VRAM + for(uint n = 0xfe00; n <= 0xfe9f; n++) bus.mmio[n] = this; //OAM bus.mmio[0xff40] = this; //LCDC bus.mmio[0xff41] = this; //STAT @@ -174,7 +173,4 @@ void PPU::power() { window.data = 0; } -PPU::PPU() { -} - } diff --git a/gb/ppu/ppu.hpp b/gb/ppu/ppu.hpp index 436a62f2..33e035af 100644 --- a/gb/ppu/ppu.hpp +++ b/gb/ppu/ppu.hpp @@ -1,4 +1,37 @@ struct PPU : Thread, MMIO { + static auto Main() -> void; + auto main() -> void; + auto add_clocks(uint clocks) -> void; + auto scanline() -> void; + auto frame() -> void; + + auto hflip(uint data) const -> uint; + + //mmio.cpp + auto vram_addr(uint16 addr) const -> uint; + auto mmio_read(uint16 addr) -> uint8; + auto mmio_write(uint16 addr, uint8 data) -> void; + + //dmg.cpp + auto dmg_read_tile(bool select, uint x, uint y, uint& data) -> void; + auto dmg_scanline() -> void; + auto dmg_run() -> void; + auto dmg_run_bg() -> void; + auto dmg_run_window() -> void; + auto dmg_run_ob() -> void; + + //cgb.cpp + auto cgb_read_tile(bool select, uint x, uint y, uint& attr, uint& data) -> void; + auto cgb_scanline() -> void; + auto cgb_run() -> void; + auto cgb_run_bg() -> void; + auto cgb_run_window() -> void; + auto cgb_run_ob() -> void; + + auto power() -> void; + + auto serialize(serializer&) -> void; + uint8 vram[16384]; //GB = 8192, GBC = 16384 uint8 oam[160]; uint8 bgp[4]; @@ -7,7 +40,7 @@ struct PPU : Thread, MMIO { uint8 obpd[64]; struct Status { - unsigned lx; + uint lx; //$ff40 LCDC bool display_enable; @@ -66,57 +99,23 @@ struct PPU : Thread, MMIO { Pixel ob; struct Sprite { - unsigned x; - unsigned y; - unsigned tile; - unsigned attr; - unsigned data; + uint x; + uint y; + uint tile; + uint attr; + uint data; }; Sprite sprite[10]; - unsigned sprites; + uint sprites; - unsigned px; + uint px; struct Background { - unsigned attr; - unsigned data; + uint attr; + uint data; }; Background background; Background window; - - static void Main(); - void main(); - void add_clocks(unsigned clocks); - void scanline(); - void frame(); - - unsigned hflip(unsigned data) const; - - //mmio.cpp - unsigned vram_addr(uint16 addr) const; - uint8 mmio_read(uint16 addr); - void mmio_write(uint16 addr, uint8 data); - - //dmg.cpp - void dmg_read_tile(bool select, unsigned x, unsigned y, unsigned& data); - void dmg_scanline(); - void dmg_run(); - void dmg_run_bg(); - void dmg_run_window(); - void dmg_run_ob(); - - //cgb.cpp - void cgb_read_tile(bool select, unsigned x, unsigned y, unsigned& attr, unsigned& data); - void cgb_scanline(); - void cgb_run(); - void cgb_run_bg(); - void cgb_run_window(); - void cgb_run_ob(); - - void power(); - - void serialize(serializer&); - PPU(); }; extern PPU ppu; diff --git a/gb/ppu/serialization.cpp b/gb/ppu/serialization.cpp index 3845de65..8ce748fc 100644 --- a/gb/ppu/serialization.cpp +++ b/gb/ppu/serialization.cpp @@ -1,6 +1,4 @@ -#ifdef PPU_CPP - -void PPU::serialize(serializer& s) { +auto PPU::serialize(serializer& s) -> void { Thread::serialize(s); s.array(vram); @@ -68,5 +66,3 @@ void PPU::serialize(serializer& s) { s.integer(window.attr); s.integer(window.data); } - -#endif diff --git a/gb/scheduler/scheduler.cpp b/gb/scheduler/scheduler.cpp index aeef2027..b804ba5f 100644 --- a/gb/scheduler/scheduler.cpp +++ b/gb/scheduler/scheduler.cpp @@ -1,30 +1,23 @@ #include -#define SCHEDULER_CPP namespace GameBoy { Scheduler scheduler; -void Scheduler::enter() { +auto Scheduler::init() -> void { + host_thread = co_active(); + active_thread = cpu.thread; +} + +auto Scheduler::enter() -> void { host_thread = co_active(); co_switch(active_thread); } -void Scheduler::exit(ExitReason reason) { +auto Scheduler::exit(ExitReason reason) -> void { exit_reason = reason; active_thread = co_active(); co_switch(host_thread); } -void Scheduler::init() { - host_thread = co_active(); - active_thread = cpu.thread; -} - -Scheduler::Scheduler() { - exit_reason = ExitReason::UnknownEvent; - host_thread = nullptr; - active_thread = nullptr; -} - } diff --git a/gb/scheduler/scheduler.hpp b/gb/scheduler/scheduler.hpp index 875fe4f0..eb483d15 100644 --- a/gb/scheduler/scheduler.hpp +++ b/gb/scheduler/scheduler.hpp @@ -1,16 +1,14 @@ -struct Scheduler : property { - enum class SynchronizeMode : unsigned { None, CPU, All } sync; - enum class ExitReason : unsigned { UnknownEvent, StepEvent, FrameEvent, SynchronizeEvent }; - readonly exit_reason; +struct Scheduler { + enum class SynchronizeMode : uint { None, CPU, All } sync; + enum class ExitReason : uint { UnknownEvent, StepEvent, FrameEvent, SynchronizeEvent }; - cothread_t host_thread; - cothread_t active_thread; + auto init() -> void; + auto enter() -> void; + auto exit(ExitReason) -> void; - void enter(); - void exit(ExitReason); - - void init(); - Scheduler(); + cothread_t host_thread = nullptr; + cothread_t active_thread = nullptr; + ExitReason exit_reason = ExitReason::UnknownEvent; }; extern Scheduler scheduler; diff --git a/gb/system/serialization.cpp b/gb/system/serialization.cpp index 0c951c35..bded1639 100644 --- a/gb/system/serialization.cpp +++ b/gb/system/serialization.cpp @@ -1,9 +1,7 @@ -#ifdef SYSTEM_CPP - -serializer System::serialize() { +auto System::serialize() -> serializer { serializer s(serialize_size); - unsigned signature = 0x31545342, version = Info::SerializerVersion; + uint signature = 0x31545342, version = Info::SerializerVersion; char hash[64], description[512]; memcpy(&hash, (const char*)cartridge.sha256(), 64); memset(&description, 0, sizeof description); @@ -17,8 +15,8 @@ serializer System::serialize() { return s; } -bool System::unserialize(serializer& s) { - unsigned signature, version; +auto System::unserialize(serializer& s) -> bool { + uint signature, version; char hash[64], description[512]; s.integer(signature); @@ -34,11 +32,11 @@ bool System::unserialize(serializer& s) { return true; } -void System::serialize(serializer& s) { +auto System::serialize(serializer& s) -> void { s.integer(clocks_executed); } -void System::serialize_all(serializer& s) { +auto System::serialize_all(serializer& s) -> void { cartridge.serialize(s); system.serialize(s); cpu.serialize(s); @@ -46,10 +44,10 @@ void System::serialize_all(serializer& s) { apu.serialize(s); } -void System::serialize_init() { +auto System::serialize_init() -> void { serializer s; - unsigned signature = 0, version = 0, crc32 = 0; + uint signature = 0, version = 0, crc32 = 0; char hash[64], description[512]; s.integer(signature); @@ -60,5 +58,3 @@ void System::serialize_init() { serialize_all(s); serialize_size = s.size(); } - -#endif diff --git a/gb/system/system.cpp b/gb/system/system.cpp index 9813e141..858b9dd0 100644 --- a/gb/system/system.cpp +++ b/gb/system/system.cpp @@ -1,21 +1,26 @@ #include -#define SYSTEM_CPP namespace GameBoy { #include "serialization.cpp" System system; -void System::run() { +System::System() { + for(auto& byte : bootROM.dmg) byte = 0; + for(auto& byte : bootROM.sgb) byte = 0; + for(auto& byte : bootROM.cgb) byte = 0; +} + +auto System::run() -> void { scheduler.sync = Scheduler::SynchronizeMode::None; scheduler.enter(); - if(scheduler.exit_reason() == Scheduler::ExitReason::FrameEvent) { + if(scheduler.exit_reason == Scheduler::ExitReason::FrameEvent) { interface->videoRefresh(video.palette, ppu.screen, 4 * 160, 160, 144); } } -void System::runtosave() { +auto System::runtosave() -> void { scheduler.sync = Scheduler::SynchronizeMode::CPU; runthreadtosave(); @@ -30,21 +35,21 @@ void System::runtosave() { scheduler.sync = Scheduler::SynchronizeMode::None; } -void System::runthreadtosave() { +auto System::runthreadtosave() -> void { while(true) { scheduler.enter(); - if(scheduler.exit_reason() == Scheduler::ExitReason::SynchronizeEvent) break; - if(scheduler.exit_reason() == Scheduler::ExitReason::FrameEvent) { + if(scheduler.exit_reason == Scheduler::ExitReason::SynchronizeEvent) break; + if(scheduler.exit_reason == Scheduler::ExitReason::FrameEvent) { interface->videoRefresh(video.palette, ppu.screen, 4 * 160, 160, 144); } } } -void System::init() { +auto System::init() -> void { assert(interface != nullptr); } -void System::load(Revision revision) { +auto System::load(Revision revision) -> void { this->revision = revision; serialize_init(); if(revision == Revision::SuperGameBoy) return; //Super Famicom core loads boot ROM for SGB @@ -60,7 +65,7 @@ void System::load(Revision revision) { } } -void System::power() { +auto System::power() -> void { bus.power(); cartridge.power(); cpu.power(); @@ -71,10 +76,4 @@ void System::power() { clocks_executed = 0; } -System::System() { - for(auto& byte : bootROM.dmg) byte = 0; - for(auto& byte : bootROM.sgb) byte = 0; - for(auto& byte : bootROM.cgb) byte = 0; -} - } diff --git a/gb/system/system.hpp b/gb/system/system.hpp index bd3a4a51..9371d020 100644 --- a/gb/system/system.hpp +++ b/gb/system/system.hpp @@ -1,19 +1,37 @@ class Interface; -enum class Input : unsigned { +enum class Input : uint { Up, Down, Left, Right, B, A, Select, Start, }; struct System { - enum class Revision : unsigned { + enum class Revision : uint { GameBoy, SuperGameBoy, GameBoyColor, } revision; - inline bool dmg() const { return revision == Revision::GameBoy; } - inline bool sgb() const { return revision == Revision::SuperGameBoy; } - inline bool cgb() const { return revision == Revision::GameBoyColor; } + System(); + + inline auto dmg() const { return revision == Revision::GameBoy; } + inline auto sgb() const { return revision == Revision::SuperGameBoy; } + inline auto cgb() const { return revision == Revision::GameBoyColor; } + + auto run() -> void; + auto runtosave() -> void; + auto runthreadtosave() -> void; + + auto init() -> void; + auto load(Revision) -> void; + auto power() -> void; + + //serialization.cpp + auto serialize() -> serializer; + auto unserialize(serializer&) -> bool; + + auto serialize(serializer&) -> void; + auto serialize_all(serializer&) -> void; + auto serialize_init() -> void; struct BootROM { uint8 dmg[ 256]; @@ -21,31 +39,12 @@ struct System { uint8 cgb[2048]; } bootROM; - void run(); - void runtosave(); - void runthreadtosave(); - - void init(); - void load(Revision); - void power(); - - unsigned clocks_executed; - - //serialization.cpp - unsigned serialize_size; - - serializer serialize(); - bool unserialize(serializer&); - - void serialize(serializer&); - void serialize_all(serializer&); - void serialize_init(); - - System(); - struct Information { string manifest; } information; + + uint clocks_executed = 0; + uint serialize_size = 0; }; #include diff --git a/gb/video/video.cpp b/gb/video/video.cpp index f08a9400..30564e6e 100644 --- a/gb/video/video.cpp +++ b/gb/video/video.cpp @@ -1,17 +1,9 @@ #include -#define VIDEO_CPP namespace GameBoy { Video video; -void Video::generate_palette(Emulator::Interface::PaletteMode mode) { - this->mode = mode; - if(system.dmg()) for(unsigned n = 0; n < 4; n++) palette[n] = palette_dmg(n); - if(system.sgb()) for(unsigned n = 0; n < 4; n++) palette[n] = palette_sgb(n); - if(system.cgb()) for(unsigned n = 0; n < (1 << 15); n++) palette[n] = palette_cgb(n); -} - Video::Video() { palette = new uint32_t[1 << 15](); } @@ -20,43 +12,50 @@ Video::~Video() { delete[] palette; } -unsigned Video::palette_dmg(unsigned color) const { +auto Video::generate_palette(Emulator::Interface::PaletteMode mode) -> void { + this->mode = mode; + if(system.dmg()) for(auto n : range(4)) palette[n] = paletteDMG(n); + if(system.sgb()) for(auto n : range(4)) palette[n] = paletteSGB(n); + if(system.cgb()) for(auto n : range(1 << 15)) palette[n] = paletteCGB(n); +} + +auto Video::paletteDMG(uint color) const -> uint { if(mode == Emulator::Interface::PaletteMode::Literal) { return color; } if(mode == Emulator::Interface::PaletteMode::Channel) { - unsigned L = image::normalize(color, 2, 16); + uint L = image::normalize(color, 2, 16); return interface->videoColor(color, 0, 0, 0, L); } if(mode == Emulator::Interface::PaletteMode::Standard) { - unsigned L = image::normalize(3 - color, 2, 16); + uint L = image::normalize(3 - color, 2, 16); return interface->videoColor(color, 0, L, L, L); } if(mode == Emulator::Interface::PaletteMode::Emulation) { - unsigned R = monochrome[color][0]; - unsigned G = monochrome[color][1]; - unsigned B = monochrome[color][2]; + uint R = monochrome[color][0]; + uint G = monochrome[color][1]; + uint B = monochrome[color][2]; return interface->videoColor(color, 0, R, G, B); } return 0; } -unsigned Video::palette_sgb(unsigned color) const { +auto Video::paletteSGB(uint color) const -> uint { return color; } -unsigned Video::palette_cgb(unsigned color) const { +auto Video::paletteCGB(uint color) const -> uint { if(mode == Emulator::Interface::PaletteMode::Literal) { return color; } - unsigned r = (color >> 0) & 31; - unsigned g = (color >> 5) & 31; - unsigned b = (color >> 10) & 31; + uint r = (color >> 0) & 31; + uint g = (color >> 5) & 31; + uint b = (color >> 10) & 31; if(mode == Emulator::Interface::PaletteMode::Channel) { r = image::normalize(r, 5, 16); @@ -73,9 +72,9 @@ unsigned Video::palette_cgb(unsigned color) const { } if(mode == Emulator::Interface::PaletteMode::Emulation) { - unsigned R = (r * 26 + g * 4 + b * 2); - unsigned G = ( g * 24 + b * 8); - unsigned B = (r * 6 + g * 4 + b * 22); + uint R = (r * 26 + g * 4 + b * 2); + uint G = ( g * 24 + b * 8); + uint B = (r * 6 + g * 4 + b * 22); R = min(960, R); G = min(960, G); diff --git a/gb/video/video.hpp b/gb/video/video.hpp index 90b1f666..17ef9f97 100644 --- a/gb/video/video.hpp +++ b/gb/video/video.hpp @@ -1,16 +1,17 @@ struct Video { - uint32_t* palette = nullptr; - void generate_palette(Emulator::Interface::PaletteMode mode); - Video(); ~Video(); + auto generate_palette(Emulator::Interface::PaletteMode mode) -> void; + + uint32* palette = nullptr; + private: Emulator::Interface::PaletteMode mode; static const uint16 monochrome[4][3]; - uint32_t palette_dmg(unsigned color) const; - uint32_t palette_sgb(unsigned color) const; - uint32_t palette_cgb(unsigned color) const; + auto paletteDMG(uint color) const -> uint; + auto paletteSGB(uint color) const -> uint; + auto paletteCGB(uint color) const -> uint; }; extern Video video; diff --git a/nall/dsp/buffer.hpp b/nall/dsp/buffer.hpp index bdaab79c..27bcef99 100644 --- a/nall/dsp/buffer.hpp +++ b/nall/dsp/buffer.hpp @@ -1,14 +1,16 @@ #ifdef NALL_DSP_INTERNAL_HPP struct Buffer { - double** sample = nullptr; - uint16_t rdoffset = 0; - uint16_t wroffset = 0; - unsigned channels = 0; + Buffer() { + } - void setChannels(unsigned channels) { + ~Buffer() { + setChannels(0); + } + + auto setChannels(uint channels) -> void { if(sample) { - for(unsigned c = 0; c < this->channels; c++) { + for(auto c : range(this->channels)) { if(sample[c]) delete[] sample[c]; } delete[] sample; @@ -18,22 +20,22 @@ struct Buffer { if(channels == 0) return; sample = new double*[channels]; - for(unsigned c = 0; c < channels; c++) { + for(auto c : range(channels)) { sample[c] = new double[65536](); } } - inline double& read(unsigned channel, signed offset = 0) { - return sample[channel][(uint16_t)(rdoffset + offset)]; + inline auto read(uint channel, int offset = 0) -> double& { + return sample[channel][(uint16)(rdoffset + offset)]; } - inline double& write(unsigned channel, signed offset = 0) { - return sample[channel][(uint16_t)(wroffset + offset)]; + inline auto write(uint channel, int offset = 0) -> double& { + return sample[channel][(uint16)(wroffset + offset)]; } - inline void clear() { - for(unsigned c = 0; c < channels; c++) { - for(unsigned n = 0; n < 65536; n++) { + inline auto clear() -> void { + for(auto c : range(channels)) { + for(auto n : range(65536)) { sample[c][n] = 0; } } @@ -41,12 +43,10 @@ struct Buffer { wroffset = 0; } - Buffer() { - } - - ~Buffer() { - setChannels(0); - } + double** sample = nullptr; + uint16 rdoffset = 0; + uint16 wroffset = 0; + uint channels = 0; }; #endif diff --git a/nall/dsp/core.hpp b/nall/dsp/core.hpp index 9a00f630..73aa89a3 100644 --- a/nall/dsp/core.hpp +++ b/nall/dsp/core.hpp @@ -6,24 +6,22 @@ namespace nall { -//precision: can be float, double or long double -#define real float - struct DSP; struct Resampler { - DSP& dsp; - real frequency; - - virtual void setFrequency() = 0; - virtual void clear() = 0; - virtual void sample() = 0; Resampler(DSP& dsp) : dsp(dsp) {} virtual ~Resampler() {} + + virtual auto setFrequency() -> void = 0; + virtual auto clear() -> void = 0; + virtual auto sample() -> void = 0; + + DSP& dsp; + double frequency = 44100.0; }; struct DSP { - enum class ResampleEngine : unsigned { + enum class ResampleEngine : uint { Nearest, Linear, Cosine, @@ -33,24 +31,48 @@ struct DSP { Sinc, }; - inline void setChannels(unsigned channels); - inline void setPrecision(unsigned precision); - inline void setFrequency(real frequency); //inputFrequency - inline void setVolume(real volume); - inline void setBalance(real balance); - - inline void setResampler(ResampleEngine resamplingEngine); - inline void setResamplerFrequency(real frequency); //outputFrequency - - inline void sample(signed channel[]); - inline bool pending(); - inline void read(signed channel[]); - - inline void clear(); inline DSP(); inline ~DSP(); + inline auto setChannels(uint channels) -> void; + inline auto setPrecision(uint precision) -> void; + inline auto setFrequency(double frequency) -> void; //inputFrequency + inline auto setVolume(double volume) -> void; + inline auto setBalance(double balance) -> void; + + inline auto setResampler(ResampleEngine resamplingEngine) -> void; + inline auto setResamplerFrequency(double frequency) -> void; //outputFrequency + + inline auto sample(int channel[]) -> void; + inline auto pending() const -> bool; + inline auto read(int channel[]) -> void; + + inline auto clear() -> void; + protected: + inline auto write(double channel[]) -> void; + inline auto adjustVolume() -> void; + inline auto adjustBalance() -> void; + inline auto clamp(const uint bits, const int input) -> int; + + struct Settings { + uint channels; + uint precision; + double frequency; + double volume; + double balance; + + //internal + double intensity; + double intensityInverse; + } settings; + + Resampler* resampler = nullptr; + + #include "buffer.hpp" + Buffer buffer; + Buffer output; + friend class ResampleNearest; friend class ResampleLinear; friend class ResampleCosine; @@ -58,29 +80,6 @@ protected: friend class ResampleAverage; friend class ResampleHermite; friend class ResampleSinc; - - struct Settings { - unsigned channels; - unsigned precision; - real frequency; - real volume; - real balance; - - //internal - real intensity; - real intensityInverse; - } settings; - - Resampler* resampler = nullptr; - inline void write(real channel[]); - - #include "buffer.hpp" - Buffer buffer; - Buffer output; - - inline void adjustVolume(); - inline void adjustBalance(); - inline signed clamp(const unsigned bits, const signed x); }; #include "resample/nearest.hpp" @@ -92,59 +91,6 @@ protected: #include "resample/sinc.hpp" #include "settings.hpp" -void DSP::sample(signed channel[]) { - for(unsigned c = 0; c < settings.channels; c++) { - buffer.write(c) = (real)channel[c] * settings.intensityInverse; - } - buffer.wroffset++; - resampler->sample(); -} - -bool DSP::pending() { - return output.rdoffset != output.wroffset; -} - -void DSP::read(signed channel[]) { - adjustVolume(); - adjustBalance(); - - for(unsigned c = 0; c < settings.channels; c++) { - channel[c] = clamp(settings.precision, output.read(c) * settings.intensity); - } - output.rdoffset++; -} - -void DSP::write(real channel[]) { - for(unsigned c = 0; c < settings.channels; c++) { - output.write(c) = channel[c]; - } - output.wroffset++; -} - -void DSP::adjustVolume() { - for(unsigned c = 0; c < settings.channels; c++) { - output.read(c) *= settings.volume; - } -} - -void DSP::adjustBalance() { - if(settings.channels != 2) return; //TODO: support > 2 channels - if(settings.balance < 0.0) output.read(1) *= 1.0 + settings.balance; - if(settings.balance > 0.0) output.read(0) *= 1.0 - settings.balance; -} - -signed DSP::clamp(const unsigned bits, const signed x) { - const signed b = 1U << (bits - 1); - const signed m = (1U << (bits - 1)) - 1; - return (x > m) ? m : (x < -b) ? -b : x; -} - -void DSP::clear() { - buffer.clear(); - output.clear(); - resampler->clear(); -} - DSP::DSP() { setResampler(ResampleEngine::Hermite); setResamplerFrequency(44100.0); @@ -162,7 +108,58 @@ DSP::~DSP() { if(resampler) delete resampler; } -#undef real +auto DSP::sample(int channel[]) -> void { + for(auto c : range(settings.channels)) { + buffer.write(c) = (double)channel[c] * settings.intensityInverse; + } + buffer.wroffset++; + resampler->sample(); +} + +auto DSP::pending() const -> bool { + return output.rdoffset != output.wroffset; +} + +auto DSP::read(int channel[]) -> void { + adjustVolume(); + adjustBalance(); + + for(auto c : range(settings.channels)) { + channel[c] = clamp(settings.precision, output.read(c) * settings.intensity); + } + output.rdoffset++; +} + +auto DSP::write(double channel[]) -> void { + for(auto c : range(settings.channels)) { + output.write(c) = channel[c]; + } + output.wroffset++; +} + +auto DSP::adjustVolume() -> void { + for(auto c : range(settings.channels)) { + output.read(c) *= settings.volume; + } +} + +auto DSP::adjustBalance() -> void { + if(settings.channels != 2) return; //TODO: support > 2 channels + if(settings.balance < 0.0) output.read(1) *= 1.0 + settings.balance; + if(settings.balance > 0.0) output.read(0) *= 1.0 - settings.balance; +} + +auto DSP::clamp(const uint bits, const int x) -> int { + const int b = 1U << (bits - 1); + const int m = (1U << (bits - 1)) - 1; + return (x > m) ? m : (x < -b) ? -b : x; +} + +auto DSP::clear() -> void { + buffer.clear(); + output.clear(); + resampler->clear(); +} } diff --git a/nall/dsp/resample/average.hpp b/nall/dsp/resample/average.hpp index db3b29f6..2051fe8c 100644 --- a/nall/dsp/resample/average.hpp +++ b/nall/dsp/resample/average.hpp @@ -1,46 +1,48 @@ #ifdef NALL_DSP_INTERNAL_HPP struct ResampleAverage : Resampler { - inline void setFrequency(); - inline void clear(); - inline void sample(); - inline void sampleLinear(); ResampleAverage(DSP& dsp) : Resampler(dsp) {} - real fraction; - real step; + inline auto setFrequency() -> void; + inline auto clear() -> void; + inline auto sample() -> void; + inline auto sampleLinear() -> void; + +private: + double fraction; + double step; }; -void ResampleAverage::setFrequency() { +auto ResampleAverage::setFrequency() -> void { fraction = 0.0; step = dsp.settings.frequency / frequency; } -void ResampleAverage::clear() { +auto ResampleAverage::clear() -> void { fraction = 0.0; } -void ResampleAverage::sample() { +auto ResampleAverage::sample() -> void { //can only average if input frequency >= output frequency if(step < 1.0) return sampleLinear(); fraction += 1.0; - real scalar = 1.0; + double scalar = 1.0; if(fraction > step) scalar = 1.0 - (fraction - step); - for(unsigned c = 0; c < dsp.settings.channels; c++) { + for(auto c : range(dsp.settings.channels)) { dsp.output.write(c) += dsp.buffer.read(c) * scalar; } if(fraction >= step) { - for(unsigned c = 0; c < dsp.settings.channels; c++) { + for(auto c : range(dsp.settings.channels)) { dsp.output.write(c) /= step; } dsp.output.wroffset++; fraction -= step; - for(unsigned c = 0; c < dsp.settings.channels; c++) { + for(auto c : range(dsp.settings.channels)) { dsp.output.write(c) = dsp.buffer.read(c) * fraction; } } @@ -48,15 +50,15 @@ void ResampleAverage::sample() { dsp.buffer.rdoffset++; } -void ResampleAverage::sampleLinear() { +auto ResampleAverage::sampleLinear() -> void { while(fraction <= 1.0) { - real channel[dsp.settings.channels]; + double channel[dsp.settings.channels]; - for(unsigned n = 0; n < dsp.settings.channels; n++) { - real a = dsp.buffer.read(n, -1); - real b = dsp.buffer.read(n, -0); + for(auto n : range(dsp.settings.channels)) { + double a = dsp.buffer.read(n, -1); + double b = dsp.buffer.read(n, -0); - real mu = fraction; + double mu = fraction; channel[n] = a * (1.0 - mu) + b * mu; } diff --git a/nall/dsp/resample/cosine.hpp b/nall/dsp/resample/cosine.hpp index ea65afdb..40665284 100644 --- a/nall/dsp/resample/cosine.hpp +++ b/nall/dsp/resample/cosine.hpp @@ -1,33 +1,35 @@ #ifdef NALL_DSP_INTERNAL_HPP struct ResampleCosine : Resampler { - inline void setFrequency(); - inline void clear(); - inline void sample(); ResampleCosine(DSP& dsp) : Resampler(dsp) {} - real fraction; - real step; + inline auto setFrequency() -> void; + inline auto clear() -> void; + inline auto sample() -> void; + +private: + double fraction; + double step; }; -void ResampleCosine::setFrequency() { +auto ResampleCosine::setFrequency() -> void { fraction = 0.0; step = dsp.settings.frequency / frequency; } -void ResampleCosine::clear() { +auto ResampleCosine::clear() -> void { fraction = 0.0; } -void ResampleCosine::sample() { +auto ResampleCosine::sample() -> void { while(fraction <= 1.0) { - real channel[dsp.settings.channels]; + double channel[dsp.settings.channels]; - for(unsigned n = 0; n < dsp.settings.channels; n++) { - real a = dsp.buffer.read(n, -1); - real b = dsp.buffer.read(n, -0); + for(auto n : range(dsp.settings.channels)) { + double a = dsp.buffer.read(n, -1); + double b = dsp.buffer.read(n, -0); - real mu = fraction; + double mu = fraction; mu = (1.0 - cos(mu * 3.14159265)) / 2.0; channel[n] = a * (1.0 - mu) + b * mu; diff --git a/nall/dsp/resample/cubic.hpp b/nall/dsp/resample/cubic.hpp index 6265e2a4..90039e71 100644 --- a/nall/dsp/resample/cubic.hpp +++ b/nall/dsp/resample/cubic.hpp @@ -1,40 +1,42 @@ #ifdef NALL_DSP_INTERNAL_HPP struct ResampleCubic : Resampler { - inline void setFrequency(); - inline void clear(); - inline void sample(); ResampleCubic(DSP& dsp) : Resampler(dsp) {} - real fraction; - real step; + inline auto setFrequency() -> void; + inline auto clear() -> void; + inline auto sample() -> void; + +private: + double fraction; + double step; }; -void ResampleCubic::setFrequency() { +auto ResampleCubic::setFrequency() -> void { fraction = 0.0; step = dsp.settings.frequency / frequency; } -void ResampleCubic::clear() { +auto ResampleCubic::clear() -> void { fraction = 0.0; } -void ResampleCubic::sample() { +auto ResampleCubic::sample() -> void { while(fraction <= 1.0) { - real channel[dsp.settings.channels]; + double channel[dsp.settings.channels]; - for(unsigned n = 0; n < dsp.settings.channels; n++) { - real a = dsp.buffer.read(n, -3); - real b = dsp.buffer.read(n, -2); - real c = dsp.buffer.read(n, -1); - real d = dsp.buffer.read(n, -0); + for(auto n : range(dsp.settings.channels)) { + double a = dsp.buffer.read(n, -3); + double b = dsp.buffer.read(n, -2); + double c = dsp.buffer.read(n, -1); + double d = dsp.buffer.read(n, -0); - real mu = fraction; + double mu = fraction; - real A = d - c - a + b; - real B = a - b - A; - real C = c - a; - real D = b; + double A = d - c - a + b; + double B = a - b - A; + double C = c - a; + double D = b; channel[n] = A * (mu * 3) + B * (mu * 2) + C * mu + D; } diff --git a/nall/dsp/resample/hermite.hpp b/nall/dsp/resample/hermite.hpp index 04c850c1..0a79bf4f 100644 --- a/nall/dsp/resample/hermite.hpp +++ b/nall/dsp/resample/hermite.hpp @@ -1,38 +1,40 @@ #ifdef NALL_DSP_INTERNAL_HPP struct ResampleHermite : Resampler { - inline void setFrequency(); - inline void clear(); - inline void sample(); ResampleHermite(DSP& dsp) : Resampler(dsp) {} - real fraction; - real step; + inline auto setFrequency() -> void; + inline auto clear() -> void; + inline auto sample() -> void; + +private: + double fraction; + double step; }; -void ResampleHermite::setFrequency() { +auto ResampleHermite::setFrequency() -> void { fraction = 0.0; step = dsp.settings.frequency / frequency; } -void ResampleHermite::clear() { +auto ResampleHermite::clear() -> void { fraction = 0.0; } -void ResampleHermite::sample() { +auto ResampleHermite::sample() -> void { while(fraction <= 1.0) { - real channel[dsp.settings.channels]; + double channel[dsp.settings.channels]; - for(unsigned n = 0; n < dsp.settings.channels; n++) { - real a = dsp.buffer.read(n, -3); - real b = dsp.buffer.read(n, -2); - real c = dsp.buffer.read(n, -1); - real d = dsp.buffer.read(n, -0); + for(auto n : range(dsp.settings.channels)) { + double a = dsp.buffer.read(n, -3); + double b = dsp.buffer.read(n, -2); + double c = dsp.buffer.read(n, -1); + double d = dsp.buffer.read(n, -0); - const real tension = 0.0; //-1 = low, 0 = normal, +1 = high - const real bias = 0.0; //-1 = left, 0 = even, +1 = right + const double tension = 0.0; //-1 = low, 0 = normal, +1 = high + const double bias = 0.0; //-1 = left, 0 = even, +1 = right - real mu1, mu2, mu3, m0, m1, a0, a1, a2, a3; + double mu1, mu2, mu3, m0, m1, a0, a1, a2, a3; mu1 = fraction; mu2 = mu1 * mu1; diff --git a/nall/dsp/resample/linear.hpp b/nall/dsp/resample/linear.hpp index e302b5a3..03f010c6 100644 --- a/nall/dsp/resample/linear.hpp +++ b/nall/dsp/resample/linear.hpp @@ -1,33 +1,35 @@ #ifdef NALL_DSP_INTERNAL_HPP struct ResampleLinear : Resampler { - inline void setFrequency(); - inline void clear(); - inline void sample(); ResampleLinear(DSP& dsp) : Resampler(dsp) {} - real fraction; - real step; + inline auto setFrequency() -> void; + inline auto clear() -> void; + inline auto sample() -> void; + +private: + double fraction; + double step; }; -void ResampleLinear::setFrequency() { +auto ResampleLinear::setFrequency() -> void { fraction = 0.0; step = dsp.settings.frequency / frequency; } -void ResampleLinear::clear() { +auto ResampleLinear::clear() -> void { fraction = 0.0; } -void ResampleLinear::sample() { +auto ResampleLinear::sample() -> void { while(fraction <= 1.0) { - real channel[dsp.settings.channels]; + double channel[dsp.settings.channels]; - for(unsigned n = 0; n < dsp.settings.channels; n++) { - real a = dsp.buffer.read(n, -1); - real b = dsp.buffer.read(n, -0); + for(auto n : range(dsp.settings.channels)) { + double a = dsp.buffer.read(n, -1); + double b = dsp.buffer.read(n, -0); - real mu = fraction; + double mu = fraction; channel[n] = a * (1.0 - mu) + b * mu; } diff --git a/nall/dsp/resample/nearest.hpp b/nall/dsp/resample/nearest.hpp index 51b261b1..a110679e 100644 --- a/nall/dsp/resample/nearest.hpp +++ b/nall/dsp/resample/nearest.hpp @@ -1,33 +1,35 @@ #ifdef NALL_DSP_INTERNAL_HPP struct ResampleNearest : Resampler { - inline void setFrequency(); - inline void clear(); - inline void sample(); ResampleNearest(DSP& dsp) : Resampler(dsp) {} - real fraction; - real step; + inline auto setFrequency() -> void; + inline auto clear() -> void; + inline auto sample() -> void; + +private: + double fraction; + double step; }; -void ResampleNearest::setFrequency() { +auto ResampleNearest::setFrequency() -> void { fraction = 0.0; step = dsp.settings.frequency / frequency; } -void ResampleNearest::clear() { +auto ResampleNearest::clear() -> void { fraction = 0.0; } -void ResampleNearest::sample() { +auto ResampleNearest::sample() -> void { while(fraction <= 1.0) { - real channel[dsp.settings.channels]; + double channel[dsp.settings.channels]; - for(unsigned n = 0; n < dsp.settings.channels; n++) { - real a = dsp.buffer.read(n, -1); - real b = dsp.buffer.read(n, -0); + for(auto n : range(dsp.settings.channels)) { + double a = dsp.buffer.read(n, -1); + double b = dsp.buffer.read(n, -0); - real mu = fraction; + double mu = fraction; channel[n] = mu < 0.5 ? a : b; } diff --git a/nall/dsp/resample/sinc.hpp b/nall/dsp/resample/sinc.hpp index e23e458c..65ca10f3 100644 --- a/nall/dsp/resample/sinc.hpp +++ b/nall/dsp/resample/sinc.hpp @@ -3,51 +3,61 @@ #include "lib/sinc.hpp" struct ResampleSinc : Resampler { - inline void setFrequency(); - inline void clear(); - inline void sample(); inline ResampleSinc(DSP& dsp); + inline ~ResampleSinc(); + + inline auto setFrequency() -> void; + inline auto clear() -> void; + inline auto sample() -> void; private: inline void remakeSinc(); - SincResample* sinc_resampler[8]; + SincResample* sincResampler[8] = {0}; }; -void ResampleSinc::setFrequency() { +ResampleSinc::ResampleSinc(DSP& dsp) : Resampler(dsp) { + for(auto n : range(8)) { + sincResampler[n] = nullptr; + } +} + +ResampleSinc::~ResampleSinc() { + for(auto n : range(8)) { + if(sincResampler[n]) delete sincResampler[n]; + } +} + +auto ResampleSinc::setFrequency() -> void { remakeSinc(); } -void ResampleSinc::clear() { +auto ResampleSinc::clear() -> void { remakeSinc(); } -void ResampleSinc::sample() { - for(unsigned c = 0; c < dsp.settings.channels; c++) { - sinc_resampler[c]->write(dsp.buffer.read(c)); +auto ResampleSinc::sample() -> void { + for(auto c : range(dsp.settings.channels)) { + sincResampler[c]->write(dsp.buffer.read(c)); } - if(sinc_resampler[0]->output_avail()) { + if(sincResampler[0]->output_avail()) { do { - for(unsigned c = 0; c < dsp.settings.channels; c++) { - dsp.output.write(c) = sinc_resampler[c]->read(); + for(auto c : range(dsp.settings.channels)) { + dsp.output.write(c) = sincResampler[c]->read(); } dsp.output.wroffset++; - } while(sinc_resampler[0]->output_avail()); + } while(sincResampler[0]->output_avail()); } dsp.buffer.rdoffset++; } -ResampleSinc::ResampleSinc(DSP& dsp) : Resampler(dsp) { - for(unsigned n = 0; n < 8; n++) sinc_resampler[n] = nullptr; -} - -void ResampleSinc::remakeSinc() { +auto ResampleSinc::remakeSinc() -> void { assert(dsp.settings.channels < 8); - for(unsigned c = 0; c < dsp.settings.channels; c++) { - if(sinc_resampler[c]) delete sinc_resampler[c]; - sinc_resampler[c] = new SincResample(dsp.settings.frequency, frequency, 0.85, SincResample::QUALITY_HIGH); + for(auto c : range(dsp.settings.channels)) { + if(sincResampler[c]) delete sincResampler[c]; + sincResampler[c] = new SincResample(dsp.settings.frequency, frequency, 0.85, SincResample::QUALITY_HIGH); } } diff --git a/nall/dsp/settings.hpp b/nall/dsp/settings.hpp index 3a8f24c6..a7b766dd 100644 --- a/nall/dsp/settings.hpp +++ b/nall/dsp/settings.hpp @@ -1,35 +1,35 @@ #ifdef NALL_DSP_INTERNAL_HPP -void DSP::setChannels(unsigned channels) { - assert(channels > 0); +auto DSP::setChannels(uint channels) -> void { + channels = max(1u, channels); buffer.setChannels(channels); output.setChannels(channels); settings.channels = channels; } -void DSP::setPrecision(unsigned precision) { +auto DSP::setPrecision(uint precision) -> void { settings.precision = precision; settings.intensity = 1 << (settings.precision - 1); settings.intensityInverse = 1.0 / settings.intensity; } -void DSP::setFrequency(real frequency) { +auto DSP::setFrequency(double frequency) -> void { settings.frequency = frequency; resampler->setFrequency(); } -void DSP::setVolume(real volume) { +auto DSP::setVolume(double volume) -> void { settings.volume = volume; } -void DSP::setBalance(real balance) { +auto DSP::setBalance(double balance) -> void { settings.balance = balance; } -void DSP::setResampler(ResampleEngine engine) { +auto DSP::setResampler(ResampleEngine engine) -> void { if(resampler) delete resampler; - switch(engine) { + switch(engine) { default: case ResampleEngine::Nearest: resampler = new ResampleNearest(*this); return; case ResampleEngine::Linear: resampler = new ResampleLinear (*this); return; case ResampleEngine::Cosine: resampler = new ResampleCosine (*this); return; @@ -38,11 +38,9 @@ void DSP::setResampler(ResampleEngine engine) { case ResampleEngine::Average: resampler = new ResampleAverage(*this); return; case ResampleEngine::Sinc: resampler = new ResampleSinc (*this); return; } - - throw; } -void DSP::setResamplerFrequency(real frequency) { +auto DSP::setResamplerFrequency(double frequency) -> void { resampler->frequency = frequency; resampler->setFrequency(); } diff --git a/processor/hg51b/hg51b.cpp b/processor/hg51b/hg51b.cpp index aaa5838b..7fc40baa 100644 --- a/processor/hg51b/hg51b.cpp +++ b/processor/hg51b/hg51b.cpp @@ -7,7 +7,7 @@ namespace Processor { #include "instructions.cpp" #include "serialization.cpp" -void HG51B::exec(uint24 addr) { +auto HG51B::exec(uint24 addr) -> void { if(regs.halt) return; addr = addr + regs.pc * 2; opcode = bus_read(addr++) << 0; @@ -16,7 +16,7 @@ void HG51B::exec(uint24 addr) { instruction(); } -void HG51B::power() { +auto HG51B::power() -> void { regs.halt = true; regs.n = 0; diff --git a/processor/hg51b/hg51b.hpp b/processor/hg51b/hg51b.hpp index 76b9a027..7b13807f 100644 --- a/processor/hg51b/hg51b.hpp +++ b/processor/hg51b/hg51b.hpp @@ -1,29 +1,56 @@ +//Hitachi HG51B169 (HG51BS family/derivative?) + #ifndef PROCESSOR_HG51B_HPP #define PROCESSOR_HG51B_HPP namespace Processor { -//Hitachi HG51B169 (HG51BS family/derivative?) - struct HG51B { + auto exec(uint24 addr) -> void; + virtual auto bus_read(uint24 addr) -> uint8 = 0; + virtual auto bus_write(uint24 addr, uint8 data) -> void = 0; + + auto power() -> void; + auto serialize(serializer&) -> void; + //uint16 programROM[2][256]; uint24 dataROM[1024]; uint8 dataRAM[3072]; - #include "registers.hpp" - void exec(uint24 addr); - virtual uint8 bus_read(uint24 addr) = 0; - virtual void bus_write(uint24 addr, uint8 data) = 0; - - void power(); - void serialize(serializer&); protected: - void push(); - void pull(); - unsigned sa(); - unsigned ri(); - unsigned np(); - void instruction(); + auto push() -> void; + auto pull() -> void; + auto sa() -> uint; + auto ri() -> uint; + auto np() -> uint; + auto instruction() -> void; + + //registers.cpp + auto reg_read(uint8 addr) const -> uint24; + auto reg_write(uint8 addr, uint24 data) -> void; + + struct Registers { + bool halt; + + uint24 pc; + uint16 p; + bool n; + bool z; + bool c; + + uint24 a; + uint24 acch; + uint24 accl; + uint24 busdata; + uint24 romdata; + uint24 ramdata; + uint24 busaddr; + uint24 ramaddr; + uint24 gpr[16]; + } regs; + + uint24 stack[8]; + uint16 opcode; }; } diff --git a/processor/hg51b/instructions.cpp b/processor/hg51b/instructions.cpp index ac9c3bb6..05d492d3 100644 --- a/processor/hg51b/instructions.cpp +++ b/processor/hg51b/instructions.cpp @@ -1,6 +1,6 @@ #ifdef PROCESSOR_HG51B_HPP -void HG51B::push() { +auto HG51B::push() -> void { stack[7] = stack[6]; stack[6] = stack[5]; stack[5] = stack[4]; @@ -11,7 +11,7 @@ void HG51B::push() { stack[0] = regs.pc; } -void HG51B::pull() { +auto HG51B::pull() -> void { regs.pc = stack[0]; stack[0] = stack[1]; stack[1] = stack[2]; @@ -24,7 +24,7 @@ void HG51B::pull() { } //Shift-A: math opcodes can shift A register prior to ALU operation -unsigned HG51B::sa() { +auto HG51B::sa() -> uint { switch(opcode & 0x0300) { default: case 0x0000: return regs.a << 0; case 0x0100: return regs.a << 1; @@ -34,18 +34,18 @@ unsigned HG51B::sa() { } //Register-or-Immediate: most opcodes can load from a register or immediate -unsigned HG51B::ri() { +auto HG51B::ri() -> uint { if(opcode & 0x0400) return opcode & 0xff; return reg_read(opcode & 0xff); } //New-PC: determine jump target address; opcode.d9 = long jump flag (1 = yes) -unsigned HG51B::np() { +auto HG51B::np() -> uint { if(opcode & 0x0200) return (regs.p << 8) | (opcode & 0xff); return (regs.pc & 0xffff00) | (opcode & 0xff); } -void HG51B::instruction() { +auto HG51B::instruction() -> void { if((opcode & 0xffff) == 0x0000) { //0000 0000 0000 0000 //nop diff --git a/processor/hg51b/registers.cpp b/processor/hg51b/registers.cpp index 597ef504..d4521a50 100644 --- a/processor/hg51b/registers.cpp +++ b/processor/hg51b/registers.cpp @@ -1,6 +1,6 @@ #ifdef PROCESSOR_HG51B_HPP -uint24 HG51B::reg_read(uint8 addr) const { +auto HG51B::reg_read(uint8 addr) const -> uint24 { switch(addr) { case 0x00: return regs.a; case 0x01: return regs.acch; @@ -46,7 +46,7 @@ uint24 HG51B::reg_read(uint8 addr) const { return 0x000000; } -void HG51B::reg_write(uint8 addr, uint24 data) { +auto HG51B::reg_write(uint8 addr, uint24 data) -> void { switch(addr) { case 0x00: regs.a = data; return; case 0x01: regs.acch = data; return; diff --git a/processor/hg51b/registers.hpp b/processor/hg51b/registers.hpp deleted file mode 100644 index 123660ee..00000000 --- a/processor/hg51b/registers.hpp +++ /dev/null @@ -1,25 +0,0 @@ -struct Registers { - bool halt; - - uint24 pc; - uint16 p; - bool n; - bool z; - bool c; - - uint24 a; - uint24 acch; - uint24 accl; - uint24 busdata; - uint24 romdata; - uint24 ramdata; - uint24 busaddr; - uint24 ramaddr; - uint24 gpr[16]; -} regs; - -uint24 stack[8]; -uint16 opcode; - -uint24 reg_read(uint8 addr) const; -void reg_write(uint8 addr, uint24 data); diff --git a/processor/hg51b/serialization.cpp b/processor/hg51b/serialization.cpp index 945c55bf..6b1c6579 100644 --- a/processor/hg51b/serialization.cpp +++ b/processor/hg51b/serialization.cpp @@ -1,6 +1,6 @@ #ifdef PROCESSOR_HG51B_HPP -void HG51B::serialize(serializer& s) { +auto HG51B::serialize(serializer& s) -> void { s.array(dataRAM); for(auto& n : stack) s.integer(n); s.integer(opcode); diff --git a/processor/lr35902/disassembler.cpp b/processor/lr35902/disassembler.cpp index e64a7e30..c4286a3a 100644 --- a/processor/lr35902/disassembler.cpp +++ b/processor/lr35902/disassembler.cpp @@ -1,9 +1,9 @@ -string LR35902::disassemble(uint16 pc) { +auto LR35902::disassemble(uint16 pc) -> string { char output[80]; memset(output, ' ', sizeof output); output[79] = 0; - string opcode = disassemble_opcode(pc); + string opcode = disassembleOpcode(pc); string registers = { " AF:", hex(r[AF], 4L), " BC:", hex(r[BC], 4L), @@ -19,7 +19,7 @@ string LR35902::disassemble(uint16 pc) { return output; } -string LR35902::disassemble_opcode(uint16 pc) { +auto LR35902::disassembleOpcode(uint16 pc) -> string { uint8 opcode = debugger_read(pc); uint8 p0 = debugger_read(pc + 1); uint8 p1 = debugger_read(pc + 2); @@ -229,7 +229,7 @@ string LR35902::disassemble_opcode(uint16 pc) { case 0xc8: return { "ret z" }; case 0xc9: return { "ret" }; case 0xca: return { "jp z,$", hex(p1, 2L), hex(p0, 2L) }; - case 0xcb: return disassemble_opcode_cb(pc + 1); + case 0xcb: return disassembleOpcodeCB(pc + 1); case 0xcc: return { "call z,$", hex(p1, 2L), hex(p0, 2L) }; case 0xcd: return { "call $", hex(p1, 2L), hex(p0, 2L) }; case 0xce: return { "adc a,$", hex(p0, 2L) }; @@ -287,7 +287,7 @@ string LR35902::disassemble_opcode(uint16 pc) { return ""; } -string LR35902::disassemble_opcode_cb(uint16 pc) { +auto LR35902::disassembleOpcodeCB(uint16 pc) -> string { uint8 opcode = debugger_read(pc); uint8 p0 = debugger_read(pc + 1); uint8 p1 = debugger_read(pc + 2); diff --git a/processor/lr35902/instructions.cpp b/processor/lr35902/instructions.cpp index 6dd8e683..5760aae3 100644 --- a/processor/lr35902/instructions.cpp +++ b/processor/lr35902/instructions.cpp @@ -1,121 +1,121 @@ -void LR35902::op_xx() { +auto LR35902::op_xx() { } -void LR35902::op_cb() { - exec_cb(); +auto LR35902::op_cb() { + execCB(); } //8-bit load commands -template void LR35902::op_ld_r_r() { +template auto LR35902::op_ld_r_r() { r[x] = r[y]; } -template void LR35902::op_ld_r_n() { +template auto LR35902::op_ld_r_n() { r[x] = op_read(r[PC]++); } -template void LR35902::op_ld_r_hl() { +template auto LR35902::op_ld_r_hl() { r[x] = op_read(r[HL]); } -template void LR35902::op_ld_hl_r() { +template auto LR35902::op_ld_hl_r() { op_write(r[HL], r[x]); } -void LR35902::op_ld_hl_n() { +auto LR35902::op_ld_hl_n() { op_write(r[HL], op_read(r[PC]++)); } -template void LR35902::op_ld_a_rr() { +template auto LR35902::op_ld_a_rr() { r[A] = op_read(r[x]); } -void LR35902::op_ld_a_nn() { +auto LR35902::op_ld_a_nn() { uint8 lo = op_read(r[PC]++); uint8 hi = op_read(r[PC]++); r[A] = op_read((hi << 8) | (lo << 0)); } -template void LR35902::op_ld_rr_a() { +template auto LR35902::op_ld_rr_a() { op_write(r[x], r[A]); } -void LR35902::op_ld_nn_a() { +auto LR35902::op_ld_nn_a() { uint8 lo = op_read(r[PC]++); uint8 hi = op_read(r[PC]++); op_write((hi << 8) | (lo << 0), r[A]); } -void LR35902::op_ld_a_ffn() { +auto LR35902::op_ld_a_ffn() { r[A] = op_read(0xff00 + op_read(r[PC]++)); } -void LR35902::op_ld_ffn_a() { +auto LR35902::op_ld_ffn_a() { op_write(0xff00 + op_read(r[PC]++), r[A]); } -void LR35902::op_ld_a_ffc() { +auto LR35902::op_ld_a_ffc() { r[A] = op_read(0xff00 + r[C]); } -void LR35902::op_ld_ffc_a() { +auto LR35902::op_ld_ffc_a() { op_write(0xff00 + r[C], r[A]); } -void LR35902::op_ldi_hl_a() { +auto LR35902::op_ldi_hl_a() { op_write(r[HL], r[A]); r[HL]++; } -void LR35902::op_ldi_a_hl() { +auto LR35902::op_ldi_a_hl() { r[A] = op_read(r[HL]); r[HL]++; } -void LR35902::op_ldd_hl_a() { +auto LR35902::op_ldd_hl_a() { op_write(r[HL], r[A]); r[HL]--; } -void LR35902::op_ldd_a_hl() { +auto LR35902::op_ldd_a_hl() { r[A] = op_read(r[HL]); r[HL]--; } //16-bit load commands -template void LR35902::op_ld_rr_nn() { +template auto LR35902::op_ld_rr_nn() { r[x] = op_read(r[PC]++) << 0; r[x] |= op_read(r[PC]++) << 8; } -void LR35902::op_ld_nn_sp() { +auto LR35902::op_ld_nn_sp() { uint16 addr = op_read(r[PC]++) << 0; addr |= op_read(r[PC]++) << 8; op_write(addr + 0, r[SP] >> 0); op_write(addr + 1, r[SP] >> 8); } -void LR35902::op_ld_sp_hl() { +auto LR35902::op_ld_sp_hl() { r[SP] = r[HL]; op_io(); } -template void LR35902::op_push_rr() { +template auto LR35902::op_push_rr() { op_write(--r[SP], r[x] >> 8); op_write(--r[SP], r[x] >> 0); op_io(); } -template void LR35902::op_pop_rr() { +template auto LR35902::op_pop_rr() { r[x] = op_read(r[SP]++) << 0; r[x] |= op_read(r[SP]++) << 8; } //8-bit arithmetic commands -void LR35902::opi_add_a(uint8 x) { +auto LR35902::opi_add_a(uint8 x) { uint16 rh = r[A] + x; uint16 rl = (r[A] & 0x0f) + (x & 0x0f); r[A] = rh; @@ -125,11 +125,11 @@ void LR35902::opi_add_a(uint8 x) { r.f.c = rh > 0xff; } -template void LR35902::op_add_a_r() { opi_add_a(r[x]); } -void LR35902::op_add_a_n() { opi_add_a(op_read(r[PC]++)); } -void LR35902::op_add_a_hl() { opi_add_a(op_read(r[HL])); } +template auto LR35902::op_add_a_r() { opi_add_a(r[x]); } +auto LR35902::op_add_a_n() { opi_add_a(op_read(r[PC]++)); } +auto LR35902::op_add_a_hl() { opi_add_a(op_read(r[HL])); } -void LR35902::opi_adc_a(uint8 x) { +auto LR35902::opi_adc_a(uint8 x) { uint16 rh = r[A] + x + r.f.c; uint16 rl = (r[A] & 0x0f) + (x & 0x0f) + r.f.c; r[A] = rh; @@ -139,11 +139,11 @@ void LR35902::opi_adc_a(uint8 x) { r.f.c = rh > 0xff; } -template void LR35902::op_adc_a_r() { opi_adc_a(r[x]); } -void LR35902::op_adc_a_n() { opi_adc_a(op_read(r[PC]++)); } -void LR35902::op_adc_a_hl() { opi_adc_a(op_read(r[HL])); } +template auto LR35902::op_adc_a_r() { opi_adc_a(r[x]); } +auto LR35902::op_adc_a_n() { opi_adc_a(op_read(r[PC]++)); } +auto LR35902::op_adc_a_hl() { opi_adc_a(op_read(r[HL])); } -void LR35902::opi_sub_a(uint8 x) { +auto LR35902::opi_sub_a(uint8 x) { uint16 rh = r[A] - x; uint16 rl = (r[A] & 0x0f) - (x & 0x0f); r[A] = rh; @@ -153,11 +153,11 @@ void LR35902::opi_sub_a(uint8 x) { r.f.c = rh > 0xff; } -template void LR35902::op_sub_a_r() { opi_sub_a(r[x]); } -void LR35902::op_sub_a_n() { opi_sub_a(op_read(r[PC]++)); } -void LR35902::op_sub_a_hl() { opi_sub_a(op_read(r[HL])); } +template auto LR35902::op_sub_a_r() { opi_sub_a(r[x]); } +auto LR35902::op_sub_a_n() { opi_sub_a(op_read(r[PC]++)); } +auto LR35902::op_sub_a_hl() { opi_sub_a(op_read(r[HL])); } -void LR35902::opi_sbc_a(uint8 x) { +auto LR35902::opi_sbc_a(uint8 x) { uint16 rh = r[A] - x - r.f.c; uint16 rl = (r[A] & 0x0f) - (x & 0x0f) - r.f.c; r[A] = rh; @@ -167,11 +167,11 @@ void LR35902::opi_sbc_a(uint8 x) { r.f.c = rh > 0xff; } -template void LR35902::op_sbc_a_r() { opi_sbc_a(r[x]); } -void LR35902::op_sbc_a_n() { opi_sbc_a(op_read(r[PC]++)); } -void LR35902::op_sbc_a_hl() { opi_sbc_a(op_read(r[HL])); } +template auto LR35902::op_sbc_a_r() { opi_sbc_a(r[x]); } +auto LR35902::op_sbc_a_n() { opi_sbc_a(op_read(r[PC]++)); } +auto LR35902::op_sbc_a_hl() { opi_sbc_a(op_read(r[HL])); } -void LR35902::opi_and_a(uint8 x) { +auto LR35902::opi_and_a(uint8 x) { r[A] &= x; r.f.z = r[A] == 0; r.f.n = 0; @@ -179,11 +179,11 @@ void LR35902::opi_and_a(uint8 x) { r.f.c = 0; } -template void LR35902::op_and_a_r() { opi_and_a(r[x]); } -void LR35902::op_and_a_n() { opi_and_a(op_read(r[PC]++)); } -void LR35902::op_and_a_hl() { opi_and_a(op_read(r[HL])); } +template auto LR35902::op_and_a_r() { opi_and_a(r[x]); } +auto LR35902::op_and_a_n() { opi_and_a(op_read(r[PC]++)); } +auto LR35902::op_and_a_hl() { opi_and_a(op_read(r[HL])); } -void LR35902::opi_xor_a(uint8 x) { +auto LR35902::opi_xor_a(uint8 x) { r[A] ^= x; r.f.z = r[A] == 0; r.f.n = 0; @@ -191,11 +191,11 @@ void LR35902::opi_xor_a(uint8 x) { r.f.c = 0; } -template void LR35902::op_xor_a_r() { opi_xor_a(r[x]); } -void LR35902::op_xor_a_n() { opi_xor_a(op_read(r[PC]++)); } -void LR35902::op_xor_a_hl() { opi_xor_a(op_read(r[HL])); } +template auto LR35902::op_xor_a_r() { opi_xor_a(r[x]); } +auto LR35902::op_xor_a_n() { opi_xor_a(op_read(r[PC]++)); } +auto LR35902::op_xor_a_hl() { opi_xor_a(op_read(r[HL])); } -void LR35902::opi_or_a(uint8 x) { +auto LR35902::opi_or_a(uint8 x) { r[A] |= x; r.f.z = r[A] == 0; r.f.n = 0; @@ -203,11 +203,11 @@ void LR35902::opi_or_a(uint8 x) { r.f.c = 0; } -template void LR35902::op_or_a_r() { opi_or_a(r[x]); } -void LR35902::op_or_a_n() { opi_or_a(op_read(r[PC]++)); } -void LR35902::op_or_a_hl() { opi_or_a(op_read(r[HL])); } +template auto LR35902::op_or_a_r() { opi_or_a(r[x]); } +auto LR35902::op_or_a_n() { opi_or_a(op_read(r[PC]++)); } +auto LR35902::op_or_a_hl() { opi_or_a(op_read(r[HL])); } -void LR35902::opi_cp_a(uint8 x) { +auto LR35902::opi_cp_a(uint8 x) { uint16 rh = r[A] - x; uint16 rl = (r[A] & 0x0f) - (x & 0x0f); r.f.z = (uint8)rh == 0; @@ -216,18 +216,18 @@ void LR35902::opi_cp_a(uint8 x) { r.f.c = rh > 0xff; } -template void LR35902::op_cp_a_r() { opi_cp_a(r[x]); } -void LR35902::op_cp_a_n() { opi_cp_a(op_read(r[PC]++)); } -void LR35902::op_cp_a_hl() { opi_cp_a(op_read(r[HL])); } +template auto LR35902::op_cp_a_r() { opi_cp_a(r[x]); } +auto LR35902::op_cp_a_n() { opi_cp_a(op_read(r[PC]++)); } +auto LR35902::op_cp_a_hl() { opi_cp_a(op_read(r[HL])); } -template void LR35902::op_inc_r() { +template auto LR35902::op_inc_r() { r[x]++; r.f.z = r[x] == 0; r.f.n = 0; r.f.h = (r[x] & 0x0f) == 0x00; } -void LR35902::op_inc_hl() { +auto LR35902::op_inc_hl() { uint8 n = op_read(r[HL]); op_write(r[HL], ++n); r.f.z = n == 0; @@ -235,14 +235,14 @@ void LR35902::op_inc_hl() { r.f.h = (n & 0x0f) == 0x00; } -template void LR35902::op_dec_r() { +template auto LR35902::op_dec_r() { r[x]--; r.f.z = r[x] == 0; r.f.n = 1; r.f.h = (r[x] & 0x0f) == 0x0f; } -void LR35902::op_dec_hl() { +auto LR35902::op_dec_hl() { uint8 n = op_read(r[HL]); op_write(r[HL], --n); r.f.z = n == 0; @@ -250,7 +250,7 @@ void LR35902::op_dec_hl() { r.f.h = (n & 0x0f) == 0x0f; } -void LR35902::op_daa() { +auto LR35902::op_daa() { uint16 a = r[A]; if(r.f.n == 0) { if(r.f.h || (a & 0x0f) > 0x09) a += 0x06; @@ -268,7 +268,7 @@ void LR35902::op_daa() { r.f.c |= a & 0x100; } -void LR35902::op_cpl() { +auto LR35902::op_cpl() { r[A] ^= 0xff; r.f.n = 1; r.f.h = 1; @@ -276,7 +276,7 @@ void LR35902::op_cpl() { //16-bit arithmetic commands -template void LR35902::op_add_hl_rr() { +template auto LR35902::op_add_hl_rr() { op_io(); uint32 rb = (r[HL] + r[x]); uint32 rn = (r[HL] & 0xfff) + (r[x] & 0xfff); @@ -286,20 +286,20 @@ template void LR35902::op_add_hl_rr() { r.f.c = rb > 0xffff; } -template void LR35902::op_inc_rr() { +template auto LR35902::op_inc_rr() { op_io(); r[x]++; } -template void LR35902::op_dec_rr() { +template auto LR35902::op_dec_rr() { op_io(); r[x]--; } -void LR35902::op_add_sp_n() { +auto LR35902::op_add_sp_n() { op_io(); op_io(); - signed n = (int8)op_read(r[PC]++); + int n = (int8)op_read(r[PC]++); r.f.z = 0; r.f.n = 0; r.f.h = ((r[SP] & 0x0f) + (n & 0x0f)) > 0x0f; @@ -307,9 +307,9 @@ void LR35902::op_add_sp_n() { r[SP] += n; } -void LR35902::op_ld_hl_sp_n() { +auto LR35902::op_ld_hl_sp_n() { op_io(); - signed n = (int8)op_read(r[PC]++); + int n = (int8)op_read(r[PC]++); r.f.z = 0; r.f.n = 0; r.f.h = ((r[SP] & 0x0f) + (n & 0x0f)) > 0x0f; @@ -319,7 +319,7 @@ void LR35902::op_ld_hl_sp_n() { //rotate/shift commands -void LR35902::op_rlca() { +auto LR35902::op_rlca() { r[A] = (r[A] << 1) | (r[A] >> 7); r.f.z = 0; r.f.n = 0; @@ -327,7 +327,7 @@ void LR35902::op_rlca() { r.f.c = r[A] & 0x01; } -void LR35902::op_rla() { +auto LR35902::op_rla() { bool c = r[A] & 0x80; r[A] = (r[A] << 1) | (r.f.c << 0); r.f.z = 0; @@ -336,7 +336,7 @@ void LR35902::op_rla() { r.f.c = c; } -void LR35902::op_rrca() { +auto LR35902::op_rrca() { r[A] = (r[A] >> 1) | (r[A] << 7); r.f.z = 0; r.f.n = 0; @@ -344,7 +344,7 @@ void LR35902::op_rrca() { r.f.c = r[A] & 0x80; } -void LR35902::op_rra() { +auto LR35902::op_rra() { bool c = r[A] & 0x01; r[A] = (r[A] >> 1) | (r.f.c << 7); r.f.z = 0; @@ -353,7 +353,7 @@ void LR35902::op_rra() { r.f.c = c; } -template void LR35902::op_rlc_r() { +template auto LR35902::op_rlc_r() { r[x] = (r[x] << 1) | (r[x] >> 7); r.f.z = r[x] == 0; r.f.n = 0; @@ -361,7 +361,7 @@ template void LR35902::op_rlc_r() { r.f.c = r[x] & 0x01; } -void LR35902::op_rlc_hl() { +auto LR35902::op_rlc_hl() { uint8 n = op_read(r[HL]); n = (n << 1) | (n >> 7); op_write(r[HL], n); @@ -371,7 +371,7 @@ void LR35902::op_rlc_hl() { r.f.c = n & 0x01; } -template void LR35902::op_rl_r() { +template auto LR35902::op_rl_r() { bool c = r[x] & 0x80; r[x] = (r[x] << 1) | (r.f.c << 0); r.f.z = r[x] == 0; @@ -380,7 +380,7 @@ template void LR35902::op_rl_r() { r.f.c = c; } -void LR35902::op_rl_hl() { +auto LR35902::op_rl_hl() { uint8 n = op_read(r[HL]); bool c = n & 0x80; n = (n << 1) | (r.f.c << 0); @@ -391,7 +391,7 @@ void LR35902::op_rl_hl() { r.f.c = c; } -template void LR35902::op_rrc_r() { +template auto LR35902::op_rrc_r() { r[x] = (r[x] >> 1) | (r[x] << 7); r.f.z = r[x] == 0; r.f.n = 0; @@ -399,7 +399,7 @@ template void LR35902::op_rrc_r() { r.f.c = r[x] & 0x80; } -void LR35902::op_rrc_hl() { +auto LR35902::op_rrc_hl() { uint8 n = op_read(r[HL]); n = (n >> 1) | (n << 7); op_write(r[HL], n); @@ -409,7 +409,7 @@ void LR35902::op_rrc_hl() { r.f.c = n & 0x80; } -template void LR35902::op_rr_r() { +template auto LR35902::op_rr_r() { bool c = r[x] & 0x01; r[x] = (r[x] >> 1) | (r.f.c << 7); r.f.z = r[x] == 0; @@ -418,7 +418,7 @@ template void LR35902::op_rr_r() { r.f.c = c; } -void LR35902::op_rr_hl() { +auto LR35902::op_rr_hl() { uint8 n = op_read(r[HL]); bool c = n & 0x01; n = (n >> 1) | (r.f.c << 7); @@ -429,7 +429,7 @@ void LR35902::op_rr_hl() { r.f.c = c; } -template void LR35902::op_sla_r() { +template auto LR35902::op_sla_r() { bool c = r[x] & 0x80; r[x] <<= 1; r.f.z = r[x] == 0; @@ -438,7 +438,7 @@ template void LR35902::op_sla_r() { r.f.c = c; } -void LR35902::op_sla_hl() { +auto LR35902::op_sla_hl() { uint8 n = op_read(r[HL]); bool c = n & 0x80; n <<= 1; @@ -449,7 +449,7 @@ void LR35902::op_sla_hl() { r.f.c = c; } -template void LR35902::op_swap_r() { +template auto LR35902::op_swap_r() { r[x] = (r[x] << 4) | (r[x] >> 4); r.f.z = r[x] == 0; r.f.n = 0; @@ -457,7 +457,7 @@ template void LR35902::op_swap_r() { r.f.c = 0; } -void LR35902::op_swap_hl() { +auto LR35902::op_swap_hl() { uint8 n = op_read(r[HL]); n = (n << 4) | (n >> 4); op_write(r[HL], n); @@ -467,7 +467,7 @@ void LR35902::op_swap_hl() { r.f.c = 0; } -template void LR35902::op_sra_r() { +template auto LR35902::op_sra_r() { bool c = r[x] & 0x01; r[x] = (int8)r[x] >> 1; r.f.z = r[x] == 0; @@ -476,7 +476,7 @@ template void LR35902::op_sra_r() { r.f.c = c; } -void LR35902::op_sra_hl() { +auto LR35902::op_sra_hl() { uint8 n = op_read(r[HL]); bool c = n & 0x01; n = (int8)n >> 1; @@ -487,7 +487,7 @@ void LR35902::op_sra_hl() { r.f.c = c; } -template void LR35902::op_srl_r() { +template auto LR35902::op_srl_r() { bool c = r[x] & 0x01; r[x] >>= 1; r.f.z = r[x] == 0; @@ -496,7 +496,7 @@ template void LR35902::op_srl_r() { r.f.c = c; } -void LR35902::op_srl_hl() { +auto LR35902::op_srl_hl() { uint8 n = op_read(r[HL]); bool c = n & 0x01; n >>= 1; @@ -509,34 +509,34 @@ void LR35902::op_srl_hl() { //single-bit commands -template void LR35902::op_bit_n_r() { +template auto LR35902::op_bit_n_r() { r.f.z = (r[x] & (1 << b)) == 0; r.f.n = 0; r.f.h = 1; } -template void LR35902::op_bit_n_hl() { +template auto LR35902::op_bit_n_hl() { uint8 n = op_read(r[HL]); r.f.z = (n & (1 << b)) == 0; r.f.n = 0; r.f.h = 1; } -template void LR35902::op_set_n_r() { +template auto LR35902::op_set_n_r() { r[x] |= 1 << b; } -template void LR35902::op_set_n_hl() { +template auto LR35902::op_set_n_hl() { uint8 n = op_read(r[HL]); n |= 1 << b; op_write(r[HL], n); } -template void LR35902::op_res_n_r() { +template auto LR35902::op_res_n_r() { r[x] &= ~(1 << b); } -template void LR35902::op_res_n_hl() { +template auto LR35902::op_res_n_hl() { uint8 n = op_read(r[HL]); n &= ~(1 << b); op_write(r[HL], n); @@ -544,55 +544,55 @@ template void LR35902::op_res_n_hl() { //control commands -void LR35902::op_ccf() { +auto LR35902::op_ccf() { r.f.n = 0; r.f.h = 0; r.f.c = !r.f.c; } -void LR35902::op_scf() { +auto LR35902::op_scf() { r.f.n = 0; r.f.h = 0; r.f.c = 1; } -void LR35902::op_nop() { +auto LR35902::op_nop() { } -void LR35902::op_halt() { +auto LR35902::op_halt() { r.halt = true; while(r.halt == true) op_io(); } -void LR35902::op_stop() { +auto LR35902::op_stop() { if(stop()) return; r.stop = true; while(r.stop == true) op_io(); } -void LR35902::op_di() { +auto LR35902::op_di() { r.ime = 0; } -void LR35902::op_ei() { +auto LR35902::op_ei() { r.ei = true; //r.ime = 1; } //jump commands -void LR35902::op_jp_nn() { +auto LR35902::op_jp_nn() { uint8 lo = op_read(r[PC]++); uint8 hi = op_read(r[PC]++); r[PC] = (hi << 8) | (lo << 0); op_io(); } -void LR35902::op_jp_hl() { +auto LR35902::op_jp_hl() { r[PC] = r[HL]; } -template void LR35902::op_jp_f_nn() { +template auto LR35902::op_jp_f_nn() { uint8 lo = op_read(r[PC]++); uint8 hi = op_read(r[PC]++); if(r.f[x] == y) { @@ -601,13 +601,13 @@ template void LR35902::op_jp_f_nn() { } } -void LR35902::op_jr_n() { +auto LR35902::op_jr_n() { int8 n = op_read(r[PC]++); r[PC] += n; op_io(); } -template void LR35902::op_jr_f_n() { +template auto LR35902::op_jr_f_n() { int8 n = op_read(r[PC]++); if(r.f[x] == y) { r[PC] += n; @@ -615,7 +615,7 @@ template void LR35902::op_jr_f_n() { } } -void LR35902::op_call_nn() { +auto LR35902::op_call_nn() { uint8 lo = op_read(r[PC]++); uint8 hi = op_read(r[PC]++); op_write(--r[SP], r[PC] >> 8); @@ -624,7 +624,7 @@ void LR35902::op_call_nn() { op_io(); } -template void LR35902::op_call_f_nn() { +template auto LR35902::op_call_f_nn() { uint8 lo = op_read(r[PC]++); uint8 hi = op_read(r[PC]++); if(r.f[x] == y) { @@ -635,14 +635,14 @@ template void LR35902::op_call_f_nn() { } } -void LR35902::op_ret() { +auto LR35902::op_ret() { uint8 lo = op_read(r[SP]++); uint8 hi = op_read(r[SP]++); r[PC] = (hi << 8) | (lo << 0); op_io(); } -template void LR35902::op_ret_f() { +template auto LR35902::op_ret_f() { op_io(); if(r.f[x] == y) { uint8 lo = op_read(r[SP]++); @@ -652,7 +652,7 @@ template void LR35902::op_ret_f() { } } -void LR35902::op_reti() { +auto LR35902::op_reti() { uint8 lo = op_read(r[SP]++); uint8 hi = op_read(r[SP]++); r[PC] = (hi << 8) | (lo << 0); @@ -660,7 +660,7 @@ void LR35902::op_reti() { r.ime = 1; } -template void LR35902::op_rst_n() { +template auto LR35902::op_rst_n() { op_write(--r[SP], r[PC] >> 8); op_write(--r[SP], r[PC] >> 0); r[PC] = n; diff --git a/processor/lr35902/lr35902.cpp b/processor/lr35902/lr35902.cpp index a0491fd2..d60dee21 100644 --- a/processor/lr35902/lr35902.cpp +++ b/processor/lr35902/lr35902.cpp @@ -7,14 +7,14 @@ namespace Processor { #include "disassembler.cpp" #include "serialization.cpp" -void LR35902::power() { +auto LR35902::power() -> void { r.halt = false; r.stop = false; r.ei = false; r.ime = false; } -void LR35902::exec() { +auto LR35902::exec() -> void { uint8 opcode = op_read(r[PC]++); switch(opcode) { case 0x00: return op_nop(); @@ -276,7 +276,7 @@ void LR35902::exec() { } } -void LR35902::exec_cb() { +auto LR35902::execCB() -> void { uint8 opcode = op_read(r[PC]++); switch(opcode) { case 0x00: return op_rlc_r(); diff --git a/processor/lr35902/lr35902.hpp b/processor/lr35902/lr35902.hpp index 412605a0..490f0956 100644 --- a/processor/lr35902/lr35902.hpp +++ b/processor/lr35902/lr35902.hpp @@ -1,165 +1,166 @@ +//Sharp LR35902 (Game Boy Z80-derivative) + #ifndef PROCESSOR_LR35902_HPP #define PROCESSOR_LR35902_HPP namespace Processor { -//Sharp LR35902 (Game Boy Z80-derivative) - struct LR35902 { + virtual auto op_io() -> void = 0; + virtual auto op_read(uint16 addr) -> uint8 = 0; + virtual auto op_write(uint16 addr, uint8 data) -> void = 0; + virtual auto stop() -> bool = 0; + virtual auto debugger_read(uint16 addr) -> uint8 { return 0u; } + + auto power() -> void; + auto exec() -> void; + auto execCB() -> void; + + auto serialize(serializer&) -> void; + #include "registers.hpp" - virtual void op_io() = 0; - virtual uint8 op_read(uint16 addr) = 0; - virtual void op_write(uint16 addr, uint8 data) = 0; - virtual bool stop() = 0; - virtual uint8 debugger_read(uint16 addr) { return 0u; } - - void power(); - void exec(); - void exec_cb(); - void serialize(serializer&); - privileged: - void op_xx(); - void op_cb(); + auto op_xx(); + auto op_cb(); //8-bit load commands - template void op_ld_r_r(); - template void op_ld_r_n(); - template void op_ld_r_hl(); - template void op_ld_hl_r(); - void op_ld_hl_n(); - template void op_ld_a_rr(); - void op_ld_a_nn(); - template void op_ld_rr_a(); - void op_ld_nn_a(); - void op_ld_a_ffn(); - void op_ld_ffn_a(); - void op_ld_a_ffc(); - void op_ld_ffc_a(); - void op_ldi_hl_a(); - void op_ldi_a_hl(); - void op_ldd_hl_a(); - void op_ldd_a_hl(); + template auto op_ld_r_r(); + template auto op_ld_r_n(); + template auto op_ld_r_hl(); + template auto op_ld_hl_r(); + auto op_ld_hl_n(); + template auto op_ld_a_rr(); + auto op_ld_a_nn(); + template auto op_ld_rr_a(); + auto op_ld_nn_a(); + auto op_ld_a_ffn(); + auto op_ld_ffn_a(); + auto op_ld_a_ffc(); + auto op_ld_ffc_a(); + auto op_ldi_hl_a(); + auto op_ldi_a_hl(); + auto op_ldd_hl_a(); + auto op_ldd_a_hl(); //16-bit load commands - template void op_ld_rr_nn(); - void op_ld_nn_sp(); - void op_ld_sp_hl(); - template void op_push_rr(); - template void op_pop_rr(); + template auto op_ld_rr_nn(); + auto op_ld_nn_sp(); + auto op_ld_sp_hl(); + template auto op_push_rr(); + template auto op_pop_rr(); //8-bit arithmetic commands - void opi_add_a(uint8 x); - template void op_add_a_r(); - void op_add_a_n(); - void op_add_a_hl(); + auto opi_add_a(uint8 x); + template auto op_add_a_r(); + auto op_add_a_n(); + auto op_add_a_hl(); - void opi_adc_a(uint8 x); - template void op_adc_a_r(); - void op_adc_a_n(); - void op_adc_a_hl(); + auto opi_adc_a(uint8 x); + template auto op_adc_a_r(); + auto op_adc_a_n(); + auto op_adc_a_hl(); - void opi_sub_a(uint8 x); - template void op_sub_a_r(); - void op_sub_a_n(); - void op_sub_a_hl(); + auto opi_sub_a(uint8 x); + template auto op_sub_a_r(); + auto op_sub_a_n(); + auto op_sub_a_hl(); - void opi_sbc_a(uint8 x); - template void op_sbc_a_r(); - void op_sbc_a_n(); - void op_sbc_a_hl(); + auto opi_sbc_a(uint8 x); + template auto op_sbc_a_r(); + auto op_sbc_a_n(); + auto op_sbc_a_hl(); - void opi_and_a(uint8 x); - template void op_and_a_r(); - void op_and_a_n(); - void op_and_a_hl(); + auto opi_and_a(uint8 x); + template auto op_and_a_r(); + auto op_and_a_n(); + auto op_and_a_hl(); - void opi_xor_a(uint8 x); - template void op_xor_a_r(); - void op_xor_a_n(); - void op_xor_a_hl(); + auto opi_xor_a(uint8 x); + template auto op_xor_a_r(); + auto op_xor_a_n(); + auto op_xor_a_hl(); - void opi_or_a(uint8 x); - template void op_or_a_r(); - void op_or_a_n(); - void op_or_a_hl(); + auto opi_or_a(uint8 x); + template auto op_or_a_r(); + auto op_or_a_n(); + auto op_or_a_hl(); - void opi_cp_a(uint8 x); - template void op_cp_a_r(); - void op_cp_a_n(); - void op_cp_a_hl(); + auto opi_cp_a(uint8 x); + template auto op_cp_a_r(); + auto op_cp_a_n(); + auto op_cp_a_hl(); - template void op_inc_r(); - void op_inc_hl(); - template void op_dec_r(); - void op_dec_hl(); - void op_daa(); - void op_cpl(); + template auto op_inc_r(); + auto op_inc_hl(); + template auto op_dec_r(); + auto op_dec_hl(); + auto op_daa(); + auto op_cpl(); //16-bit arithmetic commands - template void op_add_hl_rr(); - template void op_inc_rr(); - template void op_dec_rr(); - void op_add_sp_n(); - void op_ld_hl_sp_n(); + template auto op_add_hl_rr(); + template auto op_inc_rr(); + template auto op_dec_rr(); + auto op_add_sp_n(); + auto op_ld_hl_sp_n(); //rotate/shift commands - void op_rlca(); - void op_rla(); - void op_rrca(); - void op_rra(); - template void op_rlc_r(); - void op_rlc_hl(); - template void op_rl_r(); - void op_rl_hl(); - template void op_rrc_r(); - void op_rrc_hl(); - template void op_rr_r(); - void op_rr_hl(); - template void op_sla_r(); - void op_sla_hl(); - template void op_swap_r(); - void op_swap_hl(); - template void op_sra_r(); - void op_sra_hl(); - template void op_srl_r(); - void op_srl_hl(); + auto op_rlca(); + auto op_rla(); + auto op_rrca(); + auto op_rra(); + template auto op_rlc_r(); + auto op_rlc_hl(); + template auto op_rl_r(); + auto op_rl_hl(); + template auto op_rrc_r(); + auto op_rrc_hl(); + template auto op_rr_r(); + auto op_rr_hl(); + template auto op_sla_r(); + auto op_sla_hl(); + template auto op_swap_r(); + auto op_swap_hl(); + template auto op_sra_r(); + auto op_sra_hl(); + template auto op_srl_r(); + auto op_srl_hl(); //single-bit commands - template void op_bit_n_r(); - template void op_bit_n_hl(); - template void op_set_n_r(); - template void op_set_n_hl(); - template void op_res_n_r(); - template void op_res_n_hl(); + template auto op_bit_n_r(); + template auto op_bit_n_hl(); + template auto op_set_n_r(); + template auto op_set_n_hl(); + template auto op_res_n_r(); + template auto op_res_n_hl(); //control commands - void op_ccf(); - void op_scf(); - void op_nop(); - void op_halt(); - void op_stop(); - void op_di(); - void op_ei(); + auto op_ccf(); + auto op_scf(); + auto op_nop(); + auto op_halt(); + auto op_stop(); + auto op_di(); + auto op_ei(); //jump commands - void op_jp_nn(); - void op_jp_hl(); - template void op_jp_f_nn(); - void op_jr_n(); - template void op_jr_f_n(); - void op_call_nn(); - template void op_call_f_nn(); - void op_ret(); - template void op_ret_f(); - void op_reti(); - template void op_rst_n(); + auto op_jp_nn(); + auto op_jp_hl(); + template auto op_jp_f_nn(); + auto op_jr_n(); + template auto op_jr_f_n(); + auto op_call_nn(); + template auto op_call_f_nn(); + auto op_ret(); + template auto op_ret_f(); + auto op_reti(); + template auto op_rst_n(); //disassembler.cpp - string disassemble(uint16 pc); - string disassemble_opcode(uint16 pc); - string disassemble_opcode_cb(uint16 pc); + auto disassemble(uint16 pc) -> string; + auto disassembleOpcode(uint16 pc) -> string; + auto disassembleOpcodeCB(uint16 pc) -> string; }; } diff --git a/processor/lr35902/serialization.cpp b/processor/lr35902/serialization.cpp index 1f5f7260..63beee28 100644 --- a/processor/lr35902/serialization.cpp +++ b/processor/lr35902/serialization.cpp @@ -1,4 +1,4 @@ -void LR35902::serialize(serializer& s) { +auto LR35902::serialize(serializer& s) -> void { s.integer(r.a.data); s.integer(r.f.z); s.integer(r.f.n); diff --git a/processor/r6502/disassembler.cpp b/processor/r6502/disassembler.cpp index 24879b5f..d1ceed27 100644 --- a/processor/r6502/disassembler.cpp +++ b/processor/r6502/disassembler.cpp @@ -1,18 +1,18 @@ -string R6502::disassemble() { - string output = { hex(regs.pc, 4L), " " }; +auto R6502::disassemble() -> string { + string output = {hex(regs.pc, 4L), " "}; - auto abs = [&]() -> string { return { "$", hex(debugger_read(regs.pc + 2), 2L), hex(debugger_read(regs.pc + 1), 2L) }; }; - auto abx = [&]() -> string { return { "$", hex(debugger_read(regs.pc + 2), 2L), hex(debugger_read(regs.pc + 1), 2L), ",x" }; }; - auto aby = [&]() -> string { return { "$", hex(debugger_read(regs.pc + 2), 2L), hex(debugger_read(regs.pc + 1), 2L), ",y" }; }; - auto iab = [&]() -> string { return { "($", hex(debugger_read(regs.pc + 2), 2L), hex(debugger_read(regs.pc + 1), 2L), ")" }; }; - auto imm = [&]() -> string { return { "#$", hex(debugger_read(regs.pc + 1), 2L) }; }; - auto imp = [&]() -> string { return ""; }; - auto izx = [&]() -> string { return { "($", hex(debugger_read(regs.pc + 1), 2L), ",x)" }; }; - auto izy = [&]() -> string { return { "($", hex(debugger_read(regs.pc + 1), 2L), "),y" }; }; - auto rel = [&]() -> string { return { "$", hex((regs.pc + 2) + (int8)debugger_read(regs.pc + 1), 4L) }; }; - auto zpg = [&]() -> string { return { "$", hex(debugger_read(regs.pc + 1), 2L) }; }; - auto zpx = [&]() -> string { return { "$", hex(debugger_read(regs.pc + 1), 2L), ",x" }; }; - auto zpy = [&]() -> string { return { "$", hex(debugger_read(regs.pc + 1), 2L), ",y" }; }; + auto abs = [&]() -> string { return {"$", hex(debugger_read(regs.pc + 2), 2L), hex(debugger_read(regs.pc + 1), 2L)}; }; + auto abx = [&]() -> string { return {"$", hex(debugger_read(regs.pc + 2), 2L), hex(debugger_read(regs.pc + 1), 2L), ",x"}; }; + auto aby = [&]() -> string { return {"$", hex(debugger_read(regs.pc + 2), 2L), hex(debugger_read(regs.pc + 1), 2L), ",y"}; }; + auto iab = [&]() -> string { return {"($", hex(debugger_read(regs.pc + 2), 2L), hex(debugger_read(regs.pc + 1), 2L), ")"}; }; + auto imm = [&]() -> string { return {"#$", hex(debugger_read(regs.pc + 1), 2L)}; }; + auto imp = [&]() -> string { return {""}; }; + auto izx = [&]() -> string { return {"($", hex(debugger_read(regs.pc + 1), 2L), ",x)"}; }; + auto izy = [&]() -> string { return {"($", hex(debugger_read(regs.pc + 1), 2L), "),y"}; }; + auto rel = [&]() -> string { return {"$", hex((regs.pc + 2) + (int8)debugger_read(regs.pc + 1), 4L)}; }; + auto zpg = [&]() -> string { return {"$", hex(debugger_read(regs.pc + 1), 2L)}; }; + auto zpx = [&]() -> string { return {"$", hex(debugger_read(regs.pc + 1), 2L), ",x"}; }; + auto zpy = [&]() -> string { return {"$", hex(debugger_read(regs.pc + 1), 2L), ",y"}; }; #define op(byte, prefix, mode) \ case byte: output.append(#prefix, " ", mode()); \ diff --git a/processor/r6502/instructions.cpp b/processor/r6502/instructions.cpp index 9d551c05..0f0d7b95 100644 --- a/processor/r6502/instructions.cpp +++ b/processor/r6502/instructions.cpp @@ -1,8 +1,8 @@ //opcode functions //================ -void R6502::opf_adc() { - signed result = regs.a + rd + regs.p.c; +auto R6502::opf_adc() { + int result = regs.a + rd + regs.p.c; regs.p.v = ~(regs.a ^ rd) & (regs.a ^ result) & 0x80; regs.p.c = (result > 0xff); regs.p.n = (result & 0x80); @@ -10,140 +10,140 @@ void R6502::opf_adc() { regs.a = result; } -void R6502::opf_and() { +auto R6502::opf_and() { regs.a &= rd; regs.p.n = (regs.a & 0x80); regs.p.z = (regs.a == 0); } -void R6502::opf_asl() { +auto R6502::opf_asl() { regs.p.c = rd & 0x80; rd <<= 1; regs.p.n = (rd & 0x80); regs.p.z = (rd == 0); } -void R6502::opf_bit() { +auto R6502::opf_bit() { regs.p.n = (rd & 0x80); regs.p.v = (rd & 0x40); regs.p.z = ((rd & regs.a) == 0); } -void R6502::opf_cmp() { - signed r = regs.a - rd; +auto R6502::opf_cmp() { + int r = regs.a - rd; regs.p.n = (r & 0x80); regs.p.z = (uint8)(r == 0); regs.p.c = (r >= 0); } -void R6502::opf_cpx() { - signed r = regs.x - rd; +auto R6502::opf_cpx() { + int r = regs.x - rd; regs.p.n = (r & 0x80); regs.p.z = (uint8)(r == 0); regs.p.c = (r >= 0); } -void R6502::opf_cpy() { - signed r = regs.y - rd; +auto R6502::opf_cpy() { + int r = regs.y - rd; regs.p.n = (r & 0x80); regs.p.z = (uint8)(r == 0); regs.p.c = (r >= 0); } -void R6502::opf_dec() { +auto R6502::opf_dec() { rd--; regs.p.n = (rd & 0x80); regs.p.z = (rd == 0); } -void R6502::opf_eor() { +auto R6502::opf_eor() { regs.a ^= rd; regs.p.n = (regs.a & 0x80); regs.p.z = (regs.a == 0); } -void R6502::opf_inc() { +auto R6502::opf_inc() { rd++; regs.p.n = (rd & 0x80); regs.p.z = (rd == 0); } -void R6502::opf_lda() { +auto R6502::opf_lda() { regs.a = rd; regs.p.n = (regs.a & 0x80); regs.p.z = (regs.a == 0); } -void R6502::opf_ldx() { +auto R6502::opf_ldx() { regs.x = rd; regs.p.n = (regs.x & 0x80); regs.p.z = (regs.x == 0); } -void R6502::opf_ldy() { +auto R6502::opf_ldy() { regs.y = rd; regs.p.n = (regs.y & 0x80); regs.p.z = (regs.y == 0); } -void R6502::opf_lsr() { +auto R6502::opf_lsr() { regs.p.c = rd & 0x01; rd >>= 1; regs.p.n = (rd & 0x80); regs.p.z = (rd == 0); } -void R6502::opf_ora() { +auto R6502::opf_ora() { regs.a |= rd; regs.p.n = (regs.a & 0x80); regs.p.z = (regs.a == 0); } -void R6502::opf_rla() { - unsigned carry = (unsigned)regs.p.c; +auto R6502::opf_rla() { + uint carry = (uint)regs.p.c; regs.p.c = regs.a & 0x80; regs.a = (regs.a << 1) | carry; regs.p.n = (regs.a & 0x80); regs.p.z = (regs.a == 0); } -void R6502::opf_rol() { - unsigned carry = (unsigned)regs.p.c; +auto R6502::opf_rol() { + uint carry = (uint)regs.p.c; regs.p.c = rd & 0x80; rd = (rd << 1) | carry; regs.p.n = (rd & 0x80); regs.p.z = (rd == 0); } -void R6502::opf_ror() { - unsigned carry = (unsigned)regs.p.c << 7; +auto R6502::opf_ror() { + uint carry = (uint)regs.p.c << 7; regs.p.c = rd & 0x01; rd = carry | (rd >> 1); regs.p.n = (rd & 0x80); regs.p.z = (rd == 0); } -void R6502::opf_rra() { - unsigned carry = (unsigned)regs.p.c << 7; +auto R6502::opf_rra() { + uint carry = (uint)regs.p.c << 7; regs.p.c = regs.a & 0x01; regs.a = carry | (regs.a >> 1); regs.p.n = (regs.a & 0x80); regs.p.z = (regs.a == 0); } -void R6502::opf_sbc() { +auto R6502::opf_sbc() { rd ^= 0xff; return opf_adc(); } -void R6502::opf_sla() { +auto R6502::opf_sla() { regs.p.c = regs.a & 0x80; regs.a <<= 1; regs.p.n = (regs.a & 0x80); regs.p.z = (regs.a == 0); } -void R6502::opf_sra() { +auto R6502::opf_sra() { regs.p.c = regs.a & 0x01; regs.a >>= 1; regs.p.n = (regs.a & 0x80); @@ -153,7 +153,7 @@ void R6502::opf_sra() { //opcode implementations //====================== -void R6502::opi_branch(bool condition) { +auto R6502::opi_branch(bool condition) { if(condition == false) { L rd = op_readpci(); } else { @@ -165,26 +165,26 @@ L op_readpc(); } } -void R6502::opi_clear_flag(bool& flag) { +auto R6502::opi_clear_flag(bool& flag) { L op_readpc(); flag = 0; } -void R6502::opi_decrement(uint8& r) { +auto R6502::opi_decrement(uint8& r) { L op_readpc(); r--; regs.p.n = (r & 0x80); regs.p.z = (r == 0); } -void R6502::opi_increment(uint8& r) { +auto R6502::opi_increment(uint8& r) { L op_readpc(); r++; regs.p.n = (r & 0x80); regs.p.z = (r == 0); } -void R6502::opi_pull(uint8& r) { +auto R6502::opi_pull(uint8& r) { op_readpc(); op_readpc(); L r = op_readsp(); @@ -192,21 +192,21 @@ L r = op_readsp(); regs.p.z = (r == 0); } -void R6502::opi_push(uint8& r) { +auto R6502::opi_push(uint8& r) { op_readpc(); L op_writesp(r); } -template -void R6502::opi_read_absolute() { +template void> +auto R6502::opi_read_absolute() { abs.l = op_readpci(); abs.h = op_readpci(); L rd = op_read(abs.w); call(op); } -template -void R6502::opi_read_absolute_x() { +template void> +auto R6502::opi_read_absolute_x() { abs.l = op_readpci(); abs.h = op_readpci(); op_page(abs.w, abs.w + regs.x); @@ -214,8 +214,8 @@ L rd = op_read(abs.w + regs.x); call(op); } -template -void R6502::opi_read_absolute_y() { +template void> +auto R6502::opi_read_absolute_y() { abs.l = op_readpci(); abs.h = op_readpci(); op_page(abs.w, abs.w + regs.y); @@ -223,14 +223,14 @@ L rd = op_read(abs.w + regs.y); call(op); } -template -void R6502::opi_read_immediate() { +template void> +auto R6502::opi_read_immediate() { L rd = op_readpci(); call(op); } -template -void R6502::opi_read_indirect_zero_page_x() { +template void> +auto R6502::opi_read_indirect_zero_page_x() { zp = op_readpci(); op_readzp(zp); abs.l = op_readzp(zp++ + regs.x); @@ -239,8 +239,8 @@ L rd = op_read(abs.w); call(op); } -template -void R6502::opi_read_indirect_zero_page_y() { +template void> +auto R6502::opi_read_indirect_zero_page_y() { rd = op_readpci(); abs.l = op_readzp(rd++); abs.h = op_readzp(rd++); @@ -249,31 +249,31 @@ L rd = op_read(abs.w + regs.y); call(op); } -template -void R6502::opi_read_zero_page() { +template void> +auto R6502::opi_read_zero_page() { zp = op_readpci(); L rd = op_readzp(zp); call(op); } -template -void R6502::opi_read_zero_page_x() { +template void> +auto R6502::opi_read_zero_page_x() { zp = op_readpci(); op_readzp(zp); L rd = op_readzp(zp + regs.x); call(op); } -template -void R6502::opi_read_zero_page_y() { +template void> +auto R6502::opi_read_zero_page_y() { zp = op_readpci(); op_readzp(zp); L rd = op_readzp(zp + regs.y); call(op); } -template -void R6502::opi_rmw_absolute() { +template void> +auto R6502::opi_rmw_absolute() { abs.l = op_readpci(); abs.h = op_readpci(); rd = op_read(abs.w); @@ -282,8 +282,8 @@ void R6502::opi_rmw_absolute() { L op_write(abs.w, rd); } -template -void R6502::opi_rmw_absolute_x() { +template void> +auto R6502::opi_rmw_absolute_x() { abs.l = op_readpci(); abs.h = op_readpci(); op_page_always(abs.w, abs.w + regs.x); @@ -293,8 +293,8 @@ void R6502::opi_rmw_absolute_x() { L op_write(abs.w + regs.x, rd); } -template -void R6502::opi_rmw_zero_page() { +template void> +auto R6502::opi_rmw_zero_page() { zp = op_readpci(); rd = op_readzp(zp); op_writezp(zp, rd); @@ -302,8 +302,8 @@ void R6502::opi_rmw_zero_page() { L op_writezp(zp, rd); } -template -void R6502::opi_rmw_zero_page_x() { +template void> +auto R6502::opi_rmw_zero_page_x() { zp = op_readpci(); op_readzp(zp); rd = op_readzp(zp + regs.x); @@ -312,38 +312,38 @@ void R6502::opi_rmw_zero_page_x() { L op_writezp(zp + regs.x, rd); } -void R6502::opi_set_flag(bool& flag) { +auto R6502::opi_set_flag(bool& flag) { L op_readpc(); flag = 1; } -template -void R6502::opi_shift() { +template void> +auto R6502::opi_shift() { L op_readpc(); call(op); } -void R6502::opi_store_absolute(uint8& r) { +auto R6502::opi_store_absolute(uint8& r) { abs.l = op_readpci(); abs.h = op_readpci(); L op_write(abs.w, r); } -void R6502::opi_store_absolute_x(uint8& r) { +auto R6502::opi_store_absolute_x(uint8& r) { abs.l = op_readpci(); abs.h = op_readpci(); op_page_always(abs.w, abs.w + regs.x); L op_write(abs.w + regs.x, r); } -void R6502::opi_store_absolute_y(uint8& r) { +auto R6502::opi_store_absolute_y(uint8& r) { abs.l = op_readpci(); abs.h = op_readpci(); op_page_always(abs.w, abs.w + regs.y); L op_write(abs.w + regs.y, r); } -void R6502::opi_store_indirect_zero_page_x(uint8& r) { +auto R6502::opi_store_indirect_zero_page_x(uint8& r) { zp = op_readpci(); op_readzp(zp); abs.l = op_readzp(zp++ + regs.x); @@ -351,7 +351,7 @@ void R6502::opi_store_indirect_zero_page_x(uint8& r) { L op_write(abs.w, r); } -void R6502::opi_store_indirect_zero_page_y(uint8& r) { +auto R6502::opi_store_indirect_zero_page_y(uint8& r) { rd = op_readpci(); abs.l = op_readzp(rd++); abs.h = op_readzp(rd++); @@ -359,24 +359,24 @@ void R6502::opi_store_indirect_zero_page_y(uint8& r) { L op_write(abs.w + regs.y, r); } -void R6502::opi_store_zero_page(uint8& r) { +auto R6502::opi_store_zero_page(uint8& r) { zp = op_readpci(); L op_writezp(zp, r); } -void R6502::opi_store_zero_page_x(uint8& r) { +auto R6502::opi_store_zero_page_x(uint8& r) { zp = op_readpci(); op_readzp(zp); L op_writezp(zp + regs.x, r); } -void R6502::opi_store_zero_page_y(uint8& r) { +auto R6502::opi_store_zero_page_y(uint8& r) { zp = op_readpci(); op_readzp(zp); L op_writezp(zp + regs.y, r); } -void R6502::opi_transfer(uint8& s, uint8& d, bool flag) { +auto R6502::opi_transfer(uint8& s, uint8& d, bool flag) { L op_readpc(); d = s; if(flag == false) return; @@ -387,7 +387,7 @@ L op_readpc(); //opcodes //======= -void R6502::op_brk() { +auto R6502::op_brk() { op_readpci(); op_writesp(regs.pc >> 8); op_writesp(regs.pc >> 0); @@ -399,13 +399,13 @@ L abs.h = op_read(0xffff); regs.pc = abs.w; } -void R6502::op_jmp_absolute() { +auto R6502::op_jmp_absolute() { abs.l = op_readpci(); L abs.h = op_readpci(); regs.pc = abs.w; } -void R6502::op_jmp_indirect_absolute() { +auto R6502::op_jmp_indirect_absolute() { abs.l = op_readpci(); abs.h = op_readpci(); iabs.l = op_read(abs.w); abs.l++; @@ -413,7 +413,7 @@ L iabs.h = op_read(abs.w); abs.l++; regs.pc = iabs.w; } -void R6502::op_jsr_absolute() { +auto R6502::op_jsr_absolute() { abs.l = op_readpci(); abs.h = op_readpci(); op_readpc(); @@ -423,22 +423,22 @@ L op_writesp(regs.pc >> 0); regs.pc = abs.w; } -void R6502::op_nop() { +auto R6502::op_nop() { L op_readpc(); } -void R6502::op_php() { +auto R6502::op_php() { op_readpc(); L op_writesp(regs.p | 0x30); } -void R6502::op_plp() { +auto R6502::op_plp() { op_readpc(); op_readpc(); L regs.p = op_readsp(); } -void R6502::op_rti() { +auto R6502::op_rti() { op_readpc(); op_readpc(); regs.p = op_readsp(); @@ -447,7 +447,7 @@ L abs.h = op_readsp(); regs.pc = abs.w; } -void R6502::op_rts() { +auto R6502::op_rts() { op_readpc(); op_readpc(); abs.l = op_readsp(); @@ -459,7 +459,7 @@ L op_readpc(); //illegal opcodes //=============== -void R6502::opill_arr_immediate() { +auto R6502::opill_arr_immediate() { L rd = op_readpci(); regs.a &= rd; regs.a = (regs.p.c << 7) | (regs.a >> 1); @@ -469,33 +469,33 @@ L rd = op_readpci(); regs.p.v = regs.p.c ^ ((regs.a >> 5) & 1); } -void R6502::opill_nop_absolute() { +auto R6502::opill_nop_absolute() { abs.l = op_readpci(); abs.h = op_readpci(); L op_readpc(); } -void R6502::opill_nop_absolute_x() { +auto R6502::opill_nop_absolute_x() { abs.l = op_readpci(); abs.h = op_readpci(); op_page(abs.w, abs.w + regs.x); L op_readpc(); } -void R6502::opill_nop_immediate() { +auto R6502::opill_nop_immediate() { L rd = op_readpc(); } -void R6502::opill_nop_implied() { +auto R6502::opill_nop_implied() { L op_readpc(); } -void R6502::opill_nop_zero_page() { +auto R6502::opill_nop_zero_page() { zp = op_readpci(); L op_readzp(zp); } -void R6502::opill_nop_zero_page_x() { +auto R6502::opill_nop_zero_page_x() { zp = op_readpci(); op_readzp(zp); L op_readzp(zp + regs.x); diff --git a/processor/r6502/memory.cpp b/processor/r6502/memory.cpp index ec0529e7..eb4a4aed 100644 --- a/processor/r6502/memory.cpp +++ b/processor/r6502/memory.cpp @@ -1,35 +1,35 @@ -uint8 R6502::op_readpc() { +auto R6502::op_readpc() -> uint8 { return op_read(regs.pc); } -uint8 R6502::op_readpci() { +auto R6502::op_readpci() -> uint8 { return op_read(regs.pc++); } -uint8 R6502::op_readsp() { +auto R6502::op_readsp() -> uint8 { return op_read(0x0100 | ++regs.s); } -uint8 R6502::op_readzp(uint8 addr) { +auto R6502::op_readzp(uint8 addr) -> uint8 { return op_read(addr); } // -void R6502::op_writesp(uint8 data) { +auto R6502::op_writesp(uint8 data) -> void { op_write(0x0100 | regs.s--, data); } -void R6502::op_writezp(uint8 addr, uint8 data) { +auto R6502::op_writezp(uint8 addr, uint8 data) -> void { op_write(addr, data); } // -void R6502::op_page(uint16 x, uint16 y) { +auto R6502::op_page(uint16 x, uint16 y) -> void { if((x & 0xff00) != (y & 0xff00)) op_read((x & 0xff00) | (y & 0x00ff)); } -void R6502::op_page_always(uint16 x, uint16 y) { +auto R6502::op_page_always(uint16 x, uint16 y) -> void { op_read((x & 0xff00) | (y & 0x00ff)); } diff --git a/processor/r6502/r6502.cpp b/processor/r6502/r6502.cpp index b5600595..570fcf26 100644 --- a/processor/r6502/r6502.cpp +++ b/processor/r6502/r6502.cpp @@ -12,11 +12,11 @@ namespace Processor { #include "disassembler.cpp" #include "serialization.cpp" -uint8 R6502::mdr() const { +auto R6502::mdr() const -> uint8 { return regs.mdr; } -void R6502::power() { +auto R6502::power() -> void { regs.a = 0x00; regs.x = 0x00; regs.y = 0x00; @@ -24,13 +24,13 @@ void R6502::power() { regs.p = 0x04; } -void R6502::reset() { +auto R6502::reset() -> void { regs.mdr = 0x00; regs.s -= 3; regs.p.i = 1; } -void R6502::interrupt() { +auto R6502::interrupt() -> void { op_readpc(); op_readpc(); op_writesp(regs.pc >> 8); @@ -45,7 +45,7 @@ L abs.h = op_read(vector++); regs.pc = abs.w; } -void R6502::exec() { +auto R6502::exec() -> void { uint8 opcode = op_readpci(); switch(opcode) { case 0x00: return op_brk(); diff --git a/processor/r6502/r6502.hpp b/processor/r6502/r6502.hpp index e6d5dadf..5c9147f5 100644 --- a/processor/r6502/r6502.hpp +++ b/processor/r6502/r6502.hpp @@ -1,116 +1,116 @@ +//Ricoh 6502 +//* Ricoh 2A03 +//* Ricoh 2A07 + #ifndef PROCESSOR_R6502_HPP #define PROCESSOR_R6502_HPP namespace Processor { -//Ricoh 6502 -//* Ricoh 2A03 -//* Ricoh 2A07 - struct R6502 { - #include "registers.hpp" + virtual auto op_read(uint16 addr) -> uint8 = 0; + virtual auto op_write(uint16 addr, uint8 data) -> void = 0; + virtual auto last_cycle() -> void = 0; + virtual auto nmi(uint16& vector) -> void = 0; + virtual auto debugger_read(uint16 addr) -> uint8 { return 0u; } - virtual uint8 op_read(uint16 addr) = 0; - virtual void op_write(uint16 addr, uint8 data) = 0; - virtual void last_cycle() = 0; - virtual void nmi(uint16& vector) = 0; - virtual uint8 debugger_read(uint16 addr) { return 0u; } + auto mdr() const -> uint8; + auto power() -> void; + auto reset() -> void; + auto interrupt() -> void; + auto exec() -> void; - uint8 mdr() const; - void power(); - void reset(); - void interrupt(); - void exec(); - - void serialize(serializer&); + auto serialize(serializer&) -> void; //memory.cpp - uint8 op_readpc(); - uint8 op_readpci(); - uint8 op_readsp(); - uint8 op_readzp(uint8 addr); + auto op_readpc() -> uint8; + auto op_readpci() -> uint8; + auto op_readsp() -> uint8; + auto op_readzp(uint8 addr) -> uint8; - void op_writesp(uint8 data); - void op_writezp(uint8 addr, uint8 data); + auto op_writesp(uint8 data) -> void; + auto op_writezp(uint8 addr, uint8 data) -> void; - void op_page(uint16 x, uint16 y); - void op_page_always(uint16 x, uint16 y); + auto op_page(uint16 x, uint16 y) -> void; + auto op_page_always(uint16 x, uint16 y) -> void; //instructions.cpp - void opf_asl(); - void opf_adc(); - void opf_and(); - void opf_bit(); - void opf_cmp(); - void opf_cpx(); - void opf_cpy(); - void opf_dec(); - void opf_eor(); - void opf_inc(); - void opf_lda(); - void opf_ldx(); - void opf_ldy(); - void opf_lsr(); - void opf_ora(); - void opf_rla(); - void opf_rol(); - void opf_ror(); - void opf_rra(); - void opf_sbc(); - void opf_sla(); - void opf_sra(); + auto opf_asl(); + auto opf_adc(); + auto opf_and(); + auto opf_bit(); + auto opf_cmp(); + auto opf_cpx(); + auto opf_cpy(); + auto opf_dec(); + auto opf_eor(); + auto opf_inc(); + auto opf_lda(); + auto opf_ldx(); + auto opf_ldy(); + auto opf_lsr(); + auto opf_ora(); + auto opf_rla(); + auto opf_rol(); + auto opf_ror(); + auto opf_rra(); + auto opf_sbc(); + auto opf_sla(); + auto opf_sra(); - void opi_branch(bool condition); - void opi_clear_flag(bool& flag); - void opi_decrement(uint8& r); - void opi_increment(uint8& r); - void opi_pull(uint8& r); - void opi_push(uint8& r); - template void opi_read_absolute(); - template void opi_read_absolute_x(); - template void opi_read_absolute_y(); - template void opi_read_immediate(); - template void opi_read_indirect_zero_page_x(); - template void opi_read_indirect_zero_page_y(); - template void opi_read_zero_page(); - template void opi_read_zero_page_x(); - template void opi_read_zero_page_y(); - template void opi_rmw_absolute(); - template void opi_rmw_absolute_x(); - template void opi_rmw_zero_page(); - template void opi_rmw_zero_page_x(); - void opi_set_flag(bool& flag); - template void opi_shift(); - void opi_store_absolute(uint8& r); - void opi_store_absolute_x(uint8& r); - void opi_store_absolute_y(uint8& r); - void opi_store_indirect_zero_page_x(uint8& r); - void opi_store_indirect_zero_page_y(uint8& r); - void opi_store_zero_page(uint8& r); - void opi_store_zero_page_x(uint8& r); - void opi_store_zero_page_y(uint8& r); - void opi_transfer(uint8& s, uint8& d, bool flag); + auto opi_branch(bool condition); + auto opi_clear_flag(bool& flag); + auto opi_decrement(uint8& r); + auto opi_increment(uint8& r); + auto opi_pull(uint8& r); + auto opi_push(uint8& r); + template void> auto opi_read_absolute(); + template void> auto opi_read_absolute_x(); + template void> auto opi_read_absolute_y(); + template void> auto opi_read_immediate(); + template void> auto opi_read_indirect_zero_page_x(); + template void> auto opi_read_indirect_zero_page_y(); + template void> auto opi_read_zero_page(); + template void> auto opi_read_zero_page_x(); + template void> auto opi_read_zero_page_y(); + template void> auto opi_rmw_absolute(); + template void> auto opi_rmw_absolute_x(); + template void> auto opi_rmw_zero_page(); + template void> auto opi_rmw_zero_page_x(); + auto opi_set_flag(bool& flag); + template void> auto opi_shift(); + auto opi_store_absolute(uint8& r); + auto opi_store_absolute_x(uint8& r); + auto opi_store_absolute_y(uint8& r); + auto opi_store_indirect_zero_page_x(uint8& r); + auto opi_store_indirect_zero_page_y(uint8& r); + auto opi_store_zero_page(uint8& r); + auto opi_store_zero_page_x(uint8& r); + auto opi_store_zero_page_y(uint8& r); + auto opi_transfer(uint8& s, uint8& d, bool flag); - void op_brk(); - void op_jmp_absolute(); - void op_jmp_indirect_absolute(); - void op_jsr_absolute(); - void op_nop(); - void op_php(); - void op_plp(); - void op_rti(); - void op_rts(); + auto op_brk(); + auto op_jmp_absolute(); + auto op_jmp_indirect_absolute(); + auto op_jsr_absolute(); + auto op_nop(); + auto op_php(); + auto op_plp(); + auto op_rti(); + auto op_rts(); - void opill_arr_immediate(); - void opill_nop_absolute(); - void opill_nop_absolute_x(); - void opill_nop_immediate(); - void opill_nop_implied(); - void opill_nop_zero_page(); - void opill_nop_zero_page_x(); + auto opill_arr_immediate(); + auto opill_nop_absolute(); + auto opill_nop_absolute_x(); + auto opill_nop_immediate(); + auto opill_nop_implied(); + auto opill_nop_zero_page(); + auto opill_nop_zero_page_x(); //disassembler.cpp - string disassemble(); + auto disassemble() -> string; + + #include "registers.hpp" }; } diff --git a/processor/r6502/registers.hpp b/processor/r6502/registers.hpp index a4860ade..681eaf2a 100644 --- a/processor/r6502/registers.hpp +++ b/processor/r6502/registers.hpp @@ -1,15 +1,15 @@ struct Flags { - bool n, v, d, i, z, c; - - inline operator unsigned() { + inline operator uint() { return (n << 7) | (v << 6) | (d << 3) | (i << 2) | (z << 1) | (c << 0); } - inline Flags& operator=(uint8 data) { + inline auto operator=(uint8 data) -> Flags& { n = data & 0x80; v = data & 0x40; d = data & 0x08; i = data & 0x04; z = data & 0x02; c = data & 0x01; return *this; } + + bool n, v, d, i, z, c; }; struct Registers { diff --git a/processor/r6502/serialization.cpp b/processor/r6502/serialization.cpp index 089d1e83..6021cf2e 100644 --- a/processor/r6502/serialization.cpp +++ b/processor/r6502/serialization.cpp @@ -1,4 +1,4 @@ -void R6502::serialize(serializer& s) { +auto R6502::serialize(serializer& s) -> void { s.integer(regs.mdr); s.integer(regs.pc); s.integer(regs.a); diff --git a/processor/spc700/algorithms.cpp b/processor/spc700/algorithms.cpp index 65451cc2..8b1486c3 100644 --- a/processor/spc700/algorithms.cpp +++ b/processor/spc700/algorithms.cpp @@ -1,4 +1,4 @@ -uint8 SPC700::op_adc(uint8 x, uint8 y) { +auto SPC700::op_adc(uint8 x, uint8 y) -> uint8 { int r = x + y + regs.p.c; regs.p.n = r & 0x80; regs.p.v = ~(x ^ y) & (x ^ r) & 0x80; @@ -8,14 +8,14 @@ uint8 SPC700::op_adc(uint8 x, uint8 y) { return r; } -uint8 SPC700::op_and(uint8 x, uint8 y) { +auto SPC700::op_and(uint8 x, uint8 y) -> uint8 { x &= y; regs.p.n = x & 0x80; regs.p.z = x == 0; return x; } -uint8 SPC700::op_asl(uint8 x) { +auto SPC700::op_asl(uint8 x) -> uint8 { regs.p.c = x & 0x80; x <<= 1; regs.p.n = x & 0x80; @@ -23,7 +23,7 @@ uint8 SPC700::op_asl(uint8 x) { return x; } -uint8 SPC700::op_cmp(uint8 x, uint8 y) { +auto SPC700::op_cmp(uint8 x, uint8 y) -> uint8 { int r = x - y; regs.p.n = r & 0x80; regs.p.z = (uint8)r == 0; @@ -31,34 +31,34 @@ uint8 SPC700::op_cmp(uint8 x, uint8 y) { return x; } -uint8 SPC700::op_dec(uint8 x) { +auto SPC700::op_dec(uint8 x) -> uint8 { x--; regs.p.n = x & 0x80; regs.p.z = x == 0; return x; } -uint8 SPC700::op_eor(uint8 x, uint8 y) { +auto SPC700::op_eor(uint8 x, uint8 y) -> uint8 { x ^= y; regs.p.n = x & 0x80; regs.p.z = x == 0; return x; } -uint8 SPC700::op_inc(uint8 x) { +auto SPC700::op_inc(uint8 x) -> uint8 { x++; regs.p.n = x & 0x80; regs.p.z = x == 0; return x; } -uint8 SPC700::op_ld(uint8 x, uint8 y) { +auto SPC700::op_ld(uint8 x, uint8 y) -> uint8 { regs.p.n = y & 0x80; regs.p.z = y == 0; return y; } -uint8 SPC700::op_lsr(uint8 x) { +auto SPC700::op_lsr(uint8 x) -> uint8 { regs.p.c = x & 0x01; x >>= 1; regs.p.n = x & 0x80; @@ -66,15 +66,15 @@ uint8 SPC700::op_lsr(uint8 x) { return x; } -uint8 SPC700::op_or(uint8 x, uint8 y) { +auto SPC700::op_or(uint8 x, uint8 y) -> uint8 { x |= y; regs.p.n = x & 0x80; regs.p.z = x == 0; return x; } -uint8 SPC700::op_rol(uint8 x) { - unsigned carry = regs.p.c << 0; +auto SPC700::op_rol(uint8 x) -> uint8 { + uint carry = regs.p.c << 0; regs.p.c = x & 0x80; x = (x << 1) | carry; regs.p.n = x & 0x80; @@ -82,8 +82,8 @@ uint8 SPC700::op_rol(uint8 x) { return x; } -uint8 SPC700::op_ror(uint8 x) { - unsigned carry = regs.p.c << 7; +auto SPC700::op_ror(uint8 x) -> uint8 { + uint carry = regs.p.c << 7; regs.p.c = x & 0x01; x = carry | (x >> 1); regs.p.n = x & 0x80; @@ -91,17 +91,17 @@ uint8 SPC700::op_ror(uint8 x) { return x; } -uint8 SPC700::op_sbc(uint8 x, uint8 y) { +auto SPC700::op_sbc(uint8 x, uint8 y) -> uint8 { return op_adc(x, ~y); } -uint8 SPC700::op_st(uint8 x, uint8 y) { +auto SPC700::op_st(uint8 x, uint8 y) -> uint8 { return y; } // -uint16 SPC700::op_adw(uint16 x, uint16 y) { +auto SPC700::op_adw(uint16 x, uint16 y) -> uint16 { uint16 r; regs.p.c = 0; r = op_adc(x, y); @@ -110,7 +110,7 @@ uint16 SPC700::op_adw(uint16 x, uint16 y) { return r; } -uint16 SPC700::op_cpw(uint16 x, uint16 y) { +auto SPC700::op_cpw(uint16 x, uint16 y) -> uint16 { int r = x - y; regs.p.n = r & 0x8000; regs.p.z = (uint16)r == 0; @@ -118,13 +118,13 @@ uint16 SPC700::op_cpw(uint16 x, uint16 y) { return x; } -uint16 SPC700::op_ldw(uint16 x, uint16 y) { +auto SPC700::op_ldw(uint16 x, uint16 y) -> uint16 { regs.p.n = y & 0x8000; regs.p.z = y == 0; return y; } -uint16 SPC700::op_sbw(uint16 x, uint16 y) { +auto SPC700::op_sbw(uint16 x, uint16 y) -> uint16 { uint16 r; regs.p.c = 1; r = op_sbc(x, y); diff --git a/processor/spc700/disassembler.cpp b/processor/spc700/disassembler.cpp index 548b3cb5..f158d5a4 100644 --- a/processor/spc700/disassembler.cpp +++ b/processor/spc700/disassembler.cpp @@ -1,20 +1,20 @@ -string SPC700::disassemble_opcode(uint16 addr, bool p) { +auto SPC700::disassemble(uint16 addr, bool p) -> string { auto read = [&](uint16 addr) -> uint8 { return disassembler_read(addr); }; - auto relative = [&](unsigned length, int8 offset) -> uint16 { + auto relative = [&](uint length, int8 offset) -> uint16 { uint16 pc = addr + length; return pc + offset; }; auto a = [&] { return hex((read(addr + 1) << 0) + (read(addr + 2) << 8), 4L); }; - auto b = [&](unsigned n) { return hex(read(addr + 1 + n), 2L); }; - auto r = [&](unsigned r, unsigned n = 0) { return hex(addr + r + (int8)read(addr + 1 + n), 4L); }; - auto dp = [&](unsigned n) { return hex((p << 8) + read(addr + 1 + n), 3L); }; + auto b = [&](uint n) { return hex(read(addr + 1 + n), 2L); }; + auto r = [&](uint r, uint n = 0) { return hex(addr + r + (int8)read(addr + 1 + n), 4L); }; + auto dp = [&](uint n) { return hex((p << 8) + read(addr + 1 + n), 3L); }; auto ab = [&] { - unsigned n = (read(addr + 1) << 0) + (read(addr + 2) << 8); - return string{ hex(n & 0x1fff, 4L), ":", hex(n >> 13, 1L) }; + uint n = (read(addr + 1) << 0) + (read(addr + 2) << 8); + return string{hex(n & 0x1fff, 4L), ":", hex(n >> 13, 1L)}; }; auto mnemonic = [&]() -> string { @@ -279,9 +279,9 @@ string SPC700::disassemble_opcode(uint16 addr, bool p) { throw; }; - string output = { "..", hex(addr, 4L), " ", mnemonic() }; + string output = {"..", hex(addr, 4L), " ", mnemonic()}; - unsigned length = output.length(); + uint length = output.length(); while(length++ < 30) output.append(" "); output.append( diff --git a/processor/spc700/instructions.cpp b/processor/spc700/instructions.cpp index 7b7a99a3..39b4919c 100644 --- a/processor/spc700/instructions.cpp +++ b/processor/spc700/instructions.cpp @@ -1,13 +1,13 @@ #define call (this->*op) -template -void SPC700::op_adjust(uint8& r) { +template uint8> +auto SPC700::op_adjust(uint8& r) -> void { op_io(); r = call(r); } -template -void SPC700::op_adjust_addr() { +template uint8> +auto SPC700::op_adjust_addr() -> void { dp.l = op_readpc(); dp.h = op_readpc(); rd = op_read(dp); @@ -15,15 +15,15 @@ void SPC700::op_adjust_addr() { op_write(dp, rd); } -template -void SPC700::op_adjust_dp() { +template uint8> +auto SPC700::op_adjust_dp() -> void { dp = op_readpc(); rd = op_readdp(dp); rd = call(rd); op_writedp(dp, rd); } -void SPC700::op_adjust_dpw(signed n) { +auto SPC700::op_adjust_dpw(int n) -> void { dp = op_readpc(); rd.w = op_readdp(dp) + n; op_writedp(dp++, rd.l); @@ -33,8 +33,8 @@ void SPC700::op_adjust_dpw(signed n) { regs.p.z = rd == 0; } -template -void SPC700::op_adjust_dpx() { +template uint8> +auto SPC700::op_adjust_dpx() -> void { dp = op_readpc(); op_io(); rd = op_readdp(dp + regs.x); @@ -42,7 +42,7 @@ void SPC700::op_adjust_dpx() { op_writedp(dp + regs.x, rd); } -void SPC700::op_branch(bool condition) { +auto SPC700::op_branch(bool condition) -> void { rd = op_readpc(); if(condition == false) return; op_io(); @@ -50,7 +50,7 @@ void SPC700::op_branch(bool condition) { regs.pc += (int8)rd; } -void SPC700::op_branch_bit() { +auto SPC700::op_branch_bit() -> void { dp = op_readpc(); sp = op_readdp(dp); rd = op_readpc(); @@ -61,28 +61,28 @@ void SPC700::op_branch_bit() { regs.pc += (int8)rd; } -void SPC700::op_pull(uint8& r) { +auto SPC700::op_pull(uint8& r) -> void { op_io(); op_io(); r = op_readsp(); } -void SPC700::op_push(uint8 r) { +auto SPC700::op_push(uint8 r) -> void { op_io(); op_io(); op_writesp(r); } -template -void SPC700::op_read_addr(uint8& r) { +template uint8> +auto SPC700::op_read_addr(uint8& r) -> void { dp.l = op_readpc(); dp.h = op_readpc(); rd = op_read(dp); r = call(r, rd); } -template -void SPC700::op_read_addri(uint8& r) { +template uint8> +auto SPC700::op_read_addri(uint8& r) -> void { dp.l = op_readpc(); dp.h = op_readpc(); op_io(); @@ -90,29 +90,29 @@ void SPC700::op_read_addri(uint8& r) { regs.a = call(regs.a, rd); } -template -void SPC700::op_read_const(uint8& r) { +template uint8> +auto SPC700::op_read_const(uint8& r) -> void { rd = op_readpc(); r = call(r, rd); } -template -void SPC700::op_read_dp(uint8& r) { +template uint8> +auto SPC700::op_read_dp(uint8& r) -> void { dp = op_readpc(); rd = op_readdp(dp); r = call(r, rd); } -template -void SPC700::op_read_dpi(uint8& r, uint8& i) { +template uint8> +auto SPC700::op_read_dpi(uint8& r, uint8& i) -> void { dp = op_readpc(); op_io(); rd = op_readdp(dp + i); r = call(r, rd); } -template -void SPC700::op_read_dpw() { +template uint16> +auto SPC700::op_read_dpw() -> void { dp = op_readpc(); rd.l = op_readdp(dp++); if(op != &SPC700::op_cpw) op_io(); @@ -120,8 +120,8 @@ void SPC700::op_read_dpw() { regs.ya = call(regs.ya, rd); } -template -void SPC700::op_read_idpx() { +template uint8> +auto SPC700::op_read_idpx() -> void { dp = op_readpc() + regs.x; op_io(); sp.l = op_readdp(dp++); @@ -130,8 +130,8 @@ void SPC700::op_read_idpx() { regs.a = call(regs.a, rd); } -template -void SPC700::op_read_idpy() { +template uint8> +auto SPC700::op_read_idpy() -> void { dp = op_readpc(); op_io(); sp.l = op_readdp(dp++); @@ -140,14 +140,14 @@ void SPC700::op_read_idpy() { regs.a = call(regs.a, rd); } -template -void SPC700::op_read_ix() { +template uint8> +auto SPC700::op_read_ix() -> void { op_io(); rd = op_readdp(regs.x); regs.a = call(regs.a, rd); } -void SPC700::op_set_addr_bit() { +auto SPC700::op_set_addr_bit() -> void { dp.l = op_readpc(); dp.h = op_readpc(); bit = dp >> 13; @@ -182,19 +182,19 @@ void SPC700::op_set_addr_bit() { } } -void SPC700::op_set_bit() { +auto SPC700::op_set_bit() -> void { dp = op_readpc(); rd = op_readdp(dp) & ~(1 << (opcode >> 5)); op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); } -void SPC700::op_set_flag(bool& flag, bool data) { +auto SPC700::op_set_flag(bool& flag, bool data) -> void { op_io(); if(&flag == ®s.p.i) op_io(); flag = data; } -void SPC700::op_test_addr(bool set) { +auto SPC700::op_test_addr(bool set) -> void { dp.l = op_readpc(); dp.h = op_readpc(); rd = op_read(dp); @@ -204,7 +204,7 @@ void SPC700::op_test_addr(bool set) { op_write(dp, set ? rd | regs.a : rd & ~regs.a); } -void SPC700::op_transfer(uint8& from, uint8& to) { +auto SPC700::op_transfer(uint8& from, uint8& to) -> void { op_io(); to = from; if(&to == ®s.s) return; @@ -212,14 +212,14 @@ void SPC700::op_transfer(uint8& from, uint8& to) { regs.p.z = (to == 0); } -void SPC700::op_write_addr(uint8& r) { +auto SPC700::op_write_addr(uint8& r) -> void { dp.l = op_readpc(); dp.h = op_readpc(); op_read(dp); op_write(dp, r); } -void SPC700::op_write_addri(uint8& i) { +auto SPC700::op_write_addri(uint8& i) -> void { dp.l = op_readpc(); dp.h = op_readpc(); op_io(); @@ -228,21 +228,21 @@ void SPC700::op_write_addri(uint8& i) { op_write(dp, regs.a); } -void SPC700::op_write_dp(uint8& r) { +auto SPC700::op_write_dp(uint8& r) -> void { dp = op_readpc(); op_readdp(dp); op_writedp(dp, r); } -void SPC700::op_write_dpi(uint8& r, uint8& i) { +auto SPC700::op_write_dpi(uint8& r, uint8& i) -> void { dp = op_readpc() + i; op_io(); op_readdp(dp); op_writedp(dp, r); } -template -void SPC700::op_write_dp_const() { +template uint8> +auto SPC700::op_write_dp_const() -> void { rd = op_readpc(); dp = op_readpc(); wr = op_readdp(dp); @@ -250,8 +250,8 @@ void SPC700::op_write_dp_const() { op != &SPC700::op_cmp ? op_writedp(dp, wr) : op_io(); } -template -void SPC700::op_write_dp_dp() { +template uint8> +auto SPC700::op_write_dp_dp() -> void { sp = op_readpc(); rd = op_readdp(sp); dp = op_readpc(); @@ -260,8 +260,8 @@ void SPC700::op_write_dp_dp() { op != &SPC700::op_cmp ? op_writedp(dp, wr) : op_io(); } -template -void SPC700::op_write_ix_iy() { +template uint8> +auto SPC700::op_write_ix_iy() -> void { op_io(); rd = op_readdp(regs.y); wr = op_readdp(regs.x); @@ -271,7 +271,7 @@ void SPC700::op_write_ix_iy() { // -void SPC700::op_bne_dp() { +auto SPC700::op_bne_dp() -> void { dp = op_readpc(); sp = op_readdp(dp); rd = op_readpc(); @@ -282,7 +282,7 @@ void SPC700::op_bne_dp() { regs.pc += (int8)rd; } -void SPC700::op_bne_dpdec() { +auto SPC700::op_bne_dpdec() -> void { dp = op_readpc(); wr = op_readdp(dp); op_writedp(dp, --wr); @@ -293,7 +293,7 @@ void SPC700::op_bne_dpdec() { regs.pc += (int8)rd; } -void SPC700::op_bne_dpx() { +auto SPC700::op_bne_dpx() -> void { dp = op_readpc(); op_io(); sp = op_readdp(dp + regs.x); @@ -305,7 +305,7 @@ void SPC700::op_bne_dpx() { regs.pc += (int8)rd; } -void SPC700::op_bne_ydec() { +auto SPC700::op_bne_ydec() -> void { rd = op_readpc(); op_io(); op_io(); @@ -315,7 +315,7 @@ void SPC700::op_bne_ydec() { regs.pc += (int8)rd; } -void SPC700::op_brk() { +auto SPC700::op_brk() -> void { rd.l = op_read(0xffde); rd.h = op_read(0xffdf); op_io(); @@ -328,19 +328,19 @@ void SPC700::op_brk() { regs.p.i = 0; } -void SPC700::op_clv() { +auto SPC700::op_clv() -> void { op_io(); regs.p.v = 0; regs.p.h = 0; } -void SPC700::op_cmc() { +auto SPC700::op_cmc() -> void { op_io(); op_io(); regs.p.c = !regs.p.c; } -void SPC700::op_daa() { +auto SPC700::op_daa() -> void { op_io(); op_io(); if(regs.p.c || (regs.a) > 0x99) { @@ -354,7 +354,7 @@ void SPC700::op_daa() { regs.p.z = (regs.a == 0); } -void SPC700::op_das() { +auto SPC700::op_das() -> void { op_io(); op_io(); if(!regs.p.c || (regs.a) > 0x99) { @@ -368,7 +368,7 @@ void SPC700::op_das() { regs.p.z = (regs.a == 0); } -void SPC700::op_div_ya_x() { +auto SPC700::op_div_ya_x() -> void { op_io(); op_io(); op_io(); @@ -399,13 +399,13 @@ void SPC700::op_div_ya_x() { regs.p.z = (regs.a == 0); } -void SPC700::op_jmp_addr() { +auto SPC700::op_jmp_addr() -> void { rd.l = op_readpc(); rd.h = op_readpc(); regs.pc = rd; } -void SPC700::op_jmp_iaddrx() { +auto SPC700::op_jmp_iaddrx() -> void { dp.l = op_readpc(); dp.h = op_readpc(); op_io(); @@ -415,7 +415,7 @@ void SPC700::op_jmp_iaddrx() { regs.pc = rd; } -void SPC700::op_jsp_dp() { +auto SPC700::op_jsp_dp() -> void { rd = op_readpc(); op_io(); op_io(); @@ -424,7 +424,7 @@ void SPC700::op_jsp_dp() { regs.pc = 0xff00 | rd; } -void SPC700::op_jsr_addr() { +auto SPC700::op_jsr_addr() -> void { rd.l = op_readpc(); rd.h = op_readpc(); op_io(); @@ -435,7 +435,7 @@ void SPC700::op_jsr_addr() { regs.pc = rd; } -void SPC700::op_jst() { +auto SPC700::op_jst() -> void { dp = 0xffde - ((opcode >> 4) << 1); rd.l = op_read(dp++); rd.h = op_read(dp++); @@ -447,7 +447,7 @@ void SPC700::op_jst() { regs.pc = rd; } -void SPC700::op_lda_ixinc() { +auto SPC700::op_lda_ixinc() -> void { op_io(); regs.a = op_readdp(regs.x++); op_io(); @@ -455,7 +455,7 @@ void SPC700::op_lda_ixinc() { regs.p.z = regs.a == 0; } -void SPC700::op_mul_ya() { +auto SPC700::op_mul_ya() -> void { op_io(); op_io(); op_io(); @@ -472,17 +472,17 @@ void SPC700::op_mul_ya() { regs.p.z = (regs.y == 0); } -void SPC700::op_nop() { +auto SPC700::op_nop() -> void { op_io(); } -void SPC700::op_plp() { +auto SPC700::op_plp() -> void { op_io(); op_io(); regs.p = op_readsp(); } -void SPC700::op_rti() { +auto SPC700::op_rti() -> void { regs.p = op_readsp(); rd.l = op_readsp(); rd.h = op_readsp(); @@ -491,7 +491,7 @@ void SPC700::op_rti() { regs.pc = rd; } -void SPC700::op_rts() { +auto SPC700::op_rts() -> void { rd.l = op_readsp(); rd.h = op_readsp(); op_io(); @@ -499,7 +499,7 @@ void SPC700::op_rts() { regs.pc = rd; } -void SPC700::op_sta_idpx() { +auto SPC700::op_sta_idpx() -> void { sp = op_readpc() + regs.x; op_io(); dp.l = op_readdp(sp++); @@ -508,7 +508,7 @@ void SPC700::op_sta_idpx() { op_write(dp, regs.a); } -void SPC700::op_sta_idpy() { +auto SPC700::op_sta_idpy() -> void { sp = op_readpc(); dp.l = op_readdp(sp++); dp.h = op_readdp(sp++); @@ -518,33 +518,33 @@ void SPC700::op_sta_idpy() { op_write(dp, regs.a); } -void SPC700::op_sta_ix() { +auto SPC700::op_sta_ix() -> void { op_io(); op_readdp(regs.x); op_writedp(regs.x, regs.a); } -void SPC700::op_sta_ixinc() { +auto SPC700::op_sta_ixinc() -> void { op_io(); op_io(); op_writedp(regs.x++, regs.a); } -void SPC700::op_stw_dp() { +auto SPC700::op_stw_dp() -> void { dp = op_readpc(); op_readdp(dp); op_writedp(dp++, regs.a); op_writedp(dp++, regs.y); } -void SPC700::op_wait() { +auto SPC700::op_wait() -> void { while(true) { op_io(); op_io(); } } -void SPC700::op_xcn() { +auto SPC700::op_xcn() -> void { op_io(); op_io(); op_io(); diff --git a/processor/spc700/memory.hpp b/processor/spc700/memory.hpp index c4b6d99f..03b70240 100644 --- a/processor/spc700/memory.hpp +++ b/processor/spc700/memory.hpp @@ -1,19 +1,19 @@ -alwaysinline uint8 op_readpc() { +alwaysinline auto op_readpc() -> uint8 { return op_read(regs.pc++); } -alwaysinline uint8 op_readsp() { +alwaysinline auto op_readsp() -> uint8 { return op_read(0x0100 | ++regs.s); } -alwaysinline void op_writesp(uint8 data) { +alwaysinline auto op_writesp(uint8 data) -> void { return op_write(0x0100 | regs.s--, data); } -alwaysinline uint8 op_readdp(uint8 addr) { +alwaysinline auto op_readdp(uint8 addr) -> uint8 { return op_read((regs.p.p << 8) + addr); } -alwaysinline void op_writedp(uint8 addr, uint8 data) { +alwaysinline auto op_writedp(uint8 addr, uint8 data) -> void { return op_write((regs.p.p << 8) + addr, data); } diff --git a/processor/spc700/registers.hpp b/processor/spc700/registers.hpp index 48aa92c8..bd222bc3 100644 --- a/processor/spc700/registers.hpp +++ b/processor/spc700/registers.hpp @@ -1,51 +1,51 @@ -struct flag_t { - bool n, v, p, b, h, i, z, c; - - inline operator unsigned() const { +struct Flag { + inline operator uint() const { return (n << 7) | (v << 6) | (p << 5) | (b << 4) | (h << 3) | (i << 2) | (z << 1) | (c << 0); } - inline unsigned operator=(uint8 data) { + inline auto operator=(uint8 data) -> uint { n = data & 0x80; v = data & 0x40; p = data & 0x20; b = data & 0x10; h = data & 0x08; i = data & 0x04; z = data & 0x02; c = data & 0x01; return data; } - inline unsigned operator|=(uint8 data) { return operator=(operator unsigned() | data); } - inline unsigned operator^=(uint8 data) { return operator=(operator unsigned() ^ data); } - inline unsigned operator&=(uint8 data) { return operator=(operator unsigned() & data); } + inline auto operator|=(uint8 data) -> uint { return operator=(operator uint() | data); } + inline auto operator^=(uint8 data) -> uint { return operator=(operator uint() ^ data); } + inline auto operator&=(uint8 data) -> uint { return operator=(operator uint() & data); } + + bool n, v, p, b, h, i, z, c; }; -struct word_t { +struct Word { + inline operator uint() const { return w; } + inline auto operator=(uint data) -> uint { return w = data; } + + inline auto operator++() -> uint { return ++w; } + inline auto operator--() -> uint { return --w; } + + inline auto operator++(int) -> uint { unsigned data = w++; return data; } + inline auto operator--(int) -> uint { unsigned data = w--; return data; } + + inline auto operator+=(uint data) -> uint { return w += data;; } + inline auto operator-=(uint data) -> uint { return w -= data;; } + + inline auto operator|=(uint data) -> uint { return w |= data; } + inline auto operator^=(uint data) -> uint { return w ^= data; } + inline auto operator&=(uint data) -> uint { return w &= data; } + union { uint16 w; struct { uint8 order_lsb2(l, h); }; }; - - inline operator unsigned() const { return w; } - inline unsigned operator=(unsigned data) { return w = data; } - - inline unsigned operator++() { return ++w; } - inline unsigned operator--() { return --w; } - - inline unsigned operator++(int) { unsigned data = w++; return data; } - inline unsigned operator--(int) { unsigned data = w--; return data; } - - inline unsigned operator+=(unsigned data) { return w += data;; } - inline unsigned operator-=(unsigned data) { return w -= data;; } - - inline unsigned operator|=(unsigned data) { return w |= data; } - inline unsigned operator^=(unsigned data) { return w ^= data; } - inline unsigned operator&=(unsigned data) { return w &= data; } }; -struct regs_t { - word_t pc; +struct Regs { + Word pc; union { uint16 ya; struct { uint8 order_lsb2(a, y); }; }; uint8 x, s; - flag_t p; + Flag p; }; diff --git a/processor/spc700/serialization.cpp b/processor/spc700/serialization.cpp index 87a79e37..942e7e5c 100644 --- a/processor/spc700/serialization.cpp +++ b/processor/spc700/serialization.cpp @@ -1,4 +1,4 @@ -void SPC700::serialize(serializer& s) { +auto SPC700::serialize(serializer& s) -> void { s.integer(regs.pc); s.integer(regs.a); s.integer(regs.x); diff --git a/processor/spc700/spc700.cpp b/processor/spc700/spc700.cpp index e172da83..e129b568 100644 --- a/processor/spc700/spc700.cpp +++ b/processor/spc700/spc700.cpp @@ -8,7 +8,7 @@ namespace Processor { #include "disassembler.cpp" #include "serialization.cpp" -void SPC700::op_step() { +auto SPC700::op_step() -> void { switch(opcode = op_readpc()) { case 0x00: return op_nop(); case 0x01: return op_jst(); diff --git a/processor/spc700/spc700.hpp b/processor/spc700/spc700.hpp index 68ee7a85..02605715 100644 --- a/processor/spc700/spc700.hpp +++ b/processor/spc700/spc700.hpp @@ -4,102 +4,103 @@ namespace Processor { struct SPC700 { - virtual void op_io() = 0; - virtual uint8 op_read(uint16 addr) = 0; - virtual void op_write(uint16 addr, uint8 data) = 0; - void op_step(); + virtual auto op_io() -> void = 0; + virtual auto op_read(uint16 addr) -> uint8 = 0; + virtual auto op_write(uint16 addr, uint8 data) -> void = 0; + virtual auto disassembler_read(uint16 addr) -> uint8 = 0; - virtual uint8 disassembler_read(uint16 addr) = 0; + auto op_step() -> void; + + auto serialize(serializer&) -> void; + + auto disassemble(uint16 addr, bool p) -> string; #include "registers.hpp" #include "memory.hpp" - regs_t regs; - word_t dp, sp, rd, wr, bit, ya; + Regs regs; + Word dp, sp, rd, wr, bit, ya; uint8 opcode; - void serialize(serializer&); - string disassemble_opcode(uint16 addr, bool p); - protected: - uint8 op_adc(uint8, uint8); - uint8 op_and(uint8, uint8); - uint8 op_asl(uint8); - uint8 op_cmp(uint8, uint8); - uint8 op_dec(uint8); - uint8 op_eor(uint8, uint8); - uint8 op_inc(uint8); - uint8 op_ld (uint8, uint8); - uint8 op_lsr(uint8); - uint8 op_or (uint8, uint8); - uint8 op_rol(uint8); - uint8 op_ror(uint8); - uint8 op_sbc(uint8, uint8); - uint8 op_st (uint8, uint8); - uint16 op_adw(uint16, uint16); - uint16 op_cpw(uint16, uint16); - uint16 op_ldw(uint16, uint16); - uint16 op_sbw(uint16, uint16); + auto op_adc(uint8, uint8) -> uint8; + auto op_and(uint8, uint8) -> uint8; + auto op_asl(uint8) -> uint8; + auto op_cmp(uint8, uint8) -> uint8; + auto op_dec(uint8) -> uint8; + auto op_eor(uint8, uint8) -> uint8; + auto op_inc(uint8) -> uint8; + auto op_ld (uint8, uint8) -> uint8; + auto op_lsr(uint8) -> uint8; + auto op_or (uint8, uint8) -> uint8; + auto op_rol(uint8) -> uint8; + auto op_ror(uint8) -> uint8; + auto op_sbc(uint8, uint8) -> uint8; + auto op_st (uint8, uint8) -> uint8; + auto op_adw(uint16, uint16) -> uint16; + auto op_cpw(uint16, uint16) -> uint16; + auto op_ldw(uint16, uint16) -> uint16; + auto op_sbw(uint16, uint16) -> uint16; - template void op_adjust(uint8&); - template void op_adjust_addr(); - template void op_adjust_dp(); - void op_adjust_dpw(signed); - template void op_adjust_dpx(); - void op_branch(bool); - void op_branch_bit(); - void op_pull(uint8&); - void op_push(uint8); - template void op_read_addr(uint8&); - template void op_read_addri(uint8&); - template void op_read_const(uint8&); - template void op_read_dp(uint8&); - template void op_read_dpi(uint8&, uint8&); - template void op_read_dpw(); - template void op_read_idpx(); - template void op_read_idpy(); - template void op_read_ix(); - void op_set_addr_bit(); - void op_set_bit(); - void op_set_flag(bool&, bool); - void op_test_addr(bool); - void op_transfer(uint8&, uint8&); - void op_write_addr(uint8&); - void op_write_addri(uint8&); - void op_write_dp(uint8&); - void op_write_dpi(uint8&, uint8&); - template void op_write_dp_const(); - template void op_write_dp_dp(); - template void op_write_ix_iy(); + template uint8> auto op_adjust(uint8&) -> void; + template uint8> auto op_adjust_addr() -> void; + template uint8> auto op_adjust_dp() -> void; + auto op_adjust_dpw(int) -> void; + template uint8> auto op_adjust_dpx() -> void; + auto op_branch(bool) -> void; + auto op_branch_bit() -> void; + auto op_pull(uint8&) -> void; + auto op_push(uint8) -> void; + template uint8> auto op_read_addr(uint8&) -> void; + template uint8> auto op_read_addri(uint8&) -> void; + template uint8> auto op_read_const(uint8&) -> void; + template uint8> auto op_read_dp(uint8&) -> void; + template uint8> auto op_read_dpi(uint8&, uint8&) -> void; + template uint16> auto op_read_dpw() -> void; + template uint8> auto op_read_idpx() -> void; + template uint8> auto op_read_idpy() -> void; + template uint8> auto op_read_ix() -> void; + auto op_set_addr_bit() -> void; + auto op_set_bit() -> void; + auto op_set_flag(bool&, bool) -> void; + auto op_test_addr(bool) -> void; + auto op_transfer(uint8&, uint8&) -> void; + auto op_write_addr(uint8&) -> void; + auto op_write_addri(uint8&) -> void; + auto op_write_dp(uint8&) -> void; + auto op_write_dpi(uint8&, uint8&) -> void; + template uint8> auto op_write_dp_const() -> void; + template uint8> auto op_write_dp_dp() -> void; + template uint8> auto op_write_ix_iy() -> void; - void op_bne_dp(); - void op_bne_dpdec(); - void op_bne_dpx(); - void op_bne_ydec(); - void op_brk(); - void op_clv(); - void op_cmc(); - void op_daa(); - void op_das(); - void op_div_ya_x(); - void op_jmp_addr(); - void op_jmp_iaddrx(); - void op_jsp_dp(); - void op_jsr_addr(); - void op_jst(); - void op_lda_ixinc(); - void op_mul_ya(); - void op_nop(); - void op_plp(); - void op_rti(); - void op_rts(); - void op_sta_idpx(); - void op_sta_idpy(); - void op_sta_ix(); - void op_sta_ixinc(); - void op_stw_dp(); - void op_wait(); - void op_xcn(); + auto op_bne_dp() -> void; + auto op_bne_dpdec() -> void; + auto op_bne_dpx() -> void; + auto op_bne_ydec() -> void; + auto op_brk() -> void; + auto op_clv() -> void; + auto op_cmc() -> void; + auto op_daa() -> void; + auto op_das() -> void; + auto op_div_ya_x() -> void; + auto op_jmp_addr() -> void; + auto op_jmp_iaddrx() -> void; + auto op_jsp_dp() -> void; + auto op_jsr_addr() -> void; + auto op_jst() -> void; + auto op_lda_ixinc() -> void; + auto op_mul_ya() -> void; + auto op_nop() -> void; + auto op_plp() -> void; + auto op_rti() -> void; + auto op_rts() -> void; + auto op_sta_idpx() -> void; + auto op_sta_idpy() -> void; + auto op_sta_ix() -> void; + auto op_sta_ixinc() -> void; + auto op_stw_dp() -> void; + auto op_wait() -> void; + auto op_xcn() -> void; }; } diff --git a/processor/upd96050/disassembler.cpp b/processor/upd96050/disassembler.cpp index 08c3552a..8fb64520 100644 --- a/processor/upd96050/disassembler.cpp +++ b/processor/upd96050/disassembler.cpp @@ -1,7 +1,5 @@ -#ifdef NECDSP_CPP - -string NECDSP::disassemble(uint14 ip) { - string output = { hex<4>(ip), " " }; +auto uPD96050::disassemble(uint14 ip) -> string { + string output = {hex(ip, 4L), " "}; uint24 opcode = programROM[ip]; uint2 type = opcode >> 22; @@ -98,7 +96,7 @@ string NECDSP::disassemble(uint14 ip) { } if(dphm) { - output.append("\n m", hex<1>(dphm)); + output.append("\n m", hex(dphm, 1L)); } if(rpdcr == 1) { @@ -160,7 +158,7 @@ string NECDSP::disassemble(uint14 ip) { default: output.append("?????? "); break; } - output.append("$", hex<4>(jp)); + output.append("$", hex(jp, 4L)); } if(type == 3) { //LD @@ -168,7 +166,7 @@ string NECDSP::disassemble(uint14 ip) { uint16 id = opcode >> 6; uint4 dst = opcode >> 0; - output.append("$", hex<4>(id), ","); + output.append("$", hex(id, 4L), ","); switch(dst) { case 0: output.append("non"); break; @@ -192,5 +190,3 @@ string NECDSP::disassemble(uint14 ip) { return output; } - -#endif diff --git a/processor/upd96050/instructions.cpp b/processor/upd96050/instructions.cpp index c9fcb4c0..c96ae148 100644 --- a/processor/upd96050/instructions.cpp +++ b/processor/upd96050/instructions.cpp @@ -1,10 +1,10 @@ -void uPD96050::exec() { +auto uPD96050::exec() -> void { uint24 opcode = programROM[regs.pc++]; switch(opcode >> 22) { - case 0: exec_op(opcode); break; - case 1: exec_rt(opcode); break; - case 2: exec_jp(opcode); break; - case 3: exec_ld(opcode); break; + case 0: execOP(opcode); break; + case 1: execRT(opcode); break; + case 2: execJP(opcode); break; + case 3: execLD(opcode); break; } int32 result = (int32)regs.k * regs.l; //sign + 30-bit result @@ -12,7 +12,7 @@ void uPD96050::exec() { regs.n = result << 1; //store low 15-bits + zero } -void uPD96050::exec_op(uint24 opcode) { +auto uPD96050::execOP(uint24 opcode) -> void { uint2 pselect = opcode >> 20; //P select uint4 alu = opcode >> 16; //ALU operation mode uint1 asl = opcode >> 15; //accumulator select @@ -123,7 +123,7 @@ void uPD96050::exec_op(uint24 opcode) { } } - exec_ld((idb << 6) + dst); + execLD((idb << 6) + dst); switch(dpl) { case 1: regs.dp = (regs.dp & 0xf0) + ((regs.dp + 1) & 0x0f); break; //DPINC @@ -136,12 +136,12 @@ void uPD96050::exec_op(uint24 opcode) { if(rpdcr) regs.rp--; } -void uPD96050::exec_rt(uint24 opcode) { - exec_op(opcode); +auto uPD96050::execRT(uint24 opcode) -> void { + execOP(opcode); regs.pc = regs.stack[--regs.sp]; } -void uPD96050::exec_jp(uint24 opcode) { +auto uPD96050::execJP(uint24 opcode) -> void { uint9 brch = opcode >> 13; //branch uint11 na = opcode >> 2; //next address uint2 bank = opcode >> 0; //bank address @@ -197,7 +197,7 @@ void uPD96050::exec_jp(uint24 opcode) { } } -void uPD96050::exec_ld(uint24 opcode) { +auto uPD96050::execLD(uint24 opcode) -> void { uint16 id = opcode >> 6; //immediate data uint4 dst = opcode >> 0; //destination diff --git a/processor/upd96050/memory.cpp b/processor/upd96050/memory.cpp index 62c5bb62..1d3df9a2 100644 --- a/processor/upd96050/memory.cpp +++ b/processor/upd96050/memory.cpp @@ -1,11 +1,11 @@ -uint8 uPD96050::sr_read() { +auto uPD96050::readSR() -> uint8 { return regs.sr >> 8; } -void uPD96050::sr_write(uint8 data) { +auto uPD96050::writeSR(uint8 data) -> void { } -uint8 uPD96050::dr_read() { +auto uPD96050::readDR() -> uint8 { if(regs.sr.drc == 0) { //16-bit if(regs.sr.drs == 0) { @@ -23,7 +23,7 @@ uint8 uPD96050::dr_read() { } } -void uPD96050::dr_write(uint8 data) { +auto uPD96050::writeDR(uint8 data) -> void { if(regs.sr.drc == 0) { //16-bit if(regs.sr.drs == 0) { @@ -41,7 +41,7 @@ void uPD96050::dr_write(uint8 data) { } } -uint8 uPD96050::dp_read(uint12 addr) { +auto uPD96050::readDP(uint12 addr) -> uint8 { bool hi = addr & 1; addr = (addr >> 1) & 2047; @@ -52,7 +52,7 @@ uint8 uPD96050::dp_read(uint12 addr) { } } -void uPD96050::dp_write(uint12 addr, uint8 data) { +auto uPD96050::writeDP(uint12 addr, uint8 data) -> void { bool hi = addr & 1; addr = (addr >> 1) & 2047; diff --git a/processor/upd96050/registers.cpp b/processor/upd96050/registers.cpp new file mode 100644 index 00000000..1aaa2db4 --- /dev/null +++ b/processor/upd96050/registers.cpp @@ -0,0 +1,21 @@ +uPD96050::Flag::operator uint() const { + return (s1 << 5) + (s0 << 4) + (c << 3) + (z << 2) + (ov1 << 1) + (ov0 << 0); +} + +auto uPD96050::Flag::operator=(uint d) -> uint { + s1 = d & 0x20; s0 = d & 0x10; c = d & 0x08; z = d & 0x04; ov1 = d & 0x02; ov0 = d & 0x01; + return d; +} + +uPD96050::Status::operator uint() const { + return (rqm << 15) + (usf1 << 14) + (usf0 << 13) + (drs << 12) + + (dma << 11) + (drc << 10) + (soc << 9) + (sic << 8) + + (ei << 7) + (p1 << 1) + (p0 << 0); +} + +auto uPD96050::Status::operator=(uint d) -> uint { + rqm = d & 0x8000; usf1 = d & 0x4000; usf0 = d & 0x2000; drs = d & 0x1000; + dma = d & 0x0800; drc = d & 0x0400; soc = d & 0x0200; sic = d & 0x0100; + ei = d & 0x0080; p1 = d & 0x0002; p0 = d & 0x0001; + return d; +} diff --git a/processor/upd96050/registers.hpp b/processor/upd96050/registers.hpp deleted file mode 100644 index ff5de61f..00000000 --- a/processor/upd96050/registers.hpp +++ /dev/null @@ -1,51 +0,0 @@ -struct Flag { - bool s1, s0, c, z, ov1, ov0; - - inline operator unsigned() const { - return (s1 << 5) + (s0 << 4) + (c << 3) + (z << 2) + (ov1 << 1) + (ov0 << 0); - } - - inline unsigned operator=(unsigned d) { - s1 = d & 0x20; s0 = d & 0x10; c = d & 0x08; z = d & 0x04; ov1 = d & 0x02; ov0 = d & 0x01; - return d; - } -}; - -struct Status { - bool rqm, usf1, usf0, drs, dma, drc, soc, sic, ei, p1, p0; - - inline operator unsigned() const { - return (rqm << 15) + (usf1 << 14) + (usf0 << 13) + (drs << 12) - + (dma << 11) + (drc << 10) + (soc << 9) + (sic << 8) - + (ei << 7) + (p1 << 1) + (p0 << 0); - } - - inline unsigned operator=(unsigned d) { - rqm = d & 0x8000; usf1 = d & 0x4000; usf0 = d & 0x2000; drs = d & 0x1000; - dma = d & 0x0800; drc = d & 0x0400; soc = d & 0x0200; sic = d & 0x0100; - ei = d & 0x0080; p1 = d & 0x0002; p0 = d & 0x0001; - return d; - } -}; - -struct Regs { - uint16 stack[16]; //LIFO - varuint pc; //program counter - varuint rp; //ROM pointer - varuint dp; //data pointer - uint4 sp; //stack pointer - int16 k; - int16 l; - int16 m; - int16 n; - int16 a; //accumulator - int16 b; //accumulator - Flag flaga; - Flag flagb; - uint16 tr; //temporary register - uint16 trb; //temporary register - Status sr; //status register - uint16 dr; //data register - uint16 si; - uint16 so; -} regs; diff --git a/processor/upd96050/serialization.cpp b/processor/upd96050/serialization.cpp index d94821d4..4c69bbfa 100644 --- a/processor/upd96050/serialization.cpp +++ b/processor/upd96050/serialization.cpp @@ -1,4 +1,4 @@ -void uPD96050::serialize(serializer& s) { +auto uPD96050::serialize(serializer& s) -> void { s.array(dataRAM); s.array(regs.stack); diff --git a/processor/upd96050/upd96050.cpp b/processor/upd96050/upd96050.cpp index 390cfefb..c9f6e870 100644 --- a/processor/upd96050/upd96050.cpp +++ b/processor/upd96050/upd96050.cpp @@ -3,12 +3,13 @@ namespace Processor { +#include "registers.cpp" #include "instructions.cpp" #include "memory.cpp" #include "disassembler.cpp" #include "serialization.cpp" -void uPD96050::power() { +auto uPD96050::power() -> void { if(revision == Revision::uPD7725) { regs.pc.bits(11); regs.rp.bits(10); @@ -21,7 +22,7 @@ void uPD96050::power() { regs.dp.bits(11); } - for(unsigned n = 0; n < 16; n++) regs.stack[n] = 0x0000; + for(auto n : range(16)) regs.stack[n] = 0x0000; regs.pc = 0x0000; regs.rp = 0x0000; regs.dp = 0x0000; diff --git a/processor/upd96050/upd96050.hpp b/processor/upd96050/upd96050.hpp index a20cfa67..dcede251 100644 --- a/processor/upd96050/upd96050.hpp +++ b/processor/upd96050/upd96050.hpp @@ -1,38 +1,74 @@ +//NEC uPD7720 (not supported) +//NEC uPD7725 +//NEC uPD96050 + #ifndef PROCESSOR_UPD96050_HPP #define PROCESSOR_UPD96050_HPP namespace Processor { -//NEC uPD7720 (not supported) -//NEC uPD7725 -//NEC uPD96050 - struct uPD96050 { - enum class Revision : unsigned { uPD7725, uPD96050 } revision; + auto power() -> void; + auto exec() -> void; + auto serialize(serializer&) -> void; + + auto execOP(uint24 opcode) -> void; + auto execRT(uint24 opcode) -> void; + auto execJP(uint24 opcode) -> void; + auto execLD(uint24 opcode) -> void; + + auto readSR() -> uint8; + auto writeSR(uint8 data) -> void; + + auto readDR() -> uint8; + auto writeDR(uint8 data) -> void; + + auto readDP(uint12 addr) -> uint8; + auto writeDP(uint12 addr, uint8 data) -> void; + + auto disassemble(uint14 ip) -> string; + + enum class Revision : uint { uPD7725, uPD96050 } revision; uint24 programROM[16384]; uint16 dataROM[2048]; uint16 dataRAM[2048]; - #include "registers.hpp" - void power(); - void exec(); - void serialize(serializer&); + //registers.cpp + struct Flag { + inline operator uint() const; + inline auto operator=(uint d) -> uint; - void exec_op(uint24 opcode); - void exec_rt(uint24 opcode); - void exec_jp(uint24 opcode); - void exec_ld(uint24 opcode); + bool s1, s0, c, z, ov1, ov0; + }; - uint8 sr_read(); - void sr_write(uint8 data); + struct Status { + inline operator uint() const; + inline auto operator=(uint d) -> uint; - uint8 dr_read(); - void dr_write(uint8 data); + bool rqm, usf1, usf0, drs, dma, drc, soc, sic, ei, p1, p0; + }; - uint8 dp_read(uint12 addr); - void dp_write(uint12 addr, uint8 data); - - string disassemble(uint14 ip); + struct Regs { + uint16 stack[16]; //LIFO + varuint pc; //program counter + varuint rp; //ROM pointer + varuint dp; //data pointer + uint4 sp; //stack pointer + int16 k; + int16 l; + int16 m; + int16 n; + int16 a; //accumulator + int16 b; //accumulator + Flag flaga; + Flag flagb; + uint16 tr; //temporary register + uint16 trb; //temporary register + Status sr; //status register + uint16 dr; //data register + uint16 si; + uint16 so; + } regs; }; } diff --git a/ruby/GNUmakefile b/ruby/GNUmakefile index b73d0bb8..44cdb57c 100644 --- a/ruby/GNUmakefile +++ b/ruby/GNUmakefile @@ -21,6 +21,7 @@ rubylink += $(if $(findstring audio.ao,$(ruby)),-lao) rubylink += $(if $(findstring audio.directsound,$(ruby)),-ldsound) rubylink += $(if $(findstring audio.pulseaudio,$(ruby)),-lpulse) rubylink += $(if $(findstring audio.pulseaudiosimple,$(ruby)),-lpulse-simple) +rubylink += $(if $(findstring audio.wasapi,$(ruby)),-lavrt -luuid) rubylink += $(if $(findstring audio.xaudio2,$(ruby)),-lole32) rubylink += $(if $(findstring input.udev,$(ruby)),-ludev) diff --git a/ruby/audio/wasapi.cpp b/ruby/audio/wasapi.cpp new file mode 100644 index 00000000..adc28650 --- /dev/null +++ b/ruby/audio/wasapi.cpp @@ -0,0 +1,169 @@ +#include +#include +#include +#include +#include +#include + +#include + +struct AudioWASAPI : Audio { + ~AudioWASAPI() { term(); } + + struct { + bool exclusive = false; + bool synchronize = false; + uint frequency = 44100; + } settings; + + auto cap(const string& name) -> bool { + if(name == Audio::Exclusive) return true; + if(name == Audio::Synchronize) return true; + if(name == Audio::Frequency) return true; + return false; + } + + auto get(const string& name) -> any { + if(name == Audio::Exclusive) return settings.exclusive; + if(name == Audio::Synchronize) return settings.synchronize; + if(name == Audio::Frequency) return settings.frequency; + return {}; + } + + auto set(const string& name, const any& value) -> bool { + if(name == Audio::Exclusive && value.get()) { + settings.exclusive = value.get(); + return true; + } + + if(name == Audio::Synchronize && value.is()) { + settings.synchronize = value.get(); + return true; + } + + if(name == Audio::Frequency && value.is()) { + settings.frequency = value.get(); + dsp.setFrequency(settings.frequency); + return true; + } + + return false; + } + + auto sample(uint16 left, uint16 right) -> void { + int samples[] = {(int16)left, (int16)right}; + dsp.sample(samples); + while(dsp.pending()) { + dsp.read(samples); + write(samples); + } + } + + auto clear() -> void { + audioClient->Stop(); + renderClient->GetBuffer(bufferFrameCount, &bufferData); + + renderClient->ReleaseBuffer(bufferFrameCount, 0); + audioClient->Start(); + } + + auto init() -> bool { + if(CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&enumerator) != S_OK) return false; + if(enumerator->GetDefaultAudioEndpoint(eRender, eConsole, &device) != S_OK) return false; + if(device->Activate(IID_IAudioClient, CLSCTX_ALL, nullptr, (void**)&audioClient) != S_OK) return false; + + if(settings.exclusive) { + if(device->OpenPropertyStore(STGM_READ, &propertyStore) != S_OK) return false; + if(propertyStore->GetValue(PKEY_AudioEngine_DeviceFormat, &propVariant) != S_OK) return false; + waveFormat = (WAVEFORMATEX*)propVariant.blob.pBlobData; + if(audioClient->GetDevicePeriod(nullptr, &devicePeriod) != S_OK) return false; + if(audioClient->Initialize(AUDCLNT_SHAREMODE_EXCLUSIVE, 0, devicePeriod, devicePeriod, waveFormat, nullptr) != S_OK) return false; + taskHandle = AvSetMmThreadCharacteristics(L"Pro Audio", &taskIndex); + } else { + if(audioClient->GetMixFormat(&waveFormat) != S_OK) return false; + if(audioClient->GetDevicePeriod(&devicePeriod, nullptr)) return false; + if(audioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, 0, devicePeriod, 0, waveFormat, nullptr) != S_OK) return false; + } + + if(audioClient->GetService(IID_IAudioRenderClient, (void**)&renderClient) != S_OK) return false; + if(audioClient->GetBufferSize(&bufferFrameCount) != S_OK) return false; + + switch(((WAVEFORMATEXTENSIBLE*)waveFormat)->SubFormat.Data1) { + case 1: ieee = false; break; //fixed point + case 3: ieee = true; break; //floating point + default: return false; //unknown format; abort + } + + dsp.setChannels(2); + dsp.setPrecision(16); + dsp.setFrequency(settings.frequency); + + dsp.setResampler(DSP::ResampleEngine::Linear); + dsp.setResamplerFrequency(waveFormat->nSamplesPerSec); + dsp.setChannels(waveFormat->nChannels); + dsp.setPrecision(waveFormat->wBitsPerSample); + + print("[WASAPI]\n"); + print("Channels: ", waveFormat->nChannels, "\n"); + print("Precision: ", waveFormat->wBitsPerSample, "\n"); + print("Frequency: ", waveFormat->nSamplesPerSec, "\n"); + print("IEEE-754: ", ieee, "\n"); + print("Exclusive: ", settings.exclusive, "\n\n"); + + audioClient->Start(); + return true; + } + + auto term() -> void { + if(audioClient) { + audioClient->Stop(); + } + + if(taskHandle) { + AvRevertMmThreadCharacteristics(taskHandle); + taskHandle = nullptr; + } + } + +private: + auto write(int samples[]) -> void { + while(true) { + uint32 padding = 0; + audioClient->GetCurrentPadding(&padding); + if(bufferFrameCount - padding < 1) { + if(!settings.synchronize) return; + continue; + } + break; + } + + renderClient->GetBuffer(1, &bufferData); + + if(ieee) { + auto buffer = (float*)bufferData; + buffer[0] = (int16)samples[0] / 32768.0; + buffer[1] = (int16)samples[1] / 32768.0; + } else { + auto buffer = (int16*)bufferData; + buffer[0] = (int16)samples[0]; + buffer[1] = (int16)samples[1]; + } + + renderClient->ReleaseBuffer(1, 0); + } + + DSP dsp; + IMMDeviceEnumerator* enumerator = nullptr; + IMMDevice* device = nullptr; + IPropertyStore* propertyStore = nullptr; + IAudioClient* audioClient = nullptr; + IAudioRenderClient* renderClient = nullptr; + WAVEFORMATEX* waveFormat = nullptr; + PROPVARIANT propVariant; + HANDLE taskHandle = nullptr; + DWORD taskIndex = 0; + REFERENCE_TIME devicePeriod = 0; + uint32 bufferFrameCount = 0; + uint8* bufferData = nullptr; + bool ieee = false; +}; diff --git a/ruby/ruby.cpp b/ruby/ruby.cpp index 14e80020..fc3e84e3 100644 --- a/ruby/ruby.cpp +++ b/ruby/ruby.cpp @@ -1,3 +1,8 @@ +#ifdef _WIN32 + #include + #include +#endif + #include using namespace nall; using namespace ruby; @@ -250,6 +255,10 @@ auto Video::availableDrivers() -> lstring { #include #endif +#if defined(AUDIO_WASAPI) + #include +#endif + #if defined(AUDIO_XAUDIO2) #include #endif @@ -257,6 +266,7 @@ auto Video::availableDrivers() -> lstring { namespace ruby { const string Audio::Device = "Device"; +const string Audio::Exclusive = "Exclusive"; const string Audio::Handle = "Handle"; const string Audio::Synchronize = "Synchronize"; const string Audio::Frequency = "Frequency"; @@ -293,6 +303,10 @@ auto Audio::create(const string& driver) -> Audio* { if(driver == "PulseAudioSimple") return new AudioPulseAudioSimple; #endif + #if defined(AUDIO_WASAPI) + if(driver == "WASAPI") return new AudioWASAPI; + #endif + #if defined(AUDIO_XAUDIO2) if(driver == "XAudio2") return new AudioXAudio2; #endif @@ -301,7 +315,9 @@ auto Audio::create(const string& driver) -> Audio* { } auto Audio::optimalDriver() -> string { - #if defined(AUDIO_XAUDIO2) + #if defined(AUDIO_WASAPI) + return "WASAPI"; + #elif defined(AUDIO_XAUDIO2) return "XAudio2"; #elif defined(AUDIO_DIRECTSOUND) return "DirectSound"; @@ -325,6 +341,8 @@ auto Audio::optimalDriver() -> string { auto Audio::safestDriver() -> string { #if defined(AUDIO_DIRECTSOUND) return "DirectSound"; + #elif defined(AUDIO_WASAPI) + return "WASAPI"; #elif defined(AUDIO_XAUDIO2) return "XAudio2"; #elif defined(AUDIO_ALSA) @@ -347,6 +365,10 @@ auto Audio::safestDriver() -> string { auto Audio::availableDrivers() -> lstring { return { + #if defined(AUDIO_WASAPI) + "WASAPI", + #endif + #if defined(AUDIO_XAUDIO2) "XAudio2", #endif diff --git a/ruby/ruby.hpp b/ruby/ruby.hpp index d7e66940..30d5cf81 100644 --- a/ruby/ruby.hpp +++ b/ruby/ruby.hpp @@ -1,7 +1,7 @@ /* ruby * author: byuu * license: ISC - * version: 0.13 (2015-06-18) + * version: 0.14 (2015-11-19) * * ruby is a cross-platform hardware abstraction layer * it provides a common interface to video, audio and input devices @@ -46,6 +46,7 @@ struct Video { struct Audio { static const nall::string Device; + static const nall::string Exclusive; static const nall::string Handle; static const nall::string Synchronize; static const nall::string Frequency; diff --git a/sfc/cartridge/markup.cpp b/sfc/cartridge/markup.cpp index 1b4a4280..f96a7ecb 100644 --- a/sfc/cartridge/markup.cpp +++ b/sfc/cartridge/markup.cpp @@ -421,7 +421,7 @@ auto Cartridge::parseMarkupNECDSP(Markup::Node root) -> void { } if(node["id"].text() == "ram") { - Mapping m({&NECDSP::ram_read, &necdsp}, {&NECDSP::ram_write, &necdsp}); + Mapping m({&NECDSP::readRAM, &necdsp}, {&NECDSP::writeRAM, &necdsp}); parseMarkupMap(m, node); mapping.append(m); } diff --git a/sfc/coprocessor/necdsp/necdsp.cpp b/sfc/coprocessor/necdsp/necdsp.cpp index 99a3d095..86d1dbb9 100644 --- a/sfc/coprocessor/necdsp/necdsp.cpp +++ b/sfc/coprocessor/necdsp/necdsp.cpp @@ -22,29 +22,29 @@ auto NECDSP::enter() -> void { auto NECDSP::read(uint addr) -> uint8 { cpu.synchronizeCoprocessors(); if(addr & Select) { - return uPD96050::sr_read(); + return uPD96050::readSR(); } else { - return uPD96050::dr_read(); + return uPD96050::readDR(); } } auto NECDSP::write(uint addr, uint8 data) -> void { cpu.synchronizeCoprocessors(); if(addr & Select) { - return uPD96050::sr_write(data); + return uPD96050::writeSR(data); } else { - return uPD96050::dr_write(data); + return uPD96050::writeDR(data); } } -auto NECDSP::ram_read(uint addr) -> uint8 { +auto NECDSP::readRAM(uint addr) -> uint8 { cpu.synchronizeCoprocessors(); - return uPD96050::dp_read(addr); + return uPD96050::readDP(addr); } -auto NECDSP::ram_write(uint addr, uint8 data) -> void { +auto NECDSP::writeRAM(uint addr, uint8 data) -> void { cpu.synchronizeCoprocessors(); - return uPD96050::dp_write(addr, data); + return uPD96050::writeDP(addr, data); } auto NECDSP::init() -> void { diff --git a/sfc/coprocessor/necdsp/necdsp.hpp b/sfc/coprocessor/necdsp/necdsp.hpp index 34292c86..b4457607 100644 --- a/sfc/coprocessor/necdsp/necdsp.hpp +++ b/sfc/coprocessor/necdsp/necdsp.hpp @@ -5,8 +5,8 @@ struct NECDSP : Processor::uPD96050, Coprocessor { auto read(uint addr) -> uint8; auto write(uint addr, uint8 data) -> void; - auto ram_read(uint addr) -> uint8; - auto ram_write(uint addr, uint8 data) -> void; + auto readRAM(uint addr) -> uint8; + auto writeRAM(uint addr, uint8 data) -> void; auto init() -> void; auto load() -> void;