diff --git a/emulator/emulator.hpp b/emulator/emulator.hpp index 2d0c50ee2..2337b6fb1 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.03"; + static const string Version = "095.04"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; @@ -54,75 +54,6 @@ template struct hook { #define privileged private #endif -typedef int1_t int1; -typedef int2_t int2; -typedef int3_t int3; -typedef int4_t int4; -typedef int5_t int5; -typedef int6_t int6; -typedef int7_t int7; -typedef int8_t int8; -typedef int9_t int9; -typedef int10_t int10; -typedef int11_t int11; -typedef int12_t int12; -typedef int13_t int13; -typedef int14_t int14; -typedef int15_t int15; -typedef int16_t int16; -typedef int17_t int17; -typedef int18_t int18; -typedef int19_t int19; -typedef int20_t int20; -typedef int21_t int21; -typedef int22_t int22; -typedef int23_t int23; -typedef int24_t int24; -typedef int25_t int25; -typedef int26_t int26; -typedef int27_t int27; -typedef int28_t int28; -typedef int29_t int29; -typedef int30_t int30; -typedef int31_t int31; -typedef int32_t int32; -typedef int64_t int64; - -typedef uint1_t uint1; -typedef uint2_t uint2; -typedef uint3_t uint3; -typedef uint4_t uint4; -typedef uint5_t uint5; -typedef uint6_t uint6; -typedef uint7_t uint7; -typedef uint8_t uint8; -typedef uint9_t uint9; -typedef uint10_t uint10; -typedef uint11_t uint11; -typedef uint12_t uint12; -typedef uint13_t uint13; -typedef uint14_t uint14; -typedef uint15_t uint15; -typedef uint16_t uint16; -typedef uint17_t uint17; -typedef uint18_t uint18; -typedef uint19_t uint19; -typedef uint20_t uint20; -typedef uint21_t uint21; -typedef uint22_t uint22; -typedef uint23_t uint23; -typedef uint24_t uint24; -typedef uint25_t uint25; -typedef uint26_t uint26; -typedef uint27_t uint27; -typedef uint28_t uint28; -typedef uint29_t uint29; -typedef uint30_t uint30; -typedef uint31_t uint31; -typedef uint32_t uint32; -typedef uint_t<33> uint33; -typedef uint64_t uint64; - -typedef varuint_t varuint; +using varuint = varuint_t; #endif diff --git a/emulator/interface.hpp b/emulator/interface.hpp index b06552908..fdb97fcd0 100644 --- a/emulator/interface.hpp +++ b/emulator/interface.hpp @@ -6,8 +6,8 @@ namespace Emulator { struct Interface { struct Information { string name; - unsigned width; - unsigned height; + uint width; + uint height; bool overscan; double aspectRatio; bool resettable; @@ -18,7 +18,7 @@ struct Interface { } information; struct Media { - unsigned id; + uint id; string name; string type; bool bootable; //false for cartridge slots (eg Sufami Turbo cartridges) @@ -26,52 +26,52 @@ struct Interface { vector media; struct Device { - unsigned id; - unsigned portmask; + uint id; + uint portmask; string name; struct Input { - unsigned id; - unsigned type; //0 = digital, 1 = analog (relative), 2 = rumble + uint id; + uint type; //0 = digital, 1 = analog (relative), 2 = rumble string name; uintptr_t guid; //user data field }; vector input; - vector order; + vector order; }; struct Port { - unsigned id; + uint id; string name; vector device; }; vector port; struct Bind { - virtual auto loadRequest(unsigned, string, string, bool) -> void {} - virtual auto loadRequest(unsigned, string, bool) -> void {} - virtual auto saveRequest(unsigned, string) -> void {} - virtual auto videoColor(unsigned, uint16_t, uint16_t, uint16_t, uint16_t) -> uint32_t { return 0u; } - virtual auto videoRefresh(const uint32_t*, const uint32_t*, unsigned, unsigned, unsigned) -> void {} - virtual auto audioSample(int16_t, int16_t) -> void {} - virtual auto inputPoll(unsigned, unsigned, unsigned) -> int16_t { return 0; } - virtual auto inputRumble(unsigned, unsigned, unsigned, bool) -> void {} - virtual auto dipSettings(const Markup::Node&) -> unsigned { return 0; } - virtual auto path(unsigned) -> string { return ""; } + virtual auto loadRequest(uint, string, string, bool) -> void {} + virtual auto loadRequest(uint, string, bool) -> void {} + virtual auto saveRequest(uint, string) -> void {} + virtual auto videoColor(uint, uint16, uint16, uint16, uint16) -> uint32 { return 0u; } + virtual auto videoRefresh(const uint32*, const uint32*, uint, uint, uint) -> void {} + virtual auto audioSample(int16, int16) -> void {} + virtual auto inputPoll(uint, uint, uint) -> int16 { return 0; } + virtual auto inputRumble(uint, uint, uint, bool) -> void {} + virtual auto dipSettings(const Markup::Node&) -> uint { return 0; } + virtual auto path(uint) -> string { return ""; } virtual auto notify(string text) -> void { print(text, "\n"); } }; Bind* bind = nullptr; //callback bindings (provided by user interface) - auto loadRequest(unsigned id, string name, string type, bool required) -> void { return bind->loadRequest(id, name, type, required); } - auto loadRequest(unsigned id, string path, bool required) -> void { return bind->loadRequest(id, path, required); } - auto saveRequest(unsigned id, string path) -> void { return bind->saveRequest(id, path); } - auto videoColor(unsigned source, uint16_t alpha, uint16_t red, uint16_t green, uint16_t blue) -> uint32_t { return bind->videoColor(source, alpha, red, green, blue); } - auto videoRefresh(const uint32_t* palette, const uint32_t* data, unsigned pitch, unsigned width, unsigned height) -> void { return bind->videoRefresh(palette, data, pitch, width, height); } - auto audioSample(int16_t lsample, int16_t rsample) -> void { return bind->audioSample(lsample, rsample); } - auto inputPoll(unsigned port, unsigned device, unsigned input) -> int16_t { return bind->inputPoll(port, device, input); } - auto inputRumble(unsigned port, unsigned device, unsigned input, bool enable) -> void { return bind->inputRumble(port, device, input, enable); } - auto dipSettings(const Markup::Node& node) -> unsigned { return bind->dipSettings(node); } - auto path(unsigned group) -> string { return bind->path(group); } + auto loadRequest(uint id, string name, string type, bool required) -> void { return bind->loadRequest(id, name, type, required); } + auto loadRequest(uint id, string path, bool required) -> void { return bind->loadRequest(id, path, required); } + auto saveRequest(uint id, string path) -> void { return bind->saveRequest(id, path); } + auto videoColor(uint source, uint16 alpha, uint16 red, uint16 green, uint16 blue) -> uint32 { return bind->videoColor(source, alpha, red, green, blue); } + auto videoRefresh(const uint32* palette, const uint32* data, uint pitch, uint width, uint height) -> void { return bind->videoRefresh(palette, data, pitch, width, height); } + auto audioSample(int16 lsample, int16 rsample) -> void { return bind->audioSample(lsample, rsample); } + auto inputPoll(uint port, uint device, uint input) -> int16 { return bind->inputPoll(port, device, input); } + auto inputRumble(uint port, uint device, uint input, bool enable) -> void { return bind->inputRumble(port, device, input, enable); } + auto dipSettings(const Markup::Node& node) -> uint { return bind->dipSettings(node); } + auto path(uint group) -> string { return bind->path(group); } template auto notify(P&&... p) -> void { return bind->notify({forward

