diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 4c643c40..fd1951e1 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -9,7 +9,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "098.17"; + static const string Version = "098.18"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/gb/ppu/mmio.cpp b/higan/gb/ppu/mmio.cpp index cc438708..7c8c86a6 100644 --- a/higan/gb/ppu/mmio.cpp +++ b/higan/gb/ppu/mmio.cpp @@ -139,6 +139,12 @@ auto PPU::mmio_write(uint16 addr, uint8 data) -> void { status.interrupt_oam = data & 0x20; status.interrupt_vblank = data & 0x10; status.interrupt_hblank = data & 0x08; + + //hardware bug: writes to STAT on DMG,SGB during blanking triggers STAT IRQ + if(!system.cgb() && status.mode < 2) { + cpu.raise(CPU::Interrupt::Stat); + } + return; } diff --git a/higan/processor/r65816/opcode_misc.cpp b/higan/processor/r65816/opcode_misc.cpp index ea300cf2..241a3404 100644 --- a/higan/processor/r65816/opcode_misc.cpp +++ b/higan/processor/r65816/opcode_misc.cpp @@ -9,7 +9,9 @@ L readPC(); auto R65816::op_xba() { io(); L io(); - swap(r.a.l, r.a.h); + r.a.l ^= r.a.h; + r.a.h ^= r.a.l; + r.a.l ^= r.a.h; r.p.n = (r.a.l & 0x80); r.p.z = (r.a.l == 0); } diff --git a/higan/processor/r65816/registers.hpp b/higan/processor/r65816/registers.hpp index dbe92d8b..84a852e3 100644 --- a/higan/processor/r65816/registers.hpp +++ b/higan/processor/r65816/registers.hpp @@ -23,6 +23,8 @@ struct Flags { struct reg16 { union { uint16_t w = 0; + //BitField l; + //BitField h; struct { uint8_t order_lsb2(l, h); }; }; @@ -43,6 +45,12 @@ struct reg16 { struct reg24 { union { uint32_t d = 0; + //BitField w; + //BitField wh; + //BitField l; + //BitField h; + //BitField b; + //BitField bh; struct { uint16_t order_lsb2(w, wh); }; struct { uint8_t order_lsb4(l, h, b, bh); }; }; diff --git a/hiro/extension/browser-dialog.cpp b/hiro/extension/browser-dialog.cpp index 22601081..46eb9586 100644 --- a/hiro/extension/browser-dialog.cpp +++ b/hiro/extension/browser-dialog.cpp @@ -181,6 +181,7 @@ auto BrowserDialogWindow::setPath(string path) -> void { } Application::processEvents(); + view->resizeColumns(); //todo: on Windows, adding items may add vertical scrollbar; this hack corrects column width view.setFocused().doChange(); } diff --git a/hiro/windows/widget/table-view.cpp b/hiro/windows/widget/table-view.cpp index fb0c3040..8ee4e221 100644 --- a/hiro/windows/widget/table-view.cpp +++ b/hiro/windows/widget/table-view.cpp @@ -46,6 +46,7 @@ auto pTableView::destruct() -> void { } auto pTableView::append(sTableViewHeader header) -> void { + resizeColumns(); } auto pTableView::append(sTableViewItem item) -> void { diff --git a/nall/bit.hpp b/nall/bit.hpp index 8c8c5172..f2a54b6e 100644 --- a/nall/bit.hpp +++ b/nall/bit.hpp @@ -49,12 +49,12 @@ namespace bit { } //clear_lowest(0b1110) == 0b1100 - constexpr inline auto clear_lowest(const uintmax x) -> uintmax { + constexpr inline auto clearLowest(const uintmax x) -> uintmax { return x & (x - 1); } //set_lowest(0b0101) == 0b0111 - constexpr inline auto set_lowest(const uintmax x) -> uintmax { + constexpr inline auto setLowest(const uintmax x) -> uintmax { return x | (x + 1); } diff --git a/nall/primitives.hpp b/nall/primitives.hpp index f551aa54..0c8a4d2b 100644 --- a/nall/primitives.hpp +++ b/nall/primitives.hpp @@ -5,6 +5,52 @@ namespace nall { +template struct BitField { + static_assert(Lo <= Hi, ""); + static_assert(Hi < sizeof(Type) * 8, ""); + + inline BitField() = default; + inline BitField(const BitField& value) { set(value.data); } + template inline BitField(const T& value) { set(value << Lo); } + +//inline explicit operator bool() const { return data & Mask; } + inline operator Type() const { return get(); } + + inline auto& operator=(const BitField& value) { return set(value.data); } + template inline auto& operator=(const T& value) { return set(value << Lo); } + + inline auto operator++(int) { Type value = get(); set(data + (1 << Lo)); return value; } + inline auto operator--(int) { Type value = get(); set(data - (1 << Lo)); return value; } + + inline auto& operator++() { return set(data + (1 << Lo)); } + inline auto& operator--() { return set(data - (1 << Lo)); } + + inline auto& operator &=(const Type value) { return set(data & (value << Lo)); } + inline auto& operator |=(const Type value) { return set(data | (value << Lo)); } + inline auto& operator ^=(const Type value) { return set(data ^ (value << Lo)); } + inline auto& operator<<=(const Type value) { return set(data << value); } + inline auto& operator>>=(const Type value) { return set(data >> value); } + inline auto& operator +=(const Type value) { return set(data + (value << Lo)); } + inline auto& operator -=(const Type value) { return set(data - (value << Lo)); } + inline auto& operator *=(const Type value) { return set((get() * value) << Lo); } + inline auto& operator /=(const Type value) { return set((get() / value) << Lo); } + inline auto& operator %=(const Type value) { return set((get() % value) << Lo); } + +private: + enum : uint { Bits = Hi - Lo + 1 }; + enum : uint { Mask = ((1ull << Bits) - 1) << Lo }; + Type data; + + inline auto get() const -> Type { + return (data & Mask) >> Lo; + } + + inline auto set(Type value) -> BitField& { + data = (data & ~Mask) | (value & Mask); + return *this; + } +}; + struct Boolean { inline Boolean() : data(false) {} template inline Boolean(const T& value) : data(value) {} @@ -29,27 +75,27 @@ template struct Natural { enum : type { Mask = ~0ull >> (64 - Bits) }; inline Natural() : data(0) {} - template inline Natural(const T& value) { assign(value); } + template inline Natural(const T& value) { set(value); } inline operator type() const { return data; } - template inline auto& operator=(const T& value) { assign(value); return *this; } + template inline auto& operator=(const T& value) { set(value); return *this; } - inline auto operator++(int) { type value = data; assign(data + 1); return value; } - inline auto operator--(int) { type value = data; assign(data - 1); return value; } + inline auto operator++(int) { type value = data; set(data + 1); return value; } + inline auto operator--(int) { type value = data; set(data - 1); return value; } - inline auto& operator++() { assign(data + 1); return *this; } - inline auto& operator--() { assign(data - 1); return *this; } + inline auto& operator++() { set(data + 1); return *this; } + inline auto& operator--() { set(data - 1); return *this; } - inline auto& operator &=(const type value) { assign(data & value); return *this; } - inline auto& operator |=(const type value) { assign(data | value); return *this; } - inline auto& operator ^=(const type value) { assign(data ^ value); return *this; } - inline auto& operator<<=(const type value) { assign(data << value); return *this; } - inline auto& operator>>=(const type value) { assign(data >> value); return *this; } - inline auto& operator +=(const type value) { assign(data + value); return *this; } - inline auto& operator -=(const type value) { assign(data - value); return *this; } - inline auto& operator *=(const type value) { assign(data * value); return *this; } - inline auto& operator /=(const type value) { assign(data / value); return *this; } - inline auto& operator %=(const type value) { assign(data % value); return *this; } + inline auto& operator &=(const type value) { set(data & value); return *this; } + inline auto& operator |=(const type value) { set(data | value); return *this; } + inline auto& operator ^=(const type value) { set(data ^ value); return *this; } + inline auto& operator<<=(const type value) { set(data << value); return *this; } + inline auto& operator>>=(const type value) { set(data >> value); return *this; } + inline auto& operator +=(const type value) { set(data + value); return *this; } + inline auto& operator -=(const type value) { set(data - value); return *this; } + inline auto& operator *=(const type value) { set(data * value); return *this; } + inline auto& operator /=(const type value) { set(data / value); return *this; } + inline auto& operator %=(const type value) { set(data % value); return *this; } inline auto serialize(serializer& s) { s(data); } @@ -92,7 +138,7 @@ template struct Natural { } private: - auto assign(type value) -> void { + auto set(type value) -> void { data = value & Mask; } @@ -111,27 +157,27 @@ template struct Integer { enum : utype { Mask = ~0ull >> (64 - Bits), Sign = 1ull << (Bits - 1) }; inline Integer() : data(0) {} - template inline Integer(const T& value) { assign(value); } + template inline Integer(const T& value) { set(value); } inline operator type() const { return data; } - template inline auto& operator=(const T& value) { assign(value); return *this; } + template inline auto& operator=(const T& value) { set(value); return *this; } - inline auto operator++(int) { type value = data; assign(data + 1); return value; } - inline auto operator--(int) { type value = data; assign(data - 1); return value; } + inline auto operator++(int) { type value = data; set(data + 1); return value; } + inline auto operator--(int) { type value = data; set(data - 1); return value; } - inline auto& operator++() { assign(data + 1); return *this; } - inline auto& operator--() { assign(data - 1); return *this; } + inline auto& operator++() { set(data + 1); return *this; } + inline auto& operator--() { set(data - 1); return *this; } - inline auto& operator &=(const type value) { assign(data & value); return *this; } - inline auto& operator |=(const type value) { assign(data | value); return *this; } - inline auto& operator ^=(const type value) { assign(data ^ value); return *this; } - inline auto& operator<<=(const type value) { assign(data << value); return *this; } - inline auto& operator>>=(const type value) { assign(data >> value); return *this; } - inline auto& operator +=(const type value) { assign(data + value); return *this; } - inline auto& operator -=(const type value) { assign(data - value); return *this; } - inline auto& operator *=(const type value) { assign(data * value); return *this; } - inline auto& operator /=(const type value) { assign(data / value); return *this; } - inline auto& operator %=(const type value) { assign(data % value); return *this; } + inline auto& operator &=(const type value) { set(data & value); return *this; } + inline auto& operator |=(const type value) { set(data | value); return *this; } + inline auto& operator ^=(const type value) { set(data ^ value); return *this; } + inline auto& operator<<=(const type value) { set(data << value); return *this; } + inline auto& operator>>=(const type value) { set(data >> value); return *this; } + inline auto& operator +=(const type value) { set(data + value); return *this; } + inline auto& operator -=(const type value) { set(data - value); return *this; } + inline auto& operator *=(const type value) { set(data * value); return *this; } + inline auto& operator /=(const type value) { set(data / value); return *this; } + inline auto& operator %=(const type value) { set(data % value); return *this; } inline auto serialize(serializer& s) { s(data); } @@ -174,7 +220,7 @@ template struct Integer { } private: - auto assign(type value) -> void { + auto set(type value) -> void { data = ((value & Mask) ^ Sign) - Sign; } @@ -208,6 +254,7 @@ template struct Real { inline auto serialize(serializer& s) { s(data); } +private: type data; };