diff --git a/emulator/emulator.hpp b/emulator/emulator.hpp index 6090a003..38560166 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.09"; + static const string Version = "095.10"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/gb/apu/noise/noise.cpp b/gb/apu/noise/noise.cpp index 27cf3138..fc17f0d2 100644 --- a/gb/apu/noise/noise.cpp +++ b/gb/apu/noise/noise.cpp @@ -57,7 +57,7 @@ auto APU::Noise::write(uint r, uint8 data) -> void { if(initialize) { enable = dac_enable(); - lfsr = ~0U; + lfsr = -1; envelope_period = envelope_frequency; volume = envelope_volume; } diff --git a/gba/apu/noise.cpp b/gba/apu/noise.cpp index ed6a105a..68f6d934 100644 --- a/gba/apu/noise.cpp +++ b/gba/apu/noise.cpp @@ -65,7 +65,7 @@ auto APU::Noise::write(uint addr, uint8 byte) -> void { if(initialize) { enable = envelope.dacEnable(); - lfsr = ~0u; + lfsr = -1; envelope.period = envelope.frequency; volume = envelope.volume; } diff --git a/nall/nall.hpp b/nall/nall.hpp index 0e51d148..573dd05d 100644 --- a/nall/nall.hpp +++ b/nall/nall.hpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/nall/primitives.hpp b/nall/primitives.hpp new file mode 100644 index 00000000..4171bbe4 --- /dev/null +++ b/nall/primitives.hpp @@ -0,0 +1,216 @@ +#ifndef NALL_PRIMITIVES_HPP +#define NALL_PRIMITIVES_HPP + +#include +#include + +namespace nall { + +struct Boolean { + inline Boolean() : data(false) {} + inline Boolean(bool value) : data(value) {} + + inline operator bool() const { return data; } + inline auto& operator=(const bool value) { data = value; return *this; } + + inline auto serialize(serializer& s) { s(data); } + + bool data; +}; + +template struct Natural { + using type = + type_if, uint8_t, + type_if, uint16_t, + type_if, uint32_t, + type_if, uint64_t, + void>>>>; + + enum : type { Mask = ~0ull >> (64 - Bits) }; + + inline Natural() : data(0) {} + inline Natural(const type value) : data(clip(value)) {} + template inline Natural(const Natural value) : data(clip(value)) {} + + inline operator type() const { return data; } + inline auto& operator=(const type value) { data = clip(value); return *this; } + template inline auto& operator=(const Natural value) { data = clip(value); return *this; } + + inline auto operator++(int) { type value = data; data = clip(data + 1); return value; } + inline auto operator--(int) { type value = data; data = clip(data - 1); return value; } + + inline auto& operator++() { data = clip(data + 1); return *this; } + inline auto& operator--() { data = clip(data - 1); return *this; } + + inline auto& operator &=(const type value) { data = clip(data & value); return *this; } + inline auto& operator |=(const type value) { data = clip(data | value); return *this; } + inline auto& operator ^=(const type value) { data = clip(data ^ value); return *this; } + inline auto& operator<<=(const type value) { data = clip(data << value); return *this; } + inline auto& operator>>=(const type value) { data = clip(data >> value); return *this; } + inline auto& operator +=(const type value) { data = clip(data + value); return *this; } + inline auto& operator -=(const type value) { data = clip(data - value); return *this; } + inline auto& operator *=(const type value) { data = clip(data * value); return *this; } + inline auto& operator /=(const type value) { data = clip(data / value); return *this; } + inline auto& operator %=(const type value) { data = clip(data % value); return *this; } + + inline auto serialize(serializer& s) { s(data); } + + template struct Range { + enum : type { RangeBits = Hi - Lo + 1, RangeMask = (((1ull << RangeBits) - 1) << Lo) & Mask }; + + inline operator type() const { + return (self() & RangeMask) >> Lo; + } + + inline auto& operator=(const type value) { + self() = (self() & ~RangeMask) | ((value << Lo) & RangeMask); + return *this; + } + + private: + inline auto self() const -> type& { return *(type*)this; } + }; + + union { + type data; + + Range< 0, 7> b0; + Range< 8, 15> b1; + Range<16, 23> b2; + Range<24, 31> b3; + Range<32, 39> b4; + Range<40, 47> b5; + Range<48, 55> b6; + Range<56, 63> b7; + + Range< 0, 15> h0; + Range<16, 31> h1; + Range<32, 47> h2; + Range<48, 63> h3; + + Range< 0, 31> w0; + Range<32, 63> w1; + }; + +private: + auto clip(type value) const -> type { + return value & Mask; + } +}; + +template struct Integer { + using type = + type_if, int8_t, + type_if, int16_t, + type_if, int32_t, + type_if, int64_t, + void>>>>; + using utype = typename Natural::type; + + enum : utype { Mask = ~0ull >> (64 - Bits), Sign = 1ull << (Bits - 1) }; + + inline Integer() : data(0) {} + inline Integer(const type value) : data(clip(value)) {} + template inline Integer(const Integer value) : data(clip(value)) {} + + inline operator type() const { return data; } + inline auto& operator=(const type value) { data = clip(value); return *this; } + template inline auto& operator=(const Integer value) { data = clip(value); return *this; } + + inline auto operator++(int) { type value = data; data = clip(data + 1); return value; } + inline auto operator--(int) { type value = data; data = clip(data - 1); return value; } + + inline auto& operator++() { data = clip(data + 1); return *this; } + inline auto& operator--() { data = clip(data - 1); return *this; } + + inline auto& operator &=(const type value) { data = clip(data & value); return *this; } + inline auto& operator |=(const type value) { data = clip(data | value); return *this; } + inline auto& operator ^=(const type value) { data = clip(data ^ value); return *this; } + inline auto& operator<<=(const type value) { data = clip(data << value); return *this; } + inline auto& operator>>=(const type value) { data = clip(data >> value); return *this; } + inline auto& operator +=(const type value) { data = clip(data + value); return *this; } + inline auto& operator -=(const type value) { data = clip(data - value); return *this; } + inline auto& operator *=(const type value) { data = clip(data * value); return *this; } + inline auto& operator /=(const type value) { data = clip(data / value); return *this; } + inline auto& operator %=(const type value) { data = clip(data % value); return *this; } + + inline auto serialize(serializer& s) { s(data); } + + template struct Range { + enum : utype { RangeBits = Hi - Lo + 1, RangeMask = (((1ull << RangeBits) - 1) << Lo) & Mask }; + + inline operator utype() const { + return (self() & RangeMask) >> Lo; + } + + inline auto& operator=(const utype value) { + self() = (((self() & ~RangeMask) | ((value << Lo) & RangeMask)) ^ Sign) - Sign; + return *this; + } + + private: + inline auto self() const -> utype& { return *(utype*)this; } + }; + + union { + type data; + + Range< 0, 7> b0; + Range< 8, 15> b1; + Range<16, 23> b2; + Range<24, 31> b3; + Range<32, 39> b4; + Range<40, 47> b5; + Range<48, 55> b6; + Range<56, 63> b7; + + Range< 0, 15> h0; + Range<16, 31> h1; + Range<32, 47> h2; + Range<48, 63> h3; + + Range< 0, 31> w0; + Range<32, 63> w1; + }; + +private: + auto clip(type value) const -> type { + return ((value & Mask) ^ Sign) - Sign; + } +}; + +template struct Real { + using type = + type_if, float32_t, + type_if, float64_t, + type_if, float80_t, + void>>>; + + inline Real() : data(0.0) {} + inline Real(const type value) : data(value) {} + template inline Real(const Real value) : data((type)value) {} + + inline operator type() const { return data; } + inline auto& operator=(const type value) { data = value; return *this; } + template inline auto& operator=(const Real value) { data = (type)value; return *this; } + + inline auto operator++(int) { type value = data; ++data; return value; } + inline auto operator--(int) { type value = data; --data; return value; } + + inline auto& operator++() { data++; return *this; } + inline auto& operator--() { data--; return *this; } + + inline auto& operator+=(const type value) { data = data + value; return *this; } + inline auto& operator-=(const type value) { data = data - value; return *this; } + inline auto& operator*=(const type value) { data = data * value; return *this; } + inline auto& operator/=(const type value) { data = data / value; return *this; } + inline auto& operator%=(const type value) { data = data % value; return *this; } + + inline auto serialize(serializer& s) { s(data); } + + type data; +}; + +} + +#endif diff --git a/nall/stdint.hpp b/nall/stdint.hpp index 65470c1d..97a35d01 100644 --- a/nall/stdint.hpp +++ b/nall/stdint.hpp @@ -32,7 +32,9 @@ using uint128_t = unsigned __int128; #endif -namespace nall { +using float32_t = float; +using float64_t = double; +using float80_t = long double; static_assert(sizeof(int8_t) == 1, "int8_t is not of the correct size" ); static_assert(sizeof(int16_t) == 2, "int16_t is not of the correct size"); @@ -44,6 +46,10 @@ static_assert(sizeof(uint16_t) == 2, "int16_t is not of the correct size"); static_assert(sizeof(uint32_t) == 4, "int32_t is not of the correct size"); static_assert(sizeof(uint64_t) == 8, "int64_t is not of the correct size"); +static_assert(sizeof(float) >= 4, "float32_t is not of the correct size"); +static_assert(sizeof(double) >= 8, "float64_t is not of the correct size"); +static_assert(sizeof(long double) >= 10, "float80_t is not of the correct size"); + using int8 = int8_t; using int16 = int16_t; using int32 = int32_t; @@ -64,6 +70,4 @@ using int128 = int128_t; using uint128 = uint128_t; #endif -} - #endif diff --git a/nall/string.hpp b/nall/string.hpp index 539d3201..716b76a0 100644 --- a/nall/string.hpp +++ b/nall/string.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/nall/string/base.hpp b/nall/string/base.hpp index 13b377a4..61a33334 100644 --- a/nall/string/base.hpp +++ b/nall/string/base.hpp @@ -21,7 +21,7 @@ template struct stringify; //format.hpp template inline auto print(P&&...) -> void; inline auto integer(intmax value, long precision = 0, char padchar = '0') -> string; -inline auto decimal(uintmax value, long precision = 0, char padchar = '0') -> string; +inline auto natural(uintmax value, long precision = 0, char padchar = '0') -> string; inline auto hex(uintmax value, long precision = 0, char padchar = '0') -> string; inline auto octal(uintmax value, long precision = 0, char padchar = '0') -> string; inline auto binary(uintmax value, long precision = 0, char padchar = '0') -> string; @@ -61,7 +61,7 @@ inline auto temppath() -> string; inline auto slice(rstring self, int offset = 0, int length = -1) -> string; inline auto integer(char* result, intmax value) -> char*; -inline auto decimal(char* result, uintmax value) -> char*; +inline auto natural(char* result, uintmax value) -> char*; inline auto real(char* str, long double value) -> uint; struct string { diff --git a/nall/string/cast.hpp b/nall/string/cast.hpp index 549e3714..eaf385ab 100644 --- a/nall/string/cast.hpp +++ b/nall/string/cast.hpp @@ -5,199 +5,215 @@ namespace nall { -//base types +//booleans template<> struct stringify { - bool _value; + stringify(bool value) : _value(value) {} auto data() const -> const char* { return _value ? "true" : "false"; } auto size() const -> unsigned { return _value ? 4 : 5; } - stringify(bool value) : _value(value) {} + bool _value; }; +template<> struct stringify { + stringify(bool value) : _value(value) {} + auto data() const -> const char* { return _value ? "true" : "false"; } + auto size() const -> uint { return _value ? 4 : 5; } + bool _value; +}; + +//characters + template<> struct stringify { - char _data[2]; + stringify(char source) { _data[0] = source; _data[1] = 0; } auto data() const -> const char* { return _data; } auto size() const -> unsigned { return 1; } - stringify(char source) { _data[0] = source; _data[1] = 0; } + char _data[2]; }; //signed integers template<> struct stringify { - char _data[2 + sizeof(signed char) * 3]; + stringify(signed char source) { integer(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(signed char source) { integer(_data, source); } + char _data[2 + sizeof(signed char) * 3]; }; template<> struct stringify { - char _data[2 + sizeof(signed short) * 3]; + stringify(signed short source) { integer(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(signed short source) { integer(_data, source); } + char _data[2 + sizeof(signed short) * 3]; }; template<> struct stringify { - char _data[2 + sizeof(signed int) * 3]; + stringify(signed int source) { integer(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(signed int source) { integer(_data, source); } + char _data[2 + sizeof(signed int) * 3]; }; template<> struct stringify { - char _data[2 + sizeof(signed long) * 3]; + stringify(signed long source) { integer(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(signed long source) { integer(_data, source); } + char _data[2 + sizeof(signed long) * 3]; }; template<> struct stringify { - char _data[2 + sizeof(signed long long) * 3]; + stringify(signed long long source) { integer(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(signed long long source) { integer(_data, source); } + char _data[2 + sizeof(signed long long) * 3]; }; -template struct stringify> { - char _data[2 + sizeof(intmax_t) * 3]; +template struct stringify> { + stringify(Integer source) { integer(_data, source); } auto data() const -> const char* { return _data; } - auto size() const -> unsigned { return strlen(_data); } - stringify(int_t source) { integer(_data, source); } + auto size() const -> uint { return strlen(_data); } + char _data[2 + sizeof(int64_t) * 3]; }; //unsigned integers template<> struct stringify { - char _data[1 + sizeof(unsigned char) * 3]; + stringify(unsigned char source) { natural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(unsigned char source) { decimal(_data, source); } + char _data[1 + sizeof(unsigned char) * 3]; }; template<> struct stringify { - char _data[1 + sizeof(unsigned short) * 3]; + stringify(unsigned short source) { natural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(unsigned short source) { decimal(_data, source); } + char _data[1 + sizeof(unsigned short) * 3]; }; template<> struct stringify { - char _data[1 + sizeof(unsigned int) * 3]; + stringify(unsigned int source) { natural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(unsigned int source) { decimal(_data, source); } + char _data[1 + sizeof(unsigned int) * 3]; }; template<> struct stringify { - char _data[1 + sizeof(unsigned long) * 3]; + stringify(unsigned long source) { natural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(unsigned long source) { decimal(_data, source); } + char _data[1 + sizeof(unsigned long) * 3]; }; template<> struct stringify { - char _data[1 + sizeof(unsigned long long) * 3]; + stringify(unsigned long long source) { natural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(unsigned long long source) { decimal(_data, source); } + char _data[1 + sizeof(unsigned long long) * 3]; }; -template struct stringify> { - char _data[1 + sizeof(uintmax_t) * 3]; +template struct stringify> { + stringify(Natural source) { natural(_data, source); } auto data() const -> const char* { return _data; } - auto size() const -> unsigned { return strlen(_data); } - stringify(uint_t source) { decimal(_data, source); } + auto size() const -> uint { return strlen(_data); } + char _data[1 + sizeof(uint64_t) * 3]; }; //floating-point template<> struct stringify { - char _data[256]; + stringify(float source) { real(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(float source) { real(_data, source); } + char _data[256]; }; template<> struct stringify { - char _data[256]; + stringify(double source) { real(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(double source) { real(_data, source); } + char _data[256]; }; template<> struct stringify { - char _data[256]; + stringify(long double source) { real(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(long double source) { real(_data, source); } + char _data[256]; +}; + +template struct stringify> { + stringify(Real source) { real(_data, source); } + auto data() const -> const char* { return _data; } + auto size() const -> uint { return strlen(_data); } + char _data[256]; }; //arrays template<> struct stringify> { - vector _text; - auto data() const -> const char* { return _text.data(); } - auto size() const -> unsigned { return _text.size(); } stringify(vector source) { _text.resize(source.size()); memory::copy(_text.data(), source.data(), source.size()); } + auto data() const -> const char* { return _text.data(); } + auto size() const -> unsigned { return _text.size(); } + vector _text; }; template<> struct stringify&> { - vector _text; - auto data() const -> const char* { return _text.data(); } - auto size() const -> unsigned { return _text.size(); } stringify(const vector& source) { _text.resize(source.size()); memory::copy(_text.data(), source.data(), source.size()); } + auto data() const -> const char* { return _text.data(); } + auto size() const -> unsigned { return _text.size(); } + vector _text; }; //char arrays template<> struct stringify { - const char* _data; + stringify(char* source) : _data(source ? source : "") {} auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(char* source) : _data(source ? source : "") {} + const char* _data; }; template<> struct stringify { - const char* _data; + stringify(const char* source) : _data(source ? source : "") {} auto data() const -> const char* { return _data; } auto size() const -> unsigned { return strlen(_data); } - stringify(const char* source) : _data(source ? source : "") {} + const char* _data; }; //strings template<> struct stringify { - const string& _text; + stringify(const string& source) : _text(source) {} auto data() const -> const char* { return _text.data(); } auto size() const -> unsigned { return _text.size(); } - stringify(const string& source) : _text(source) {} + const string& _text; }; template<> struct stringify { - const string& _text; + stringify(const string& source) : _text(source) {} auto data() const -> const char* { return _text.data(); } auto size() const -> unsigned { return _text.size(); } - stringify(const string& source) : _text(source) {} + const string& _text; }; template<> struct stringify { - const string_view& _view; + stringify(const string_view& source) : _view(source) {} auto data() const -> const char* { return _view.data(); } auto size() const -> unsigned { return _view.size(); } - stringify(const string_view& source) : _view(source) {} + const string_view& _view; }; template<> struct stringify { - const string_view& _view; + stringify(const string_view& source) : _view(source) {} auto data() const -> const char* { return _view.data(); } auto size() const -> unsigned { return _view.size(); } - stringify(const string_view& source) : _view(source) {} + const string_view& _view; }; // diff --git a/nall/string/datetime.hpp b/nall/string/datetime.hpp index 95016026..f03ad291 100644 --- a/nall/string/datetime.hpp +++ b/nall/string/datetime.hpp @@ -6,9 +6,9 @@ auto string::date(time_t timestamp) -> string { if(timestamp == 0) timestamp = ::time(nullptr); tm* info = localtime(×tamp); return { - nall::decimal(1900 + info->tm_year, 4L), "-", - nall::decimal(1 + info->tm_mon, 2L), "-", - nall::decimal(info->tm_mday, 2L) + nall::natural(1900 + info->tm_year, 4L), "-", + nall::natural(1 + info->tm_mon, 2L), "-", + nall::natural(info->tm_mday, 2L) }; } @@ -16,9 +16,9 @@ auto string::time(time_t timestamp) -> string { if(timestamp == 0) timestamp = ::time(nullptr); tm* info = localtime(×tamp); return { - nall::decimal(info->tm_hour, 2L), ":", - nall::decimal(info->tm_min, 2L), ":", - nall::decimal(info->tm_sec, 2L) + nall::natural(info->tm_hour, 2L), ":", + nall::natural(info->tm_min, 2L), ":", + nall::natural(info->tm_sec, 2L) }; } diff --git a/nall/string/format.hpp b/nall/string/format.hpp index 74189f8b..f44c1336 100644 --- a/nall/string/format.hpp +++ b/nall/string/format.hpp @@ -92,7 +92,7 @@ auto integer(intmax value, long precision, char padchar) -> string { return buffer; } -auto decimal(uintmax value, long precision, char padchar) -> string { +auto natural(uintmax value, long precision, char padchar) -> string { string buffer; buffer.resize(sizeof(uintmax) * 3); char* p = buffer.get(); diff --git a/nall/string/utility.hpp b/nall/string/utility.hpp index e9beda14..bd541e94 100644 --- a/nall/string/utility.hpp +++ b/nall/string/utility.hpp @@ -111,7 +111,7 @@ auto integer(char* result, intmax value) -> char* { return result; } -auto decimal(char* result, uintmax value) -> char* { +auto natural(char* result, uintmax value) -> char* { char buffer[64]; uint size = 0; diff --git a/nall/varint.hpp b/nall/varint.hpp index e03304b7..577fc229 100644 --- a/nall/varint.hpp +++ b/nall/varint.hpp @@ -1,7 +1,7 @@ #ifndef NALL_VARINT_HPP #define NALL_VARINT_HPP -#include +#include #include #include @@ -49,70 +49,6 @@ struct varint { } }; -template struct uint_t { - using type_t = type_if, unsigned, uintmax_t>; - - inline operator type_t() const { return data; } - inline auto operator ++(int) { type_t r = data; data = uclip(data + 1); return r; } - inline auto operator --(int) { type_t r = data; data = uclip(data - 1); return r; } - inline auto operator ++() { return data = uclip(data + 1); } - inline auto operator --() { return data = uclip(data - 1); } - inline auto operator =(const type_t i) { return data = uclip(i); } - inline auto operator |=(const type_t i) { return data = uclip(data | i); } - inline auto operator ^=(const type_t i) { return data = uclip(data ^ i); } - inline auto operator &=(const type_t i) { return data = uclip(data & i); } - inline auto operator<<=(const type_t i) { return data = uclip(data << i); } - inline auto operator>>=(const type_t i) { return data = uclip(data >> i); } - inline auto operator +=(const type_t i) { return data = uclip(data + i); } - inline auto operator -=(const type_t i) { return data = uclip(data - i); } - inline auto operator *=(const type_t i) { return data = uclip(data * i); } - inline auto operator /=(const type_t i) { return data = uclip(data / i); } - inline auto operator %=(const type_t i) { return data = uclip(data % i); } - - inline uint_t() : data(0) {} - inline uint_t(const type_t i) : data(uclip(i)) {} - - template inline uint_t(const uint_t& i) : data(uclip(i)) {} - template inline auto operator=(const uint_t& i) { return data = uclip((type_t)i); } - - auto serialize(serializer& s) { s(data); } - -private: - type_t data; -}; - -template struct int_t { - using type_t = type_if, signed, intmax_t>; - - inline operator type_t() const { return data; } - inline auto operator ++(int) { type_t r = data; data = sclip(data + 1); return r; } - inline auto operator --(int) { type_t r = data; data = sclip(data - 1); return r; } - inline auto operator ++() { return data = sclip(data + 1); } - inline auto operator --() { return data = sclip(data - 1); } - inline auto operator =(const type_t i) { return data = sclip(i); } - inline auto operator |=(const type_t i) { return data = sclip(data | i); } - inline auto operator ^=(const type_t i) { return data = sclip(data ^ i); } - inline auto operator &=(const type_t i) { return data = sclip(data & i); } - inline auto operator<<=(const type_t i) { return data = sclip(data << i); } - inline auto operator>>=(const type_t i) { return data = sclip(data >> i); } - inline auto operator +=(const type_t i) { return data = sclip(data + i); } - inline auto operator -=(const type_t i) { return data = sclip(data - i); } - inline auto operator *=(const type_t i) { return data = sclip(data * i); } - inline auto operator /=(const type_t i) { return data = sclip(data / i); } - inline auto operator %=(const type_t i) { return data = sclip(data % i); } - - inline int_t() : data(0) {} - inline int_t(const type_t i) : data(sclip(i)) {} - - template inline int_t(const int_t& i) : data(sclip(i)) {} - template inline auto operator=(const int_t& i) { return data = sclip((type_t)i); } - - auto serialize(serializer& s) { s(data); } - -private: - type_t data; -}; - template struct varuint_t { inline operator type_t() const { return data; } inline auto operator ++(int) { type_t r = data; data = (data + 1) & mask; return r; } @@ -144,132 +80,134 @@ private: } -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 int1 = nall::Integer< 1>; +using int2 = nall::Integer< 2>; +using int3 = nall::Integer< 3>; +using int4 = nall::Integer< 4>; +using int5 = nall::Integer< 5>; +using int6 = nall::Integer< 6>; +using int7 = nall::Integer< 7>; +//using int8 = nall::Integer< 8>; +using int9 = nall::Integer< 9>; +using int10 = nall::Integer<10>; +using int11 = nall::Integer<11>; +using int12 = nall::Integer<12>; +using int13 = nall::Integer<13>; +using int14 = nall::Integer<14>; +using int15 = nall::Integer<15>; +//using int16 = nall::Integer<16>; +using int17 = nall::Integer<17>; +using int18 = nall::Integer<18>; +using int19 = nall::Integer<19>; +using int20 = nall::Integer<20>; +using int21 = nall::Integer<21>; +using int22 = nall::Integer<22>; +using int23 = nall::Integer<23>; +using int24 = nall::Integer<24>; +using int25 = nall::Integer<25>; +using int26 = nall::Integer<26>; +using int27 = nall::Integer<27>; +using int28 = nall::Integer<28>; +using int29 = nall::Integer<29>; +using int30 = nall::Integer<30>; +using int31 = nall::Integer<31>; +//using int32 = nall::Integer<32>; +using int33 = nall::Integer<33>; +using int34 = nall::Integer<34>; +using int35 = nall::Integer<35>; +using int36 = nall::Integer<36>; +using int37 = nall::Integer<37>; +using int38 = nall::Integer<38>; +using int39 = nall::Integer<39>; +using int40 = nall::Integer<40>; +using int41 = nall::Integer<41>; +using int42 = nall::Integer<42>; +using int43 = nall::Integer<43>; +using int44 = nall::Integer<44>; +using int45 = nall::Integer<45>; +using int46 = nall::Integer<46>; +using int47 = nall::Integer<47>; +using int48 = nall::Integer<48>; +using int49 = nall::Integer<49>; +using int50 = nall::Integer<50>; +using int51 = nall::Integer<51>; +using int52 = nall::Integer<52>; +using int53 = nall::Integer<53>; +using int54 = nall::Integer<54>; +using int55 = nall::Integer<55>; +using int56 = nall::Integer<56>; +using int57 = nall::Integer<57>; +using int58 = nall::Integer<58>; +using int59 = nall::Integer<59>; +using int60 = nall::Integer<60>; +using int61 = nall::Integer<61>; +using int62 = nall::Integer<62>; +using int63 = nall::Integer<63>; +//using int64 = nall::Integer<64>; -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 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 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 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 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 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 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 uint1 = nall::Natural< 1>; +using uint2 = nall::Natural< 2>; +using uint3 = nall::Natural< 3>; +using uint4 = nall::Natural< 4>; +using uint5 = nall::Natural< 5>; +using uint6 = nall::Natural< 6>; +using uint7 = nall::Natural< 7>; +//using uint8 = nall::Natural< 8>; +using uint9 = nall::Natural< 9>; +using uint10 = nall::Natural<10>; +using uint11 = nall::Natural<11>; +using uint12 = nall::Natural<12>; +using uint13 = nall::Natural<13>; +using uint14 = nall::Natural<14>; +using uint15 = nall::Natural<15>; +//using uint16 = nall::Natural<16>; +using uint17 = nall::Natural<17>; +using uint18 = nall::Natural<18>; +using uint19 = nall::Natural<19>; +using uint20 = nall::Natural<20>; +using uint21 = nall::Natural<21>; +using uint22 = nall::Natural<22>; +using uint23 = nall::Natural<23>; +using uint24 = nall::Natural<24>; +using uint25 = nall::Natural<25>; +using uint26 = nall::Natural<26>; +using uint27 = nall::Natural<27>; +using uint28 = nall::Natural<28>; +using uint29 = nall::Natural<29>; +using uint30 = nall::Natural<30>; +using uint31 = nall::Natural<31>; +//using uint32 = nall::Natural<32>; +using uint33 = nall::Natural<33>; +using uint34 = nall::Natural<34>; +using uint35 = nall::Natural<35>; +using uint36 = nall::Natural<36>; +using uint37 = nall::Natural<37>; +using uint38 = nall::Natural<38>; +using uint39 = nall::Natural<39>; +using uint40 = nall::Natural<40>; +using uint41 = nall::Natural<41>; +using uint42 = nall::Natural<42>; +using uint43 = nall::Natural<43>; +using uint44 = nall::Natural<44>; +using uint45 = nall::Natural<45>; +using uint46 = nall::Natural<46>; +using uint47 = nall::Natural<47>; +using uint48 = nall::Natural<48>; +using uint49 = nall::Natural<49>; +using uint50 = nall::Natural<50>; +using uint51 = nall::Natural<51>; +using uint52 = nall::Natural<52>; +using uint53 = nall::Natural<53>; +using uint54 = nall::Natural<54>; +using uint55 = nall::Natural<55>; +using uint56 = nall::Natural<56>; +using uint57 = nall::Natural<57>; +using uint58 = nall::Natural<58>; +using uint59 = nall::Natural<59>; +using uint60 = nall::Natural<60>; +using uint61 = nall::Natural<61>; +using uint62 = nall::Natural<62>; +using uint63 = nall::Natural<63>; +//using uint64 = nall::Natural<64>; #endif diff --git a/sfc/alt/cpu/cpu.cpp b/sfc/alt/cpu/cpu.cpp index 3d93a781..20e94588 100644 --- a/sfc/alt/cpu/cpu.cpp +++ b/sfc/alt/cpu/cpu.cpp @@ -1,6 +1,5 @@ #include -#define CPU_CPP namespace SuperFamicom { CPU cpu; @@ -11,10 +10,14 @@ CPU cpu; #include "mmio.cpp" #include "timing.cpp" -void CPU::step(unsigned clocks) { +CPU::CPU() : queue(512, {&CPU::queue_event, this}) { + PPUcounter::scanline = {&CPU::scanline, this}; +} + +auto CPU::step(uint clocks) -> void { smp.clock -= clocks * (uint64)smp.frequency; ppu.clock -= clocks; - for(unsigned i = 0; i < coprocessors.size(); i++) { + for(uint i = 0; i < coprocessors.size(); i++) { auto& chip = *coprocessors[i]; chip.clock -= clocks * (uint64)chip.frequency; } @@ -23,7 +26,7 @@ void CPU::step(unsigned clocks) { synchronizeDevices(); } -void CPU::synchronizeSMP() { +auto CPU::synchronizeSMP() -> void { if(SMP::Threaded == true) { if(smp.clock < 0) co_switch(smp.thread); } else { @@ -31,7 +34,7 @@ void CPU::synchronizeSMP() { } } -void CPU::synchronizePPU() { +auto CPU::synchronizePPU() -> void { if(PPU::Threaded == true) { if(ppu.clock < 0) co_switch(ppu.thread); } else { @@ -39,21 +42,21 @@ void CPU::synchronizePPU() { } } -void CPU::synchronizeCoprocessors() { - for(unsigned i = 0; i < coprocessors.size(); i++) { +auto CPU::synchronizeCoprocessors() -> void { + for(uint i = 0; i < coprocessors.size(); i++) { auto& chip = *coprocessors[i]; if(chip.clock < 0) co_switch(chip.thread); } } -void CPU::synchronizeDevices() { +auto CPU::synchronizeDevices() -> void { 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(); } +auto CPU::Enter() -> void { cpu.enter(); } -void CPU::enter() { +auto CPU::enter() -> void { while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::CPU) { scheduler.sync = Scheduler::SynchronizeMode::All; @@ -76,9 +79,9 @@ void CPU::enter() { } } -void CPU::enable() { - function reader = {&CPU::mmio_read, (CPU*)&cpu}; - function writer = {&CPU::mmio_write, (CPU*)&cpu}; +auto CPU::enable() -> void { + function reader = {&CPU::mmio_read, (CPU*)&cpu}; + function writer = {&CPU::mmio_write, (CPU*)&cpu}; bus.map(reader, writer, 0x00, 0x3f, 0x2140, 0x2183); bus.map(reader, writer, 0x80, 0xbf, 0x2140, 0x2183); @@ -92,15 +95,15 @@ void CPU::enable() { bus.map(reader, writer, 0x00, 0x3f, 0x4300, 0x437f); bus.map(reader, writer, 0x80, 0xbf, 0x4300, 0x437f); - reader = [](unsigned addr) { return cpu.wram[addr]; }; - writer = [](unsigned addr, uint8 data) { cpu.wram[addr] = data; }; + reader = [](uint addr) { return cpu.wram[addr]; }; + writer = [](uint addr, uint8 data) { cpu.wram[addr] = data; }; bus.map(reader, writer, 0x00, 0x3f, 0x0000, 0x1fff, 0x002000); bus.map(reader, writer, 0x80, 0xbf, 0x0000, 0x1fff, 0x002000); bus.map(reader, writer, 0x7e, 0x7f, 0x0000, 0xffff, 0x020000); } -void CPU::power() { +auto CPU::power() -> void { regs.a = 0x0000; regs.x = 0x0000; regs.y = 0x0000; @@ -109,7 +112,7 @@ void CPU::power() { reset(); } -void CPU::reset() { +auto CPU::reset() -> void { create(Enter, system.cpuFrequency()); coprocessors.reset(); PPUcounter::reset(); @@ -166,11 +169,4 @@ void CPU::reset() { dma_reset(); } -CPU::CPU() : queue(512, {&CPU::queue_event, this}) { - PPUcounter::scanline = {&CPU::scanline, this}; -} - -CPU::~CPU() { -} - } diff --git a/sfc/alt/cpu/cpu.hpp b/sfc/alt/cpu/cpu.hpp index 6e6aae4d..b7ad51be 100644 --- a/sfc/alt/cpu/cpu.hpp +++ b/sfc/alt/cpu/cpu.hpp @@ -1,72 +1,74 @@ struct CPU : Processor::R65816, Thread, public PPUcounter { - uint8 wram[128 * 1024]; - enum : bool { Threaded = true }; - vector coprocessors; - alwaysinline void step(unsigned clocks); - alwaysinline void synchronizeSMP(); - void synchronizePPU(); - void synchronizeCoprocessors(); - void synchronizeDevices(); - uint8 pio(); - bool joylatch(); - bool interrupt_pending(); - uint8 port_read(uint8 port); - void port_write(uint8 port, uint8 data); - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - void op_io(); - uint8 op_read(unsigned addr); - void op_write(unsigned addr, uint8 data); - - void enter(); - void enable(); - void power(); - void reset(); - - void serialize(serializer&); CPU(); - ~CPU(); + + alwaysinline auto step(uint clocks) -> void; + alwaysinline auto synchronizeSMP() -> void; + auto synchronizePPU() -> void; + auto synchronizeCoprocessors() -> void; + auto synchronizeDevices() -> void; + + auto pio() -> uint8; + auto joylatch() -> bool; + auto interrupt_pending() -> bool; + auto port_read(uint8 port) -> uint8; + auto port_write(uint8 port, uint8 data) -> void; + auto mmio_read(uint addr) -> uint8; + auto mmio_write(uint addr, uint8 data) -> void; + + auto op_io() -> void; + auto op_read(uint addr) -> uint8; + auto op_write(uint addr, uint8 data) -> void; + + auto enter() -> void; + auto enable() -> void; + auto power() -> void; + auto reset() -> void; + + auto serialize(serializer&) -> void; + + uint8 wram[128 * 1024]; + vector coprocessors; private: //cpu - static void Enter(); + static auto Enter() -> void; //timing + auto queue_event(uint id) -> void; + auto last_cycle() -> void; + auto add_clocks(uint clocks) -> void; + auto scanline() -> void; + auto run_auto_joypad_poll() -> void; + struct QueueEvent { - enum : unsigned { + enum : uint { DramRefresh, HdmaRun, }; }; - nall::priority_queue queue; - void queue_event(unsigned id); - void last_cycle(); - void add_clocks(unsigned clocks); - void scanline(); - void run_auto_joypad_poll(); + nall::priority_queue queue; //memory - unsigned speed(unsigned addr) const; + auto speed(uint addr) const -> uint; //dma - bool dma_transfer_valid(uint8 bbus, unsigned abus); - bool dma_addr_valid(unsigned abus); - uint8 dma_read(unsigned abus); - void dma_write(bool valid, unsigned addr, uint8 data); - void dma_transfer(bool direction, uint8 bbus, unsigned abus); - uint8 dma_bbus(unsigned i, unsigned index); - unsigned dma_addr(unsigned i); - unsigned hdma_addr(unsigned i); - unsigned hdma_iaddr(unsigned i); - void dma_run(); - bool hdma_active_after(unsigned i); - void hdma_update(unsigned i); - void hdma_run(); - void hdma_init(); - void dma_reset(); + auto dma_transfer_valid(uint8 bbus, uint abus) -> bool; + auto dma_addr_valid(uint abus) -> bool; + auto dma_read(uint abus) -> uint8; + auto dma_write(bool valid, uint addr, uint8 data) -> void; + auto dma_transfer(bool direction, uint8 bbus, uint abus) -> void; + auto dma_bbus(uint i, uint index) -> uint8; + auto dma_addr(uint i) -> uint; + auto hdma_addr(uint i) -> uint; + auto hdma_iaddr(uint i) -> uint; + auto dma_run() -> void; + auto hdma_active_after(uint i) -> bool; + auto hdma_update(uint i) -> void; + auto hdma_run() -> void; + auto hdma_init() -> void; + auto dma_reset() -> void; //registers uint8 port_data[4]; @@ -114,7 +116,7 @@ private: bool irq_lock; bool hdma_pending; - unsigned wram_addr; + uint wram_addr; bool joypad_strobe_latch; @@ -133,7 +135,7 @@ private: uint16 htime; uint16 vtime; - unsigned rom_speed; + uint rom_speed; uint16 rddiv; uint16 rdmpy; diff --git a/sfc/alt/cpu/dma.cpp b/sfc/alt/cpu/dma.cpp index addb6dbc..c97c49ab 100644 --- a/sfc/alt/cpu/dma.cpp +++ b/sfc/alt/cpu/dma.cpp @@ -1,12 +1,10 @@ -#ifdef CPU_CPP - -bool CPU::dma_transfer_valid(uint8 bbus, unsigned abus) { +auto CPU::dma_transfer_valid(uint8 bbus, uint abus) -> bool { //transfers from WRAM to WRAM are invalid; chip only has one address bus if(bbus == 0x80 && ((abus & 0xfe0000) == 0x7e0000 || (abus & 0x40e000) == 0x0000)) return false; return true; } -bool CPU::dma_addr_valid(unsigned abus) { +auto CPU::dma_addr_valid(uint abus) -> bool { //A-bus access to B-bus or S-CPU registers are invalid if((abus & 0x40ff00) == 0x2100) return false; //$[00-3f|80-bf]:[2100-21ff] if((abus & 0x40fe00) == 0x4000) return false; //$[00-3f|80-bf]:[4000-41ff] @@ -15,16 +13,16 @@ bool CPU::dma_addr_valid(unsigned abus) { return true; } -uint8 CPU::dma_read(unsigned abus) { +auto CPU::dma_read(uint abus) -> uint8 { if(dma_addr_valid(abus) == false) return 0x00; return bus.read(abus); } -void CPU::dma_write(bool valid, unsigned addr, uint8 data) { +auto CPU::dma_write(bool valid, uint addr, uint8 data) -> void { if(valid) bus.write(addr, data); } -void CPU::dma_transfer(bool direction, uint8 bbus, unsigned abus) { +auto CPU::dma_transfer(bool direction, uint8 bbus, uint abus) -> void { if(direction == 0) { uint8 data = dma_read(abus); add_clocks(8); @@ -36,7 +34,7 @@ void CPU::dma_transfer(bool direction, uint8 bbus, unsigned abus) { } } -uint8 CPU::dma_bbus(unsigned i, unsigned index) { +auto CPU::dma_bbus(uint i, uint index) -> uint8 { switch(channel[i].transfer_mode) { default: case 0: return (channel[i].dest_addr); //0 case 1: return (channel[i].dest_addr + (index & 1)); //0,1 @@ -49,8 +47,8 @@ uint8 CPU::dma_bbus(unsigned i, unsigned index) { } } -unsigned CPU::dma_addr(unsigned i) { - unsigned result = (channel[i].source_bank << 16) | (channel[i].source_addr); +auto CPU::dma_addr(uint i) -> uint { + uint result = (channel[i].source_bank << 16) | (channel[i].source_addr); if(channel[i].fixed_transfer == false) { if(channel[i].reverse_transfer == false) { @@ -63,22 +61,22 @@ unsigned CPU::dma_addr(unsigned i) { return result; } -unsigned CPU::hdma_addr(unsigned i) { +auto CPU::hdma_addr(uint i) -> uint { return (channel[i].source_bank << 16) | (channel[i].hdma_addr++); } -unsigned CPU::hdma_iaddr(unsigned i) { +auto CPU::hdma_iaddr(uint i) -> uint { return (channel[i].indirect_bank << 16) | (channel[i].indirect_addr++); } -void CPU::dma_run() { +auto CPU::dma_run() -> void { add_clocks(16); - for(unsigned i = 0; i < 8; i++) { + for(uint i = 0; i < 8; i++) { if(channel[i].dma_enabled == false) continue; add_clocks(8); - unsigned index = 0; + uint index = 0; do { dma_transfer(channel[i].direction, dma_bbus(i, index++), dma_addr(i)); } while(channel[i].dma_enabled && --channel[i].transfer_size); @@ -89,14 +87,14 @@ void CPU::dma_run() { status.irq_lock = true; } -bool CPU::hdma_active_after(unsigned i) { - for(unsigned n = i + 1; i < 8; i++) { +auto CPU::hdma_active_after(uint i) -> bool { + for(uint n = i + 1; i < 8; i++) { if(channel[i].hdma_enabled && !channel[i].hdma_completed) return true; } return false; } -void CPU::hdma_update(unsigned i) { +auto CPU::hdma_update(uint i) -> void { if((channel[i].line_counter & 0x7f) == 0) { channel[i].line_counter = dma_read(hdma_addr(i)); channel[i].hdma_completed = (channel[i].line_counter == 0); @@ -117,29 +115,29 @@ void CPU::hdma_update(unsigned i) { } } -void CPU::hdma_run() { - unsigned channels = 0; - for(unsigned i = 0; i < 8; i++) { +auto CPU::hdma_run() -> void { + uint channels = 0; + for(uint i = 0; i < 8; i++) { if(channel[i].hdma_enabled) channels++; } if(channels == 0) return; add_clocks(16); - for(unsigned i = 0; i < 8; i++) { + for(uint i = 0; i < 8; i++) { if(channel[i].hdma_enabled == false || channel[i].hdma_completed == true) continue; channel[i].dma_enabled = false; if(channel[i].hdma_do_transfer) { - static const unsigned transfer_length[] = { 1, 2, 2, 4, 4, 4, 2, 4 }; - unsigned length = transfer_length[channel[i].transfer_mode]; - for(unsigned index = 0; index < length; index++) { - unsigned addr = channel[i].indirect == false ? hdma_addr(i) : hdma_iaddr(i); + static const uint transfer_length[] = {1, 2, 2, 4, 4, 4, 2, 4}; + uint length = transfer_length[channel[i].transfer_mode]; + for(uint index = 0; index < length; index++) { + uint addr = channel[i].indirect == false ? hdma_addr(i) : hdma_iaddr(i); dma_transfer(channel[i].direction, dma_bbus(i, index), addr); } } } - for(unsigned i = 0; i < 8; i++) { + for(uint i = 0; i < 8; i++) { if(channel[i].hdma_enabled == false || channel[i].hdma_completed == true) continue; channel[i].line_counter--; @@ -150,8 +148,8 @@ void CPU::hdma_run() { status.irq_lock = true; } -void CPU::hdma_init() { - unsigned channels = 0; +auto CPU::hdma_init() -> void { + uint channels = 0; for(unsigned i = 0; i < 8; i++) { channel[i].hdma_completed = false; channel[i].hdma_do_transfer = false; @@ -160,7 +158,7 @@ void CPU::hdma_init() { if(channels == 0) return; add_clocks(16); - for(unsigned i = 0; i < 8; i++) { + for(uint i = 0; i < 8; i++) { if(!channel[i].hdma_enabled) continue; channel[i].dma_enabled = false; @@ -172,8 +170,8 @@ void CPU::hdma_init() { status.irq_lock = true; } -void CPU::dma_reset() { - for(unsigned i = 0; i < 8; i++) { +auto CPU::dma_reset() -> void { + for(uint i = 0; i < 8; i++) { channel[i].dma_enabled = false; channel[i].hdma_enabled = false; @@ -200,5 +198,3 @@ void CPU::dma_reset() { channel[i].hdma_do_transfer = false; } } - -#endif diff --git a/sfc/alt/cpu/memory.cpp b/sfc/alt/cpu/memory.cpp index fed9870a..efc7233d 100644 --- a/sfc/alt/cpu/memory.cpp +++ b/sfc/alt/cpu/memory.cpp @@ -1,41 +1,39 @@ -#ifdef CPU_CPP - -uint8 CPU::pio() { +auto CPU::pio() -> uint8 { return status.pio; } -bool CPU::joylatch() { +auto CPU::joylatch() -> bool { return status.joypad_strobe_latch; } -bool CPU::interrupt_pending() { +auto CPU::interrupt_pending() -> bool { return false; } -uint8 CPU::port_read(uint8 port) { +auto CPU::port_read(uint8 port) -> uint8 { return port_data[port & 3]; } -void CPU::port_write(uint8 port, uint8 data) { +auto CPU::port_write(uint8 port, uint8 data) -> void { port_data[port & 3] = data; } -void CPU::op_io() { +auto CPU::op_io() -> void { add_clocks(6); } -uint8 CPU::op_read(unsigned addr) { +auto CPU::op_read(uint addr) -> uint8 { regs.mdr = bus.read(addr); add_clocks(speed(addr)); return regs.mdr; } -void CPU::op_write(unsigned addr, uint8 data) { +auto CPU::op_write(uint addr, uint8 data) -> void { add_clocks(speed(addr)); bus.write(addr, regs.mdr = data); } -unsigned CPU::speed(unsigned addr) const { +auto CPU::speed(uint addr) const -> uint { if(addr & 0x408000) { if(addr & 0x800000) return status.rom_speed; return 8; @@ -44,5 +42,3 @@ unsigned CPU::speed(unsigned addr) const { if((addr - 0x4000) & 0x7e00) return 6; return 12; } - -#endif diff --git a/sfc/alt/cpu/mmio.cpp b/sfc/alt/cpu/mmio.cpp index 0113f37d..ee1cac7c 100644 --- a/sfc/alt/cpu/mmio.cpp +++ b/sfc/alt/cpu/mmio.cpp @@ -1,6 +1,4 @@ -#ifdef CPU_CPP - -uint8 CPU::mmio_read(unsigned addr) { +auto CPU::mmio_read(uint addr) -> uint8 { if((addr & 0xffc0) == 0x2140) { synchronizeSMP(); return smp.port_read(addr & 3); @@ -97,7 +95,7 @@ uint8 CPU::mmio_read(unsigned addr) { return regs.mdr; } -void CPU::mmio_write(unsigned addr, uint8 data) { +auto CPU::mmio_write(uint addr, uint8 data) -> void { if((addr & 0xffc0) == 0x2140) { synchronizeSMP(); port_write(addr & 3, data); @@ -230,7 +228,7 @@ void CPU::mmio_write(unsigned addr, uint8 data) { } if((addr & 0xff80) == 0x4300) { - unsigned i = (addr >> 4) & 7; + uint i = (addr >> 4) & 7; switch(addr & 0xff8f) { case 0x4300: { channel[i].direction = data & 0x80; @@ -299,5 +297,3 @@ void CPU::mmio_write(unsigned addr, uint8 data) { } } } - -#endif diff --git a/sfc/alt/cpu/serialization.cpp b/sfc/alt/cpu/serialization.cpp index ed7ac3fe..0309e85e 100644 --- a/sfc/alt/cpu/serialization.cpp +++ b/sfc/alt/cpu/serialization.cpp @@ -1,6 +1,4 @@ -#ifdef CPU_CPP - -void CPU::serialize(serializer& s) { +auto CPU::serialize(serializer& s) -> void { R65816::serialize(s); Thread::serialize(s); PPUcounter::serialize(s); @@ -10,7 +8,7 @@ void CPU::serialize(serializer& s) { queue.serialize(s); s.array(port_data); - for(unsigned i = 0; i < 8; i++) { + for(uint i = 0; i < 8; i++) { s.integer(channel[i].dma_enabled); s.integer(channel[i].hdma_enabled); @@ -82,5 +80,3 @@ void CPU::serialize(serializer& s) { s.integer(status.joy4l); s.integer(status.joy4h); } - -#endif diff --git a/sfc/alt/cpu/timing.cpp b/sfc/alt/cpu/timing.cpp index d00a0253..5ac063d4 100644 --- a/sfc/alt/cpu/timing.cpp +++ b/sfc/alt/cpu/timing.cpp @@ -1,13 +1,11 @@ -#ifdef CPU_CPP - -void CPU::queue_event(unsigned id) { +auto CPU::queue_event(uint id) -> void { switch(id) { case QueueEvent::DramRefresh: return add_clocks(40); case QueueEvent::HdmaRun: return hdma_run(); } } -void CPU::last_cycle() { +auto CPU::last_cycle() -> void { if(status.irq_lock) { status.irq_lock = false; return; @@ -26,18 +24,18 @@ void CPU::last_cycle() { } } -void CPU::add_clocks(unsigned clocks) { +auto CPU::add_clocks(uint clocks) -> void { if(status.hirq_enabled) { if(status.virq_enabled) { - unsigned cpu_time = vcounter() * 1364 + hcounter(); - unsigned irq_time = status.vtime * 1364 + status.htime * 4; - unsigned framelines = (system.region() == System::Region::NTSC ? 262 : 312) + (ppu.interlace() && !field()); + uint cpu_time = vcounter() * 1364 + hcounter(); + uint irq_time = status.vtime * 1364 + status.htime * 4; + uint framelines = (system.region() == System::Region::NTSC ? 262 : 312) + (ppu.interlace() && !field()); if(cpu_time > irq_time) irq_time += framelines * 1364; bool irq_valid = status.irq_valid; status.irq_valid = cpu_time <= irq_time && cpu_time + clocks > irq_time; if(!irq_valid && status.irq_valid) status.irq_line = true; } else { - unsigned irq_time = status.htime * 4; + uint irq_time = status.htime * 4; if(hcounter() > irq_time) irq_time += 1364; bool irq_valid = status.irq_valid; status.irq_valid = hcounter() <= irq_time && hcounter() + clocks > irq_time; @@ -58,7 +56,7 @@ void CPU::add_clocks(unsigned clocks) { step(clocks); } -void CPU::scanline() { +auto CPU::scanline() -> void { synchronizeSMP(); synchronizePPU(); synchronizeCoprocessors(); @@ -86,14 +84,14 @@ void CPU::scanline() { } } -void CPU::run_auto_joypad_poll() { +auto CPU::run_auto_joypad_poll() -> void { device.controllerPort1->latch(1); device.controllerPort2->latch(1); device.controllerPort1->latch(0); device.controllerPort2->latch(0); uint16 joy1 = 0, joy2 = 0, joy3 = 0, joy4 = 0; - for(unsigned i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { uint8 port0 = device.controllerPort1->data(); uint8 port1 = device.controllerPort2->data(); @@ -115,5 +113,3 @@ void CPU::run_auto_joypad_poll() { status.joy4l = joy4; status.joy4h = joy4 >> 8; } - -#endif diff --git a/sfc/alt/ppu-performance/background/background.cpp b/sfc/alt/ppu-performance/background/background.cpp index a177542c..852a48b1 100644 --- a/sfc/alt/ppu-performance/background/background.cpp +++ b/sfc/alt/ppu-performance/background/background.cpp @@ -1,12 +1,30 @@ -#ifdef PPU_CPP - #include "mode7.cpp" -unsigned PPU::Background::get_tile(unsigned hoffset, unsigned voffset) { - unsigned tile_x = (hoffset & mask_x) >> tile_width; - unsigned tile_y = (voffset & mask_y) >> tile_height; +PPU::Background::Background(PPU& self, uint id) : self(self), id(id) { + priority0_enable = true; + priority1_enable = true; - unsigned tile_pos = ((tile_y & 0x1f) << 5) + (tile_x & 0x1f); + opt_valid_bit = (id == ID::BG1 ? 0x2000 : id == ID::BG2 ? 0x4000 : 0x0000); + + mosaic_table = new uint16*[16]; + for(uint m = 0; m < 16; m++) { + mosaic_table[m] = new uint16[4096]; + for(uint x = 0; x < 4096; x++) { + mosaic_table[m][x] = (x / (m + 1)) * (m + 1); + } + } +} + +PPU::Background::~Background() { + for(uint m = 0; m < 16; m++) delete[] mosaic_table[m]; + delete[] mosaic_table; +} + +auto PPU::Background::get_tile(uint hoffset, uint voffset) -> uint { + uint tile_x = (hoffset & mask_x) >> tile_width; + uint tile_y = (voffset & mask_y) >> tile_height; + + uint tile_pos = ((tile_y & 0x1f) << 5) + (tile_x & 0x1f); if(tile_y & 0x20) tile_pos += scy; if(tile_x & 0x20) tile_pos += scx; @@ -14,8 +32,8 @@ unsigned PPU::Background::get_tile(unsigned hoffset, unsigned voffset) { return (ppu.vram[tiledata_addr + 0] << 0) + (ppu.vram[tiledata_addr + 1] << 8); } -void PPU::Background::offset_per_tile(unsigned x, unsigned y, unsigned& hoffset, unsigned& voffset) { - unsigned opt_x = (x + (hscroll & 7)), hval, vval; +auto PPU::Background::offset_per_tile(uint x, uint y, uint& hoffset, uint& voffset) -> void { + uint opt_x = (x + (hscroll & 7)), hval, vval; if(opt_x >= 8) { hval = self.bg3.get_tile((opt_x - 8) + (self.bg3.regs.hoffset & ~7), self.bg3.regs.voffset + 0); if(self.regs.bgmode != 4) @@ -40,7 +58,7 @@ void PPU::Background::offset_per_tile(unsigned x, unsigned y, unsigned& hoffset, } } -void PPU::Background::scanline() { +auto PPU::Background::scanline() -> void { if(self.vcounter() == 1) { mosaic_vcounter = regs.mosaic + 1; mosaic_voffset = 1; @@ -68,7 +86,7 @@ void PPU::Background::scanline() { if(regs.screen_size == 3) scy <<= 1; } -void PPU::Background::render() { +auto PPU::Background::render() -> void { if(regs.mode == Mode::Inactive) return; if(regs.main_enable == false && regs.sub_enable == false) return; @@ -76,38 +94,38 @@ void PPU::Background::render() { if(regs.sub_enable) window.render(1); if(regs.mode == Mode::Mode7) return render_mode7(); - unsigned priority0 = (priority0_enable ? regs.priority0 : 0); - unsigned priority1 = (priority1_enable ? regs.priority1 : 0); + uint priority0 = (priority0_enable ? regs.priority0 : 0); + uint priority1 = (priority1_enable ? regs.priority1 : 0); if(priority0 + priority1 == 0) return; - unsigned mosaic_hcounter = 1; - unsigned mosaic_palette = 0; - unsigned mosaic_priority = 0; - unsigned mosaic_color = 0; + uint mosaic_hcounter = 1; + uint mosaic_palette = 0; + uint mosaic_priority = 0; + uint mosaic_color = 0; - const unsigned bgpal_index = (self.regs.bgmode == 0 ? id << 5 : 0); - const unsigned pal_size = 2 << regs.mode; - const unsigned tile_mask = 0x0fff >> regs.mode; - const unsigned tiledata_index = regs.tiledata_addr >> (4 + regs.mode); + const uint bgpal_index = (self.regs.bgmode == 0 ? id << 5 : 0); + const uint pal_size = 2 << regs.mode; + const uint tile_mask = 0x0fff >> regs.mode; + const uint tiledata_index = regs.tiledata_addr >> (4 + regs.mode); hscroll = regs.hoffset; vscroll = regs.voffset; - unsigned y = (regs.mosaic == 0 ? self.vcounter() : mosaic_voffset); + uint y = (regs.mosaic == 0 ? self.vcounter() : mosaic_voffset); if(hires) { hscroll <<= 1; if(self.regs.interlace) y = (y << 1) + self.field(); } - unsigned tile_pri, tile_num; - unsigned pal_index, pal_num; - unsigned hoffset, voffset, col; + uint tile_pri, tile_num; + uint pal_index, pal_num; + uint hoffset, voffset, col; bool mirror_x, mirror_y; const bool is_opt_mode = (self.regs.bgmode == 2 || self.regs.bgmode == 4 || self.regs.bgmode == 6); const bool is_direct_color_mode = (self.screen.regs.direct_color == true && id == ID::BG1 && (self.regs.bgmode == 3 || self.regs.bgmode == 4)); - signed x = 0 - (hscroll & 7); + int x = 0 - (hscroll & 7); while(x < width) { hoffset = x + hscroll; voffset = y + vscroll; @@ -127,12 +145,12 @@ void PPU::Background::render() { tile_num = ((tile_num & 0x03ff) + tiledata_index) & tile_mask; if(mirror_y) voffset ^= 7; - unsigned mirror_xmask = !mirror_x ? 0 : 7; + uint mirror_xmask = !mirror_x ? 0 : 7; uint8* tiledata = self.cache.tile(regs.mode, tile_num); tiledata += ((voffset & 7) * 8); - for(unsigned n = 0; n < 8; n++, x++) { + for(uint n = 0; n < 8; n++, x++) { if(x & width) continue; if(--mosaic_hcounter == 0) { mosaic_hcounter = regs.mosaic + 1; @@ -150,7 +168,7 @@ void PPU::Background::render() { if(regs.main_enable && !window.main[x]) self.screen.output.plot_main(x, mosaic_color, mosaic_priority, id); if(regs.sub_enable && !window.sub[x]) self.screen.output.plot_sub(x, mosaic_color, mosaic_priority, id); } else { - signed half_x = x >> 1; + int half_x = x >> 1; if(x & 1) { if(regs.main_enable && !window.main[half_x]) self.screen.output.plot_main(half_x, mosaic_color, mosaic_priority, id); } else { @@ -160,25 +178,3 @@ void PPU::Background::render() { } } } - -PPU::Background::Background(PPU& self, unsigned id) : self(self), id(id) { - priority0_enable = true; - priority1_enable = true; - - opt_valid_bit = (id == ID::BG1 ? 0x2000 : id == ID::BG2 ? 0x4000 : 0x0000); - - mosaic_table = new uint16*[16]; - for(unsigned m = 0; m < 16; m++) { - mosaic_table[m] = new uint16[4096]; - for(unsigned x = 0; x < 4096; x++) { - mosaic_table[m][x] = (x / (m + 1)) * (m + 1); - } - } -} - -PPU::Background::~Background() { - for(unsigned m = 0; m < 16; m++) delete[] mosaic_table[m]; - delete[] mosaic_table; -} - -#endif diff --git a/sfc/alt/ppu-performance/background/background.hpp b/sfc/alt/ppu-performance/background/background.hpp index 926ab0a6..ba86314b 100644 --- a/sfc/alt/ppu-performance/background/background.hpp +++ b/sfc/alt/ppu-performance/background/background.hpp @@ -1,66 +1,68 @@ class Background { - struct ID { enum { BG1, BG2, BG3, BG4 }; }; - struct Mode { enum { BPP2, BPP4, BPP8, Mode7, Inactive }; }; - struct ScreenSize { enum { Size32x32, Size32x64, Size64x32, Size64x64 }; }; - struct TileSize { enum { Size8x8, Size16x16 }; }; + struct ID { enum : uint { BG1, BG2, BG3, BG4 }; }; + struct Mode { enum : uint { BPP2, BPP4, BPP8, Mode7, Inactive }; }; + struct ScreenSize { enum : uint { Size32x32, Size32x64, Size64x32, Size64x64 }; }; + struct TileSize { enum : uint { Size8x8, Size16x16 }; }; + + Background(PPU& self, uint id); + ~Background(); + + alwaysinline auto get_tile(uint hoffset, uint voffset) -> uint; + auto offset_per_tile(uint x, uint y, uint& hoffset, uint& voffset) -> void; + auto scanline() -> void; + auto render() -> void; + auto render_mode7() -> void; + + auto serialize(serializer&) -> void; + + PPU& self; bool priority0_enable; bool priority1_enable; struct Regs { - unsigned mode; - unsigned priority0; - unsigned priority1; + uint mode; + uint priority0; + uint priority1; bool tile_size; - unsigned mosaic; + uint mosaic; - unsigned screen_addr; - unsigned screen_size; - unsigned tiledata_addr; + uint screen_addr; + uint screen_size; + uint tiledata_addr; - unsigned hoffset; - unsigned voffset; + uint hoffset; + uint voffset; bool main_enable; bool sub_enable; } regs; - uint16 **mosaic_table; + uint16** mosaic_table; - const unsigned id; - unsigned opt_valid_bit; + const uint id; + uint opt_valid_bit; bool hires; signed width; - unsigned tile_width; - unsigned tile_height; + uint tile_width; + uint tile_height; - unsigned mask_x; - unsigned mask_y; + uint mask_x; + uint mask_y; - unsigned scx; - unsigned scy; + uint scx; + uint scy; - unsigned hscroll; - unsigned vscroll; + uint hscroll; + uint vscroll; - unsigned mosaic_vcounter; - unsigned mosaic_voffset; + uint mosaic_vcounter; + uint mosaic_voffset; LayerWindow window; - alwaysinline unsigned get_tile(unsigned hoffset, unsigned voffset); - void offset_per_tile(unsigned x, unsigned y, unsigned& hoffset, unsigned& voffset); - void scanline(); - void render(); - void render_mode7(); - - void serialize(serializer&); - Background(PPU& self, unsigned id); - ~Background(); - - PPU& self; friend class PPU; }; diff --git a/sfc/alt/ppu-performance/background/mode7.cpp b/sfc/alt/ppu-performance/background/mode7.cpp index 762dd45b..a53dbcbb 100644 --- a/sfc/alt/ppu-performance/background/mode7.cpp +++ b/sfc/alt/ppu-performance/background/mode7.cpp @@ -1,22 +1,20 @@ -#ifdef PPU_CPP - #define Clip(x) (((x) & 0x2000) ? ((x) | ~0x03ff) : ((x) & 0x03ff)) -void PPU::Background::render_mode7() { - signed px, py; - signed tx, ty, tile, palette; +auto PPU::Background::render_mode7() -> void { + int px, py; + int tx, ty, tile, palette; - signed a = sclip<16>(self.regs.m7a); - signed b = sclip<16>(self.regs.m7b); - signed c = sclip<16>(self.regs.m7c); - signed d = sclip<16>(self.regs.m7d); + int a = sclip<16>(self.regs.m7a); + int b = sclip<16>(self.regs.m7b); + int c = sclip<16>(self.regs.m7c); + int d = sclip<16>(self.regs.m7d); - signed cx = sclip<13>(self.regs.m7x); - signed cy = sclip<13>(self.regs.m7y); - signed hofs = sclip<13>(self.regs.mode7_hoffset); - signed vofs = sclip<13>(self.regs.mode7_voffset); + int cx = sclip<13>(self.regs.m7x); + int cy = sclip<13>(self.regs.m7y); + int hofs = sclip<13>(self.regs.mode7_hoffset); + int vofs = sclip<13>(self.regs.mode7_voffset); - signed y = (self.regs.mode7_vflip == false ? self.vcounter() : 255 - self.vcounter()); + int y = (self.regs.mode7_vflip == false ? self.vcounter() : 255 - self.vcounter()); uint16* mosaic_x; uint16* mosaic_y; @@ -28,13 +26,13 @@ void PPU::Background::render_mode7() { mosaic_y = mosaic_table[self.bg1.regs.mosaic]; } - unsigned priority0 = (priority0_enable ? regs.priority0 : 0); - unsigned priority1 = (priority1_enable ? regs.priority1 : 0); + uint priority0 = (priority0_enable ? regs.priority0 : 0); + uint priority1 = (priority1_enable ? regs.priority1 : 0); if(priority0 + priority1 == 0) return; - signed psx = ((a * Clip(hofs - cx)) & ~63) + ((b * Clip(vofs - cy)) & ~63) + ((b * mosaic_y[y]) & ~63) + (cx << 8); - signed psy = ((c * Clip(hofs - cx)) & ~63) + ((d * Clip(vofs - cy)) & ~63) + ((d * mosaic_y[y]) & ~63) + (cy << 8); - for(signed x = 0; x < 256; x++) { + int psx = ((a * Clip(hofs - cx)) & ~63) + ((b * Clip(vofs - cy)) & ~63) + ((b * mosaic_y[y]) & ~63) + (cx << 8); + int psy = ((c * Clip(hofs - cx)) & ~63) + ((d * Clip(vofs - cy)) & ~63) + ((d * mosaic_y[y]) & ~63) + (cy << 8); + for(int x = 0; x < 256; x++) { px = (psx + (a * mosaic_x[x])) >> 8; py = (psy + (c * mosaic_x[x])) >> 8; @@ -78,7 +76,7 @@ void PPU::Background::render_mode7() { } } - unsigned priority; + uint priority; if(id == ID::BG1) { priority = priority0; } else { @@ -87,9 +85,9 @@ void PPU::Background::render_mode7() { } if(palette == 0) continue; - unsigned plot_x = (self.regs.mode7_hflip == false ? x : 255 - x); + uint plot_x = (self.regs.mode7_hflip == false ? x : 255 - x); - unsigned color; + uint color; if(self.screen.regs.direct_color && id == ID::BG1) { color = self.screen.get_direct_color(0, palette); } else { @@ -102,5 +100,3 @@ void PPU::Background::render_mode7() { } #undef Clip - -#endif diff --git a/sfc/alt/ppu-performance/cache/cache.cpp b/sfc/alt/ppu-performance/cache/cache.cpp index ad587067..b9bb6151 100644 --- a/sfc/alt/ppu-performance/cache/cache.cpp +++ b/sfc/alt/ppu-performance/cache/cache.cpp @@ -1,12 +1,19 @@ -#ifdef PPU_CPP +PPU::Cache::Cache(PPU& self) : self(self) { + tiledata[0] = new uint8[262144](); + tiledata[1] = new uint8[131072](); + tiledata[2] = new uint8[ 65536](); + tilevalid[0] = new uint8[ 4096](); + tilevalid[1] = new uint8[ 2048](); + tilevalid[2] = new uint8[ 1024](); +} -uint8* PPU::Cache::tile_2bpp(unsigned tile) { +auto PPU::Cache::tile_2bpp(uint tile) -> uint8* { if(tilevalid[0][tile] == 0) { tilevalid[0][tile] = 1; uint8* output = (uint8*)tiledata[0] + (tile << 6); - unsigned offset = tile << 4; - unsigned y = 8; - unsigned color, d0, d1; + uint offset = tile << 4; + uint y = 8; + uint color, d0, d1; while(y--) { d0 = ppu.vram[offset + 0]; d1 = ppu.vram[offset + 1]; @@ -29,13 +36,13 @@ uint8* PPU::Cache::tile_2bpp(unsigned tile) { return tiledata[0] + (tile << 6); } -uint8* PPU::Cache::tile_4bpp(unsigned tile) { +auto PPU::Cache::tile_4bpp(uint tile) -> uint8* { if(tilevalid[1][tile] == 0) { tilevalid[1][tile] = 1; uint8* output = (uint8*)tiledata[1] + (tile << 6); - unsigned offset = tile << 5; - unsigned y = 8; - unsigned color, d0, d1, d2, d3; + uint offset = tile << 5; + uint y = 8; + uint color, d0, d1, d2, d3; while(y--) { d0 = ppu.vram[offset + 0]; d1 = ppu.vram[offset + 1]; @@ -62,13 +69,13 @@ uint8* PPU::Cache::tile_4bpp(unsigned tile) { return tiledata[1] + (tile << 6); } -uint8* PPU::Cache::tile_8bpp(unsigned tile) { +auto PPU::Cache::tile_8bpp(uint tile) -> uint8* { if(tilevalid[2][tile] == 0) { tilevalid[2][tile] = 1; uint8* output = (uint8*)tiledata[2] + (tile << 6); - unsigned offset = tile << 6; - unsigned y = 8; - unsigned color, d0, d1, d2, d3, d4, d5, d6, d7; + uint offset = tile << 6; + uint y = 8; + uint color, d0, d1, d2, d3, d4, d5, d6, d7; while(y--) { d0 = ppu.vram[offset + 0]; d1 = ppu.vram[offset + 1]; @@ -103,21 +110,10 @@ uint8* PPU::Cache::tile_8bpp(unsigned tile) { return tiledata[2] + (tile << 6); } -uint8* PPU::Cache::tile(unsigned bpp, unsigned tile) { +auto PPU::Cache::tile(uint bpp, uint tile) -> uint8* { switch(bpp) { - case 0: return tile_2bpp(tile); - case 1: return tile_4bpp(tile); - case 2: return tile_8bpp(tile); + case 0: return tile_2bpp(tile); + case 1: return tile_4bpp(tile); + case 2: return tile_8bpp(tile); } } - -PPU::Cache::Cache(PPU& self) : self(self) { - tiledata[0] = new uint8[262144](); - tiledata[1] = new uint8[131072](); - tiledata[2] = new uint8[ 65536](); - tilevalid[0] = new uint8[ 4096](); - tilevalid[1] = new uint8[ 2048](); - tilevalid[2] = new uint8[ 1024](); -} - -#endif diff --git a/sfc/alt/ppu-performance/cache/cache.hpp b/sfc/alt/ppu-performance/cache/cache.hpp index cc370c8b..4778f25b 100644 --- a/sfc/alt/ppu-performance/cache/cache.hpp +++ b/sfc/alt/ppu-performance/cache/cache.hpp @@ -1,15 +1,16 @@ struct Cache { + Cache(PPU& self); + + auto tile_2bpp(uint tile) -> uint8*; + auto tile_4bpp(uint tile) -> uint8*; + auto tile_8bpp(uint tile) -> uint8*; + auto tile(uint bpp, uint tile) -> uint8*; + + auto serialize(serializer&) -> void; + + PPU& self; uint8* tiledata[3]; uint8* tilevalid[3]; - uint8* tile_2bpp(unsigned tile); - uint8* tile_4bpp(unsigned tile); - uint8* tile_8bpp(unsigned tile); - uint8* tile(unsigned bpp, unsigned tile); - - void serialize(serializer&); - Cache(PPU& self); - - PPU& self; friend class PPU; }; diff --git a/sfc/alt/ppu-performance/mmio/mmio.cpp b/sfc/alt/ppu-performance/mmio/mmio.cpp index ca99aa33..1f4809f5 100644 --- a/sfc/alt/ppu-performance/mmio/mmio.cpp +++ b/sfc/alt/ppu-performance/mmio/mmio.cpp @@ -1,16 +1,14 @@ -#ifdef PPU_CPP - -void PPU::latch_counters() { +auto PPU::latch_counters() -> void { regs.hcounter = cpu.hdot(); regs.vcounter = cpu.vcounter(); regs.counters_latched = true; } -bool PPU::interlace() const { return display.interlace; } -bool PPU::overscan() const { return display.overscan; } -bool PPU::hires() const { return regs.pseudo_hires || regs.bgmode == 5 || regs.bgmode == 6; } +auto PPU::interlace() const -> bool { return display.interlace; } +auto PPU::overscan() const -> bool { return display.overscan; } +auto PPU::hires() const -> bool { return regs.pseudo_hires || regs.bgmode == 5 || regs.bgmode == 6; } -uint16 PPU::get_vram_addr() { +auto PPU::get_vram_addr() -> uint16 { uint16 addr = regs.vram_addr; switch(regs.vram_mapping) { case 0: break; @@ -21,13 +19,13 @@ uint16 PPU::get_vram_addr() { return (addr << 1); } -uint8 PPU::vram_read(unsigned addr) { +auto PPU::vram_read(uint addr) -> uint8 { if(regs.display_disable) return vram[addr]; if(cpu.vcounter() >= display.height) return vram[addr]; return 0x00; } -void PPU::vram_write(unsigned addr, uint8 data) { +auto PPU::vram_write(uint addr, uint8 data) -> void { if(regs.display_disable || cpu.vcounter() >= display.height) { vram[addr] = data; cache.tilevalid[0][addr >> 4] = false; @@ -37,29 +35,29 @@ void PPU::vram_write(unsigned addr, uint8 data) { } } -uint8 PPU::oam_read(unsigned addr) { +auto PPU::oam_read(uint addr) -> uint8 { if(addr & 0x0200) addr &= 0x021f; if(regs.display_disable) return oam[addr]; if(cpu.vcounter() >= display.height) return oam[addr]; return oam[0x0218]; } -void PPU::oam_write(unsigned addr, uint8 data) { +auto PPU::oam_write(uint addr, uint8 data) -> void { if(addr & 0x0200) addr &= 0x021f; if(!regs.display_disable && cpu.vcounter() < display.height) addr = 0x0218; oam[addr] = data; sprite.update_list(addr, data); } -uint8 PPU::cgram_read(unsigned addr) { +auto PPU::cgram_read(uint addr) -> uint8 { return cgram[addr]; } -void PPU::cgram_write(unsigned addr, uint8 data) { +auto PPU::cgram_write(uint addr, uint8 data) -> void { cgram[addr] = data; } -void PPU::mmio_update_video_mode() { +auto PPU::mmio_update_video_mode() -> void { switch(regs.bgmode) { case 0: { bg1.regs.mode = Background::Mode::BPP2; bg1.regs.priority0 = 8; bg1.regs.priority1 = 11; @@ -157,7 +155,7 @@ void PPU::mmio_update_video_mode() { } } -uint8 PPU::mmio_read(unsigned addr) { +auto PPU::mmio_read(uint addr) -> uint8 { cpu.synchronizePPU(); switch(addr & 0xffff) { @@ -278,7 +276,7 @@ uint8 PPU::mmio_read(unsigned addr) { return cpu.regs.mdr; } -void PPU::mmio_write(unsigned addr, uint8 data) { +auto PPU::mmio_write(uint addr, uint8 data) -> void { cpu.synchronizePPU(); switch(addr & 0xffff) { @@ -680,7 +678,7 @@ void PPU::mmio_write(unsigned addr, uint8 data) { } } -void PPU::mmio_reset() { +auto PPU::mmio_reset() -> void { //internal regs.ppu1_mdr = 0; regs.ppu2_mdr = 0; @@ -887,5 +885,3 @@ void PPU::mmio_reset() { mmio_update_video_mode(); } - -#endif diff --git a/sfc/alt/ppu-performance/mmio/mmio.hpp b/sfc/alt/ppu-performance/mmio/mmio.hpp index 36b5af4d..4f1bd657 100644 --- a/sfc/alt/ppu-performance/mmio/mmio.hpp +++ b/sfc/alt/ppu-performance/mmio/mmio.hpp @@ -1,6 +1,6 @@ public: - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); + auto mmio_read(uint addr) -> uint8; + auto mmio_write(uint addr, uint8 data) -> void; private: @@ -21,7 +21,7 @@ struct Regs { //$2100 bool display_disable; - unsigned display_brightness; + uint display_brightness; //$2102-$2103 uint16 oam_baseaddr; @@ -30,7 +30,7 @@ struct Regs { //$2105 bool bg3_priority; - unsigned bgmode; + uint bgmode; //$210d uint16 mode7_hoffset; @@ -40,14 +40,14 @@ struct Regs { //$2115 bool vram_incmode; - unsigned vram_mapping; - unsigned vram_incsize; + uint vram_mapping; + uint vram_incsize; //$2116-$2117 uint16 vram_addr; //$211a - unsigned mode7_repeat; + uint mode7_repeat; bool mode7_vflip; bool mode7_hflip; @@ -63,10 +63,10 @@ struct Regs { uint16 cgram_addr; //$2126-$212a - unsigned window_one_left; - unsigned window_one_right; - unsigned window_two_left; - unsigned window_two_right; + uint window_one_left; + uint window_one_right; + uint window_two_left; + uint window_two_right; //$2133 bool mode7_extbg; @@ -81,15 +81,15 @@ struct Regs { uint16 vcounter; } regs; -uint16 get_vram_addr(); -uint8 vram_read(unsigned addr); -void vram_write(unsigned addr, uint8 data); +auto get_vram_addr() -> uint16; +auto vram_read(uint addr) -> uint8; +auto vram_write(uint addr, uint8 data) -> void; -uint8 oam_read(unsigned addr); -void oam_write(unsigned addr, uint8 data); +auto oam_read(uint addr) -> uint8; +auto oam_write(uint addr, uint8 data) -> void; -uint8 cgram_read(unsigned addr); -void cgram_write(unsigned addr, uint8 data); +auto cgram_read(uint addr) -> uint8; +auto cgram_write(uint addr, uint8 data) -> void; -void mmio_update_video_mode(); -void mmio_reset(); +auto mmio_update_video_mode() -> void; +auto mmio_reset() -> void; diff --git a/sfc/alt/ppu-performance/ppu.cpp b/sfc/alt/ppu-performance/ppu.cpp index 9c1f7728..ef5eba3c 100644 --- a/sfc/alt/ppu-performance/ppu.cpp +++ b/sfc/alt/ppu-performance/ppu.cpp @@ -1,6 +1,5 @@ #include -#define PPU_CPP namespace SuperFamicom { PPU ppu; @@ -13,120 +12,6 @@ PPU ppu; #include "screen/screen.cpp" #include "serialization.cpp" -void PPU::step(unsigned clocks) { - clock += clocks; -} - -void PPU::synchronize_cpu() { - if(CPU::Threaded == true) { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); - } else { - while(clock >= 0) cpu.enter(); - } -} - -void PPU::Enter() { ppu.enter(); } - -void PPU::enter() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - scanline(); - if(vcounter() < display.height && vcounter()) { - add_clocks(512); - render_scanline(); - add_clocks(lineclocks() - 512); - } else { - add_clocks(lineclocks()); - } - } -} - -void PPU::add_clocks(unsigned clocks) { - tick(clocks); - step(clocks); - synchronize_cpu(); -} - -void PPU::render_scanline() { - if(display.framecounter) return; //skip this frame? - bg1.scanline(); - bg2.scanline(); - bg3.scanline(); - bg4.scanline(); - if(regs.display_disable) return screen.render_black(); - screen.scanline(); - bg1.render(); - bg2.render(); - bg3.render(); - bg4.render(); - sprite.render(); - screen.render(); -} - -void PPU::scanline() { - display.width = !hires() ? 256 : 512; - display.height = !overscan() ? 225 : 240; - if(vcounter() == 0) frame(); - if(vcounter() == display.height && regs.display_disable == false) sprite.address_reset(); -} - -void PPU::frame() { - sprite.frame(); - system.frame(); - display.interlace = regs.interlace; - display.overscan = regs.overscan; - display.framecounter = display.frameskip == 0 ? 0 : (display.framecounter + 1) % display.frameskip; -} - -void PPU::enable() { - function reader = {&PPU::mmio_read, (PPU*)&ppu}; - function writer = {&PPU::mmio_write, (PPU*)&ppu}; - - bus.map(reader, writer, 0x00, 0x3f, 0x2100, 0x213f); - bus.map(reader, writer, 0x80, 0xbf, 0x2100, 0x213f); -} - -void PPU::power() { - for(auto& n : vram) n = 0; - for(auto& n : oam) n = 0; - for(auto& n : cgram) n = 0; - reset(); -} - -void PPU::reset() { - create(Enter, system.cpuFrequency()); - PPUcounter::reset(); - memset(surface, 0, 512 * 512 * sizeof(uint32)); - mmio_reset(); - display.interlace = false; - display.overscan = false; -} - -void PPU::layer_enable(unsigned layer, unsigned priority, bool enable) { - switch(layer * 4 + priority) { - case 0: bg1.priority0_enable = enable; break; - case 1: bg1.priority1_enable = enable; break; - case 4: bg2.priority0_enable = enable; break; - case 5: bg2.priority1_enable = enable; break; - case 8: bg3.priority0_enable = enable; break; - case 9: bg3.priority1_enable = enable; break; - case 12: bg4.priority0_enable = enable; break; - case 13: bg4.priority1_enable = enable; break; - case 16: sprite.priority0_enable = enable; break; - case 17: sprite.priority1_enable = enable; break; - case 18: sprite.priority2_enable = enable; break; - case 19: sprite.priority3_enable = enable; break; - } -} - -void PPU::set_frameskip(unsigned frameskip) { - display.frameskip = frameskip; - display.framecounter = 0; -} - PPU::PPU() : cache(*this), bg1(*this, Background::ID::BG1), @@ -147,4 +32,118 @@ PPU::~PPU() { delete[] surface; } +auto PPU::step(uint clocks) -> void { + clock += clocks; +} + +auto PPU::synchronizeCPU() -> void { + if(CPU::Threaded == true) { + if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); + } else { + while(clock >= 0) cpu.enter(); + } +} + +auto PPU::Enter() -> void { ppu.enter(); } + +auto PPU::enter() -> void { + while(true) { + if(scheduler.sync == Scheduler::SynchronizeMode::All) { + scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); + } + + scanline(); + if(vcounter() < display.height && vcounter()) { + add_clocks(512); + render_scanline(); + add_clocks(lineclocks() - 512); + } else { + add_clocks(lineclocks()); + } + } +} + +auto PPU::add_clocks(uint clocks) -> void { + tick(clocks); + step(clocks); + synchronizeCPU(); +} + +auto PPU::render_scanline() -> void { + if(display.framecounter) return; //skip this frame? + bg1.scanline(); + bg2.scanline(); + bg3.scanline(); + bg4.scanline(); + if(regs.display_disable) return screen.render_black(); + screen.scanline(); + bg1.render(); + bg2.render(); + bg3.render(); + bg4.render(); + sprite.render(); + screen.render(); +} + +auto PPU::scanline() -> void { + display.width = !hires() ? 256 : 512; + display.height = !overscan() ? 225 : 240; + if(vcounter() == 0) frame(); + if(vcounter() == display.height && regs.display_disable == false) sprite.address_reset(); +} + +auto PPU::frame() -> void { + sprite.frame(); + system.frame(); + display.interlace = regs.interlace; + display.overscan = regs.overscan; + display.framecounter = display.frameskip == 0 ? 0 : (display.framecounter + 1) % display.frameskip; +} + +auto PPU::enable() -> void { + function reader = {&PPU::mmio_read, (PPU*)&ppu}; + function writer = {&PPU::mmio_write, (PPU*)&ppu}; + + bus.map(reader, writer, 0x00, 0x3f, 0x2100, 0x213f); + bus.map(reader, writer, 0x80, 0xbf, 0x2100, 0x213f); +} + +auto PPU::power() -> void { + for(auto& n : vram) n = 0; + for(auto& n : oam) n = 0; + for(auto& n : cgram) n = 0; + reset(); +} + +auto PPU::reset() -> void { + create(Enter, system.cpuFrequency()); + PPUcounter::reset(); + memset(surface, 0, 512 * 512 * sizeof(uint32)); + mmio_reset(); + display.interlace = false; + display.overscan = false; +} + +auto PPU::layer_enable(uint layer, uint priority, bool enable) -> void { + switch(layer * 4 + priority) { + case 0: bg1.priority0_enable = enable; break; + case 1: bg1.priority1_enable = enable; break; + case 4: bg2.priority0_enable = enable; break; + case 5: bg2.priority1_enable = enable; break; + case 8: bg3.priority0_enable = enable; break; + case 9: bg3.priority1_enable = enable; break; + case 12: bg4.priority0_enable = enable; break; + case 13: bg4.priority1_enable = enable; break; + case 16: sprite.priority0_enable = enable; break; + case 17: sprite.priority1_enable = enable; break; + case 18: sprite.priority2_enable = enable; break; + case 19: sprite.priority3_enable = enable; break; + } +} + +auto PPU::set_frameskip(uint frameskip) -> void { + display.frameskip = frameskip; + display.framecounter = 0; +} + } diff --git a/sfc/alt/ppu-performance/ppu.hpp b/sfc/alt/ppu-performance/ppu.hpp index b3427e29..fb001cf5 100644 --- a/sfc/alt/ppu-performance/ppu.hpp +++ b/sfc/alt/ppu-performance/ppu.hpp @@ -1,31 +1,33 @@ struct PPU : Thread, public PPUcounter { + enum : bool { Threaded = true }; + + PPU(); + ~PPU(); + + alwaysinline auto step(uint clocks) -> void; + alwaysinline auto synchronizeCPU() -> void; + + auto latch_counters() -> void; + auto interlace() const -> bool; + auto overscan() const -> bool; + auto hires() const -> bool; + + auto enter() -> void; + auto enable() -> void; + auto power() -> void; + auto reset() -> void; + auto scanline() -> void; + auto frame() -> void; + + auto layer_enable(uint layer, uint priority, bool enable) -> void; + auto set_frameskip(uint frameskip) -> void; + + auto serialize(serializer&) -> void; + uint8 vram[64 * 1024]; uint8 oam[544]; uint8 cgram[512]; - enum : bool { Threaded = true }; - alwaysinline void step(unsigned clocks); - alwaysinline void synchronize_cpu(); - - void latch_counters(); - bool interlace() const; - bool overscan() const; - bool hires() const; - - void enter(); - void enable(); - void power(); - void reset(); - void scanline(); - void frame(); - - void layer_enable(unsigned layer, unsigned priority, bool enable); - void set_frameskip(unsigned frameskip); - - void serialize(serializer&); - PPU(); - ~PPU(); - private: uint32* surface; uint32* output; @@ -48,15 +50,15 @@ private: struct Display { bool interlace; bool overscan; - unsigned width; - unsigned height; - unsigned frameskip; - unsigned framecounter; + uint width; + uint height; + uint frameskip; + uint framecounter; } display; - static void Enter(); - void add_clocks(unsigned clocks); - void render_scanline(); + static auto Enter() -> void; + auto add_clocks(uint clocks) -> void; + auto render_scanline() -> void; friend class PPU::Cache; friend class PPU::Background; diff --git a/sfc/alt/ppu-performance/screen/screen.cpp b/sfc/alt/ppu-performance/screen/screen.cpp index 3ac78ecd..0f785802 100644 --- a/sfc/alt/ppu-performance/screen/screen.cpp +++ b/sfc/alt/ppu-performance/screen/screen.cpp @@ -1,6 +1,7 @@ -#ifdef PPU_CPP +PPU::Screen::Screen(PPU& self) : self(self) { +} -unsigned PPU::Screen::get_palette(unsigned color) { +auto PPU::Screen::get_palette(uint color) -> uint { #if defined(ENDIAN_LSB) return ((uint16*)ppu.cgram)[color]; #else @@ -9,24 +10,24 @@ unsigned PPU::Screen::get_palette(unsigned color) { #endif } -unsigned PPU::Screen::get_direct_color(unsigned p, unsigned t) { +auto PPU::Screen::get_direct_color(uint p, uint t) -> uint { return ((t & 7) << 2) | ((p & 1) << 1) | (((t >> 3) & 7) << 7) | (((p >> 1) & 1) << 6) | ((t >> 6) << 13) | ((p >> 2) << 12); } -uint16 PPU::Screen::addsub(unsigned x, unsigned y, bool halve) { +auto PPU::Screen::addsub(uint x, uint y, bool halve) -> uint16 { if(!regs.color_mode) { if(!halve) { - unsigned sum = x + y; - unsigned carry = (sum - ((x ^ y) & 0x0421)) & 0x8420; + uint sum = x + y; + uint carry = (sum - ((x ^ y) & 0x0421)) & 0x8420; return (sum - carry) | (carry - (carry >> 5)); } else { return (x + y - ((x ^ y) & 0x0421)) >> 1; } } else { - unsigned diff = x - y + 0x8420; - unsigned borrow = (diff - ((x ^ y) & 0x8420)) & 0x8420; + uint diff = x - y + 0x8420; + uint borrow = (diff - ((x ^ y) & 0x8420)) & 0x8420; if(!halve) { return (diff - borrow) & (borrow - (borrow >> 5)); } else { @@ -35,12 +36,12 @@ uint16 PPU::Screen::addsub(unsigned x, unsigned y, bool halve) { } } -void PPU::Screen::scanline() { - unsigned main_color = get_palette(0); - unsigned sub_color = (self.regs.pseudo_hires == false && self.regs.bgmode != 5 && self.regs.bgmode != 6) - ? regs.color : main_color; +auto PPU::Screen::scanline() -> void { + uint main_color = get_palette(0); + uint sub_color = (self.regs.pseudo_hires == false && self.regs.bgmode != 5 && self.regs.bgmode != 6) + ? regs.color : main_color; - for(unsigned x = 0; x < 256; x++) { + for(uint x = 0; x < 256; x++) { output.main[x].color = main_color; output.main[x].priority = 0; output.main[x].source = 6; @@ -54,13 +55,13 @@ void PPU::Screen::scanline() { window.render(1); } -void PPU::Screen::render_black() { +auto PPU::Screen::render_black() -> void { uint32* data = self.output + self.vcounter() * 1024; if(self.interlace() && self.field()) data += 512; memset(data, 0, self.display.width << 2); } -uint16 PPU::Screen::get_pixel_main(unsigned x) { +auto PPU::Screen::get_pixel_main(uint x) -> uint16 { auto main = output.main[x]; auto sub = output.sub[x]; @@ -87,7 +88,7 @@ uint16 PPU::Screen::get_pixel_main(unsigned x) { return main.color; } -uint16 PPU::Screen::get_pixel_sub(unsigned x) { +auto PPU::Screen::get_pixel_sub(uint x) -> uint16 { auto main = output.sub[x]; auto sub = output.main[x]; @@ -114,29 +115,23 @@ uint16 PPU::Screen::get_pixel_sub(unsigned x) { return main.color; } -void PPU::Screen::render() { +auto PPU::Screen::render() -> void { uint32* data = self.output + self.vcounter() * 1024; if(self.interlace() && self.field()) data += 512; if(!self.regs.pseudo_hires && self.regs.bgmode != 5 && self.regs.bgmode != 6) { - for(unsigned i = 0; i < 256; i++) { + for(uint i = 0; i < 256; i++) { data[i] = self.regs.display_brightness << 15 | get_pixel_main(i); } } else { - for(unsigned i = 0; i < 256; i++) { + for(uint i = 0; i < 256; i++) { *data++ = self.regs.display_brightness << 15 | get_pixel_sub(i); *data++ = self.regs.display_brightness << 15 | get_pixel_main(i); } } } -PPU::Screen::Screen(PPU& self) : self(self) { -} - -PPU::Screen::~Screen() { -} - -void PPU::Screen::Output::plot_main(unsigned x, unsigned color, unsigned priority, unsigned source) { +auto PPU::Screen::Output::plot_main(uint x, uint color, uint priority, uint source) -> void { if(priority > main[x].priority) { main[x].color = color; main[x].priority = priority; @@ -144,12 +139,10 @@ void PPU::Screen::Output::plot_main(unsigned x, unsigned color, unsigned priorit } } -void PPU::Screen::Output::plot_sub(unsigned x, unsigned color, unsigned priority, unsigned source) { +auto PPU::Screen::Output::plot_sub(uint x, uint color, uint priority, uint source) -> void { if(priority > sub[x].priority) { sub[x].color = color; sub[x].priority = priority; sub[x].source = source; } } - -#endif diff --git a/sfc/alt/ppu-performance/screen/screen.hpp b/sfc/alt/ppu-performance/screen/screen.hpp index 2f87e811..de10572f 100644 --- a/sfc/alt/ppu-performance/screen/screen.hpp +++ b/sfc/alt/ppu-performance/screen/screen.hpp @@ -1,4 +1,19 @@ class Screen { + Screen(PPU& self); + + alwaysinline auto get_palette(uint color) -> uint; + auto get_direct_color(uint palette, uint tile) -> uint; + alwaysinline auto addsub(uint x, uint y, bool halve) -> uint16; + auto scanline() -> void; + auto render_black() -> void; + alwaysinline auto get_pixel_main(uint x) -> uint16; + alwaysinline auto get_pixel_sub(uint x) -> uint16; + auto render() -> void; + + auto serialize(serializer&) -> void; + + PPU& self; + struct Regs { bool addsub_mode; bool direct_color; @@ -7,38 +22,24 @@ class Screen { bool color_halve; bool color_enable[7]; - unsigned color_b; - unsigned color_g; - unsigned color_r; - unsigned color; + uint color_b; + uint color_g; + uint color_r; + uint color; } regs; struct Output { - struct Pixel { - unsigned color; - unsigned priority; - unsigned source; - } main[256], sub[256]; + alwaysinline auto plot_main(uint x, uint color, uint priority, uint source) -> void; + alwaysinline auto plot_sub(uint x, uint color, uint priority, uint source) -> void; - alwaysinline void plot_main(unsigned x, unsigned color, unsigned priority, unsigned source); - alwaysinline void plot_sub(unsigned x, unsigned color, unsigned priority, unsigned source); + struct Pixel { + uint color; + uint priority; + uint source; + } main[256], sub[256]; } output; ColorWindow window; - alwaysinline unsigned get_palette(unsigned color); - unsigned get_direct_color(unsigned palette, unsigned tile); - alwaysinline uint16 addsub(unsigned x, unsigned y, bool halve); - void scanline(); - void render_black(); - alwaysinline uint16 get_pixel_main(unsigned x); - alwaysinline uint16 get_pixel_sub(unsigned x); - void render(); - - void serialize(serializer&); - Screen(PPU& self); - ~Screen(); - - PPU& self; friend class PPU; }; diff --git a/sfc/alt/ppu-performance/serialization.cpp b/sfc/alt/ppu-performance/serialization.cpp index ad6c5e35..92e39a83 100644 --- a/sfc/alt/ppu-performance/serialization.cpp +++ b/sfc/alt/ppu-performance/serialization.cpp @@ -1,6 +1,4 @@ -#ifdef PPU_CPP - -void PPUcounter::serialize(serializer& s) { +auto PPUcounter::serialize(serializer& s) -> void { s.integer(status.interlace); s.integer(status.field); s.integer(status.vcounter); @@ -12,7 +10,7 @@ void PPUcounter::serialize(serializer& s) { s.integer(history.index); } -void PPU::serialize(serializer& s) { +auto PPU::serialize(serializer& s) -> void { Thread::serialize(s); PPUcounter::serialize(s); @@ -94,14 +92,14 @@ void PPU::serialize(serializer& s) { s.integer(regs.vcounter); } -void PPU::Cache::serialize(serializer& s) { +auto PPU::Cache::serialize(serializer& s) -> void { //rather than save ~512KB worth of cached tiledata, invalidate it all - for(unsigned i = 0; i < 4096; i++) tilevalid[0][i] = false; - for(unsigned i = 0; i < 2048; i++) tilevalid[1][i] = false; - for(unsigned i = 0; i < 1024; i++) tilevalid[2][i] = false; + for(uint i = 0; i < 4096; i++) tilevalid[0][i] = false; + for(uint i = 0; i < 2048; i++) tilevalid[1][i] = false; + for(uint i = 0; i < 1024; i++) tilevalid[2][i] = false; } -void PPU::Background::serialize(serializer &s) { +auto PPU::Background::serialize(serializer& s) -> void { s.integer(regs.mode); s.integer(regs.priority0); s.integer(regs.priority1); @@ -140,7 +138,7 @@ void PPU::Background::serialize(serializer &s) { window.serialize(s); } -void PPU::Sprite::serialize(serializer& s) { +auto PPU::Sprite::serialize(serializer& s) -> void { s.integer(regs.priority0); s.integer(regs.priority1); s.integer(regs.priority2); @@ -159,7 +157,7 @@ void PPU::Sprite::serialize(serializer& s) { s.integer(regs.time_over); s.integer(regs.range_over); - for(unsigned i = 0; i < 128; i++) { + for(uint i = 0; i < 128; i++) { s.integer(list[i].width); s.integer(list[i].height); s.integer(list[i].x); @@ -175,7 +173,7 @@ void PPU::Sprite::serialize(serializer& s) { s.integer(list_valid); s.array(itemlist); - for(unsigned i = 0; i < 34; i++) { + for(uint i = 0; i < 34; i++) { s.integer(tilelist[i].x); s.integer(tilelist[i].y); s.integer(tilelist[i].priority); @@ -190,7 +188,7 @@ void PPU::Sprite::serialize(serializer& s) { window.serialize(s); } -void PPU::Screen::serialize(serializer& s) { +auto PPU::Screen::serialize(serializer& s) -> void { s.integer(regs.addsub_mode); s.integer(regs.direct_color); @@ -203,7 +201,7 @@ void PPU::Screen::serialize(serializer& s) { s.integer(regs.color_r); s.integer(regs.color); - for(unsigned i = 0; i < 256; i++) { + for(uint i = 0; i < 256; i++) { s.integer(output.main[i].color); s.integer(output.main[i].priority); s.integer(output.main[i].source); @@ -216,7 +214,7 @@ void PPU::Screen::serialize(serializer& s) { window.serialize(s); } -void PPU::LayerWindow::serialize(serializer& s) { +auto PPU::LayerWindow::serialize(serializer& s) -> void { s.integer(one_enable); s.integer(one_invert); s.integer(two_enable); @@ -231,7 +229,7 @@ void PPU::LayerWindow::serialize(serializer& s) { s.array(sub); } -void PPU::ColorWindow::serialize(serializer& s) { +auto PPU::ColorWindow::serialize(serializer& s) -> void { s.integer(one_enable); s.integer(one_invert); s.integer(two_enable); @@ -245,5 +243,3 @@ void PPU::ColorWindow::serialize(serializer& s) { s.array(main); s.array(sub); } - -#endif diff --git a/sfc/alt/ppu-performance/sprite/sprite.cpp b/sfc/alt/ppu-performance/sprite/sprite.cpp index a42dc8bd..7e15817b 100644 --- a/sfc/alt/ppu-performance/sprite/sprite.cpp +++ b/sfc/alt/ppu-performance/sprite/sprite.cpp @@ -1,13 +1,18 @@ -#ifdef PPU_CPP +PPU::Sprite::Sprite(PPU& self) : self(self) { + priority0_enable = true; + priority1_enable = true; + priority2_enable = true; + priority3_enable = true; +} -void PPU::Sprite::frame() { +auto PPU::Sprite::frame() -> void { regs.time_over = false; regs.range_over = false; } -void PPU::Sprite::update_list(unsigned addr, uint8 data) { +auto PPU::Sprite::update_list(uint addr, uint8 data) -> void { if(addr < 0x0200) { - unsigned i = addr >> 2; + uint i = addr >> 2; switch(addr & 3) { case 0: list[i].x = (list[i].x & 0x0100) | data; break; case 1: list[i].y = (data + 1) & 0xff; break; @@ -20,7 +25,7 @@ void PPU::Sprite::update_list(unsigned addr, uint8 data) { break; } } else { - unsigned i = (addr & 0x1f) << 2; + uint i = (addr & 0x1f) << 2; list[i + 0].x = ((data & 0x01) << 8) | (list[i + 0].x & 0xff); list[i + 0].size = data & 0x02; list[i + 1].x = ((data & 0x04) << 6) | (list[i + 1].x & 0xff); @@ -33,36 +38,36 @@ void PPU::Sprite::update_list(unsigned addr, uint8 data) { } } -void PPU::Sprite::address_reset() { +auto PPU::Sprite::address_reset() -> void { self.regs.oam_addr = self.regs.oam_baseaddr << 1; set_first(); } -void PPU::Sprite::set_first() { +auto PPU::Sprite::set_first() -> void { regs.first_sprite = (self.regs.oam_priority == false ? 0 : (self.regs.oam_addr >> 2) & 127); } -bool PPU::Sprite::on_scanline(unsigned sprite) { +auto PPU::Sprite::on_scanline(uint sprite) -> bool { auto& s = list[sprite]; if(s.x > 256 && (s.x + s.width - 1) < 512) return false; - signed height = (regs.interlace == false ? s.height : s.height >> 1); + int height = (regs.interlace == false ? s.height : s.height >> 1); if(self.vcounter() >= s.y && self.vcounter() < (s.y + height)) return true; if((s.y + height) >= 256 && self.vcounter() < ((s.y + height) & 255)) return true; return false; } -void PPU::Sprite::render() { +auto PPU::Sprite::render() -> void { if(list_valid == false) { list_valid = true; - for(unsigned i = 0; i < 128; i++) { + for(uint i = 0; i < 128; i++) { if(list[i].size == 0) { - static unsigned width[] = { 8, 8, 8, 16, 16, 32, 16, 16 }; - static unsigned height[] = { 8, 8, 8, 16, 16, 32, 32, 32 }; + static uint width[] = {8, 8, 8, 16, 16, 32, 16, 16}; + static uint height[] = {8, 8, 8, 16, 16, 32, 32, 32}; list[i].width = width[regs.base_size]; list[i].height = height[regs.base_size]; } else { - static unsigned width[] = { 16, 32, 64, 32, 64, 64, 32, 32 }; - static unsigned height[] = { 16, 32, 64, 32, 64, 64, 64, 32 }; + static uint width[] = {16, 32, 64, 32, 64, 64, 32, 32}; + static uint height[] = {16, 32, 64, 32, 64, 64, 64, 32}; list[i].width = width[regs.base_size]; list[i].height = height[regs.base_size]; if(regs.interlace && regs.base_size >= 6) list[i].height = 16; @@ -70,25 +75,25 @@ void PPU::Sprite::render() { } } - unsigned itemcount = 0; - unsigned tilecount = 0; + uint itemcount = 0; + uint tilecount = 0; memset(output.priority, 0xff, 256); memset(itemlist, 0xff, 32); - for(unsigned i = 0; i < 34; i++) tilelist[i].tile = 0xffff; + for(uint i = 0; i < 34; i++) tilelist[i].tile = 0xffff; - for(unsigned i = 0; i < 128; i++) { - unsigned s = (regs.first_sprite + i) & 127; + for(uint i = 0; i < 128; i++) { + uint s = (regs.first_sprite + i) & 127; if(on_scanline(s) == false) continue; if(itemcount++ >= 32) break; itemlist[itemcount - 1] = s; } - for(signed i = 31; i >= 0; i--) { + for(int i = 31; i >= 0; i--) { if(itemlist[i] == 0xff) continue; auto& s = list[itemlist[i]]; - unsigned tile_width = s.width >> 3; - signed x = s.x; - signed y = (self.vcounter() - s.y) & 0xff; + uint tile_width = s.width >> 3; + int x = s.x; + int y = (self.vcounter() - s.y) & 0xff; if(regs.interlace) y <<= 1; if(s.vflip) { @@ -116,20 +121,20 @@ void PPU::Sprite::render() { chry &= 15; chry <<= 4; - for(unsigned tx = 0; tx < tile_width; tx++) { - unsigned sx = (x + (tx << 3)) & 511; + for(uint tx = 0; tx < tile_width; tx++) { + uint sx = (x + (tx << 3)) & 511; if(x != 256 && sx >= 256 && (sx + 7) < 512) continue; if(tilecount++ >= 34) break; - unsigned n = tilecount - 1; + uint n = tilecount - 1; tilelist[n].x = sx; tilelist[n].y = y; tilelist[n].priority = s.priority; tilelist[n].palette = 128 + (s.palette << 4); tilelist[n].hflip = s.hflip; - unsigned mx = (s.hflip == false) ? tx : ((tile_width - 1) - tx); - unsigned pos = tdaddr + ((chry + ((chrx + mx) & 15)) << 5); + uint mx = (s.hflip == false) ? tx : ((tile_width - 1) - tx); + uint pos = tdaddr + ((chry + ((chrx + mx) & 15)) << 5); tilelist[n].tile = (pos >> 5) & 0x07ff; } } @@ -139,17 +144,17 @@ void PPU::Sprite::render() { if(regs.main_enable == false && regs.sub_enable == false) return; - for(unsigned i = 0; i < 34; i++) { + for(uint i = 0; i < 34; i++) { if(tilelist[i].tile == 0xffff) continue; auto& t = tilelist[i]; uint8* tiledata = self.cache.tile_4bpp(t.tile); tiledata += (t.y & 7) << 3; - unsigned sx = t.x; - for(unsigned x = 0; x < 8; x++) { + uint sx = t.x; + for(uint x = 0; x < 8; x++) { sx &= 511; if(sx < 256) { - unsigned color = *(tiledata + (t.hflip == false ? x : 7 - x)); + uint color = *(tiledata + (t.hflip == false ? x : 7 - x)); if(color) { color += t.palette; output.palette[sx] = color; @@ -163,28 +168,19 @@ void PPU::Sprite::render() { if(regs.main_enable) window.render(0); if(regs.sub_enable) window.render(1); - unsigned priority0 = (priority0_enable ? regs.priority0 : 0); - unsigned priority1 = (priority1_enable ? regs.priority1 : 0); - unsigned priority2 = (priority2_enable ? regs.priority2 : 0); - unsigned priority3 = (priority3_enable ? regs.priority3 : 0); + uint priority0 = (priority0_enable ? regs.priority0 : 0); + uint priority1 = (priority1_enable ? regs.priority1 : 0); + uint priority2 = (priority2_enable ? regs.priority2 : 0); + uint priority3 = (priority3_enable ? regs.priority3 : 0); if(priority0 + priority1 + priority2 + priority3 == 0) return; - const unsigned priority_table[] = { priority0, priority1, priority2, priority3 }; + const uint priority_table[] = {priority0, priority1, priority2, priority3}; - for(unsigned x = 0; x < 256; x++) { + for(uint x = 0; x < 256; x++) { if(output.priority[x] == 0xff) continue; - unsigned priority = priority_table[output.priority[x]]; - unsigned palette = output.palette[x]; - unsigned color = self.screen.get_palette(output.palette[x]); + uint priority = priority_table[output.priority[x]]; + uint palette = output.palette[x]; + uint color = self.screen.get_palette(output.palette[x]); if(regs.main_enable && !window.main[x]) self.screen.output.plot_main(x, color, priority, 4 + (palette < 192)); if(regs.sub_enable && !window.sub[x]) self.screen.output.plot_sub(x, color, priority, 4 + (palette < 192)); } } - -PPU::Sprite::Sprite(PPU& self) : self(self) { - priority0_enable = true; - priority1_enable = true; - priority2_enable = true; - priority3_enable = true; -} - -#endif diff --git a/sfc/alt/ppu-performance/sprite/sprite.hpp b/sfc/alt/ppu-performance/sprite/sprite.hpp index 0bfefbf6..e1b0445a 100644 --- a/sfc/alt/ppu-performance/sprite/sprite.hpp +++ b/sfc/alt/ppu-performance/sprite/sprite.hpp @@ -1,19 +1,32 @@ class Sprite { + Sprite(PPU& self); + + auto frame() -> void; + auto update_list(uint addr, uint8 data) -> void; + auto address_reset() -> void; + auto set_first() -> void; + alwaysinline auto on_scanline(uint sprite) -> bool; + auto render() -> void; + + auto serialize(serializer&) -> void; + + PPU& self; + bool priority0_enable; bool priority1_enable; bool priority2_enable; bool priority3_enable; struct Regs { - unsigned priority0; - unsigned priority1; - unsigned priority2; - unsigned priority3; + uint priority0; + uint priority1; + uint priority2; + uint priority3; - unsigned base_size; - unsigned nameselect; - unsigned tiledata_addr; - unsigned first_sprite; + uint base_size; + uint nameselect; + uint tiledata_addr; + uint first_sprite; bool main_enable; bool sub_enable; @@ -25,27 +38,27 @@ class Sprite { } regs; struct List { - unsigned width; - unsigned height; - unsigned x; - unsigned y; - unsigned character; + uint width; + uint height; + uint x; + uint y; + uint character; bool use_nameselect; bool vflip; bool hflip; - unsigned palette; - unsigned priority; + uint palette; + uint priority; bool size; } list[128]; bool list_valid; uint8 itemlist[32]; struct TileList { - unsigned x; - unsigned y; - unsigned priority; - unsigned palette; - unsigned tile; + uint x; + uint y; + uint priority; + uint palette; + uint tile; bool hflip; } tilelist[34]; @@ -56,16 +69,5 @@ class Sprite { LayerWindow window; - void frame(); - void update_list(unsigned addr, uint8 data); - void address_reset(); - void set_first(); - alwaysinline bool on_scanline(unsigned sprite); - void render(); - - void serialize(serializer&); - Sprite(PPU& self); - - PPU& self; friend class PPU; }; diff --git a/sfc/alt/ppu-performance/window/window.cpp b/sfc/alt/ppu-performance/window/window.cpp index 94f9479c..375a7a9a 100644 --- a/sfc/alt/ppu-performance/window/window.cpp +++ b/sfc/alt/ppu-performance/window/window.cpp @@ -1,6 +1,4 @@ -#ifdef PPU_CPP - -void PPU::LayerWindow::render(bool screen) { +auto PPU::LayerWindow::render(bool screen) -> void { uint8* output; if(screen == 0) { output = main; @@ -23,7 +21,7 @@ void PPU::LayerWindow::render(bool screen) { if(one_enable == true && two_enable == false) { bool set = 1 ^ one_invert, clr = !set; - for(unsigned x = 0; x < 256; x++) { + for(uint x = 0; x < 256; x++) { output[x] = (x >= ppu.regs.window_one_left && x <= ppu.regs.window_one_right) ? set : clr; } return; @@ -31,13 +29,13 @@ void PPU::LayerWindow::render(bool screen) { if(one_enable == false && two_enable == true) { bool set = 1 ^ two_invert, clr = !set; - for(unsigned x = 0; x < 256; x++) { + for(uint x = 0; x < 256; x++) { output[x] = (x >= ppu.regs.window_two_left && x <= ppu.regs.window_two_right) ? set : clr; } return; } - for(unsigned x = 0; x < 256; x++) { + for(uint x = 0; x < 256; x++) { bool one_mask = (x >= ppu.regs.window_one_left && x <= ppu.regs.window_one_right) ^ one_invert; bool two_mask = (x >= ppu.regs.window_two_left && x <= ppu.regs.window_two_right) ^ two_invert; switch(mask) { @@ -51,7 +49,7 @@ void PPU::LayerWindow::render(bool screen) { // -void PPU::ColorWindow::render(bool screen) { +auto PPU::ColorWindow::render(bool screen) -> void { uint8* output = (screen == 0 ? main : sub); bool set = 1, clr = 0; @@ -69,7 +67,7 @@ void PPU::ColorWindow::render(bool screen) { if(one_enable == true && two_enable == false) { if(one_invert) { set ^= 1; clr ^= 1; } - for(unsigned x = 0; x < 256; x++) { + for(uint x = 0; x < 256; x++) { output[x] = (x >= ppu.regs.window_one_left && x <= ppu.regs.window_one_right) ? set : clr; } return; @@ -77,13 +75,13 @@ void PPU::ColorWindow::render(bool screen) { if(one_enable == false && two_enable == true) { if(two_invert) { set ^= 1; clr ^= 1; } - for(unsigned x = 0; x < 256; x++) { + for(uint x = 0; x < 256; x++) { output[x] = (x >= ppu.regs.window_two_left && x <= ppu.regs.window_two_right) ? set : clr; } return; } - for(unsigned x = 0; x < 256; x++) { + for(uint x = 0; x < 256; x++) { bool one_mask = (x >= ppu.regs.window_one_left && x <= ppu.regs.window_one_right) ^ one_invert; bool two_mask = (x >= ppu.regs.window_two_left && x <= ppu.regs.window_two_right) ^ two_invert; switch(mask) { @@ -94,5 +92,3 @@ void PPU::ColorWindow::render(bool screen) { } } } - -#endif diff --git a/sfc/alt/ppu-performance/window/window.hpp b/sfc/alt/ppu-performance/window/window.hpp index af2fb4d7..bca0b429 100644 --- a/sfc/alt/ppu-performance/window/window.hpp +++ b/sfc/alt/ppu-performance/window/window.hpp @@ -1,35 +1,35 @@ struct LayerWindow { + auto render(bool screen) -> void; + auto serialize(serializer&) -> void; + bool one_enable; bool one_invert; bool two_enable; bool two_invert; - unsigned mask; + uint mask; bool main_enable; bool sub_enable; uint8 main[256]; uint8 sub[256]; - - void render(bool screen); - void serialize(serializer&); }; struct ColorWindow { + auto render(bool screen) -> void; + auto serialize(serializer&) -> void; + bool one_enable; bool one_invert; bool two_enable; bool two_invert; - unsigned mask; + uint mask; - unsigned main_mask; - unsigned sub_mask; + uint main_mask; + uint sub_mask; uint8 main[256]; uint8 sub[256]; - - void render(bool screen); - void serialize(serializer&); }; diff --git a/sfc/alt/smp/algorithms.cpp b/sfc/alt/smp/algorithms.cpp index a55369fb..acba0b8c 100644 --- a/sfc/alt/smp/algorithms.cpp +++ b/sfc/alt/smp/algorithms.cpp @@ -1,4 +1,4 @@ -uint8 SMP::op_adc(uint8 x, uint8 y) { +auto SMP::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,7 +8,7 @@ uint8 SMP::op_adc(uint8 x, uint8 y) { return r; } -uint16 SMP::op_addw(uint16 x, uint16 y) { +auto SMP::op_addw(uint16 x, uint16 y) -> uint16 { uint16 r; regs.p.c = 0; r = op_adc(x, y); @@ -17,14 +17,14 @@ uint16 SMP::op_addw(uint16 x, uint16 y) { return r; } -uint8 SMP::op_and(uint8 x, uint8 y) { +auto SMP::op_and(uint8 x, uint8 y) -> uint8 { x &= y; regs.p.n = x & 0x80; regs.p.z = x == 0; return x; } -uint8 SMP::op_cmp(uint8 x, uint8 y) { +auto SMP::op_cmp(uint8 x, uint8 y) -> uint8 { int r = x - y; regs.p.n = r & 0x80; regs.p.z = (uint8)r == 0; @@ -32,7 +32,7 @@ uint8 SMP::op_cmp(uint8 x, uint8 y) { return x; } -uint16 SMP::op_cmpw(uint16 x, uint16 y) { +auto SMP::op_cmpw(uint16 x, uint16 y) -> uint16 { int r = x - y; regs.p.n = r & 0x8000; regs.p.z = (uint16)r == 0; @@ -40,21 +40,21 @@ uint16 SMP::op_cmpw(uint16 x, uint16 y) { return x; } -uint8 SMP::op_eor(uint8 x, uint8 y) { +auto SMP::op_eor(uint8 x, uint8 y) -> uint8 { x ^= y; regs.p.n = x & 0x80; regs.p.z = x == 0; return x; } -uint8 SMP::op_or(uint8 x, uint8 y) { +auto SMP::op_or(uint8 x, uint8 y) -> uint8 { x |= y; regs.p.n = x & 0x80; regs.p.z = x == 0; return x; } -uint8 SMP::op_sbc(uint8 x, uint8 y) { +auto SMP::op_sbc(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; @@ -64,7 +64,7 @@ uint8 SMP::op_sbc(uint8 x, uint8 y) { return r; } -uint16 SMP::op_subw(uint16 x, uint16 y) { +auto SMP::op_subw(uint16 x, uint16 y) -> uint16 { uint16 r; regs.p.c = 1; r = op_sbc(x, y); @@ -73,21 +73,21 @@ uint16 SMP::op_subw(uint16 x, uint16 y) { return r; } -uint8 SMP::op_inc(uint8 x) { +auto SMP::op_inc(uint8 x) -> uint8 { x++; regs.p.n = x & 0x80; regs.p.z = x == 0; return x; } -uint8 SMP::op_dec(uint8 x) { +auto SMP::op_dec(uint8 x) -> uint8 { x--; regs.p.n = x & 0x80; regs.p.z = x == 0; return x; } -uint8 SMP::op_asl(uint8 x) { +auto SMP::op_asl(uint8 x) -> uint8 { regs.p.c = x & 0x80; x <<= 1; regs.p.n = x & 0x80; @@ -95,7 +95,7 @@ uint8 SMP::op_asl(uint8 x) { return x; } -uint8 SMP::op_lsr(uint8 x) { +auto SMP::op_lsr(uint8 x) -> uint8 { regs.p.c = x & 0x01; x >>= 1; regs.p.n = x & 0x80; @@ -103,8 +103,8 @@ uint8 SMP::op_lsr(uint8 x) { return x; } -uint8 SMP::op_rol(uint8 x) { - unsigned carry = (unsigned)regs.p.c; +auto SMP::op_rol(uint8 x) -> uint8 { + auto carry = (uint)regs.p.c; regs.p.c = x & 0x80; x = (x << 1) | carry; regs.p.n = x & 0x80; @@ -112,8 +112,8 @@ uint8 SMP::op_rol(uint8 x) { return x; } -uint8 SMP::op_ror(uint8 x) { - unsigned carry = (unsigned)regs.p.c << 7; +auto SMP::op_ror(uint8 x) -> uint8 { + auto carry = (uint)regs.p.c << 7; regs.p.c = x & 0x01; x = carry | (x >> 1); regs.p.n = x & 0x80; diff --git a/sfc/alt/smp/core.cpp b/sfc/alt/smp/core.cpp index 986b9586..45d31129 100644 --- a/sfc/alt/smp/core.cpp +++ b/sfc/alt/smp/core.cpp @@ -1,20 +1,20 @@ -void SMP::tick() { +auto SMP::tick() -> void { timer0.tick(); timer1.tick(); timer2.tick(); clock += cycle_step_cpu; dsp.clock -= 24; - synchronize_dsp(); + synchronizeDSP(); } -void SMP::op_io() { +auto SMP::op_io() -> void { #if defined(CYCLE_ACCURATE) tick(); #endif } -uint8 SMP::op_read(uint16 addr) { +auto SMP::op_read(uint16 addr) -> uint8 { #if defined(CYCLE_ACCURATE) tick(); #endif @@ -23,7 +23,7 @@ uint8 SMP::op_read(uint16 addr) { return apuram[addr]; } -void SMP::op_write(uint16 addr, uint8 data) { +auto SMP::op_write(uint16 addr, uint8 data) -> void { #if defined(CYCLE_ACCURATE) tick(); #endif @@ -31,7 +31,7 @@ void SMP::op_write(uint16 addr, uint8 data) { apuram[addr] = data; //all writes go to RAM, even MMIO writes } -void SMP::op_step() { +auto SMP::op_step() -> void { #define op_readpc() op_read(regs.pc++) #define op_readdp(addr) op_read((regs.p.p << 8) + addr) #define op_writedp(addr, data) op_write((regs.p.p << 8) + addr, data) @@ -55,7 +55,7 @@ void SMP::op_step() { #else - unsigned opcode = op_readpc(); + uint opcode = op_readpc(); switch(opcode) { #include "core/op_misc.cpp" #include "core/op_mov.cpp" @@ -77,7 +77,7 @@ void SMP::op_step() { #endif } -const unsigned SMP::cycle_count_table[256] = { +const uint SMP::cycle_count_table[256] = { #define c 12 //0 1 2 3 4 5 6 7 8 9 A B C D E F 2,8,4,7, 3,4,3,6, 2,6,5,4, 5,4,6,8, //0 diff --git a/sfc/alt/smp/core/generate.cpp b/sfc/alt/smp/core/generate.cpp index e5ac0480..46bc6e2e 100644 --- a/sfc/alt/smp/core/generate.cpp +++ b/sfc/alt/smp/core/generate.cpp @@ -8,10 +8,10 @@ static bool cycle_accurate; struct opcode_t { string name; lstring args; - unsigned opcode; + uint opcode; }; -void generate(const char* sourceFilename, const char* targetFilename) { +auto generate(const char* sourceFilename, const char* targetFilename) -> void { file fp; fp.open(targetFilename, file::mode::write); @@ -28,7 +28,7 @@ void generate(const char* sourceFilename, const char* targetFilename) { linear_vector array; - unsigned sourceStart = 0; + uint sourceStart = 0; foreach(line, lines, currentLine) { line.transform("()", "``"); lstring part; @@ -54,7 +54,7 @@ void generate(const char* sourceFilename, const char* targetFilename) { foreach(opcode, array) { fp.print("case 0x", hex(opcode.opcode, 2L), ": {\n"); - for(unsigned n = sourceStart; n < lines.size(); n++) { + for(uint n = sourceStart; n < lines.size(); n++) { if(lines[n] == "}") break; string output; @@ -88,7 +88,7 @@ void generate(const char* sourceFilename, const char* targetFilename) { fp.print("case 0x", hex(opcode.opcode, 2L), ": {\n"); fp.print(" switch(opcode_cycle++) {\n"); - for(unsigned n = sourceStart; n < lines.size(); n++) { + for(uint n = sourceStart; n < lines.size(); n++) { if(lines[n] == "}") break; bool nextLineEndsCycle = false; @@ -135,7 +135,7 @@ void generate(const char* sourceFilename, const char* targetFilename) { fp.close(); } -int main() { +auto main() -> int { cycle_accurate = false; generate("op_misc.b", "op_misc.cpp"); generate("op_mov.b", "op_mov.cpp" ); diff --git a/sfc/alt/smp/disassembler.cpp b/sfc/alt/smp/disassembler.cpp index 754a43ff..67c4e3f8 100644 --- a/sfc/alt/smp/disassembler.cpp +++ b/sfc/alt/smp/disassembler.cpp @@ -1,14 +1,14 @@ -uint8 SMP::disassemble_read(uint16 addr) { +auto SMP::disassemble_read(uint16 addr) -> uint8 { if(addr >= 0xffc0) return smp.iplrom[addr & 0x3f]; return smp.apuram[addr]; } -uint16 SMP::relb(int8 offset, int op_len) { +auto SMP::relb(int8 offset, int op_len) -> uint16 { uint16 pc = regs.pc + op_len; return pc + offset; } -void SMP::disassemble_opcode(char* output, uint16 addr) { +auto SMP::disassemble_opcode(char* output, uint16 addr) -> void { char* s; char t[512]; uint8 op, op0, op1; diff --git a/sfc/alt/smp/memory.cpp b/sfc/alt/smp/memory.cpp index aecba720..1b5ddc76 100644 --- a/sfc/alt/smp/memory.cpp +++ b/sfc/alt/smp/memory.cpp @@ -1,12 +1,12 @@ -unsigned SMP::port_read(unsigned addr) { +auto SMP::port_read(uint addr) -> uint { return apuram[0xf4 + (addr & 3)]; } -void SMP::port_write(unsigned addr, unsigned data) { +auto SMP::port_write(uint addr, uint data) -> void { apuram[0xf4 + (addr & 3)] = data; } -unsigned SMP::mmio_read(unsigned addr) { +auto SMP::mmio_read(uint addr) -> uint { switch(addr) { case 0xf2: @@ -19,7 +19,7 @@ unsigned SMP::mmio_read(unsigned addr) { case 0xf5: case 0xf6: case 0xf7: - synchronize_cpu(); + synchronizeCPU(); return cpu.port_read(addr); case 0xf8: @@ -51,14 +51,14 @@ unsigned SMP::mmio_read(unsigned addr) { return 0x00; } -void SMP::mmio_write(unsigned addr, unsigned data) { +auto SMP::mmio_write(uint addr, uint data) -> void { switch(addr) { case 0xf1: status.iplrom_enable = data & 0x80; if(data & 0x30) { - synchronize_cpu(); + synchronizeCPU(); if(data & 0x20) { cpu.port_write(3, 0x00); cpu.port_write(2, 0x00); @@ -102,7 +102,7 @@ void SMP::mmio_write(unsigned addr, unsigned data) { case 0xf5: case 0xf6: case 0xf7: - synchronize_cpu(); + synchronizeCPU(); port_write(addr, data); break; diff --git a/sfc/alt/smp/smp.cpp b/sfc/alt/smp/smp.cpp index 0dded63d..c4bf48af 100644 --- a/sfc/alt/smp/smp.cpp +++ b/sfc/alt/smp/smp.cpp @@ -12,7 +12,12 @@ SMP smp; #include "memory.cpp" #include "timing.cpp" -void SMP::synchronize_cpu() { +SMP::SMP() { + apuram = new uint8[64 * 1024]; + for(auto& byte : iplrom) byte = 0; +} + +auto SMP::synchronizeCPU() -> void { if(CPU::Threaded == true) { //if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); } else { @@ -20,7 +25,7 @@ void SMP::synchronize_cpu() { } } -void SMP::synchronize_dsp() { +auto SMP::synchronizeDSP() -> void { if(DSP::Threaded == true) { //if(dsp.clock < 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(dsp.thread); } else { @@ -28,11 +33,11 @@ void SMP::synchronize_dsp() { } } -void SMP::enter() { +auto SMP::enter() -> void { while(clock < 0) op_step(); } -void SMP::power() { +auto SMP::power() -> void { Thread::frequency = system.apuFrequency(); Thread::clock = 0; @@ -40,7 +45,7 @@ void SMP::power() { timer1.target = 0; timer2.target = 0; - for(unsigned n = 0; n < 256; n++) { + for(uint n = 0; n < 256; n++) { cycle_table_dsp[n] = (cycle_count_table[n] * 24); cycle_table_cpu[n] = (cycle_count_table[n] * 24) * cpu.frequency; } @@ -50,8 +55,8 @@ void SMP::power() { reset(); } -void SMP::reset() { - for(unsigned n = 0x0000; n <= 0xffff; n++) apuram[n] = 0x00; +auto SMP::reset() -> void { + for(uint n = 0x0000; n <= 0xffff; n++) apuram[n] = 0x00; opcode_number = 0; opcode_cycle = 0; @@ -80,7 +85,7 @@ void SMP::reset() { timer0.stage3_ticks = timer1.stage3_ticks = timer2.stage3_ticks = 0; } -void SMP::serialize(serializer& s) { +auto SMP::serialize(serializer& s) -> void { Thread::serialize(s); s.array(apuram, 64 * 1024); @@ -137,12 +142,4 @@ void SMP::serialize(serializer& s) { s.integer(timer2.stage3_ticks); } -SMP::SMP() { - apuram = new uint8[64 * 1024]; - for(auto& byte : iplrom) byte = 0; -} - -SMP::~SMP() { -} - } diff --git a/sfc/alt/smp/smp.hpp b/sfc/alt/smp/smp.hpp index d97e8ae7..0b29459b 100644 --- a/sfc/alt/smp/smp.hpp +++ b/sfc/alt/smp/smp.hpp @@ -1,49 +1,69 @@ struct SMP : Thread { + enum : bool { Threaded = false }; + + SMP(); + + alwaysinline auto synchronizeCPU() -> void; + alwaysinline auto synchronizeDSP() -> void; + + auto port_read(uint port) -> uint; + auto port_write(uint port, unsigned data) -> void; + + auto mmio_read(uint addr) -> uint; + auto mmio_write(uint addr, uint data) -> void; + + auto enter() -> void; + auto power() -> void; + auto reset() -> void; + + auto serialize(serializer&) -> void; + + auto disassemble_opcode(char* output, uint16 addr) -> void; + uint8 iplrom[64]; uint8* apuram; - enum : bool { Threaded = false }; - alwaysinline void synchronize_cpu(); - alwaysinline void synchronize_dsp(); - - unsigned port_read(unsigned port); - void port_write(unsigned port, unsigned data); - - unsigned mmio_read(unsigned addr); - void mmio_write(unsigned addr, unsigned data); - - void enter(); - void power(); - void reset(); - - void serialize(serializer&); - SMP(); - ~SMP(); - - void disassemble_opcode(char *output, uint16 addr); - //private: - struct Flags { - bool n, v, p, b, h, i, z, c; + auto tick() -> void; + alwaysinline auto op_io() -> void; + alwaysinline auto op_read(uint16 addr) -> uint8; + alwaysinline auto op_write(uint16 addr, uint8 data) -> void; + alwaysinline auto op_step() -> void; - alwaysinline operator unsigned() const { + auto op_adc (uint8 x, uint8 y) -> uint8; + auto op_addw(uint16 x, uint16 y) -> uint16; + auto op_and (uint8 x, uint8 y) -> uint8; + auto op_cmp (uint8 x, uint8 y) -> uint8; + auto op_cmpw(uint16 x, uint16 y) -> uint16; + auto op_eor (uint8 x, uint8 y) -> uint8; + auto op_inc (uint8 x) -> uint8; + auto op_dec (uint8 x) -> uint8; + auto op_or (uint8 x, uint8 y) -> uint8; + auto op_sbc (uint8 x, uint8 y) -> uint8; + auto op_subw(uint16 x, uint16 y) -> uint16; + auto op_asl (uint8 x) -> uint8; + auto op_lsr (uint8 x) -> uint8; + auto op_rol (uint8 x) -> uint8; + auto op_ror (uint8 x) -> uint8; + + struct Flags { + alwaysinline operator uint() const { return (n << 7) | (v << 6) | (p << 5) | (b << 4) | (h << 3) | (i << 2) | (z << 1) | (c << 0); }; - alwaysinline unsigned operator=(unsigned data) { + alwaysinline auto operator=(uint 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; } - alwaysinline unsigned operator|=(unsigned data) { return operator=(operator unsigned() | data); } - alwaysinline unsigned operator^=(unsigned data) { return operator=(operator unsigned() ^ data); } - alwaysinline unsigned operator&=(unsigned data) { return operator=(operator unsigned() & data); } - }; + alwaysinline auto operator|=(uint data) -> uint { return operator=(operator uint() | data); } + alwaysinline auto operator^=(uint data) -> uint { return operator=(operator uint() ^ data); } + alwaysinline auto operator&=(uint data) -> uint { return operator=(operator uint() & data); } - unsigned opcode_number; - unsigned opcode_cycle; + bool n, v, p, b, h, i, z, c; + }; struct Regs { uint16 pc; @@ -63,54 +83,36 @@ struct SMP : Thread { bool iplrom_enable; //$00f2 - unsigned dsp_addr; + uint dsp_addr; //$00f8,$00f9 - unsigned ram00f8; - unsigned ram00f9; + uint ram00f8; + uint ram00f9; } status; - template + uint opcode_number; + uint opcode_cycle; + + template struct Timer { + auto tick() -> void; + auto tick(uint clocks) -> void; + bool enable; uint8 target; uint8 stage1_ticks; uint8 stage2_ticks; uint8 stage3_ticks; - - void tick(); - void tick(unsigned clocks); }; Timer<128> timer0; Timer<128> timer1; Timer< 16> timer2; - void tick(); - alwaysinline void op_io(); - alwaysinline uint8 op_read(uint16 addr); - alwaysinline void op_write(uint16 addr, uint8 data); - alwaysinline void op_step(); - static const unsigned cycle_count_table[256]; + static const uint cycle_count_table[256]; uint64 cycle_table_cpu[256]; - unsigned cycle_table_dsp[256]; + uint cycle_table_dsp[256]; uint64 cycle_step_cpu; - - uint8 op_adc (uint8 x, uint8 y); - uint16 op_addw(uint16 x, uint16 y); - uint8 op_and (uint8 x, uint8 y); - uint8 op_cmp (uint8 x, uint8 y); - uint16 op_cmpw(uint16 x, uint16 y); - uint8 op_eor (uint8 x, uint8 y); - uint8 op_inc (uint8 x); - uint8 op_dec (uint8 x); - uint8 op_or (uint8 x, uint8 y); - uint8 op_sbc (uint8 x, uint8 y); - uint16 op_subw(uint16 x, uint16 y); - uint8 op_asl (uint8 x); - uint8 op_lsr (uint8 x); - uint8 op_rol (uint8 x); - uint8 op_ror (uint8 x); }; extern SMP smp; diff --git a/sfc/alt/smp/timing.cpp b/sfc/alt/smp/timing.cpp index d278f6f4..2efa9e54 100644 --- a/sfc/alt/smp/timing.cpp +++ b/sfc/alt/smp/timing.cpp @@ -1,5 +1,5 @@ -template -void SMP::Timer::tick() { +template +auto SMP::Timer::tick() -> void { if(++stage1_ticks < cycle_frequency) return; stage1_ticks = 0; @@ -11,8 +11,8 @@ void SMP::Timer::tick() { stage3_ticks = (stage3_ticks + 1) & 15; } -template -void SMP::Timer::tick(unsigned clocks) { +template +auto SMP::Timer::tick(uint clocks) -> void { stage1_ticks += clocks; if(stage1_ticks < cycle_frequency) return; diff --git a/target-tomoko/presentation/presentation.cpp b/target-tomoko/presentation/presentation.cpp index 92051960..ccdfd2f0 100644 --- a/target-tomoko/presentation/presentation.cpp +++ b/target-tomoko/presentation/presentation.cpp @@ -75,7 +75,7 @@ Presentation::Presentation() { }); synchronizeAudio.setText("Synchronize Audio").setChecked(settings["Audio/Synchronize"].boolean()).onToggle([&] { settings["Audio/Synchronize"].setValue(synchronizeAudio.checked()); - audio->set(Audio::Synchronize, synchronizeVideo.checked()); + audio->set(Audio::Synchronize, synchronizeAudio.checked()); }); muteAudio.setText("Mute Audio").setChecked(settings["Audio/Mute"].boolean()).onToggle([&] { settings["Audio/Mute"].setValue(muteAudio.checked()); diff --git a/target-tomoko/program/state.cpp b/target-tomoko/program/state.cpp index 973cb0f6..1b553096 100644 --- a/target-tomoko/program/state.cpp +++ b/target-tomoko/program/state.cpp @@ -2,7 +2,7 @@ auto Program::stateName(unsigned slot, bool manager) -> string { return { folderPaths[0], "higan/states/", manager ? "managed/" : "quick/", - "slot-", decimal(slot, 2L), ".bst" + "slot-", natural(slot, 2L), ".bst" }; }