(p)...}); } //information @@ -82,15 +82,15 @@ struct Interface { //media interface virtual auto loaded() -> bool { return false; } virtual auto sha256() -> string { return ""; } - virtual auto group(unsigned id) -> unsigned = 0; - virtual auto load(unsigned id) -> void {} + virtual auto group(uint id) -> uint = 0; + virtual auto load(uint id) -> void {} virtual auto save() -> void {} - virtual auto load(unsigned id, const stream& memory) -> void {} - virtual auto save(unsigned id, const stream& memory) -> void {} + virtual auto load(uint id, const stream& memory) -> void {} + virtual auto save(uint id, const stream& memory) -> void {} virtual auto unload() -> void {} //system interface - virtual auto connect(unsigned port, unsigned device) -> void {} + virtual auto connect(uint port, uint device) -> void {} virtual auto power() -> void {} virtual auto reset() -> void {} virtual auto run() -> void {} @@ -107,7 +107,7 @@ struct Interface { virtual auto cheatSet(const lstring& = lstring{}) -> void {} //utility functions - enum class PaletteMode : unsigned { Literal, Channel, Standard, Emulation }; + enum class PaletteMode : uint { Literal, Channel, Standard, Emulation }; virtual auto paletteUpdate(PaletteMode mode) -> void {} }; diff --git a/fc/fc.hpp b/fc/fc.hpp index b19bac2d6..2003b7a7b 100644 --- a/fc/fc.hpp +++ b/fc/fc.hpp @@ -7,7 +7,7 @@ namespace Famicom { namespace Info { static const string Name = "bnes"; - static const unsigned SerializerVersion = 2; + static const uint SerializerVersion = 2; } } @@ -26,7 +26,7 @@ namespace Famicom { if(thread) co_delete(thread); } - auto create(void (*entrypoint)(), unsigned frequency) -> void { + auto create(auto (*entrypoint)() -> void, uint frequency) -> void { if(thread) co_delete(thread); thread = co_create(65536 * sizeof(void*), entrypoint); this->frequency = frequency; @@ -39,7 +39,7 @@ namespace Famicom { } cothread_t thread = nullptr; - unsigned frequency = 0; + uint frequency = 0; int64 clock = 0; }; diff --git a/gb/gb.hpp b/gb/gb.hpp index 68d172c6a..1a7cb16ec 100644 --- a/gb/gb.hpp +++ b/gb/gb.hpp @@ -7,7 +7,7 @@ namespace GameBoy { namespace Info { static const string Name = "bgb"; - static const unsigned SerializerVersion = 4; + static const uint SerializerVersion = 4; } } @@ -26,7 +26,7 @@ namespace GameBoy { if(thread) co_delete(thread); } - auto create(void (*entrypoint)(), unsigned frequency) -> void { + auto create(auto (*entrypoint)() -> void, uint frequency) -> void { if(thread) co_delete(thread); thread = co_create(65536 * sizeof(void*), entrypoint); this->frequency = frequency; @@ -39,8 +39,8 @@ namespace GameBoy { } cothread_t thread = nullptr; - unsigned frequency = 0; - int64_t clock = 0; + uint frequency = 0; + int64 clock = 0; }; #include diff --git a/gba/cartridge/cartridge.cpp b/gba/cartridge/cartridge.cpp index 1562dde18..33bccd1da 100644 --- a/gba/cartridge/cartridge.cpp +++ b/gba/cartridge/cartridge.cpp @@ -10,7 +10,6 @@ namespace GameBoyAdvance { Cartridge cartridge; Cartridge::Cartridge() { - loaded = false; mrom.data = new uint8[mrom.size = 32 * 1024 * 1024]; sram.data = new uint8[sram.size = 32 * 1024]; eeprom.data = new uint8[eeprom.size = 8 * 1024]; @@ -24,6 +23,14 @@ Cartridge::~Cartridge() { delete[] flash.data; } +auto Cartridge::loaded() const -> bool { + return isLoaded; +} + +auto Cartridge::sha256() const -> string { + return information.sha256; +} + auto Cartridge::title() const -> string { return information.title; } @@ -34,21 +41,18 @@ auto Cartridge::load() -> void { auto document = BML::unserialize(information.markup); information.title = document["information/title"].text(); - unsigned mrom_size = 0; + hasSRAM = false; + hasEEPROM = false; + hasFLASH = false; + if(auto info = document["cartridge/mrom"]) { + mrom.size = min(32 * 1024 * 1024, info["size"].decimal()); + interface->loadRequest(ID::MROM, info["name"].text(), true); - mrom_size = info["size"].decimal(); - for(unsigned addr = mrom_size; addr < mrom.size; addr++) { - mrom.data[addr] = mrom.data[Bus::mirror(addr, mrom_size)]; - } } - has_sram = false; - has_eeprom = false; - has_flash = false; - if(auto info = document["cartridge/sram"]) { - has_sram = true; + hasSRAM = true; sram.size = min(32 * 1024, info["size"].decimal()); sram.mask = sram.size - 1; for(auto n : range(sram.size)) sram.data[n] = 0xff; @@ -58,12 +62,12 @@ auto Cartridge::load() -> void { } if(auto info = document["cartridge/eeprom"]) { - has_eeprom = true; + hasEEPROM = true; eeprom.size = min(8 * 1024, info["size"].decimal()); eeprom.bits = eeprom.size <= 512 ? 6 : 14; if(eeprom.size == 0) eeprom.size = 8192, eeprom.bits = 0; //auto-detect size - eeprom.mask = mrom_size > 16 * 1024 * 1024 ? 0x0fffff00 : 0x0f000000; - eeprom.test = mrom_size > 16 * 1024 * 1024 ? 0x0dffff00 : 0x0d000000; + eeprom.mask = mrom.size > 16 * 1024 * 1024 ? 0x0fffff00 : 0x0f000000; + eeprom.test = mrom.size > 16 * 1024 * 1024 ? 0x0dffff00 : 0x0d000000; for(auto n : range(eeprom.size)) eeprom.data[n] = 0xff; interface->loadRequest(ID::EEPROM, info["name"].text(), false); @@ -71,7 +75,7 @@ auto Cartridge::load() -> void { } if(auto info = document["cartridge/flash"]) { - has_flash = true; + hasFLASH = true; flash.id = info["id"].decimal(); flash.size = min(128 * 1024, info["size"].decimal()); for(auto n : range(flash.size)) flash.data[n] = 0xff; @@ -85,15 +89,15 @@ auto Cartridge::load() -> void { memory.append({ID::FLASH, info["name"].text()}); } - sha256 = Hash::SHA256(mrom.data, mrom_size).digest(); + information.sha256 = Hash::SHA256(mrom.data, mrom.size).digest(); system.load(); - loaded = true; + isLoaded = true; } auto Cartridge::unload() -> void { - if(loaded) { - loaded = false; + if(isLoaded) { + isLoaded = false; memory.reset(); } } @@ -105,24 +109,24 @@ auto Cartridge::power() -> void { #define RAM_ANALYZE -auto Cartridge::read(unsigned mode, uint32 addr) -> uint32 { +auto Cartridge::read(uint mode, uint32 addr) -> uint32 { if(addr < 0x0e00'0000) { - if(has_eeprom && (addr & eeprom.mask) == eeprom.test) return eeprom.read(); + if(hasEEPROM && (addr & eeprom.mask) == eeprom.test) return eeprom.read(); return mrom.read(mode, addr); } else { - if(has_sram) return sram.read(mode, addr); - if(has_flash) return flash.read(addr); + if(hasSRAM) return sram.read(mode, addr); + if(hasFLASH) return flash.read(addr); return cpu.pipeline.fetch.instruction; } } -auto Cartridge::write(unsigned mode, uint32 addr, uint32 word) -> void { +auto Cartridge::write(uint mode, uint32 addr, uint32 word) -> void { if(addr < 0x0e00'0000) { - if(has_eeprom && (addr & eeprom.mask) == eeprom.test) return eeprom.write(word & 1); + if(hasEEPROM && (addr & eeprom.mask) == eeprom.test) return eeprom.write(word & 1); return mrom.write(mode, addr, word); } else { - if(has_sram) return sram.write(mode, addr, word); - if(has_flash) return flash.write(addr, word); + if(hasSRAM) return sram.write(mode, addr, word); + if(hasFLASH) return flash.write(addr, word); } } diff --git a/gba/cartridge/cartridge.hpp b/gba/cartridge/cartridge.hpp index 2b3e5f121..dee717822 100644 --- a/gba/cartridge/cartridge.hpp +++ b/gba/cartridge/cartridge.hpp @@ -1,20 +1,18 @@ -struct Cartridge : property { +struct Cartridge { #include "memory.hpp" - readonly loaded; - readonly sha256; - - readonly has_sram; - readonly has_eeprom; - readonly has_flash; + auto loaded() const -> bool; + auto sha256() const -> string; + auto title() const -> string; struct Information { string markup; + string sha256; string title; } information; struct Media { - unsigned id; + uint id; string name; }; vector memory; @@ -22,16 +20,20 @@ struct Cartridge : property { Cartridge(); ~Cartridge(); - auto title() const -> string; - auto load() -> void; auto unload() -> void; auto power() -> void; - auto read(unsigned mode, uint32 addr) -> uint32; - auto write(unsigned mode, uint32 addr, uint32 word) -> void; + auto read(uint mode, uint32 addr) -> uint32; + auto write(uint mode, uint32 addr, uint32 word) -> void; auto serialize(serializer&) -> void; + +private: + bool isLoaded = false; + bool hasSRAM = false; + bool hasEEPROM = false; + bool hasFLASH = false; }; extern Cartridge cartridge; diff --git a/gba/cartridge/eeprom.cpp b/gba/cartridge/eeprom.cpp index 07ca57b01..0c2807812 100644 --- a/gba/cartridge/eeprom.cpp +++ b/gba/cartridge/eeprom.cpp @@ -1,8 +1,8 @@ -auto Cartridge::EEPROM::read(unsigned addr) -> bool { +auto Cartridge::EEPROM::read(uint addr) -> bool { return data[addr >> 3] & 0x80 >> (addr & 7); } -auto Cartridge::EEPROM::write(unsigned addr, bool bit) -> void { +auto Cartridge::EEPROM::write(uint addr, bool bit) -> void { if(bit == 0) data[addr >> 3] &=~ (0x80 >> (addr & 7)); if(bit == 1) data[addr >> 3] |= (0x80 >> (addr & 7)); } @@ -88,7 +88,7 @@ auto Cartridge::EEPROM::serialize(serializer& s) -> void { s.integer(mask); s.integer(test); s.integer(bits); - s.integer((unsigned&)mode); + s.integer((uint&)mode); s.integer(offset); s.integer(address); } diff --git a/gba/cartridge/memory.hpp b/gba/cartridge/memory.hpp index e7f48ad07..308bc177a 100644 --- a/gba/cartridge/memory.hpp +++ b/gba/cartridge/memory.hpp @@ -1,45 +1,41 @@ -struct Memory { - auto ror(uint32 word, unsigned shift) -> uint32 { - return word << 32 - shift | word >> shift; - } -}; - -struct MROM : Memory { +struct MROM { uint8* data; - unsigned size; - unsigned mask; + uint size; + uint mask; - auto read(unsigned mode, uint32 addr) -> uint32; - auto write(unsigned mode, uint32 addr, uint32 word) -> void; + auto read(uint mode, uint32 addr) -> uint32; + auto write(uint mode, uint32 addr, uint32 word) -> void; + + auto serialize(serializer&) -> void; } mrom; -struct SRAM : Memory { +struct SRAM { uint8* data; - unsigned size; - unsigned mask; + uint size; + uint mask; - auto read(unsigned mode, uint32 addr) -> uint32; - auto write(unsigned mode, uint32 addr, uint32 word) -> void; + auto read(uint mode, uint32 addr) -> uint32; + auto write(uint mode, uint32 addr, uint32 word) -> void; auto serialize(serializer&) -> void; } sram; -struct EEPROM : Memory { +struct EEPROM { uint8* data; - unsigned size; - unsigned mask; - unsigned test; - unsigned bits; + uint size; + uint mask; + uint test; + uint bits; - enum class Mode : unsigned { + enum class Mode : uint { Wait, Command, ReadAddress, ReadValidate, ReadData, WriteAddress, WriteData, WriteValidate } mode; - unsigned offset; - unsigned address; - unsigned addressbits; + uint offset; + uint address; + uint addressbits; - auto read(unsigned addr) -> bool; - auto write(unsigned addr, bool bit) -> void; + auto read(uint addr) -> bool; + auto write(uint addr, bool bit) -> void; auto read() -> bool; auto write(bool bit) -> void; @@ -47,9 +43,9 @@ struct EEPROM : Memory { auto serialize(serializer&) -> void; } eeprom; -struct FLASH : Memory { +struct FLASH { uint8* data; - unsigned size; + uint size; uint16 id; bool unlockhi; diff --git a/gba/cartridge/mrom.cpp b/gba/cartridge/mrom.cpp index 69d35eecd..c5c3293a4 100644 --- a/gba/cartridge/mrom.cpp +++ b/gba/cartridge/mrom.cpp @@ -1,12 +1,23 @@ -auto Cartridge::MROM::read(unsigned mode, uint32 addr) -> uint32 { - if(mode & Word) addr &= ~3; +auto Cartridge::MROM::read(uint mode, uint32 addr) -> uint32 { + if(mode & Word) { + uint32 word = 0; + word |= read(mode & ~Word | Half, (addr & ~3) + 0) << 0; + word |= read(mode & ~Word | Half, (addr & ~3) + 2) << 16; + return word; + } + + addr &= 0x01ff'ffff; + if(addr >= size) return (uint16)(addr >> 1); + if(mode & Half) addr &= ~1; - auto p = data + (addr & 0x01ff'ffff); - if(mode & Word) return p[0] << 0 | p[1] << 8 | p[2] << 16 | p[3] << 24; + auto p = data + addr; if(mode & Half) return p[0] << 0 | p[1] << 8; if(mode & Byte) return p[0] << 0; return 0; //should never occur } -auto Cartridge::MROM::write(unsigned mode, uint32 addr, uint32 word) -> void { +auto Cartridge::MROM::write(uint mode, uint32 addr, uint32 word) -> void { +} + +auto Cartridge::MROM::serialize(serializer& s) -> void { } diff --git a/gba/cartridge/serialization.cpp b/gba/cartridge/serialization.cpp index 12bf580cf..a5be5a14c 100644 --- a/gba/cartridge/serialization.cpp +++ b/gba/cartridge/serialization.cpp @@ -1,5 +1,6 @@ void Cartridge::serialize(serializer& s) { - if(has_sram) sram.serialize(s); - if(has_eeprom) eeprom.serialize(s); - if(has_flash) flash.serialize(s); + mrom.serialize(s); + if(hasSRAM) sram.serialize(s); + if(hasEEPROM) eeprom.serialize(s); + if(hasFLASH) flash.serialize(s); } diff --git a/gba/cartridge/sram.cpp b/gba/cartridge/sram.cpp index 17eeff554..b714a2b69 100644 --- a/gba/cartridge/sram.cpp +++ b/gba/cartridge/sram.cpp @@ -1,15 +1,12 @@ -auto Cartridge::SRAM::read(unsigned mode, uint32 addr) -> uint32 { - if(mode & Word) addr &= ~3; - if(mode & Half) addr &= ~1; +auto Cartridge::SRAM::read(uint mode, uint32 addr) -> uint32 { uint32 word = data[addr & mask]; - word = ror(word, 8 * (addr & 3)); - if(mode & Word) { word &= 0xff; word |= word << 8; word |= word << 16; } - if(mode & Half) { word &= 0xff; word |= word << 8; } + word |= word << 8; + word |= word << 16; return word; } -auto Cartridge::SRAM::write(unsigned mode, uint32 addr, uint32 word) -> void { - data[addr & mask] = ror(word, 8 * (addr & 3)); +auto Cartridge::SRAM::write(uint mode, uint32 addr, uint32 word) -> void { + data[addr & mask] = word; } auto Cartridge::SRAM::serialize(serializer& s) -> void { diff --git a/gba/gba.hpp b/gba/gba.hpp index 19ec42b62..1ab24d1a4 100644 --- a/gba/gba.hpp +++ b/gba/gba.hpp @@ -7,7 +7,7 @@ namespace GameBoyAdvance { namespace Info { static const string Name = "bgba"; - static const unsigned SerializerVersion = 2; + static const uint SerializerVersion = 3; } } @@ -21,7 +21,7 @@ namespace GameBoyAdvance { #include namespace GameBoyAdvance { - enum : unsigned { //mode flags for bus_read, bus_write: + enum : uint { //mode flags for bus read, write: Nonsequential = 1, //N cycle Sequential = 2, //S cycle Prefetch = 4, //instruction fetch (eligible for prefetch) @@ -30,6 +30,7 @@ namespace GameBoyAdvance { Word = 32, //32-bit access Load = 64, //load operation Store = 128, //store operation + Signed = 256, //sign extended }; struct Thread { @@ -37,7 +38,7 @@ namespace GameBoyAdvance { if(thread) co_delete(thread); } - auto create(void (*entrypoint)(), unsigned frequency) -> void { + auto create(auto (*entrypoint)() -> void, uint frequency) -> void { if(thread) co_delete(thread); thread = co_create(65536 * sizeof(void*), entrypoint); this->frequency = frequency; @@ -50,8 +51,8 @@ namespace GameBoyAdvance { } cothread_t thread = nullptr; - unsigned frequency = 0; - signed clock = 0; + uint frequency = 0; + int clock = 0; }; #include diff --git a/nall/stdint.hpp b/nall/stdint.hpp index abc0094d7..662abc98e 100644 --- a/nall/stdint.hpp +++ b/nall/stdint.hpp @@ -1,6 +1,8 @@ #ifndef NALL_STDINT_HPP #define NALL_STDINT_HPP +using uint = unsigned int; + #if defined(_MSC_VER) typedef signed char int8_t; typedef signed short int16_t; diff --git a/nall/varint.hpp b/nall/varint.hpp index 386539977..71737bf59 100644 --- a/nall/varint.hpp +++ b/nall/varint.hpp @@ -145,75 +145,139 @@ private: } -//typedefs - typedef nall::uint_t< 1> uint1_t; - typedef nall::uint_t< 2> uint2_t; - typedef nall::uint_t< 3> uint3_t; - typedef nall::uint_t< 4> uint4_t; - typedef nall::uint_t< 5> uint5_t; - typedef nall::uint_t< 6> uint6_t; - typedef nall::uint_t< 7> uint7_t; -//typedef nall::uint_t< 8> uint8_t; +using int1 = nall::int_t<1>; +using int2 = nall::int_t<2>; +using int3 = nall::int_t<3>; +using int4 = nall::int_t<4>; +using int5 = nall::int_t<5>; +using int6 = nall::int_t<6>; +using int7 = nall::int_t<7>; +using int8 = int8_t; +using int9 = nall::int_t<9>; +using int10 = nall::int_t<10>; +using int11 = nall::int_t<11>; +using int12 = nall::int_t<12>; +using int13 = nall::int_t<13>; +using int14 = nall::int_t<14>; +using int15 = nall::int_t<15>; +using int16 = int16_t; +using int17 = nall::int_t<17>; +using int18 = nall::int_t<18>; +using int19 = nall::int_t<19>; +using int20 = nall::int_t<20>; +using int21 = nall::int_t<21>; +using int22 = nall::int_t<22>; +using int23 = nall::int_t<23>; +using int24 = nall::int_t<24>; +using int25 = nall::int_t<25>; +using int26 = nall::int_t<26>; +using int27 = nall::int_t<27>; +using int28 = nall::int_t<28>; +using int29 = nall::int_t<29>; +using int30 = nall::int_t<30>; +using int31 = nall::int_t<31>; +using int32 = int32_t; +using int33 = nall::int_t<33>; +using int34 = nall::int_t<34>; +using int35 = nall::int_t<35>; +using int36 = nall::int_t<36>; +using int37 = nall::int_t<37>; +using int38 = nall::int_t<38>; +using int39 = nall::int_t<39>; +using int40 = nall::int_t<40>; +using int41 = nall::int_t<41>; +using int42 = nall::int_t<42>; +using int43 = nall::int_t<43>; +using int44 = nall::int_t<44>; +using int45 = nall::int_t<45>; +using int46 = nall::int_t<46>; +using int47 = nall::int_t<47>; +using int48 = nall::int_t<48>; +using int49 = nall::int_t<49>; +using int50 = nall::int_t<50>; +using int51 = nall::int_t<51>; +using int52 = nall::int_t<52>; +using int53 = nall::int_t<53>; +using int54 = nall::int_t<54>; +using int55 = nall::int_t<55>; +using int56 = nall::int_t<56>; +using int57 = nall::int_t<57>; +using int58 = nall::int_t<58>; +using int59 = nall::int_t<59>; +using int60 = nall::int_t<60>; +using int61 = nall::int_t<61>; +using int62 = nall::int_t<62>; +using int63 = nall::int_t<63>; +using int64 = int64_t; - typedef nall::uint_t< 9> uint9_t; - typedef nall::uint_t<10> uint10_t; - typedef nall::uint_t<11> uint11_t; - typedef nall::uint_t<12> uint12_t; - typedef nall::uint_t<13> uint13_t; - typedef nall::uint_t<14> uint14_t; - typedef nall::uint_t<15> uint15_t; -//typedef nall::uint_t<16> uint16_t; +using uint1 = nall::uint_t<1>; +using uint2 = nall::uint_t<2>; +using uint3 = nall::uint_t<3>; +using uint4 = nall::uint_t<4>; +using uint5 = nall::uint_t<5>; +using uint6 = nall::uint_t<6>; +using uint7 = nall::uint_t<7>; +using uint8 = uint8_t; +using uint9 = nall::uint_t<9>; +using uint10 = nall::uint_t<10>; +using uint11 = nall::uint_t<11>; +using uint12 = nall::uint_t<12>; +using uint13 = nall::uint_t<13>; +using uint14 = nall::uint_t<14>; +using uint15 = nall::uint_t<15>; +using uint16 = uint16_t; +using uint17 = nall::uint_t<17>; +using uint18 = nall::uint_t<18>; +using uint19 = nall::uint_t<19>; +using uint20 = nall::uint_t<20>; +using uint21 = nall::uint_t<21>; +using uint22 = nall::uint_t<22>; +using uint23 = nall::uint_t<23>; +using uint24 = nall::uint_t<24>; +using uint25 = nall::uint_t<25>; +using uint26 = nall::uint_t<26>; +using uint27 = nall::uint_t<27>; +using uint28 = nall::uint_t<28>; +using uint29 = nall::uint_t<29>; +using uint30 = nall::uint_t<30>; +using uint31 = nall::uint_t<31>; +using uint32 = uint32_t; +using uint33 = nall::uint_t<33>; +using uint34 = nall::uint_t<34>; +using uint35 = nall::uint_t<35>; +using uint36 = nall::uint_t<36>; +using uint37 = nall::uint_t<37>; +using uint38 = nall::uint_t<38>; +using uint39 = nall::uint_t<39>; +using uint40 = nall::uint_t<40>; +using uint41 = nall::uint_t<41>; +using uint42 = nall::uint_t<42>; +using uint43 = nall::uint_t<43>; +using uint44 = nall::uint_t<44>; +using uint45 = nall::uint_t<45>; +using uint46 = nall::uint_t<46>; +using uint47 = nall::uint_t<47>; +using uint48 = nall::uint_t<48>; +using uint49 = nall::uint_t<49>; +using uint50 = nall::uint_t<50>; +using uint51 = nall::uint_t<51>; +using uint52 = nall::uint_t<52>; +using uint53 = nall::uint_t<53>; +using uint54 = nall::uint_t<54>; +using uint55 = nall::uint_t<55>; +using uint56 = nall::uint_t<56>; +using uint57 = nall::uint_t<57>; +using uint58 = nall::uint_t<58>; +using uint59 = nall::uint_t<59>; +using uint60 = nall::uint_t<60>; +using uint61 = nall::uint_t<61>; +using uint62 = nall::uint_t<62>; +using uint63 = nall::uint_t<63>; +using uint64 = uint64_t; - typedef nall::uint_t<17> uint17_t; - typedef nall::uint_t<18> uint18_t; - typedef nall::uint_t<19> uint19_t; - typedef nall::uint_t<20> uint20_t; - typedef nall::uint_t<21> uint21_t; - typedef nall::uint_t<22> uint22_t; - typedef nall::uint_t<23> uint23_t; - typedef nall::uint_t<24> uint24_t; - typedef nall::uint_t<25> uint25_t; - typedef nall::uint_t<26> uint26_t; - typedef nall::uint_t<27> uint27_t; - typedef nall::uint_t<28> uint28_t; - typedef nall::uint_t<29> uint29_t; - typedef nall::uint_t<30> uint30_t; - typedef nall::uint_t<31> uint31_t; -//typedef nall::uint_t<32> uint32_t; - - typedef nall::int_t< 1> int1_t; - typedef nall::int_t< 2> int2_t; - typedef nall::int_t< 3> int3_t; - typedef nall::int_t< 4> int4_t; - typedef nall::int_t< 5> int5_t; - typedef nall::int_t< 6> int6_t; - typedef nall::int_t< 7> int7_t; -//typedef nall::int_t< 8> int8_t; - - typedef nall::int_t< 9> int9_t; - typedef nall::int_t<10> int10_t; - typedef nall::int_t<11> int11_t; - typedef nall::int_t<12> int12_t; - typedef nall::int_t<13> int13_t; - typedef nall::int_t<14> int14_t; - typedef nall::int_t<15> int15_t; -//typedef nall::int_t<16> int16_t; - - typedef nall::int_t<17> int17_t; - typedef nall::int_t<18> int18_t; - typedef nall::int_t<19> int19_t; - typedef nall::int_t<20> int20_t; - typedef nall::int_t<21> int21_t; - typedef nall::int_t<22> int22_t; - typedef nall::int_t<23> int23_t; - typedef nall::int_t<24> int24_t; - typedef nall::int_t<25> int25_t; - typedef nall::int_t<26> int26_t; - typedef nall::int_t<27> int27_t; - typedef nall::int_t<28> int28_t; - typedef nall::int_t<29> int29_t; - typedef nall::int_t<30> int30_t; - typedef nall::int_t<31> int31_t; -//typedef nall::int_t<32> int32_t; +#if defined(__SIZEOF_INT128__) +using int128 = int128_t; +using uint128 = uint128_t; +#endif #endif diff --git a/sfc/GNUmakefile b/sfc/GNUmakefile index e83d76196..a2a0811c7 100644 --- a/sfc/GNUmakefile +++ b/sfc/GNUmakefile @@ -1,7 +1,7 @@ sfc_objects := sfc-interface sfc-system sfc-controller sfc_objects += sfc-cartridge sfc-cheat sfc_objects += sfc-memory sfc-cpu sfc-smp sfc-dsp sfc-ppu -sfc_objects += sfc-satellaviewbase +sfc_objects += sfc-eboot sfc-satellaviewbase sfc_objects += sfc-icd2 sfc-mcc sfc-nss sfc-event sfc_objects += sfc-sa1 sfc-superfx sfc_objects += sfc-armdsp sfc-hitachidsp sfc-necdsp @@ -44,7 +44,8 @@ obj/sfc-smp.o: $(sfcsmp)/smp.cpp $(call rwildcard,$(sfcsmp)/) obj/sfc-dsp.o: $(sfcdsp)/dsp.cpp $(call rwildcard,$(sfcdsp)/) obj/sfc-ppu.o: $(sfcppu)/ppu.cpp $(call rwildcard,$(sfcppu)/) -obj/sfc-satellaviewbase.o: $(sfc)/base/satellaview/satellaview.cpp $(call rwildcard,$(sfc)/base/satellaview/) +obj/sfc-eboot.o: $(sfc)/expansion/eboot/eboot.cpp $(call rwildcard,$(sfc)/expansion/eboot/) +obj/sfc-satellaviewbase.o: $(sfc)/expansion/satellaview/satellaview.cpp $(call rwildcard,$(sfc)/expansion/satellaview/) obj/sfc-icd2.o: $(sfc)/chip/icd2/icd2.cpp $(call rwildcard,$(sfc)/chip/icd2/) obj/sfc-mcc.o: $(sfc)/chip/mcc/mcc.cpp $(call rwildcard,$(sfc)/chip/mcc/) diff --git a/sfc/base/base.hpp b/sfc/base/base.hpp deleted file mode 100644 index e0cd5ee4e..000000000 --- a/sfc/base/base.hpp +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/sfc/chip/sa1/sa1.cpp b/sfc/chip/sa1/sa1.cpp index fbc6fcacc..aa90e7958 100644 --- a/sfc/chip/sa1/sa1.cpp +++ b/sfc/chip/sa1/sa1.cpp @@ -134,7 +134,7 @@ void SA1::power() { } void SA1::reset() { - create(SA1::Enter, system.cpu_frequency()); + create(SA1::Enter, system.cpuFrequency()); cpubwram.dma = false; for(unsigned addr = 0; addr < iram.size(); addr++) { diff --git a/sfc/chip/superfx/superfx.cpp b/sfc/chip/superfx/superfx.cpp index 8aec89c23..176878a41 100644 --- a/sfc/chip/superfx/superfx.cpp +++ b/sfc/chip/superfx/superfx.cpp @@ -54,7 +54,7 @@ auto SuperFX::power() -> void { auto SuperFX::reset() -> void { GSU::reset(); - create(SuperFX::Enter, system.cpu_frequency()); + create(SuperFX::Enter, system.cpuFrequency()); memory_reset(); timing_reset(); } diff --git a/sfc/controller/controller.cpp b/sfc/controller/controller.cpp index 7d1241f44..46725d78f 100644 --- a/sfc/controller/controller.cpp +++ b/sfc/controller/controller.cpp @@ -15,8 +15,8 @@ Controller::Controller(bool port) : port(port) { } auto Controller::Enter() -> void { - if(co_active() == input.port1->thread) input.port1->enter(); - if(co_active() == input.port2->thread) input.port2->enter(); + if(co_active() == device.controllerPort1->thread) device.controllerPort1->enter(); + if(co_active() == device.controllerPort2->thread) device.controllerPort2->enter(); } auto Controller::enter() -> void { diff --git a/sfc/controller/gamepad/gamepad.cpp b/sfc/controller/gamepad/gamepad.cpp index e3810f384..cef5061a9 100644 --- a/sfc/controller/gamepad/gamepad.cpp +++ b/sfc/controller/gamepad/gamepad.cpp @@ -11,7 +11,7 @@ Gamepad::Gamepad(bool port) : Controller(port) { auto Gamepad::data() -> uint2 { if(counter >= 16) return 1; - if(latched == 1) return interface->inputPoll(port, (unsigned)Input::Device::Joypad, (unsigned)Input::JoypadID::B); + if(latched == 1) return interface->inputPoll(port, (unsigned)Device::ID::Gamepad, B); //note: D-pad physically prevents up+down and left+right from being pressed at the same time switch(counter++) { @@ -38,19 +38,19 @@ auto Gamepad::latch(bool data) -> void { counter = 0; if(latched == 0) { - unsigned id = (unsigned)Input::Device::Joypad; - b = interface->inputPoll(port, id, 0); - y = interface->inputPoll(port, id, 1); - select = interface->inputPoll(port, id, 2); - start = interface->inputPoll(port, id, 3); - up = interface->inputPoll(port, id, 4); - down = interface->inputPoll(port, id, 5); - left = interface->inputPoll(port, id, 6); - right = interface->inputPoll(port, id, 7); - a = interface->inputPoll(port, id, 8); - x = interface->inputPoll(port, id, 9); - l = interface->inputPoll(port, id, 10); - r = interface->inputPoll(port, id, 11); + auto id = (unsigned)Device::ID::Gamepad; + b = interface->inputPoll(port, id, B); + y = interface->inputPoll(port, id, Y); + select = interface->inputPoll(port, id, Select); + start = interface->inputPoll(port, id, Start); + up = interface->inputPoll(port, id, Up); + down = interface->inputPoll(port, id, Down); + left = interface->inputPoll(port, id, Left); + right = interface->inputPoll(port, id, Right); + a = interface->inputPoll(port, id, A); + x = interface->inputPoll(port, id, X); + l = interface->inputPoll(port, id, L); + r = interface->inputPoll(port, id, R); } } diff --git a/sfc/controller/gamepad/gamepad.hpp b/sfc/controller/gamepad/gamepad.hpp index effdec3ed..a2c9e69cc 100644 --- a/sfc/controller/gamepad/gamepad.hpp +++ b/sfc/controller/gamepad/gamepad.hpp @@ -1,4 +1,8 @@ struct Gamepad : Controller { + enum : uint { + B, Y, Select, Start, Up, Down, Left, Right, A, X, L, R, + }; + Gamepad(bool port); auto data() -> uint2; diff --git a/sfc/controller/justifier/justifier.cpp b/sfc/controller/justifier/justifier.cpp index 4ff1f1220..a122398b2 100644 --- a/sfc/controller/justifier/justifier.cpp +++ b/sfc/controller/justifier/justifier.cpp @@ -3,7 +3,7 @@ Justifier::Justifier(bool port, bool chained): Controller(port), chained(chained), -device(chained == false ? (unsigned)Input::Device::Justifier : (unsigned)Input::Device::Justifiers) +device(chained == false ? (unsigned)Device::ID::Justifier : (unsigned)Device::ID::Justifiers) { create(Controller::Enter, 21477272); latched = 0; @@ -47,8 +47,8 @@ auto Justifier::enter() -> void { } if(next < prev) { - int nx1 = interface->inputPoll(port, device, 0 + (unsigned)Input::JustifierID::X); - int ny1 = interface->inputPoll(port, device, 0 + (unsigned)Input::JustifierID::Y); + int nx1 = interface->inputPoll(port, device, 0 + X); + int ny1 = interface->inputPoll(port, device, 0 + Y); nx1 += player1.x; ny1 += player1.y; player1.x = max(-16, min(256 + 16, nx1)); @@ -56,8 +56,8 @@ auto Justifier::enter() -> void { } if(next < prev && chained) { - int nx2 = interface->inputPoll(port, device, 4 + (unsigned)Input::JustifierID::X); - int ny2 = interface->inputPoll(port, device, 4 + (unsigned)Input::JustifierID::Y); + int nx2 = interface->inputPoll(port, device, 4 + X); + int ny2 = interface->inputPoll(port, device, 4 + Y); nx2 += player2.x; ny2 += player2.y; player2.x = max(-16, min(256 + 16, nx2)); @@ -73,13 +73,13 @@ auto Justifier::data() -> uint2 { if(counter >= 32) return 1; if(counter == 0) { - player1.trigger = interface->inputPoll(port, device, 0 + (unsigned)Input::JustifierID::Trigger); - player1.start = interface->inputPoll(port, device, 0 + (unsigned)Input::JustifierID::Start); + player1.trigger = interface->inputPoll(port, device, 0 + Trigger); + player1.start = interface->inputPoll(port, device, 0 + Start); } if(counter == 0 && chained) { - player2.trigger = interface->inputPoll(port, device, 4 + (unsigned)Input::JustifierID::Trigger); - player2.start = interface->inputPoll(port, device, 4 + (unsigned)Input::JustifierID::Start); + player2.trigger = interface->inputPoll(port, device, 4 + Trigger); + player2.start = interface->inputPoll(port, device, 4 + Start); } switch(counter++) { diff --git a/sfc/controller/justifier/justifier.hpp b/sfc/controller/justifier/justifier.hpp index 86b0e5ea8..bcbaa3e02 100644 --- a/sfc/controller/justifier/justifier.hpp +++ b/sfc/controller/justifier/justifier.hpp @@ -1,4 +1,8 @@ struct Justifier : Controller { + enum : uint { + X, Y, Trigger, Start, + }; + Justifier(bool port, bool chained); auto enter() -> void; diff --git a/sfc/controller/mouse/mouse.cpp b/sfc/controller/mouse/mouse.cpp index cb3e375fc..181046dc6 100644 --- a/sfc/controller/mouse/mouse.cpp +++ b/sfc/controller/mouse/mouse.cpp @@ -66,10 +66,10 @@ auto Mouse::latch(bool data) -> void { latched = data; counter = 0; - x = interface->inputPoll(port, (unsigned)Input::Device::Mouse, (unsigned)Input::MouseID::X); //-n = left, 0 = center, +n = right - y = interface->inputPoll(port, (unsigned)Input::Device::Mouse, (unsigned)Input::MouseID::Y); //-n = up, 0 = center, +n = down - l = interface->inputPoll(port, (unsigned)Input::Device::Mouse, (unsigned)Input::MouseID::Left ); - r = interface->inputPoll(port, (unsigned)Input::Device::Mouse, (unsigned)Input::MouseID::Right); + x = interface->inputPoll(port, (unsigned)Device::ID::Mouse, X); //-n = left, 0 = center, +n = right + y = interface->inputPoll(port, (unsigned)Device::ID::Mouse, Y); //-n = up, 0 = center, +n = down + l = interface->inputPoll(port, (unsigned)Device::ID::Mouse, Left); + r = interface->inputPoll(port, (unsigned)Device::ID::Mouse, Right); dx = x < 0; //0 = right, 1 = left dy = y < 0; //0 = down, 1 = up diff --git a/sfc/controller/mouse/mouse.hpp b/sfc/controller/mouse/mouse.hpp index 9ac44526c..0b24bbd0e 100644 --- a/sfc/controller/mouse/mouse.hpp +++ b/sfc/controller/mouse/mouse.hpp @@ -1,4 +1,8 @@ struct Mouse : Controller { + enum : uint { + X, Y, Left, Right, + }; + Mouse(bool port); auto data() -> uint2; diff --git a/sfc/controller/multitap/multitap.cpp b/sfc/controller/multitap/multitap.cpp index d5ae19d0c..c6eeefb5f 100644 --- a/sfc/controller/multitap/multitap.cpp +++ b/sfc/controller/multitap/multitap.cpp @@ -26,8 +26,8 @@ auto Multitap::data() -> uint2 { port2 = 3; //controller 4 } - bool data1 = interface->inputPoll(port, (unsigned)Input::Device::Multitap, port1 * 12 + index); - bool data2 = interface->inputPoll(port, (unsigned)Input::Device::Multitap, port2 * 12 + index); + bool data1 = interface->inputPoll(port, (unsigned)Device::ID::Multitap, port1 * 12 + index); + bool data2 = interface->inputPoll(port, (unsigned)Device::ID::Multitap, port2 * 12 + index); return (data2 << 1) | (data1 << 0); } diff --git a/sfc/controller/superscope/superscope.cpp b/sfc/controller/superscope/superscope.cpp index 57a7b7b73..be5fe39fa 100644 --- a/sfc/controller/superscope/superscope.cpp +++ b/sfc/controller/superscope/superscope.cpp @@ -48,8 +48,8 @@ auto SuperScope::enter() -> void { if(next < prev) { //Vcounter wrapped back to zero; update cursor coordinates for start of new frame - int nx = interface->inputPoll(port, (unsigned)Input::Device::SuperScope, (unsigned)Input::SuperScopeID::X); - int ny = interface->inputPoll(port, (unsigned)Input::Device::SuperScope, (unsigned)Input::SuperScopeID::Y); + int nx = interface->inputPoll(port, (unsigned)Device::ID::SuperScope, X); + int ny = interface->inputPoll(port, (unsigned)Device::ID::SuperScope, Y); nx += x; ny += y; x = max(-16, min(256 + 16, nx)); @@ -67,7 +67,7 @@ auto SuperScope::data() -> uint2 { if(counter == 0) { //turbo is a switch; toggle is edge sensitive - bool newturbo = interface->inputPoll(port, (unsigned)Input::Device::SuperScope, (unsigned)Input::SuperScopeID::Turbo); + bool newturbo = interface->inputPoll(port, (unsigned)Device::ID::SuperScope, Turbo); if(newturbo && !turbo) { turbo = !turbo; //toggle state turbolock = true; @@ -78,7 +78,7 @@ auto SuperScope::data() -> uint2 { //trigger is a button //if turbo is active, trigger is level sensitive; otherwise, it is edge sensitive trigger = false; - bool newtrigger = interface->inputPoll(port, (unsigned)Input::Device::SuperScope, (unsigned)Input::SuperScopeID::Trigger); + bool newtrigger = interface->inputPoll(port, (unsigned)Device::ID::SuperScope, Trigger); if(newtrigger && (turbo || !triggerlock)) { trigger = true; triggerlock = true; @@ -87,11 +87,11 @@ auto SuperScope::data() -> uint2 { } //cursor is a button; it is always level sensitive - cursor = interface->inputPoll(port, (unsigned)Input::Device::SuperScope, (unsigned)Input::SuperScopeID::Cursor); + cursor = interface->inputPoll(port, (unsigned)Device::ID::SuperScope, Cursor); //pause is a button; it is always edge sensitive pause = false; - bool newpause = interface->inputPoll(port, (unsigned)Input::Device::SuperScope, (unsigned)Input::SuperScopeID::Pause); + bool newpause = interface->inputPoll(port, (unsigned)Device::ID::SuperScope, Pause); if(newpause && !pauselock) { pause = true; pauselock = true; diff --git a/sfc/controller/superscope/superscope.hpp b/sfc/controller/superscope/superscope.hpp index 3e7b4e95d..e47a94c06 100644 --- a/sfc/controller/superscope/superscope.hpp +++ b/sfc/controller/superscope/superscope.hpp @@ -1,4 +1,8 @@ struct SuperScope : Controller { + enum : uint { + X, Y, Trigger, Cursor, Turbo, Pause, + }; + SuperScope(bool port); auto enter() -> void; diff --git a/sfc/controller/usart/usart.cpp b/sfc/controller/usart/usart.cpp index 9cab61ec8..4ffc849c1 100644 --- a/sfc/controller/usart/usart.cpp +++ b/sfc/controller/usart/usart.cpp @@ -26,7 +26,7 @@ USART::USART(bool port) : Controller(port) { txlength = 0; txdata = 0; - string filename = {interface->path(ID::SuperFamicom), "usart.so"}; + string filename{interface->path(ID::SuperFamicom), "usart.so"}; if(openAbsolute(filename)) { init = sym("usart_init"); main = sym("usart_main"); @@ -93,7 +93,7 @@ auto USART::data() -> uint2 { if(iobit()) { if(counter >= 16) return 1; uint2 result = 0; - if(counter < 12) result = interface->inputPoll(port, (unsigned)Input::Device::Joypad, counter); + if(counter < 12) result = interface->inputPoll(port, (unsigned)Device::ID::Gamepad, counter); if(latched == 0) counter++; return result; } diff --git a/sfc/cpu/cpu.cpp b/sfc/cpu/cpu.cpp index b583aba11..e4a97103b 100644 --- a/sfc/cpu/cpu.cpp +++ b/sfc/cpu/cpu.cpp @@ -18,8 +18,8 @@ void CPU::step(unsigned clocks) { auto& chip = *coprocessors[i]; chip.clock -= clocks * (uint64)chip.frequency; } - input.port1->clock -= clocks * (uint64)input.port1->frequency; - input.port2->clock -= clocks * (uint64)input.port2->frequency; + device.controllerPort1->clock -= clocks * (uint64)device.controllerPort1->frequency; + device.controllerPort2->clock -= clocks * (uint64)device.controllerPort2->frequency; synchronize_controllers(); } @@ -47,8 +47,8 @@ void CPU::synchronize_coprocessors() { } void CPU::synchronize_controllers() { - if(input.port1->clock < 0) co_switch(input.port1->thread); - if(input.port2->clock < 0) co_switch(input.port2->thread); + if(device.controllerPort1->clock < 0) co_switch(device.controllerPort1->thread); + if(device.controllerPort2->clock < 0) co_switch(device.controllerPort2->thread); } void CPU::Enter() { cpu.enter(); } @@ -125,7 +125,7 @@ void CPU::power() { } void CPU::reset() { - create(Enter, system.cpu_frequency()); + create(Enter, system.cpuFrequency()); coprocessors.reset(); PPUcounter::reset(); diff --git a/sfc/cpu/mmio/mmio.cpp b/sfc/cpu/mmio/mmio.cpp index 03b24624a..c7b47b904 100644 --- a/sfc/cpu/mmio/mmio.cpp +++ b/sfc/cpu/mmio/mmio.cpp @@ -33,8 +33,8 @@ void CPU::mmio_w2183(uint8 data) { //strobing $4016.d0 affects both controller port latches. //$4017 bit 0 writes are ignored. void CPU::mmio_w4016(uint8 data) { - input.port1->latch(data & 1); - input.port2->latch(data & 1); + device.controllerPort1->latch(data & 1); + device.controllerPort2->latch(data & 1); } //JOYSER0 @@ -42,7 +42,7 @@ void CPU::mmio_w4016(uint8 data) { //1-0 = Joypad serial data uint8 CPU::mmio_r4016() { uint8 r = regs.mdr & 0xfc; - r |= input.port1->data(); + r |= device.controllerPort1->data(); return r; } @@ -52,7 +52,7 @@ uint8 CPU::mmio_r4016() { //1-0 = Joypad serial data uint8 CPU::mmio_r4017() { uint8 r = (regs.mdr & 0xe0) | 0x1c; - r |= input.port2->data(); + r |= device.controllerPort2->data(); return r; } @@ -408,7 +408,7 @@ uint8 CPU::mmio_read(unsigned addr) { //APU if((addr & 0xffc0) == 0x2140) { //$2140-$217f synchronize_smp(); - return smp.port_read(addr); + return smp.portRead(addr); } //DMA diff --git a/sfc/cpu/timing/joypad.cpp b/sfc/cpu/timing/joypad.cpp index 179df27d0..ef0cdd44f 100644 --- a/sfc/cpu/timing/joypad.cpp +++ b/sfc/cpu/timing/joypad.cpp @@ -9,14 +9,14 @@ void CPU::step_auto_joypad_poll() { if(status.auto_joypad_active && status.auto_joypad_latch) { if(status.auto_joypad_counter == 0) { - input.port1->latch(1); - input.port2->latch(1); - input.port1->latch(0); - input.port2->latch(0); + device.controllerPort1->latch(1); + device.controllerPort2->latch(1); + device.controllerPort1->latch(0); + device.controllerPort2->latch(0); } - uint2 port0 = input.port1->data(); - uint2 port1 = input.port2->data(); + uint2 port0 = device.controllerPort1->data(); + uint2 port1 = device.controllerPort2->data(); status.joy1 = (status.joy1 << 1) | (bool)(port0 & 1); status.joy2 = (status.joy2 << 1) | (bool)(port1 & 1); diff --git a/sfc/dsp/dsp.cpp b/sfc/dsp/dsp.cpp index db7c9be09..a7d23e3a9 100644 --- a/sfc/dsp/dsp.cpp +++ b/sfc/dsp/dsp.cpp @@ -287,7 +287,7 @@ auto DSP::power() -> void { } auto DSP::reset() -> void { - create(Enter, system.apu_frequency()); + create(Enter, system.apuFrequency()); REG(FLG) = 0xe0; state.noise = 0x4000; diff --git a/sfc/dsp/dsp.hpp b/sfc/dsp/dsp.hpp index aa85f0652..a1e521260 100644 --- a/sfc/dsp/dsp.hpp +++ b/sfc/dsp/dsp.hpp @@ -1,3 +1,5 @@ +//Sony CXD1222Q-1 + struct DSP : Thread { enum : bool { Threaded = true }; diff --git a/sfc/expansion/eboot/eboot.cpp b/sfc/expansion/eboot/eboot.cpp new file mode 100644 index 000000000..f867ca066 --- /dev/null +++ b/sfc/expansion/eboot/eboot.cpp @@ -0,0 +1,50 @@ +#include + +#define EBOOT_CPP +namespace SuperFamicom { + +eBoot eboot; + +auto eBoot::init() -> void { +} + +auto eBoot::load() -> void { + resetVector = bus.read(0xfffc) << 0; + resetVector |= bus.read(0xfffd) << 8; + + for(auto& byte : ram) byte = 0xdb; + ram[0] = 0x6c; //jmp ($fffc) + ram[1] = 0xfc; + ram[2] = 0xff; + + bus.map({&eBoot::read, &eboot}, {&eBoot::write, &eboot}, 0x00, 0x00, 0xfffc, 0xfffd); + bus.map({&eBoot::read, &eboot}, {&eBoot::write, &eboot}, 0x00, 0x3f, 0x2184, 0x21ff); + bus.map({&eBoot::read, &eboot}, {&eBoot::write, &eboot}, 0x80, 0xbf, 0x2184, 0x21ff); + + if(auto buffer = file::read({interface->path(ID::System), "eboot.rom"})) { + memory::copy(ram, sizeof(ram), buffer.data(), buffer.size()); + } +} + +auto eBoot::unload() -> void { +} + +auto eBoot::power() -> void { +} + +auto eBoot::reset() -> void { + booted = false; +} + +auto eBoot::read(uint addr) -> uint8 { + addr &= 0xffff; + if(addr == 0xfffc) return booted ? resetVector >> 0 : 0x84; + if(addr == 0xfffd) return booted ? resetVector >> 8 : (booted = true, 0x21); + if(addr >= 0x2184 && addr <= 0x21ff) return ram[addr - 0x2184]; + return 0xdb; //should never occur +} + +auto eBoot::write(uint addr, uint8 data) -> void { +} + +} diff --git a/sfc/expansion/eboot/eboot.hpp b/sfc/expansion/eboot/eboot.hpp new file mode 100644 index 000000000..034d17c0c --- /dev/null +++ b/sfc/expansion/eboot/eboot.hpp @@ -0,0 +1,17 @@ +struct eBoot : Memory { + auto init() -> void; + auto load() -> void; + auto unload() -> void; + auto power() -> void; + auto reset() -> void; + + auto read(uint addr) -> uint8; + auto write(uint addr, uint8 data) -> void; + +private: + bool booted = false; + uint16 resetVector = 0; + uint8 ram[124] = {0}; +}; + +extern eBoot eboot; diff --git a/sfc/expansion/expansion.hpp b/sfc/expansion/expansion.hpp new file mode 100644 index 000000000..ea8bfc2ec --- /dev/null +++ b/sfc/expansion/expansion.hpp @@ -0,0 +1,2 @@ +#include +#include diff --git a/sfc/base/satellaview/satellaview.cpp b/sfc/expansion/satellaview/satellaview.cpp similarity index 98% rename from sfc/base/satellaview/satellaview.cpp rename to sfc/expansion/satellaview/satellaview.cpp index 64c245f79..41d9a6dc4 100644 --- a/sfc/base/satellaview/satellaview.cpp +++ b/sfc/expansion/satellaview/satellaview.cpp @@ -1,6 +1,6 @@ #include -#define SATELLAVIEW_BASE_UNIT_CPP +#define SATELLAVIEW_EXPANSION_CPP namespace SuperFamicom { SatellaviewBaseUnit satellaviewbaseunit; diff --git a/sfc/base/satellaview/satellaview.hpp b/sfc/expansion/satellaview/satellaview.hpp similarity index 100% rename from sfc/base/satellaview/satellaview.hpp rename to sfc/expansion/satellaview/satellaview.hpp diff --git a/sfc/interface/interface.cpp b/sfc/interface/interface.cpp index 94f9b9856..9fd1e7138 100644 --- a/sfc/interface/interface.cpp +++ b/sfc/interface/interface.cpp @@ -22,7 +22,11 @@ Interface::Interface() { media.append({ID::SuperFamicom, "BS-X Satellaview", "bs", false}); media.append({ID::SuperFamicom, "Sufami Turbo", "st", false}); - { Device device{0, ID::Port1 | ID::Port2, "Controller"}; + { Device device{0, ID::ControllerPort1 | ID::ControllerPort2 | ID::ExpansionPort, "None"}; + this->device.append(device); + } + + { Device device{1, ID::ControllerPort1 | ID::ControllerPort2, "Gamepad"}; device.input.append({ 0, 0, "B" }); device.input.append({ 1, 0, "Y" }); device.input.append({ 2, 0, "Select"}); @@ -39,7 +43,7 @@ Interface::Interface() { this->device.append(device); } - { Device device{1, ID::Port1 | ID::Port2, "Multitap"}; + { Device device{2, ID::ControllerPort1 | ID::ControllerPort2, "Multitap"}; for(unsigned p = 1, n = 0; p <= 4; p++, n += 12) { device.input.append({n + 0, 0, {"Port ", p, " - ", "B" }}); device.input.append({n + 1, 0, {"Port ", p, " - ", "Y" }}); @@ -59,7 +63,7 @@ Interface::Interface() { this->device.append(device); } - { Device device{2, ID::Port1 | ID::Port2, "Mouse"}; + { Device device{3, ID::ControllerPort1 | ID::ControllerPort2, "Mouse"}; device.input.append({0, 1, "X-axis"}); device.input.append({1, 1, "Y-axis"}); device.input.append({2, 0, "Left" }); @@ -68,7 +72,7 @@ Interface::Interface() { this->device.append(device); } - { Device device{3, ID::Port2, "Super Scope"}; + { Device device{4, ID::ControllerPort2, "Super Scope"}; device.input.append({0, 1, "X-axis" }); device.input.append({1, 1, "Y-axis" }); device.input.append({2, 0, "Trigger"}); @@ -79,7 +83,7 @@ Interface::Interface() { this->device.append(device); } - { Device device{4, ID::Port2, "Justifier"}; + { Device device{5, ID::ControllerPort2, "Justifier"}; device.input.append({0, 1, "X-axis" }); device.input.append({1, 1, "Y-axis" }); device.input.append({2, 0, "Trigger"}); @@ -88,7 +92,7 @@ Interface::Interface() { this->device.append(device); } - { Device device{5, ID::Port2, "Justifiers"}; + { Device device{6, ID::ControllerPort2, "Justifiers"}; device.input.append({0, 1, "Port 1 - X-axis" }); device.input.append({1, 1, "Port 1 - Y-axis" }); device.input.append({2, 0, "Port 1 - Trigger"}); @@ -102,16 +106,21 @@ Interface::Interface() { this->device.append(device); } - { Device device{6, ID::Port1, "Serial USART"}; + { Device device{7, ID::ControllerPort1, "Serial USART"}; this->device.append(device); } - { Device device{7, ID::Port1 | ID::Port2, "None"}; + { Device device{8, ID::ExpansionPort, "Satellaview"}; this->device.append(device); } - port.append({0, "Port 1"}); - port.append({1, "Port 2"}); + { Device device{9, ID::ExpansionPort, "eBoot"}; + this->device.append(device); + } + + port.append({0, "Controller Port 1"}); + port.append({1, "Controller Port 2"}); + port.append({2, "Expansion Port"}); for(auto& device : this->device) { for(auto& port : this->port) { @@ -128,13 +137,13 @@ auto Interface::title() -> string { auto Interface::videoFrequency() -> double { switch(system.region()) { default: - case System::Region::NTSC: return system.cpu_frequency() / (262.0 * 1364.0 - 4.0); - case System::Region::PAL: return system.cpu_frequency() / (312.0 * 1364.0); + case System::Region::NTSC: return system.cpuFrequency() / (262.0 * 1364.0 - 4.0); + case System::Region::PAL: return system.cpuFrequency() / (312.0 * 1364.0); } } auto Interface::audioFrequency() -> double { - return system.apu_frequency() / 768.0; + return system.apuFrequency() / 768.0; } auto Interface::loaded() -> bool { @@ -396,7 +405,7 @@ auto Interface::unload() -> void { } auto Interface::connect(unsigned port, unsigned device) -> void { - input.connect(port, (Input::Device)device); + SuperFamicom::device.connect(port, (SuperFamicom::Device::ID)device); } auto Interface::power() -> void { @@ -423,7 +432,7 @@ auto Interface::rtcsync() -> void { } auto Interface::serialize() -> serializer { - system.runtosave(); + system.runToSave(); return system.serialize(); } diff --git a/sfc/interface/interface.hpp b/sfc/interface/interface.hpp index e54c58bf3..6c765200f 100644 --- a/sfc/interface/interface.hpp +++ b/sfc/interface/interface.hpp @@ -83,9 +83,10 @@ struct ID { SufamiTurboSlotBROM, SufamiTurboSlotBRAM, - //controller ports - Port1 = 1, - Port2 = 2, + //device ports (bitmask) + ControllerPort1 = 1, + ControllerPort2 = 2, + ExpansionPort = 4, }; }; diff --git a/sfc/ppu/ppu.cpp b/sfc/ppu/ppu.cpp index 4ed7389d3..3400f8e2b 100644 --- a/sfc/ppu/ppu.cpp +++ b/sfc/ppu/ppu.cpp @@ -93,7 +93,7 @@ void PPU::power() { } void PPU::reset() { - create(Enter, system.cpu_frequency()); + create(Enter, system.cpuFrequency()); PPUcounter::reset(); memset(surface, 0, 512 * 512 * sizeof(uint32)); diff --git a/sfc/sfc.hpp b/sfc/sfc.hpp index 1a5fdc5d8..e368ea5f2 100644 --- a/sfc/sfc.hpp +++ b/sfc/sfc.hpp @@ -12,7 +12,7 @@ namespace SuperFamicom { namespace Info { static const string Name = "bsnes"; - static const unsigned SerializerVersion = 29; + static const uint SerializerVersion = 29; } } @@ -32,7 +32,7 @@ namespace SuperFamicom { if(thread) co_delete(thread); } - auto create(auto (*entrypoint)() -> void, unsigned frequency) -> void { + auto create(auto (*entrypoint)() -> void, uint frequency) -> void { if(thread) co_delete(thread); thread = co_create(65536 * sizeof(void*), entrypoint); this->frequency = frequency; @@ -45,7 +45,7 @@ namespace SuperFamicom { } cothread_t thread = nullptr; - unsigned frequency = 0; + uint frequency = 0; int64 clock = 0; }; @@ -62,7 +62,7 @@ namespace SuperFamicom { #include #include - #include + #include #include #include #include diff --git a/sfc/smp/memory.cpp b/sfc/smp/memory.cpp index 1ed07ea8c..9d1ea1565 100644 --- a/sfc/smp/memory.cpp +++ b/sfc/smp/memory.cpp @@ -1,26 +1,26 @@ #ifdef SMP_CPP -alwaysinline uint8 SMP::ram_read(uint16 addr) { - if(addr >= 0xffc0 && status.iplrom_enable) return iplrom[addr & 0x3f]; - if(status.ram_disable) return 0x5a; //0xff on mini-SNES +alwaysinline auto SMP::ramRead(uint16 addr) -> uint8 { + if(addr >= 0xffc0 && status.iplromEnable) return iplrom[addr & 0x3f]; + if(status.ramDisable) return 0x5a; //0xff on mini-SNES return apuram[addr]; } -alwaysinline void SMP::ram_write(uint16 addr, uint8 data) { +alwaysinline auto SMP::ramWrite(uint16 addr, uint8 data) -> void { //writes to $ffc0-$ffff always go to apuram, even if the iplrom is enabled - if(status.ram_writable && !status.ram_disable) apuram[addr] = data; + if(status.ramWritable && !status.ramDisable) apuram[addr] = data; } -uint8 SMP::port_read(uint2 port) const { +auto SMP::portRead(uint2 port) const -> uint8 { return apuram[0xf4 + port]; } -void SMP::port_write(uint2 port, uint8 data) { +auto SMP::portWrite(uint2 port, uint8 data) -> void { apuram[0xf4 + port] = data; } -uint8 SMP::op_busread(uint16 addr) { - unsigned result; +auto SMP::busRead(uint16 addr) -> uint8 { + uint result; switch(addr) { case 0xf0: //TEST -- write-only register @@ -30,17 +30,17 @@ uint8 SMP::op_busread(uint16 addr) { return 0x00; case 0xf2: //DSPADDR - return status.dsp_addr; + return status.dspAddr; case 0xf3: //DSPDATA //0x80-0xff are read-only mirrors of 0x00-0x7f - return dsp.read(status.dsp_addr & 0x7f); + return dsp.read(status.dspAddr & 0x7f); case 0xf4: //CPUIO0 case 0xf5: //CPUIO1 case 0xf6: //CPUIO2 case 0xf7: //CPUIO3 - synchronize_cpu(); + synchronizeCPU(); return cpu.port_read(addr); case 0xf8: //RAM0 @@ -55,50 +55,50 @@ uint8 SMP::op_busread(uint16 addr) { return 0x00; case 0xfd: //T0OUT -- 4-bit counter value - result = timer0.stage3_ticks; - timer0.stage3_ticks = 0; + result = timer0.stage3; + timer0.stage3 = 0; return result; case 0xfe: //T1OUT -- 4-bit counter value - result = timer1.stage3_ticks; - timer1.stage3_ticks = 0; + result = timer1.stage3; + timer1.stage3 = 0; return result; case 0xff: //T2OUT -- 4-bit counter value - result = timer2.stage3_ticks; - timer2.stage3_ticks = 0; + result = timer2.stage3; + timer2.stage3 = 0; return result; } - return ram_read(addr); + return ramRead(addr); } -void SMP::op_buswrite(uint16 addr, uint8 data) { +auto SMP::busWrite(uint16 addr, uint8 data) -> void { switch(addr) { case 0xf0: //TEST if(regs.p.p) break; //writes only valid when P flag is clear - status.clock_speed = (data >> 6) & 3; - status.timer_speed = (data >> 4) & 3; - status.timers_enable = data & 0x08; - status.ram_disable = data & 0x04; - status.ram_writable = data & 0x02; - status.timers_disable = data & 0x01; + status.clockSpeed = (data >> 6) & 3; + status.timerSpeed = (data >> 4) & 3; + status.timersEnable = data & 0x08; + status.ramDisable = data & 0x04; + status.ramWritable = data & 0x02; + status.timersDisable = data & 0x01; - status.timer_step = (1 << status.clock_speed) + (2 << status.timer_speed); + status.timerStep = (1 << status.clockSpeed) + (2 << status.timerSpeed); - timer0.synchronize_stage1(); - timer1.synchronize_stage1(); - timer2.synchronize_stage1(); + timer0.synchronizeStage1(); + timer1.synchronizeStage1(); + timer2.synchronizeStage1(); break; case 0xf1: //CONTROL - status.iplrom_enable = data & 0x80; + status.iplromEnable = data & 0x80; if(data & 0x30) { //one-time clearing of APU port read registers, //emulated by simulating CPU writes of 0x00 - synchronize_cpu(); + synchronizeCPU(); if(data & 0x20) { cpu.port_write(2, 0x00); cpu.port_write(3, 0x00); @@ -110,40 +110,40 @@ void SMP::op_buswrite(uint16 addr, uint8 data) { } //0->1 transistion resets timers - if(timer2.enable == false && (data & 0x04)) { - timer2.stage2_ticks = 0; - timer2.stage3_ticks = 0; + if(!timer2.enable && (data & 0x04)) { + timer2.stage2 = 0; + timer2.stage3 = 0; } timer2.enable = data & 0x04; - if(timer1.enable == false && (data & 0x02)) { - timer1.stage2_ticks = 0; - timer1.stage3_ticks = 0; + if(!timer1.enable && (data & 0x02)) { + timer1.stage2 = 0; + timer1.stage3 = 0; } timer1.enable = data & 0x02; - if(timer0.enable == false && (data & 0x01)) { - timer0.stage2_ticks = 0; - timer0.stage3_ticks = 0; + if(!timer0.enable && (data & 0x01)) { + timer0.stage2 = 0; + timer0.stage3 = 0; } timer0.enable = data & 0x01; break; case 0xf2: //DSPADDR - status.dsp_addr = data; + status.dspAddr = data; break; case 0xf3: //DSPDATA - if(status.dsp_addr & 0x80) break; //0x80-0xff are read-only mirrors of 0x00-0x7f - dsp.write(status.dsp_addr & 0x7f, data); + if(status.dspAddr & 0x80) break; //0x80-0xff are read-only mirrors of 0x00-0x7f + dsp.write(status.dspAddr & 0x7f, data); break; case 0xf4: //CPUIO0 case 0xf5: //CPUIO1 case 0xf6: //CPUIO2 case 0xf7: //CPUIO3 - synchronize_cpu(); - port_write(addr, data); + synchronizeCPU(); + portWrite(addr, data); break; case 0xf8: //RAM0 @@ -172,33 +172,33 @@ void SMP::op_buswrite(uint16 addr, uint8 data) { break; } - ram_write(addr, data); //all writes, even to MMIO registers, appear on bus + ramWrite(addr, data); //all writes, even to MMIO registers, appear on bus } -void SMP::op_io() { - add_clocks(24); - cycle_edge(); +auto SMP::op_io() -> void { + addClocks(24); + cycleEdge(); } -uint8 SMP::op_read(uint16 addr) { - add_clocks(12); - uint8 data = op_busread(addr); - add_clocks(12); - cycle_edge(); +auto SMP::op_read(uint16 addr) -> uint8 { + addClocks(12); + uint8 data = busRead(addr); + addClocks(12); + cycleEdge(); debugger.op_read(addr, data); return data; } -void SMP::op_write(uint16 addr, uint8 data) { - add_clocks(24); - op_buswrite(addr, data); - cycle_edge(); +auto SMP::op_write(uint16 addr, uint8 data) -> void { + addClocks(24); + busWrite(addr, data); + cycleEdge(); debugger.op_write(addr, data); } -uint8 SMP::disassembler_read(uint16 addr) { +auto SMP::disassembler_read(uint16 addr) -> uint8 { if((addr & 0xfff0) == 0x00f0) return 0x00; - if((addr & 0xffc0) == 0xffc0 && status.iplrom_enable) return iplrom[addr & 0x3f]; + if((addr & 0xffc0) == 0xffc0 && status.iplromEnable) return iplrom[addr & 0x3f]; return apuram[addr]; } diff --git a/sfc/smp/serialization.cpp b/sfc/smp/serialization.cpp index 57a3b4723..1ec385ec3 100644 --- a/sfc/smp/serialization.cpp +++ b/sfc/smp/serialization.cpp @@ -1,50 +1,50 @@ #ifdef SMP_CPP -void SMP::serialize(serializer& s) { +auto SMP::serialize(serializer& s) -> void { SPC700::serialize(s); Thread::serialize(s); s.array(apuram); - s.integer(status.clock_counter); - s.integer(status.dsp_counter); - s.integer(status.timer_step); + s.integer(status.clockCounter); + s.integer(status.dspCounter); + s.integer(status.timerStep); - s.integer(status.clock_speed); - s.integer(status.timer_speed); - s.integer(status.timers_enable); - s.integer(status.ram_disable); - s.integer(status.ram_writable); - s.integer(status.timers_disable); + s.integer(status.clockSpeed); + s.integer(status.timerSpeed); + s.integer(status.timersEnable); + s.integer(status.ramDisable); + s.integer(status.ramWritable); + s.integer(status.timersDisable); - s.integer(status.iplrom_enable); + s.integer(status.iplromEnable); - s.integer(status.dsp_addr); + s.integer(status.dspAddr); s.integer(status.ram00f8); s.integer(status.ram00f9); - s.integer(timer0.stage0_ticks); - s.integer(timer0.stage1_ticks); - s.integer(timer0.stage2_ticks); - s.integer(timer0.stage3_ticks); - s.integer(timer0.current_line); + s.integer(timer0.stage0); + s.integer(timer0.stage1); + s.integer(timer0.stage2); + s.integer(timer0.stage3); + s.integer(timer0.line); s.integer(timer0.enable); s.integer(timer0.target); - s.integer(timer1.stage0_ticks); - s.integer(timer1.stage1_ticks); - s.integer(timer1.stage2_ticks); - s.integer(timer1.stage3_ticks); - s.integer(timer1.current_line); + s.integer(timer1.stage0); + s.integer(timer1.stage1); + s.integer(timer1.stage2); + s.integer(timer1.stage3); + s.integer(timer1.line); s.integer(timer1.enable); s.integer(timer1.target); - s.integer(timer2.stage0_ticks); - s.integer(timer2.stage1_ticks); - s.integer(timer2.stage2_ticks); - s.integer(timer2.stage3_ticks); - s.integer(timer2.current_line); + s.integer(timer2.stage0); + s.integer(timer2.stage1); + s.integer(timer2.stage2); + s.integer(timer2.stage3); + s.integer(timer2.line); s.integer(timer2.enable); s.integer(timer2.target); } diff --git a/sfc/smp/smp.cpp b/sfc/smp/smp.cpp index fd418020b..f3c538852 100644 --- a/sfc/smp/smp.cpp +++ b/sfc/smp/smp.cpp @@ -9,30 +9,30 @@ SMP smp; #include "timing.cpp" #include "serialization.cpp" -void SMP::step(unsigned clocks) { +auto SMP::step(uint clocks) -> void { clock += clocks * (uint64)cpu.frequency; dsp.clock -= clocks; } -void SMP::synchronize_cpu() { - if(CPU::Threaded == true) { +auto SMP::synchronizeCPU() -> void { + if(CPU::Threaded) { if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); } else { while(clock >= 0) cpu.enter(); } } -void SMP::synchronize_dsp() { - if(DSP::Threaded == true) { +auto SMP::synchronizeDSP() -> void { + if(DSP::Threaded) { if(dsp.clock < 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(dsp.thread); } else { while(dsp.clock < 0) dsp.enter(); } } -void SMP::Enter() { smp.enter(); } +auto SMP::Enter() -> void { smp.enter(); } -void SMP::enter() { +auto SMP::enter() -> void { while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::All) { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); @@ -43,81 +43,75 @@ void SMP::enter() { } } -void SMP::power() { +auto SMP::power() -> void { //targets not initialized/changed upon reset timer0.target = 0; timer1.target = 0; timer2.target = 0; } -void SMP::reset() { - create(Enter, system.apu_frequency()); +auto SMP::reset() -> void { + create(Enter, system.apuFrequency()); - regs.pc = 0xffc0; + regs.pc.l = iplrom[62]; + regs.pc.h = iplrom[63]; regs.a = 0x00; regs.x = 0x00; regs.y = 0x00; regs.s = 0xef; regs.p = 0x02; - for(auto& n : apuram) n = random(0x00); + for(auto& byte : apuram) byte = random(0x00); apuram[0x00f4] = 0x00; apuram[0x00f5] = 0x00; apuram[0x00f6] = 0x00; apuram[0x00f7] = 0x00; - status.clock_counter = 0; - status.dsp_counter = 0; - status.timer_step = 3; + status.clockCounter = 0; + status.dspCounter = 0; + status.timerStep = 3; //$00f0 - status.clock_speed = 0; - status.timer_speed = 0; - status.timers_enable = true; - status.ram_disable = false; - status.ram_writable = true; - status.timers_disable = false; + status.clockSpeed = 0; + status.timerSpeed = 0; + status.timersEnable = true; + status.ramDisable = false; + status.ramWritable = true; + status.timersDisable = false; //$00f1 - status.iplrom_enable = true; + status.iplromEnable = true; //$00f2 - status.dsp_addr = 0x00; + status.dspAddr = 0x00; //$00f8,$00f9 status.ram00f8 = 0x00; status.ram00f9 = 0x00; - timer0.stage0_ticks = 0; - timer1.stage0_ticks = 0; - timer2.stage0_ticks = 0; + timer0.stage0 = 0; + timer1.stage0 = 0; + timer2.stage0 = 0; - timer0.stage1_ticks = 0; - timer1.stage1_ticks = 0; - timer2.stage1_ticks = 0; + timer0.stage1 = 0; + timer1.stage1 = 0; + timer2.stage1 = 0; - timer0.stage2_ticks = 0; - timer1.stage2_ticks = 0; - timer2.stage2_ticks = 0; + timer0.stage2 = 0; + timer1.stage2 = 0; + timer2.stage2 = 0; - timer0.stage3_ticks = 0; - timer1.stage3_ticks = 0; - timer2.stage3_ticks = 0; + timer0.stage3 = 0; + timer1.stage3 = 0; + timer2.stage3 = 0; - timer0.current_line = 0; - timer1.current_line = 0; - timer2.current_line = 0; + timer0.line = 0; + timer1.line = 0; + timer2.line = 0; timer0.enable = false; timer1.enable = false; timer2.enable = false; } -SMP::SMP() { - for(auto& byte : iplrom) byte = 0; -} - -SMP::~SMP() { -} - } diff --git a/sfc/smp/smp.hpp b/sfc/smp/smp.hpp index 1583971ac..95c83967c 100644 --- a/sfc/smp/smp.hpp +++ b/sfc/smp/smp.hpp @@ -1,52 +1,51 @@ +//Sony CXP1100Q-1 + struct SMP : Processor::SPC700, Thread { - uint8 iplrom[64]; - uint8 apuram[64 * 1024]; - enum : bool { Threaded = true }; - alwaysinline void step(unsigned clocks); - alwaysinline void synchronize_cpu(); - alwaysinline void synchronize_dsp(); - uint8 port_read(uint2 port) const; - void port_write(uint2 port, uint8 data); + alwaysinline auto step(uint clocks) -> void; + alwaysinline auto synchronizeCPU() -> void; + alwaysinline auto synchronizeDSP() -> void; - void enter(); - void power(); - void reset(); + auto portRead(uint2 port) const -> uint8; + auto portWrite(uint2 port, uint8 data) -> void; - void serialize(serializer&); - SMP(); - ~SMP(); + auto enter() -> void; + auto power() -> void; + auto reset() -> void; + + auto serialize(serializer&) -> void; + + uint8 iplrom[64] = {0}; + uint8 apuram[64 * 1024] = {0}; privileged: struct { //timing - unsigned clock_counter; - unsigned dsp_counter; - unsigned timer_step; + uint clockCounter; + uint dspCounter; + uint timerStep; //$00f0 - uint8 clock_speed; - uint8 timer_speed; - bool timers_enable; - bool ram_disable; - bool ram_writable; - bool timers_disable; + uint8 clockSpeed; + uint8 timerSpeed; + bool timersEnable; + bool ramDisable; + bool ramWritable; + bool timersDisable; //$00f1 - bool iplrom_enable; + bool iplromEnable; //$00f2 - uint8 dsp_addr; + uint8 dspAddr; //$00f8,$00f9 uint8 ram00f8; uint8 ram00f9; } status; - static void Enter(); - - friend class SMPcore; + static auto Enter() -> void; struct Debugger { hook op_exec; @@ -55,39 +54,39 @@ privileged: } debugger; //memory.cpp - uint8 ram_read(uint16 addr); - void ram_write(uint16 addr, uint8 data); + auto ramRead(uint16 addr) -> uint8; + auto ramWrite(uint16 addr, uint8 data) -> void; - uint8 op_busread(uint16 addr); - void op_buswrite(uint16 addr, uint8 data); + auto busRead(uint16 addr) -> uint8; + auto busWrite(uint16 addr, uint8 data) -> void; - void op_io(); - uint8 op_read(uint16 addr); - void op_write(uint16 addr, uint8 data); + auto op_io() -> void; + auto op_read(uint16 addr) -> uint8; + auto op_write(uint16 addr, uint8 data) -> void; - uint8 disassembler_read(uint16 addr); + auto disassembler_read(uint16 addr) -> uint8; //timing.cpp - template + template struct Timer { - uint8 stage0_ticks; - uint8 stage1_ticks; - uint8 stage2_ticks; - uint4 stage3_ticks; - bool current_line; + uint8 stage0; + uint8 stage1; + uint8 stage2; + uint4 stage3; + bool line; bool enable; uint8 target; - void tick(); - void synchronize_stage1(); + auto tick() -> void; + auto synchronizeStage1() -> void; }; Timer<192> timer0; Timer<192> timer1; Timer< 24> timer2; - alwaysinline void add_clocks(unsigned clocks); - alwaysinline void cycle_edge(); + alwaysinline auto addClocks(uint clocks) -> void; + alwaysinline auto cycleEdge() -> void; }; extern SMP smp; diff --git a/sfc/smp/timing.cpp b/sfc/smp/timing.cpp index a3eb06915..ef1f0e06a 100644 --- a/sfc/smp/timing.cpp +++ b/sfc/smp/timing.cpp @@ -1,62 +1,62 @@ #ifdef SMP_CPP -void SMP::add_clocks(unsigned clocks) { +auto SMP::addClocks(uint clocks) -> void { step(clocks); - synchronize_dsp(); + synchronizeDSP(); #if defined(DEBUGGER) - synchronize_cpu(); + synchronizeCPU(); #else //forcefully sync S-SMP to S-CPU in case chips are not communicating //sync if S-SMP is more than 24 samples ahead of S-CPU - if(clock > +(768 * 24 * (int64)24000000)) synchronize_cpu(); + if(clock > +(768 * 24 * (int64)24000000)) synchronizeCPU(); #endif } -void SMP::cycle_edge() { +auto SMP::cycleEdge() -> void { timer0.tick(); timer1.tick(); timer2.tick(); //TEST register S-SMP speed control //24 clocks have already been added for this cycle at this point - switch(status.clock_speed) { - case 0: break; //100% speed - case 1: add_clocks(24); break; // 50% speed - case 2: while(true) add_clocks(24); // 0% speed -- locks S-SMP - case 3: add_clocks(24 * 9); break; // 10% speed + switch(status.clockSpeed) { + case 0: break; //100% speed + case 1: addClocks(24); break; // 50% speed + case 2: while(true) addClocks(24); // 0% speed -- locks S-SMP + case 3: addClocks(24 * 9); break; // 10% speed } } -template -void SMP::Timer::tick() { +template +auto SMP::Timer::tick() -> void { //stage 0 increment - stage0_ticks += smp.status.timer_step; - if(stage0_ticks < timer_frequency) return; - stage0_ticks -= timer_frequency; + stage0 += smp.status.timerStep; + if(stage0 < Frequency) return; + stage0 -= Frequency; //stage 1 increment - stage1_ticks ^= 1; - synchronize_stage1(); + stage1 ^= 1; + synchronizeStage1(); } -template -void SMP::Timer::synchronize_stage1() { - bool new_line = stage1_ticks; - if(smp.status.timers_enable == false) new_line = false; - if(smp.status.timers_disable == true) new_line = false; +template +auto SMP::Timer::synchronizeStage1() -> void { + bool newLine = stage1; + if(smp.status.timersEnable == false) newLine = false; + if(smp.status.timersDisable == true) newLine = false; - bool old_line = current_line; - current_line = new_line; - if(old_line != 1 || new_line != 0) return; //only pulse on 1->0 transition + bool oldLine = line; + line = newLine; + if(oldLine != 1 || newLine != 0) return; //only pulse on 1->0 transition //stage 2 increment if(enable == false) return; - if(++stage2_ticks != target) return; + if(++stage2 != target) return; //stage 3 increment - stage2_ticks = 0; - stage3_ticks++; + stage2 = 0; + stage3++; } #endif diff --git a/sfc/system/audio.cpp b/sfc/system/audio.cpp index fb5ade7b5..24454f6c8 100644 --- a/sfc/system/audio.cpp +++ b/sfc/system/audio.cpp @@ -14,7 +14,7 @@ void Audio::coprocessor_enable(bool state) { void Audio::coprocessor_frequency(double input_frequency) { dspaudio.setFrequency(input_frequency); dspaudio.setResampler(nall::DSP::ResampleEngine::Sinc); - dspaudio.setResamplerFrequency(system.apu_frequency() / 768.0); + dspaudio.setResamplerFrequency(system.apuFrequency() / 768.0); } void Audio::sample(int16 lsample, int16 rsample) { diff --git a/sfc/system/device.cpp b/sfc/system/device.cpp new file mode 100644 index 000000000..7a6f27978 --- /dev/null +++ b/sfc/system/device.cpp @@ -0,0 +1,47 @@ +#ifdef SYSTEM_CPP + +Device device; + +Device::Device() { + connect(0, ID::Gamepad); + connect(1, ID::Gamepad); + connect(2, ID::eBoot); +} + +Device::~Device() { + if(controllerPort1) delete controllerPort1; + if(controllerPort2) delete controllerPort2; +} + +auto Device::connect(uint port, Device::ID id) -> void { + if(port == 0 || port == 1) { + Controller*& controller = (port == 0 ? controllerPort1 : controllerPort2); + + if(controller) { + delete controller; + controller = nullptr; + } + + switch(id) { default: + case ID::None: controller = new Controller(port); break; + case ID::Gamepad: controller = new Gamepad(port); break; + case ID::Multitap: controller = new Multitap(port); break; + case ID::Mouse: controller = new Mouse(port); break; + case ID::SuperScope: controller = new SuperScope(port); break; + case ID::Justifier: controller = new Justifier(port, false); break; + case ID::Justifiers: controller = new Justifier(port, true); break; + case ID::USART: controller = new USART(port); break; + } + + switch(port) { + case 0: configuration.controllerPort1 = id; break; + case 1: configuration.controllerPort2 = id; break; + } + } + + if(port == 2) { + configuration.expansionPort = id; + } +} + +#endif diff --git a/sfc/system/device.hpp b/sfc/system/device.hpp new file mode 100644 index 000000000..c5a512801 --- /dev/null +++ b/sfc/system/device.hpp @@ -0,0 +1,28 @@ +struct Device { + enum class ID : uint { + None, + + //controller port devices + Gamepad, + Multitap, + Mouse, + SuperScope, + Justifier, + Justifiers, + USART, + + //expansion port devices + Satellaview, + eBoot, + }; + + Device(); + ~Device(); + + auto connect(uint port, Device::ID id) -> void; + + Controller* controllerPort1 = nullptr; + Controller* controllerPort2 = nullptr; +}; + +extern Device device; diff --git a/sfc/system/input.cpp b/sfc/system/input.cpp deleted file mode 100644 index 2b7a57fdf..000000000 --- a/sfc/system/input.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifdef SYSTEM_CPP - -Input input; - -void Input::connect(bool port, Input::Device id) { - Controller*& controller = (port == Controller::Port1 ? port1 : port2); - if(controller) { - delete controller; - controller = nullptr; - } - - switch(id) { default: - case Device::None: controller = new Controller(port); break; - case Device::Joypad: controller = new Gamepad(port); break; - case Device::Multitap: controller = new Multitap(port); break; - case Device::Mouse: controller = new Mouse(port); break; - case Device::SuperScope: controller = new SuperScope(port); break; - case Device::Justifier: controller = new Justifier(port, false); break; - case Device::Justifiers: controller = new Justifier(port, true); break; - case Device::USART: controller = new USART(port); break; - } - - switch(port) { - case Controller::Port1: configuration.controller_port1 = id; break; - case Controller::Port2: configuration.controller_port2 = id; break; - } -} - -Input::Input() { - connect(Controller::Port1, Input::Device::Joypad); - connect(Controller::Port2, Input::Device::Joypad); -} - -Input::~Input() { - if(port1) delete port1; - if(port2) delete port2; -} - -#endif diff --git a/sfc/system/input.hpp b/sfc/system/input.hpp deleted file mode 100644 index 170cf797e..000000000 --- a/sfc/system/input.hpp +++ /dev/null @@ -1,39 +0,0 @@ -struct Input { - enum class Device : unsigned { - Joypad, - Multitap, - Mouse, - SuperScope, - Justifier, - Justifiers, - USART, - None, - }; - - enum class JoypadID : unsigned { - B = 0, Y = 1, Select = 2, Start = 3, - Up = 4, Down = 5, Left = 6, Right = 7, - A = 8, X = 9, L = 10, R = 11, - }; - - enum class MouseID : unsigned { - X = 0, Y = 1, Left = 2, Right = 3, - }; - - enum class SuperScopeID : unsigned { - X = 0, Y = 1, Trigger = 2, Cursor = 3, Turbo = 4, Pause = 5, - }; - - enum class JustifierID : unsigned { - X = 0, Y = 1, Trigger = 2, Start = 3, - }; - - Controller* port1 = nullptr; - Controller* port2 = nullptr; - - void connect(bool port, Input::Device id); - Input(); - ~Input(); -}; - -extern Input input; diff --git a/sfc/system/serialization.cpp b/sfc/system/serialization.cpp index 0447fbf37..1a8a05e9f 100644 --- a/sfc/system/serialization.cpp +++ b/sfc/system/serialization.cpp @@ -1,9 +1,9 @@ #ifdef SYSTEM_CPP -serializer System::serialize() { - serializer s(serialize_size); +auto System::serialize() -> serializer { + serializer s(serializeSize); - unsigned signature = 0x31545342, version = Info::SerializerVersion; + uint signature = 0x31545342, version = Info::SerializerVersion; char hash[64], description[512], profile[16]; memcpy(&hash, (const char*)cartridge.sha256(), 64); memset(&description, 0, sizeof description); @@ -16,12 +16,12 @@ serializer System::serialize() { s.array(description); s.array(profile); - serialize_all(s); + serializeAll(s); return s; } -bool System::unserialize(serializer& s) { - unsigned signature, version; +auto System::unserialize(serializer& s) -> bool { + uint signature, version; char hash[64], description[512], profile[16]; s.integer(signature); @@ -35,7 +35,7 @@ bool System::unserialize(serializer& s) { if(strcmp(profile, Emulator::Profile)) return false; power(); - serialize_all(s); + serializeAll(s); return true; } @@ -43,12 +43,12 @@ bool System::unserialize(serializer& s) { //internal //======== -void System::serialize(serializer& s) { - s.integer((unsigned&)region); - s.integer((unsigned&)expansion); +auto System::serialize(serializer& s) -> void { + s.integer((uint&)region); + s.integer((uint&)expansionPort); } -void System::serialize_all(serializer& s) { +auto System::serializeAll(serializer& s) -> void { cartridge.serialize(s); system.serialize(s); random.serialize(s); @@ -78,10 +78,10 @@ void System::serialize_all(serializer& s) { //perform dry-run state save: //determines exactly how many bytes are needed to save state for this cartridge, //as amount varies per game (eg different RAM sizes, special chips, etc.) -void System::serialize_init() { +auto System::serializeInit() -> void { serializer s; - unsigned signature = 0, version = 0; + uint signature = 0, version = 0; char hash[64], profile[16], description[512]; s.integer(signature); @@ -90,8 +90,8 @@ void System::serialize_init() { s.array(profile); s.array(description); - serialize_all(s); - serialize_size = s.size(); + serializeAll(s); + serializeSize = s.size(); } #endif diff --git a/sfc/system/system.cpp b/sfc/system/system.cpp index 9bff60a8e..8869dbd82 100644 --- a/sfc/system/system.cpp +++ b/sfc/system/system.cpp @@ -9,12 +9,17 @@ Random random; #include "video.cpp" #include "audio.cpp" -#include "input.cpp" +#include "device.cpp" #include "serialization.cpp" #include -void System::run() { +System::System() { + region = Region::Autodetect; + expansionPort = Device::ID::eBoot; +} + +auto System::run() -> void { scheduler.sync = Scheduler::SynchronizeMode::None; scheduler.enter(); @@ -23,35 +28,35 @@ void System::run() { } } -void System::runtosave() { +auto System::runToSave() -> void { if(CPU::Threaded == true) { scheduler.sync = Scheduler::SynchronizeMode::CPU; - runthreadtosave(); + runThreadToSave(); } if(SMP::Threaded == true) { scheduler.thread = smp.thread; - runthreadtosave(); + runThreadToSave(); } if(PPU::Threaded == true) { scheduler.thread = ppu.thread; - runthreadtosave(); + runThreadToSave(); } if(DSP::Threaded == true) { scheduler.thread = dsp.thread; - runthreadtosave(); + runThreadToSave(); } for(unsigned i = 0; i < cpu.coprocessors.size(); i++) { auto& chip = *cpu.coprocessors[i]; scheduler.thread = chip.thread; - runthreadtosave(); + runThreadToSave(); } } -void System::runthreadtosave() { +auto System::runThreadToSave() -> void { while(true) { scheduler.enter(); if(scheduler.exit_reason == Scheduler::ExitReason::SynchronizeEvent) break; @@ -61,10 +66,12 @@ void System::runthreadtosave() { } } -void System::init() { +auto System::init() -> void { assert(interface != nullptr); + eboot.init(); satellaviewbaseunit.init(); + icd2.init(); mcc.init(); nss.init(); @@ -80,20 +87,20 @@ void System::init() { sdd1.init(); obc1.init(); msu1.init(); + satellaviewcartridge.init(); video.init(); audio.init(); - input.connect(0, configuration.controller_port1); - input.connect(1, configuration.controller_port2); + device.connect(0, configuration.controllerPort1); + device.connect(1, configuration.controllerPort2); } -void System::term() { +auto System::term() -> void { } -void System::load() { -//string manifest = string::read({interface->path(ID::System), "manifest.bml"}); +auto System::load() -> void { interface->loadRequest(ID::SystemManifest, "manifest.bml", true); auto document = BML::unserialize(information.manifest); @@ -102,13 +109,12 @@ void System::load() { } region = configuration.region; - expansion = configuration.expansion_port; if(region == Region::Autodetect) { region = (cartridge.region() == Cartridge::Region::NTSC ? Region::NTSC : Region::PAL); } - - cpu_frequency = region() == Region::NTSC ? 21477272 : 21281370; - apu_frequency = 24607104; + expansionPort = configuration.expansionPort; + cpuFrequency = region() == Region::NTSC ? 21477272 : 21281370; + apuFrequency = 24606720; audio.coprocessor_enable(false); @@ -118,7 +124,9 @@ void System::load() { cpu.enable(); ppu.enable(); - if(expansion() == ExpansionPortDevice::Satellaview) satellaviewbaseunit.load(); + if(expansionPort() == Device::ID::Satellaview) satellaviewbaseunit.load(); + if(expansionPort() == Device::ID::eBoot) eboot.load(); + if(cartridge.hasICD2()) icd2.load(); if(cartridge.hasMCC()) mcc.load(); if(cartridge.hasNSSDIP()) nss.load(); @@ -138,11 +146,13 @@ void System::load() { if(cartridge.hasSatellaviewSlot()) satellaviewcartridge.load(); if(cartridge.hasSufamiTurboSlots()) sufamiturboA.load(), sufamiturboB.load(); - serialize_init(); + serializeInit(); } -void System::unload() { - if(expansion() == ExpansionPortDevice::Satellaview) satellaviewbaseunit.unload(); +auto System::unload() -> void { + if(expansionPort() == Device::ID::Satellaview) satellaviewbaseunit.unload(); + if(expansionPort() == Device::ID::eBoot) eboot.unload(); + if(cartridge.hasICD2()) icd2.unload(); if(cartridge.hasMCC()) mcc.unload(); if(cartridge.hasNSSDIP()) nss.unload(); @@ -163,15 +173,17 @@ void System::unload() { if(cartridge.hasSufamiTurboSlots()) sufamiturboA.unload(), sufamiturboB.unload(); } -void System::power() { - random.seed((unsigned)time(0)); +auto System::power() -> void { + random.seed((uint)time(0)); cpu.power(); smp.power(); dsp.power(); ppu.power(); - if(expansion() == ExpansionPortDevice::Satellaview) satellaviewbaseunit.power(); + if(expansionPort() == Device::ID::Satellaview) satellaviewbaseunit.power(); + if(expansionPort() == Device::ID::eBoot) eboot.power(); + if(cartridge.hasICD2()) icd2.power(); if(cartridge.hasMCC()) mcc.power(); if(cartridge.hasNSSDIP()) nss.power(); @@ -193,13 +205,15 @@ void System::power() { reset(); } -void System::reset() { +auto System::reset() -> void { cpu.reset(); smp.reset(); dsp.reset(); ppu.reset(); - if(expansion() == ExpansionPortDevice::Satellaview) satellaviewbaseunit.reset(); + if(expansionPort() == Device::ID::Satellaview) satellaviewbaseunit.reset(); + if(expansionPort() == Device::ID::eBoot) eboot.reset(); + if(cartridge.hasICD2()) icd2.reset(); if(cartridge.hasMCC()) mcc.reset(); if(cartridge.hasNSSDIP()) nss.reset(); @@ -231,21 +245,16 @@ void System::reset() { if(cartridge.hasMSU1()) cpu.coprocessors.append(&msu1); scheduler.init(); - input.connect(0, configuration.controller_port1); - input.connect(1, configuration.controller_port2); + device.connect(0, configuration.controllerPort1); + device.connect(1, configuration.controllerPort2); } -void System::scanline() { +auto System::scanline() -> void { video.scanline(); if(cpu.vcounter() == 241) scheduler.exit(Scheduler::ExitReason::FrameEvent); } -void System::frame() { -} - -System::System() { - region = Region::Autodetect; - expansion = ExpansionPortDevice::Satellaview; +auto System::frame() -> void { } } diff --git a/sfc/system/system.hpp b/sfc/system/system.hpp index d492a73e0..ca4b93b59 100644 --- a/sfc/system/system.hpp +++ b/sfc/system/system.hpp @@ -1,63 +1,63 @@ struct Interface; +#include "video.hpp" +#include "audio.hpp" +#include "device.hpp" + struct System : property { - enum class Region : unsigned { NTSC = 0, PAL = 1, Autodetect = 2 }; - enum class ExpansionPortDevice : unsigned { None = 0, Satellaview = 1 }; + enum class Region : uint { NTSC = 0, PAL = 1, Autodetect = 2 }; - void run(); - void runtosave(); + System(); - void init(); - void term(); - void load(); - void unload(); - void power(); - void reset(); + auto run() -> void; + auto runToSave() -> void; - void frame(); - void scanline(); + auto init() -> void; + auto term() -> void; + auto load() -> void; + auto unload() -> void; + auto power() -> void; + auto reset() -> void; + + auto frame() -> void; + auto scanline() -> void; //return *active* system information (settings are cached upon power-on) readonly region; - readonly expansion; - readonly cpu_frequency; - readonly apu_frequency; - readonly serialize_size; + readonly expansionPort; - serializer serialize(); - bool unserialize(serializer&); + readonly cpuFrequency; + readonly apuFrequency; + readonly serializeSize; - System(); + auto serialize() -> serializer; + auto unserialize(serializer&) -> bool; struct Information { string manifest; } information; private: - void runthreadtosave(); + auto runThreadToSave() -> void; - void serialize(serializer&); - void serialize_all(serializer&); - void serialize_init(); + auto serialize(serializer&) -> void; + auto serializeAll(serializer&) -> void; + auto serializeInit() -> void; friend class Cartridge; friend class Video; friend class Audio; - friend class Input; + friend class Device; }; extern System system; -#include "video.hpp" -#include "audio.hpp" -#include "input.hpp" - #include struct Configuration { - Input::Device controller_port1 = Input::Device::Joypad; - Input::Device controller_port2 = Input::Device::Joypad; - System::ExpansionPortDevice expansion_port = System::ExpansionPortDevice::Satellaview; + Device::ID controllerPort1 = Device::ID::Gamepad; + Device::ID controllerPort2 = Device::ID::Gamepad; + Device::ID expansionPort = Device::ID::eBoot; System::Region region = System::Region::Autodetect; bool random = true; }; @@ -65,21 +65,21 @@ struct Configuration { extern Configuration configuration; struct Random { - void seed(unsigned seed) { + auto seed(uint seed) -> void { iter = seed; } - unsigned operator()(unsigned result) { + auto operator()(uint result) -> uint { if(configuration.random == false) return result; return iter = (iter >> 1) ^ (((iter & 1) - 1) & 0xedb88320); } - void serialize(serializer& s) { + auto serialize(serializer& s) -> void { s.integer(iter); } private: - unsigned iter = 0; + uint iter = 0; }; extern Random random; diff --git a/sfc/system/video.cpp b/sfc/system/video.cpp index 437e7f5e5..a9b65feda 100644 --- a/sfc/system/video.cpp +++ b/sfc/system/video.cpp @@ -105,20 +105,20 @@ void Video::draw_cursor(uint16_t color, int x, int y) { } void Video::update() { - switch(configuration.controller_port2) { - case Input::Device::SuperScope: - if(dynamic_cast(input.port2)) { - SuperScope &device = (SuperScope&)*input.port2; - draw_cursor(0x7c00, device.x, device.y); + switch(configuration.controllerPort2) { + case Device::ID::SuperScope: + if(dynamic_cast(device.controllerPort2)) { + SuperScope& controller = (SuperScope&)*device.controllerPort2; + draw_cursor(0x7c00, controller.x, controller.y); } break; - case Input::Device::Justifier: - case Input::Device::Justifiers: - if(dynamic_cast(input.port2)) { - Justifier &device = (Justifier&)*input.port2; - draw_cursor(0x001f, device.player1.x, device.player1.y); - if(device.chained == false) break; - draw_cursor(0x02e0, device.player2.x, device.player2.y); + case Device::ID::Justifier: + case Device::ID::Justifiers: + if(dynamic_cast(device.controllerPort2)) { + Justifier& controller = (Justifier&)*device.controllerPort2; + draw_cursor(0x001f, controller.player1.x, controller.player1.y); + if(!controller.chained) break; + draw_cursor(0x02e0, controller.player2.x, controller.player2.y); } break; } diff --git a/target-tomoko/presentation/presentation.cpp b/target-tomoko/presentation/presentation.cpp index 295d11a13..256c5bd3a 100644 --- a/target-tomoko/presentation/presentation.cpp +++ b/target-tomoko/presentation/presentation.cpp @@ -115,11 +115,12 @@ auto Presentation::updateEmulator() -> void { resetSystem.setVisible(emulator->information.resettable); inputPort1.setVisible(false).reset(); inputPort2.setVisible(false).reset(); + inputPort3.setVisible(false).reset(); for(auto n : range(emulator->port)) { - if(n >= 2) break; + if(n >= 3) break; auto& port = emulator->port[n]; - auto& menu = (n == 0 ? inputPort1 : inputPort2); + auto& menu = (n == 0 ? inputPort1 : n == 1 ? inputPort2 : inputPort3); menu.setText(port.name); Group devices; @@ -133,7 +134,7 @@ auto Presentation::updateEmulator() -> void { if(devices.objectCount() > 1) menu.setVisible(); } - systemMenuSeparatorPorts.setVisible(inputPort1.visible() || inputPort2.visible()); + systemMenuSeparatorPorts.setVisible(inputPort1.visible() || inputPort2.visible() || inputPort3.visible()); } auto Presentation::resizeViewport() -> void { diff --git a/target-tomoko/presentation/presentation.hpp b/target-tomoko/presentation/presentation.hpp index 94a17fcdb..ab96952df 100644 --- a/target-tomoko/presentation/presentation.hpp +++ b/target-tomoko/presentation/presentation.hpp @@ -15,6 +15,7 @@ struct Presentation : Window { MenuSeparator systemMenuSeparatorPorts{&systemMenu}; Menu inputPort1{&systemMenu}; Menu inputPort2{&systemMenu}; + Menu inputPort3{&systemMenu}; MenuSeparator systemMenuSeparatorUnload{&systemMenu}; MenuItem unloadSystem{&systemMenu}; Menu settingsMenu{&menuBar};