From ea02f1e36a514f933d518ce8aa1e07048692f984 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Thu, 25 Jun 2015 19:52:32 +1000 Subject: [PATCH] Update to v094r31 release. byuu says: This WIP scores 448/920 tests passed. Gave a shot at ROM prefetch that failed miserably (ranged from 409 to 494 tests passed. Nowhere near where it would be if it were implemented correctly.) Three remaining issues: - ROM prefetch - DMA timing - timers (I suspect it's a 3-clock delay in starting, not a 3-clock into the future affair) Probably only going to be able to get the timers working without heroic amounts of effort. MUL timing is fixed to use idle cycles. STMIA is fixed to set sequential at the right moments. DMA priority support is added, so DMA 0 can interrupt DMA 1 mid-transfer. In other news ... I'm calling gtk_widget_destroy on the GtkWindow now, so hopefully those Window_configure issues go away. I realize I was leaking Display* handles in the X-video driver while I was looking at it, so I fixed those. I added DT_NOPREFIX so the Windows ListView will show & characters correctly now. --- emulator/emulator.hpp | 2 +- gba/cpu/cpu.cpp | 24 ++++----- gba/cpu/cpu.hpp | 67 +++++++++++++------------ gba/cpu/dma.cpp | 78 +++++++++++++++++------------- gba/cpu/memory.cpp | 8 +-- gba/cpu/mmio.cpp | 4 +- gba/cpu/registers.cpp | 20 ++++---- gba/cpu/registers.hpp | 40 +++++++-------- gba/cpu/serialization.cpp | 2 +- gba/cpu/timer.cpp | 6 +-- hiro/GNUmakefile | 8 +-- hiro/gtk/window.cpp | 1 + hiro/windows/widget/list-view.cpp | 2 +- processor/arm/algorithms.cpp | 8 +-- processor/arm/instructions-arm.cpp | 4 +- ruby/GNUmakefile | 4 +- ruby/video/xv.cpp | 26 +++++++--- 17 files changed, 166 insertions(+), 138 deletions(-) diff --git a/emulator/emulator.hpp b/emulator/emulator.hpp index cf7eb118..385c1c17 100644 --- a/emulator/emulator.hpp +++ b/emulator/emulator.hpp @@ -8,7 +8,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "094.30"; + static const string Version = "094.31"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/gba/cpu/cpu.cpp b/gba/cpu/cpu.cpp index 5a51130c..e391029c 100644 --- a/gba/cpu/cpu.cpp +++ b/gba/cpu/cpu.cpp @@ -10,7 +10,7 @@ namespace GameBoyAdvance { #include "serialization.cpp" CPU cpu; -void CPU::Enter() { +auto CPU::Enter() -> void { while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::CPU) { scheduler.sync = Scheduler::SynchronizeMode::All; @@ -21,7 +21,7 @@ void CPU::Enter() { } } -void CPU::main() { +auto CPU::main() -> void { #if defined(DEBUG) if(crash) { print(cpsr().t ? disassemble_thumb_instruction(pipeline.execute.address) @@ -57,12 +57,12 @@ void CPU::main() { exec(); } -void CPU::step(unsigned clocks) { +auto CPU::step(unsigned clocks) -> void { timer_step(clocks); sync_step(clocks); } -void CPU::sync_step(unsigned clocks) { +auto CPU::sync_step(unsigned clocks) -> void { ppu.clock -= clocks; if(ppu.clock < 0) co_switch(ppu.thread); @@ -70,26 +70,26 @@ void CPU::sync_step(unsigned clocks) { if(apu.clock < 0) co_switch(apu.thread); } -void CPU::bus_idle(uint32 addr) { +auto CPU::bus_idle(uint32 addr) -> void { step(1); return bus.idle(addr); } -uint32 CPU::bus_read(uint32 addr, uint32 size) { +auto CPU::bus_read(uint32 addr, uint32 size) -> uint32 { step(bus.wait(addr, size)); return bus.read(addr, size); } -void CPU::bus_write(uint32 addr, uint32 size, uint32 word) { +auto CPU::bus_write(uint32 addr, uint32 size, uint32 word) -> void { step(bus.wait(addr, size)); return bus.write(addr, size, word); } -void CPU::keypad_run() { +auto CPU::keypad_run() -> void { if(regs.keypad.control.enable == false) return; bool test = regs.keypad.control.condition; //0 = OR, 1 = AND - for(unsigned n = 0; n < 10; n++) { + for(auto n : range(10)) { if(regs.keypad.control.flag[n] == false) continue; bool input = interface->inputPoll(0, 0, n); if(regs.keypad.control.condition == 0) test |= input; @@ -98,12 +98,12 @@ void CPU::keypad_run() { if(test) regs.irq.flag.keypad = true; } -void CPU::power() { +auto CPU::power() -> void { create(CPU::Enter, 16777216); ARM::power(); - for(unsigned n = 0; n < 32 * 1024; n++) iwram[n] = 0; - for(unsigned n = 0; n < 256 * 1024; n++) ewram[n] = 0; + for(auto n : range( 32 * 1024)) iwram[n] = 0; + for(auto n : range(256 * 1024)) ewram[n] = 0; for(auto& dma : regs.dma) { dma.source = 0; diff --git a/gba/cpu/cpu.hpp b/gba/cpu/cpu.hpp index 79d34939..88208ef3 100644 --- a/gba/cpu/cpu.hpp +++ b/gba/cpu/cpu.hpp @@ -1,43 +1,50 @@ struct CPU : Processor::ARM, Thread, MMIO { - uint8* iwram; - uint8* ewram; + uint8* iwram = nullptr; + uint8* ewram = nullptr; #include "registers.hpp" #include "state.hpp" - static void Enter(); - void main(); - void step(unsigned clocks); - void sync_step(unsigned clocks); + //cpu.cpp + static auto Enter() -> void; - void bus_idle(uint32 addr); - uint32 bus_read(uint32 addr, uint32 size); - void bus_write(uint32 addr, uint32 size, uint32 word); + auto main() -> void; + auto step(unsigned clocks) -> void; + auto sync_step(unsigned clocks) -> void; - void keypad_run(); - void power(); + auto bus_idle(uint32 addr) -> void; + auto bus_read(uint32 addr, uint32 size) -> uint32; + auto bus_write(uint32 addr, uint32 size, uint32 word) -> void; - uint8 read(uint32 addr); - void write(uint32 addr, uint8 byte); + auto keypad_run() -> void; + auto power() -> void; - uint32 iwram_read(uint32 addr, uint32 size); - void iwram_write(uint32 addr, uint32 size, uint32 word); - - uint32 ewram_read(uint32 addr, uint32 size); - void ewram_write(uint32 addr, uint32 size, uint32 word); - - void dma_run(); - void dma_transfer(Registers::DMA &dma); - void dma_vblank(); - void dma_hblank(); - void dma_hdma(); - - void timer_step(unsigned clocks); - void timer_increment(unsigned n); - void timer_fifo_run(unsigned n); - - void serialize(serializer&); CPU(); ~CPU(); + + //mmio.cpp + auto read(uint32 addr) -> uint8; + auto write(uint32 addr, uint8 byte) -> void; + + auto iwram_read(uint32 addr, uint32 size) -> uint32; + auto iwram_write(uint32 addr, uint32 size, uint32 word) -> void; + + auto ewram_read(uint32 addr, uint32 size) -> uint32; + auto ewram_write(uint32 addr, uint32 size, uint32 word) -> void; + + //dma.cpp + auto dma_run() -> void; + auto dma_exec(Registers::DMA& dma) -> void; + auto dma_vblank() -> void; + auto dma_hblank() -> void; + auto dma_hdma() -> void; + + //timer.cpp + auto timer_step(unsigned clocks) -> void; + auto timer_increment(unsigned n) -> void; + auto timer_fifo_run(unsigned n) -> void; + + //serialization.cpp + auto serialize(serializer&) -> void; }; extern CPU cpu; diff --git a/gba/cpu/dma.cpp b/gba/cpu/dma.cpp index 11eda799..5bf0205a 100644 --- a/gba/cpu/dma.cpp +++ b/gba/cpu/dma.cpp @@ -1,60 +1,70 @@ -void CPU::dma_run() { - for(unsigned n = 0; n < 4; n++) { - auto& dma = regs.dma[n]; - if(dma.pending) { - dma.pending = false; - dma_transfer(dma); - if(dma.control.irq) regs.irq.flag.dma[n] = 1; - if(dma.control.drq && n == 3) regs.irq.flag.cartridge = 1; +auto CPU::dma_run() -> void { + while(true) { + bool transferred = false; + for(auto n : range(4)) { + auto& dma = regs.dma[n]; + if(dma.pending) { + dma_exec(dma); + if(dma.control.irq) regs.irq.flag.dma[n] = 1; + if(dma.control.drq && n == 3) regs.irq.flag.cartridge = 1; + transferred = true; + break; + } } + if(!transferred) break; } } -void CPU::dma_transfer(Registers::DMA& dma) { +auto CPU::dma_exec(Registers::DMA& dma) -> void { unsigned size = dma.control.size ? Word : Half; unsigned seek = dma.control.size ? 4 : 2; - sequential() = false; - do { - step(bus.wait(dma.run.source, size)); - uint32 word = bus.read(dma.run.source, size); - - step(bus.wait(dma.run.target, size)); - bus.write(dma.run.target, size, word); - + if(dma.run.length == dma.length) { + idle(); + idle(); + sequential() = false; + } else { sequential() = true; + } - switch(dma.control.sourcemode) { - case 0: dma.run.source += seek; break; - case 1: dma.run.source -= seek; break; - } + step(bus.wait(dma.run.source, size)); + uint32 word = bus.read(dma.run.source, size); - switch(dma.control.targetmode) { - case 0: dma.run.target += seek; break; - case 1: dma.run.target -= seek; break; - case 3: dma.run.target += seek; break; - } - } while(--dma.run.length); - sequential() = false; + step(bus.wait(dma.run.target, size)); + bus.write(dma.run.target, size, word); - if(dma.control.targetmode == 3) dma.run.target = dma.target; - if(dma.control.repeat == 1) dma.run.length = dma.length; - if(dma.control.repeat == 0) dma.control.enable = false; + switch(dma.control.sourcemode) { + case 0: dma.run.source += seek; break; + case 1: dma.run.source -= seek; break; + } + + switch(dma.control.targetmode) { + case 0: dma.run.target += seek; break; + case 1: dma.run.target -= seek; break; + case 3: dma.run.target += seek; break; + } + + if(--dma.run.length == 0) { + dma.pending = false; + if(dma.control.targetmode == 3) dma.run.target = dma.target; + if(dma.control.repeat == 1) dma.run.length = dma.length; + if(dma.control.repeat == 0) dma.control.enable = false; + } } -void CPU::dma_vblank() { +auto CPU::dma_vblank() -> void { for(auto& dma : regs.dma) { if(dma.control.enable && dma.control.timingmode == 1) dma.pending = true; } } -void CPU::dma_hblank() { +auto CPU::dma_hblank() -> void { for(auto& dma : regs.dma) { if(dma.control.enable && dma.control.timingmode == 2) dma.pending = true; } } -void CPU::dma_hdma() { +auto CPU::dma_hdma() -> void { auto& dma = regs.dma[3]; if(dma.control.enable && dma.control.timingmode == 3) dma.pending = true; } diff --git a/gba/cpu/memory.cpp b/gba/cpu/memory.cpp index daf83797..1059fbe1 100644 --- a/gba/cpu/memory.cpp +++ b/gba/cpu/memory.cpp @@ -1,4 +1,4 @@ -uint32 CPU::iwram_read(uint32 addr, uint32 size) { +auto CPU::iwram_read(uint32 addr, uint32 size) -> uint32 { if(regs.memory.control.disable) return cpu.pipeline.fetch.instruction; if(size == Word) return iwram_read(addr &~ 2, Half) << 0 | iwram_read(addr | 2, Half) << 16; @@ -7,7 +7,7 @@ uint32 CPU::iwram_read(uint32 addr, uint32 size) { return iwram[addr & 0x7fff]; } -void CPU::iwram_write(uint32 addr, uint32 size, uint32 word) { +auto CPU::iwram_write(uint32 addr, uint32 size, uint32 word) -> void { if(regs.memory.control.disable) return; if(size == Word) { @@ -25,7 +25,7 @@ void CPU::iwram_write(uint32 addr, uint32 size, uint32 word) { iwram[addr & 0x7fff] = word; } -uint32 CPU::ewram_read(uint32 addr, uint32 size) { +auto CPU::ewram_read(uint32 addr, uint32 size) -> uint32 { if(regs.memory.control.disable) return cpu.pipeline.fetch.instruction; if(regs.memory.control.ewram == false) return iwram_read(addr, size); @@ -35,7 +35,7 @@ uint32 CPU::ewram_read(uint32 addr, uint32 size) { return ewram[addr & 0x3ffff]; } -void CPU::ewram_write(uint32 addr, uint32 size, uint32 word) { +auto CPU::ewram_write(uint32 addr, uint32 size, uint32 word) -> void { if(regs.memory.control.disable) return; if(regs.memory.control.ewram == false) return iwram_write(addr, size, word); diff --git a/gba/cpu/mmio.cpp b/gba/cpu/mmio.cpp index 4ba17e2d..99010ae1 100644 --- a/gba/cpu/mmio.cpp +++ b/gba/cpu/mmio.cpp @@ -1,4 +1,4 @@ -uint8 CPU::read(uint32 addr) { +auto CPU::read(uint32 addr) -> uint8 { uint8 result = 0; switch(addr) { @@ -137,7 +137,7 @@ uint8 CPU::read(uint32 addr) { return 0u; } -void CPU::write(uint32 addr, uint8 byte) { +auto CPU::write(uint32 addr, uint8 byte) -> void { switch(addr) { //DMA0SAD diff --git a/gba/cpu/registers.cpp b/gba/cpu/registers.cpp index 80fb1d53..fff279ca 100644 --- a/gba/cpu/registers.cpp +++ b/gba/cpu/registers.cpp @@ -11,7 +11,7 @@ CPU::Registers::DMAControl::operator uint16() const { ); } -uint16 CPU::Registers::DMAControl::operator=(uint16 source) { +auto CPU::Registers::DMAControl::operator=(uint16 source) -> uint16 { targetmode = source >> 5; sourcemode = source >> 7; repeat = source >> 9; @@ -32,7 +32,7 @@ CPU::Registers::TimerControl::operator uint16() const { ); } -uint16 CPU::Registers::TimerControl::operator=(uint16 source) { +auto CPU::Registers::TimerControl::operator=(uint16 source) -> uint16 { frequency = source >> 0; cascade = source >> 2; irq = source >> 6; @@ -52,7 +52,7 @@ CPU::Registers::SerialControl::operator uint16() const { ); } -uint16 CPU::Registers::SerialControl::operator=(uint16 source) { +auto CPU::Registers::SerialControl::operator=(uint16 source) -> uint16 { shiftclockselect = source >> 0; shiftclockfrequency = source >> 1; transferenablereceive = source >> 2; @@ -80,7 +80,7 @@ CPU::Registers::KeypadControl::operator uint16() const { ); } -uint16 CPU::Registers::KeypadControl::operator=(uint16 source) { +auto CPU::Registers::KeypadControl::operator=(uint16 source) -> uint16 { flag[0] = source >> 0; flag[1] = source >> 1; flag[2] = source >> 2; @@ -111,7 +111,7 @@ CPU::Registers::JoybusSettings::operator uint16() const { ); } -uint16 CPU::Registers::JoybusSettings::operator=(uint16 source) { +auto CPU::Registers::JoybusSettings::operator=(uint16 source) -> uint16 { sc = source >> 0; sd = source >> 1; si = source >> 2; @@ -134,7 +134,7 @@ CPU::Registers::JoybusControl::operator uint16() const { ); } -uint16 CPU::Registers::JoybusControl::operator=(uint16 source) { +auto CPU::Registers::JoybusControl::operator=(uint16 source) -> uint16 { resetsignal = source >> 0; receivecomplete = source >> 1; sendcomplete = source >> 2; @@ -150,7 +150,7 @@ CPU::Registers::JoybusStatus::operator uint16() const { ); } -uint16 CPU::Registers::JoybusStatus::operator=(uint16 source) { +auto CPU::Registers::JoybusStatus::operator=(uint16 source) -> uint16 { receiveflag = source >> 1; sendflag = source >> 3; generalflag = source >> 4; @@ -176,7 +176,7 @@ CPU::Registers::Interrupt::operator uint16() const { ); } -uint16 CPU::Registers::Interrupt::operator=(uint16 source) { +auto CPU::Registers::Interrupt::operator=(uint16 source) -> uint16 { vblank = source >> 0; hblank = source >> 1; vcoincidence = source >> 2; @@ -209,7 +209,7 @@ CPU::Registers::WaitControl::operator uint16() const { ); } -uint16 CPU::Registers::WaitControl::operator=(uint16 source) { +auto CPU::Registers::WaitControl::operator=(uint16 source) -> uint16 { nwait[3] = (source >> 0) & 3; nwait[0] = (source >> 2) & 3; swait[0] = (source >> 4) & 1; @@ -234,7 +234,7 @@ CPU::Registers::MemoryControl::operator uint32() const { ); } -uint32 CPU::Registers::MemoryControl::operator=(uint32 source) { +auto CPU::Registers::MemoryControl::operator=(uint32 source) -> uint32 { disable = source >> 0; unknown1 = source >> 1; ewram = source >> 5; diff --git a/gba/cpu/registers.hpp b/gba/cpu/registers.hpp index f01d674c..9e2d13f4 100644 --- a/gba/cpu/registers.hpp +++ b/gba/cpu/registers.hpp @@ -10,8 +10,8 @@ struct Registers { uint1 enable; operator uint16() const; - uint16 operator=(uint16 source); - DMAControl& operator=(const DMAControl&) = delete; + auto operator=(uint16 source) -> uint16; + auto operator=(const DMAControl&) -> DMAControl& = delete; }; struct DMA { @@ -36,8 +36,8 @@ struct Registers { uint1 enable; operator uint16() const; - uint16 operator=(uint16 source); - TimerControl& operator=(const TimerControl&) = delete; + auto operator=(uint16 source) -> uint16; + auto operator=(const TimerControl&) -> TimerControl& = delete; }; struct Timer { @@ -56,8 +56,8 @@ struct Registers { uint1 irqenable; operator uint16() const; - uint16 operator=(uint16 source); - SerialControl& operator=(const SerialControl&) = delete; + auto operator=(uint16 source) -> uint16; + auto operator=(const SerialControl&) -> SerialControl& = delete; }; struct Serial { @@ -72,8 +72,8 @@ struct Registers { uint1 condition; operator uint16() const; - uint16 operator=(uint16 source); - KeypadControl& operator=(const KeypadControl&) = delete; + auto operator=(uint16 source) -> uint16; + auto operator=(const KeypadControl&) -> KeypadControl& = delete; }; struct Keypad { @@ -93,8 +93,8 @@ struct Registers { uint2 mode; operator uint16() const; - uint16 operator=(uint16 source); - JoybusSettings& operator=(const JoybusSettings&) = delete; + auto operator=(uint16 source) -> uint16; + auto operator=(const JoybusSettings&) -> JoybusSettings& = delete; }; struct JoybusControl { @@ -104,8 +104,8 @@ struct Registers { uint1 irqenable; operator uint16() const; - uint16 operator=(uint16 source); - JoybusControl& operator=(const JoybusControl&) = delete; + auto operator=(uint16 source) -> uint16; + auto operator=(const JoybusControl&) -> JoybusControl& = delete; }; struct JoybusStatus { @@ -114,8 +114,8 @@ struct Registers { uint2 generalflag; operator uint16() const; - uint16 operator=(uint16 source); - JoybusStatus& operator=(const JoybusStatus&) = delete; + auto operator=(uint16 source) -> uint16; + auto operator=(const JoybusStatus&) -> JoybusStatus& = delete; }; struct Joybus { @@ -139,8 +139,8 @@ struct Registers { uint1 cartridge; operator uint16() const; - uint16 operator=(uint16 source); - Interrupt& operator=(const Interrupt&) = delete; + auto operator=(uint16 source) -> uint16; + auto operator=(const Interrupt&) -> Interrupt& = delete; }; struct IRQ { @@ -156,8 +156,8 @@ struct Registers { uint1 gametype; operator uint16() const; - uint16 operator=(uint16 source); - WaitControl& operator=(const WaitControl&) = delete; + auto operator=(uint16 source) -> uint16; + auto operator=(const WaitControl&) -> WaitControl& = delete; }; struct Wait { @@ -172,8 +172,8 @@ struct Registers { uint4 unknown2; operator uint32() const; - uint32 operator=(uint32 source); - MemoryControl& operator=(const MemoryControl&) = delete; + auto operator=(uint32 source) -> uint32; + auto operator=(const MemoryControl&) -> MemoryControl& = delete; }; struct Memory { diff --git a/gba/cpu/serialization.cpp b/gba/cpu/serialization.cpp index ebb3a9fb..fec88d33 100644 --- a/gba/cpu/serialization.cpp +++ b/gba/cpu/serialization.cpp @@ -1,4 +1,4 @@ -void CPU::serialize(serializer& s) { +auto CPU::serialize(serializer& s) -> void { ARM::serialize(s); Thread::serialize(s); diff --git a/gba/cpu/timer.cpp b/gba/cpu/timer.cpp index 0aaa2ec4..251e6828 100644 --- a/gba/cpu/timer.cpp +++ b/gba/cpu/timer.cpp @@ -1,4 +1,4 @@ -void CPU::timer_step(unsigned clocks) { +auto CPU::timer_step(unsigned clocks) -> void { for(unsigned c = 0; c < clocks; c++) { for(unsigned n = 0; n < 4; n++) { auto& timer = regs.timer[n]; @@ -14,7 +14,7 @@ void CPU::timer_step(unsigned clocks) { } } -void CPU::timer_increment(unsigned n) { +auto CPU::timer_increment(unsigned n) -> void { auto& timer = regs.timer[n]; if(++timer.period == 0) { timer.period = timer.reload; @@ -30,7 +30,7 @@ void CPU::timer_increment(unsigned n) { } } -void CPU::timer_fifo_run(unsigned n) { +auto CPU::timer_fifo_run(unsigned n) -> void { apu.fifo[n].read(); if(apu.fifo[n].size > 16) return; diff --git a/hiro/GNUmakefile b/hiro/GNUmakefile index 585eeab0..224d049a 100644 --- a/hiro/GNUmakefile +++ b/hiro/GNUmakefile @@ -30,12 +30,12 @@ else endif ifeq ($(hiro),gtk) - hiroflags = $(cppflags) $(flags) -DHIRO_GTK `pkg-config --cflags gtk+-2.0 gtksourceview-2.0` - hirolink = `pkg-config --libs gtk+-2.0 gtksourceview-2.0` -lX11 + hiroflags = $(cppflags) $(flags) -DHIRO_GTK $(shell pkg-config --cflags gtk+-2.0 gtksourceview-2.0) + hirolink = -lX11 $(shell pkg-config --libs gtk+-2.0 gtksourceview-2.0) endif ifeq ($(hiro),qt) - hiroflags = $(cppflags) $(flags) -DHIRO_QT `pkg-config --cflags QtCore QtGui` - hirolink = `pkg-config --libs QtCore QtGui` -lX11 + hiroflags = $(cppflags) $(flags) -DHIRO_QT $(shell pkg-config --cflags QtCore QtGui) + hirolink = -lX11 $(shell pkg-config --libs QtCore QtGui) endif endif diff --git a/hiro/gtk/window.cpp b/hiro/gtk/window.cpp index 6c40acb9..d82e82a7 100644 --- a/hiro/gtk/window.cpp +++ b/hiro/gtk/window.cpp @@ -182,6 +182,7 @@ auto pWindow::construct() -> void { } auto pWindow::destruct() -> void { + gtk_widget_destroy(widget); } auto pWindow::append(sLayout layout) -> void { diff --git a/hiro/windows/widget/list-view.cpp b/hiro/windows/widget/list-view.cpp index 06edd540..85bd425e 100644 --- a/hiro/windows/widget/list-view.cpp +++ b/hiro/windows/widget/list-view.cpp @@ -307,7 +307,7 @@ auto pListView::onCustomDraw(LPARAM lparam) -> LRESULT { utf16_t wText(text); SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, selected ? GetSysColor(COLOR_HIGHLIGHTTEXT) : CreateRGB(_foregroundColor(row, column))); - auto style = DT_SINGLELINE | DT_END_ELLIPSIS; + auto style = DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS; style |= halign < 0.333 ? DT_LEFT : halign > 0.666 ? DT_RIGHT : DT_CENTER; style |= valign < 0.333 ? DT_TOP : valign > 0.666 ? DT_BOTTOM : DT_VCENTER; rc.right -= 2; diff --git a/processor/arm/algorithms.cpp b/processor/arm/algorithms.cpp index 1de57563..8339b900 100644 --- a/processor/arm/algorithms.cpp +++ b/processor/arm/algorithms.cpp @@ -45,10 +45,10 @@ auto ARM::sub(uint32 source, uint32 modify, bool carry) -> uint32 { } auto ARM::mul(uint32 product, uint32 multiplicand, uint32 multiplier) -> uint32 { - if((multiplier & 0xffffff00) == 0x00000000 || (multiplier & 0xffffff00 == 0xffffff00)) step(1); - else if((multiplier & 0xffff0000) == 0x00000000 || (multiplier & 0xffff0000 == 0xffff0000)) step(2); - else if((multiplier & 0xff000000) == 0x00000000 || (multiplier & 0xff000000 == 0xff000000)) step(3); - else step(4); + idle(); + if((multiplier & 0xffffff00) != 0x00000000 && (multiplier & 0xffffff00) != 0xffffff00) idle(); + if((multiplier & 0xffff0000) != 0x00000000 && (multiplier & 0xffff0000) != 0xffff0000) idle(); + if((multiplier & 0xff000000) != 0x00000000 && (multiplier & 0xff000000) != 0xff000000) idle(); product += multiplicand * multiplier; diff --git a/processor/arm/instructions-arm.cpp b/processor/arm/instructions-arm.cpp index 62a5f2b7..3b5e995b 100644 --- a/processor/arm/instructions-arm.cpp +++ b/processor/arm/instructions-arm.cpp @@ -521,9 +521,9 @@ auto ARM::arm_op_move_multiple() { if(usr) processor.setMode(Processor::Mode::USR); - sequential() = false; for(unsigned m = 0; m < 16; m++) { - if(list & (1 << m)) { + sequential() = false; + if(list & 1 << m) { if(l == 1) r(m) = read(rn, Word); if(l == 0) write(rn, Word, r(m)); rn += 4; diff --git a/ruby/GNUmakefile b/ruby/GNUmakefile index 8a68983d..b73d0bb8 100644 --- a/ruby/GNUmakefile +++ b/ruby/GNUmakefile @@ -5,7 +5,7 @@ else endif rubyflags += $(foreach c,$(subst .,_,$(call strupper,$(ruby))),-D$c) -rubyflags += $(if $(findstring .sdl,$(ruby)),`sdl-config --cflags`) +rubyflags += $(if $(findstring .sdl,$(ruby)),$(shell sdl-config --cflags)) rubylink = @@ -26,7 +26,7 @@ rubylink += $(if $(findstring audio.xaudio2,$(ruby)),-lole32) rubylink += $(if $(findstring input.udev,$(ruby)),-ludev) rubylink += $(if $(findstring input.windows,$(ruby)),-ldinput8 -ldxguid) -rubylink += $(if $(findstring .sdl,$(ruby)),`sdl-config --libs`) +rubylink += $(if $(findstring .sdl,$(ruby)),$(shell sdl-config --libs)) ifeq ($(platform),windows) rubylink += $(if $(findstring audio.openal,$(ruby)),-lopenal32) diff --git a/ruby/video/xv.cpp b/ruby/video/xv.cpp index 64c2c453..723ecf03 100644 --- a/ruby/video/xv.cpp +++ b/ruby/video/xv.cpp @@ -54,7 +54,10 @@ struct VideoXv : Video { auto cap(const string& name) -> bool { if(name == Video::Handle) return true; if(name == Video::Synchronize) { - return XInternAtom(XOpenDisplay(0), "XV_SYNC_TO_VBLANK", true) != None; + Display* display = XOpenDisplay(nullptr); + bool result = XInternAtom(display, "XV_SYNC_TO_VBLANK", true) != None; + XCloseDisplay(display); + return result; } return false; } @@ -72,14 +75,16 @@ struct VideoXv : Video { } if(name == Video::Synchronize && value.is()) { - Display* display = XOpenDisplay(0); + bool result = false; + Display* display = XOpenDisplay(nullptr); Atom atom = XInternAtom(display, "XV_SYNC_TO_VBLANK", true); if(atom != None && device.port >= 0) { settings.synchronize = value.get(); XvSetPortAttribute(display, device.port, atom, settings.synchronize); - return true; + result = true; } - return false; + XCloseDisplay(display); + return result; } return false; @@ -92,7 +97,7 @@ struct VideoXv : Video { XShmDetach(device.display, &device.shminfo); shmdt(device.shminfo.shmaddr); - shmctl(device.shminfo.shmid, IPC_RMID, NULL); + shmctl(device.shminfo.shmid, IPC_RMID, nullptr); XFree(device.image); delete[] buffer; @@ -161,7 +166,7 @@ struct VideoXv : Video { } auto init() -> bool { - device.display = XOpenDisplay(0); + device.display = XOpenDisplay(nullptr); if(!XShmQueryExtension(device.display)) { fprintf(stderr, "VideoXv: XShm extension not found.\n"); @@ -202,7 +207,7 @@ struct VideoXv : Video { visualtemplate.depth = device.depth; visualtemplate.visual = 0; signed visualmatches = 0; - XVisualInfo *visualinfo = XGetVisualInfo(device.display, VisualIDMask | VisualScreenMask | VisualDepthMask, &visualtemplate, &visualmatches); + XVisualInfo* visualinfo = XGetVisualInfo(device.display, VisualIDMask | VisualScreenMask | VisualDepthMask, &visualtemplate, &visualmatches); if(visualmatches < 1 || !visualinfo->visual) { if(visualinfo) XFree(visualinfo); fprintf(stderr, "VideoXv: unable to find Xv-compatible visual.\n"); @@ -323,7 +328,7 @@ struct VideoXv : Video { auto term() -> void { XShmDetach(device.display, &device.shminfo); shmdt(device.shminfo.shmaddr); - shmctl(device.shminfo.shmid, IPC_RMID, NULL); + shmctl(device.shminfo.shmid, IPC_RMID, nullptr); XFree(device.image); if(device.window) { @@ -336,6 +341,11 @@ struct VideoXv : Video { device.colormap = 0; } + if(device.display) { + XCloseDisplay(device.display); + device.display = nullptr; + } + if(buffer) { delete[] buffer; buffer = nullptr; } if(ytable) { delete[] ytable; ytable = nullptr; } if(utable) { delete[] utable; utable = nullptr; }