From a219f9c12197660c45d87b0c47af66ea4dedda62 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Sat, 21 Nov 2015 18:36:48 +1100 Subject: [PATCH] Update to v095r08 release. byuu says: Changelog: - added preliminary WASAPI driver (it's really terrible, though. Patches most welcome.) - all of processor/ updated to auto fn() -> ret syntax - all of gb/ updated to auto fn() -> ret syntax If you want to test the WASAPI driver, then edit ui-tomoko/GNUmakefile, and replace audio.xaudio2 with audio.wasapi Note that the two drivers are incompatible and cannot co-exist (yet. We can probably make it work in the future.) All that's left for the auto fn() -> ret syntax is the NES core and the balanced/performance SNES components. This is kind of a big deal because this syntax change causes diffs between WIPs to go crazy. So the sooner we get this done and out of the way, the better. It's also nice from a consistency standpoint, of course. --- emulator/emulator.hpp | 2 +- gb/apu/apu.cpp | 15 +- gb/apu/apu.hpp | 20 +- gb/apu/master/master.cpp | 16 +- gb/apu/master/master.hpp | 11 +- gb/apu/noise/noise.cpp | 18 +- gb/apu/noise/noise.hpp | 23 +-- gb/apu/serialization.cpp | 6 +- gb/apu/square1/square1.cpp | 26 ++- gb/apu/square1/square1.hpp | 27 +-- gb/apu/square2/square2.cpp | 18 +- gb/apu/square2/square2.hpp | 21 +- gb/apu/wave/wave.cpp | 16 +- gb/apu/wave/wave.hpp | 19 +- gb/cartridge/cartridge.cpp | 45 +++-- gb/cartridge/cartridge.hpp | 53 ++--- gb/cartridge/huc1/huc1.cpp | 10 +- gb/cartridge/huc1/huc1.hpp | 8 +- gb/cartridge/huc3/huc3.cpp | 10 +- gb/cartridge/huc3/huc3.hpp | 8 +- gb/cartridge/mbc0/mbc0.cpp | 10 +- gb/cartridge/mbc0/mbc0.hpp | 6 +- gb/cartridge/mbc1/mbc1.cpp | 10 +- gb/cartridge/mbc1/mbc1.hpp | 8 +- gb/cartridge/mbc2/mbc2.cpp | 10 +- gb/cartridge/mbc2/mbc2.hpp | 8 +- gb/cartridge/mbc3/mbc3.cpp | 12 +- gb/cartridge/mbc3/mbc3.hpp | 28 +-- gb/cartridge/mbc5/mbc5.cpp | 10 +- gb/cartridge/mbc5/mbc5.hpp | 8 +- gb/cartridge/mmm01/mmm01.cpp | 10 +- gb/cartridge/mmm01/mmm01.hpp | 8 +- gb/cartridge/serialization.cpp | 6 +- gb/cheat/cheat.cpp | 8 +- gb/cheat/cheat.hpp | 19 +- gb/cpu/cpu.cpp | 21 +- gb/cpu/cpu.hpp | 82 ++++---- gb/cpu/memory.cpp | 18 +- gb/cpu/mmio.cpp | 30 ++- gb/cpu/serialization.cpp | 6 +- gb/cpu/timing.cpp | 22 +-- gb/interface/interface.cpp | 284 +++++++++++++-------------- gb/interface/interface.hpp | 70 +++---- gb/memory/memory.cpp | 32 ++- gb/memory/memory.hpp | 32 +-- gb/ppu/cgb.cpp | 64 +++--- gb/ppu/dmg.cpp | 54 +++-- gb/ppu/mmio.cpp | 12 +- gb/ppu/ppu.cpp | 24 +-- gb/ppu/ppu.hpp | 87 ++++---- gb/ppu/serialization.cpp | 6 +- gb/scheduler/scheduler.cpp | 21 +- gb/scheduler/scheduler.hpp | 20 +- gb/system/serialization.cpp | 20 +- gb/system/system.cpp | 31 ++- gb/system/system.hpp | 53 +++-- gb/video/video.cpp | 43 ++-- gb/video/video.hpp | 13 +- nall/dsp/buffer.hpp | 40 ++-- nall/dsp/core.hpp | 199 +++++++++---------- nall/dsp/resample/average.hpp | 40 ++-- nall/dsp/resample/cosine.hpp | 28 +-- nall/dsp/resample/cubic.hpp | 40 ++-- nall/dsp/resample/hermite.hpp | 36 ++-- nall/dsp/resample/linear.hpp | 28 +-- nall/dsp/resample/nearest.hpp | 28 +-- nall/dsp/resample/sinc.hpp | 52 +++-- nall/dsp/settings.hpp | 20 +- processor/hg51b/hg51b.cpp | 4 +- processor/hg51b/hg51b.hpp | 57 ++++-- processor/hg51b/instructions.cpp | 12 +- processor/hg51b/registers.cpp | 4 +- processor/hg51b/registers.hpp | 25 --- processor/hg51b/serialization.cpp | 2 +- processor/lr35902/disassembler.cpp | 10 +- processor/lr35902/instructions.cpp | 228 ++++++++++----------- processor/lr35902/lr35902.cpp | 6 +- processor/lr35902/lr35902.hpp | 255 ++++++++++++------------ processor/lr35902/serialization.cpp | 2 +- processor/r6502/disassembler.cpp | 28 +-- processor/r6502/instructions.cpp | 180 ++++++++--------- processor/r6502/memory.cpp | 16 +- processor/r6502/r6502.cpp | 10 +- processor/r6502/r6502.hpp | 188 +++++++++--------- processor/r6502/registers.hpp | 8 +- processor/r6502/serialization.cpp | 2 +- processor/spc700/algorithms.cpp | 40 ++-- processor/spc700/disassembler.cpp | 18 +- processor/spc700/instructions.cpp | 148 +++++++------- processor/spc700/memory.hpp | 10 +- processor/spc700/registers.hpp | 56 +++--- processor/spc700/serialization.cpp | 2 +- processor/spc700/spc700.cpp | 2 +- processor/spc700/spc700.hpp | 173 ++++++++-------- processor/upd96050/disassembler.cpp | 14 +- processor/upd96050/instructions.cpp | 22 +-- processor/upd96050/memory.cpp | 12 +- processor/upd96050/registers.cpp | 21 ++ processor/upd96050/registers.hpp | 51 ----- processor/upd96050/serialization.cpp | 2 +- processor/upd96050/upd96050.cpp | 5 +- processor/upd96050/upd96050.hpp | 78 ++++++-- ruby/GNUmakefile | 1 + ruby/audio/wasapi.cpp | 169 ++++++++++++++++ ruby/ruby.cpp | 24 ++- ruby/ruby.hpp | 3 +- sfc/cartridge/markup.cpp | 2 +- sfc/coprocessor/necdsp/necdsp.cpp | 16 +- sfc/coprocessor/necdsp/necdsp.hpp | 4 +- 109 files changed, 2048 insertions(+), 1951 deletions(-) delete mode 100644 processor/hg51b/registers.hpp create mode 100644 processor/upd96050/registers.cpp delete mode 100644 processor/upd96050/registers.hpp create mode 100644 ruby/audio/wasapi.cpp 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;