mirror of https://github.com/bsnes-emu/bsnes.git
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.
This commit is contained in:
parent
310ff4fa3b
commit
ea02f1e36a
|
@ -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/";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,29 +1,38 @@
|
|||
void CPU::dma_run() {
|
||||
for(unsigned n = 0; n < 4; n++) {
|
||||
auto CPU::dma_run() -> void {
|
||||
while(true) {
|
||||
bool transferred = false;
|
||||
for(auto n : range(4)) {
|
||||
auto& dma = regs.dma[n];
|
||||
if(dma.pending) {
|
||||
dma.pending = false;
|
||||
dma_transfer(dma);
|
||||
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;
|
||||
|
||||
if(dma.run.length == dma.length) {
|
||||
idle();
|
||||
idle();
|
||||
sequential() = false;
|
||||
do {
|
||||
} else {
|
||||
sequential() = true;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
sequential() = true;
|
||||
|
||||
switch(dma.control.sourcemode) {
|
||||
case 0: dma.run.source += seek; break;
|
||||
case 1: dma.run.source -= seek; break;
|
||||
|
@ -34,27 +43,28 @@ void CPU::dma_transfer(Registers::DMA& dma) {
|
|||
case 1: dma.run.target -= seek; break;
|
||||
case 3: dma.run.target += seek; break;
|
||||
}
|
||||
} while(--dma.run.length);
|
||||
sequential() = false;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
void CPU::serialize(serializer& s) {
|
||||
auto CPU::serialize(serializer& s) -> void {
|
||||
ARM::serialize(s);
|
||||
Thread::serialize(s);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -182,6 +182,7 @@ auto pWindow::construct() -> void {
|
|||
}
|
||||
|
||||
auto pWindow::destruct() -> void {
|
||||
gtk_widget_destroy(widget);
|
||||
}
|
||||
|
||||
auto pWindow::append(sLayout layout) -> void {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<bool>()) {
|
||||
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<bool>();
|
||||
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; }
|
||||
|
|
Loading…
Reference in New Issue