From fbc15718897ca1aecaabfb7ba3cd3b79edbd8e84 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Tue, 22 Jan 2019 11:26:20 +1100 Subject: [PATCH] Update to v106r85 release. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit byuu says: The bad instruction was due to the instruction before it fetching one too many bytes. Didn't notice right away as the disassembler got it right. The register map was incorrect on the active 16-bit flags. I fixed and improved some other things along those lines. Hooked up some basic KnGE (VPU) timings, made it print out VRAM and some of the WRAM onto the screen each frame, tried to drive Vblank and Hblank IRQs, but ... I don't know for sure what vector addresses they belong to. MAME says "INT4" for Vblank, and says nothing for Hblank. I am wildly guessing INT4==SWI 4==0xffff10, but ... I have no idea. I'm also not emulating the interrupts properly based on line levels, I'm just firing on the 0→1 transitions. Sounds like Vblank is more nuanced too, but I guess we'll see. Emulation is running further along now, even to the point of it successfully enabling the KnGE IRQs, but VRAM doesn't appear to get much useful stuff written into it yet. I reverted the nall/primitive changes, so request for testing is I guess rescinded, for whatever it was worth. --- higan/emulator/emulator.hpp | 2 +- higan/emulator/interface.hpp | 1 - higan/fc/interface/interface.cpp | 1 - higan/gb/interface/interface.cpp | 1 - higan/gba/interface/interface.cpp | 1 - higan/md/interface/interface.cpp | 1 - higan/ms/interface/colecovision.cpp | 2 - higan/ms/interface/game-gear.cpp | 1 - higan/ms/interface/master-system.cpp | 2 - higan/ms/interface/sc-3000.cpp | 2 - higan/ms/interface/sg-1000.cpp | 2 - higan/msx/interface/interface.cpp | 1 - higan/ngp/cpu/cpu.cpp | 14 ++++- higan/ngp/cpu/cpu.hpp | 11 ++++ higan/ngp/interface/interface.cpp | 1 - higan/ngp/vpu/vpu.cpp | 33 +++++++++++- higan/ngp/vpu/vpu.hpp | 5 ++ higan/pce/interface/interface.cpp | 1 - higan/processor/tlcs900h/disassembler.cpp | 4 +- higan/processor/tlcs900h/instruction.cpp | 8 +-- higan/processor/tlcs900h/instructions.cpp | 24 ++++++--- higan/processor/tlcs900h/registers.cpp | 11 ++-- higan/processor/tlcs900h/tlcs900h.cpp | 1 + higan/processor/tlcs900h/tlcs900h.hpp | 16 +++--- higan/sfc/interface/interface.cpp | 2 - higan/ws/interface/interface.cpp | 1 - nall/primitives.hpp | 5 +- nall/primitives/bit-range.hpp | 16 +++--- nall/primitives/boolean.hpp | 4 +- nall/primitives/integer.hpp | 64 +++++++---------------- nall/primitives/natural.hpp | 64 +++++++---------------- nall/primitives/real.hpp | 15 +----- 32 files changed, 150 insertions(+), 167 deletions(-) diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 4f0b27f4..ef070174 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -31,7 +31,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "106.84"; + static const string Version = "106.85"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "https://byuu.org/"; diff --git a/higan/emulator/interface.hpp b/higan/emulator/interface.hpp index 759ba7ee..c097925b 100644 --- a/higan/emulator/interface.hpp +++ b/higan/emulator/interface.hpp @@ -24,7 +24,6 @@ struct Interface { uint internalWidth = 0; uint internalHeight = 0; double aspectCorrection = 0; - double refreshRate = 0; }; struct Port { diff --git a/higan/fc/interface/interface.cpp b/higan/fc/interface/interface.cpp index 24fddf95..70b80e66 100644 --- a/higan/fc/interface/interface.cpp +++ b/higan/fc/interface/interface.cpp @@ -22,7 +22,6 @@ auto Interface::display() -> Display { display.internalWidth = 256; display.internalHeight = 240; display.aspectCorrection = 8.0 / 7.0; - display.refreshRate = system.frequency() / (ppu.vlines() * ppu.rate() * 341.0); return display; } diff --git a/higan/gb/interface/interface.cpp b/higan/gb/interface/interface.cpp index f7dc4ec8..8e612b14 100644 --- a/higan/gb/interface/interface.cpp +++ b/higan/gb/interface/interface.cpp @@ -16,7 +16,6 @@ auto Interface::display() -> Display { display.internalWidth = 160; display.internalHeight = 144; display.aspectCorrection = 1.0; - display.refreshRate = (4.0 * 1024.0 * 1024.0) / (154.0 * 456.0); return display; } diff --git a/higan/gba/interface/interface.cpp b/higan/gba/interface/interface.cpp index a7e54330..a681b910 100644 --- a/higan/gba/interface/interface.cpp +++ b/higan/gba/interface/interface.cpp @@ -21,7 +21,6 @@ auto Interface::display() -> Display { display.internalWidth = 240; display.internalHeight = 160; display.aspectCorrection = 1.0; - display.refreshRate = system.frequency() / (228.0 * 1232.0); if(settings.rotateLeft) { swap(display.width, display.height); swap(display.internalWidth, display.internalHeight); diff --git a/higan/md/interface/interface.cpp b/higan/md/interface/interface.cpp index 1c235378..d3e38d4f 100644 --- a/higan/md/interface/interface.cpp +++ b/higan/md/interface/interface.cpp @@ -22,7 +22,6 @@ auto Interface::display() -> Display { display.internalWidth = 1280; display.internalHeight = 480; display.aspectCorrection = 1.0; - display.refreshRate = (system.frequency() / 2.0) / (vdp.frameHeight() * 1710.0); return display; } diff --git a/higan/ms/interface/colecovision.cpp b/higan/ms/interface/colecovision.cpp index b0ff5fc7..808ee873 100644 --- a/higan/ms/interface/colecovision.cpp +++ b/higan/ms/interface/colecovision.cpp @@ -15,8 +15,6 @@ auto ColecoVisionInterface::display() -> Display { display.internalWidth = 256; display.internalHeight = 192; display.aspectCorrection = 1.0; - if(Region::NTSC()) display.refreshRate = (system.colorburst() * 15.0 / 5.0) / (262.0 * 684.0); - if(Region::PAL()) display.refreshRate = (system.colorburst() * 15.0 / 5.0) / (312.0 * 684.0); return display; } diff --git a/higan/ms/interface/game-gear.cpp b/higan/ms/interface/game-gear.cpp index b3844bec..a3329503 100644 --- a/higan/ms/interface/game-gear.cpp +++ b/higan/ms/interface/game-gear.cpp @@ -15,7 +15,6 @@ auto GameGearInterface::display() -> Display { display.internalWidth = 160; display.internalHeight = 144; display.aspectCorrection = 1.0; - display.refreshRate = (system.colorburst() * 15.0 / 5.0) / (262.0 * 684.0); return display; } diff --git a/higan/ms/interface/master-system.cpp b/higan/ms/interface/master-system.cpp index 5380f608..0e5ed284 100644 --- a/higan/ms/interface/master-system.cpp +++ b/higan/ms/interface/master-system.cpp @@ -15,8 +15,6 @@ auto MasterSystemInterface::display() -> Display { display.internalWidth = 256; display.internalHeight = 240; display.aspectCorrection = 8.0 / 7.0; - if(Region::NTSC()) display.refreshRate = (system.colorburst() * 15.0 / 5.0) / (262.0 * 684.0); - if(Region::PAL()) display.refreshRate = (system.colorburst() * 15.0 / 5.0) / (312.0 * 684.0); return display; } diff --git a/higan/ms/interface/sc-3000.cpp b/higan/ms/interface/sc-3000.cpp index 5f400814..f2fbd5ea 100644 --- a/higan/ms/interface/sc-3000.cpp +++ b/higan/ms/interface/sc-3000.cpp @@ -15,8 +15,6 @@ auto SC3000Interface::display() -> Display { display.internalWidth = 256; display.internalHeight = 192; display.aspectCorrection = 1.0; - if(Region::NTSC()) display.refreshRate = (system.colorburst() * 15.0 / 5.0) / (262.0 * 684.0); - if(Region::PAL()) display.refreshRate = (system.colorburst() * 15.0 / 5.0) / (312.0 * 684.0); return display; } diff --git a/higan/ms/interface/sg-1000.cpp b/higan/ms/interface/sg-1000.cpp index 28410927..1f94a4c8 100644 --- a/higan/ms/interface/sg-1000.cpp +++ b/higan/ms/interface/sg-1000.cpp @@ -15,8 +15,6 @@ auto SG1000Interface::display() -> Display { display.internalWidth = 256; display.internalHeight = 192; display.aspectCorrection = 1.0; - if(Region::NTSC()) display.refreshRate = (system.colorburst() * 15.0 / 5.0) / (262.0 * 684.0); - if(Region::PAL()) display.refreshRate = (system.colorburst() * 15.0 / 5.0) / (312.0 * 684.0); return display; } diff --git a/higan/msx/interface/interface.cpp b/higan/msx/interface/interface.cpp index 65122783..48b429a5 100644 --- a/higan/msx/interface/interface.cpp +++ b/higan/msx/interface/interface.cpp @@ -19,7 +19,6 @@ auto Interface::display() -> Display { display.internalWidth = 256; display.internalHeight = 192; display.aspectCorrection = 1.0; - display.refreshRate = 60.0; //todo: PAL return display; } diff --git a/higan/ngp/cpu/cpu.cpp b/higan/ngp/cpu/cpu.cpp index de3a165c..874d26e9 100644 --- a/higan/ngp/cpu/cpu.cpp +++ b/higan/ngp/cpu/cpu.cpp @@ -12,8 +12,7 @@ auto CPU::Enter() -> void { auto CPU::main() -> void { static uint ctr=0; -if(++ctr < 200) print(disassemble(), "\n"); -else return step(1); +if(++ctr<200) print(disassemble(), "\n"); instruction(); step(1); } @@ -30,6 +29,17 @@ auto CPU::power() -> void { create(CPU::Enter, system.frequency()); ram.allocate(0x3000); r.pc.l.l0 = 0xff1800; + io = {}; +} + +auto CPU::setInterruptHblank(boolean line) -> void { + io.irq.hblank = line; +//if(line) interrupt(0xffff0c); +} + +auto CPU::setInterruptVblank(boolean line) -> void { + io.irq.vblank = line; + if(line) interrupt(0xffff10); } } diff --git a/higan/ngp/cpu/cpu.hpp b/higan/ngp/cpu/cpu.hpp index 4d9e9cc3..7f2ae3fe 100644 --- a/higan/ngp/cpu/cpu.hpp +++ b/higan/ngp/cpu/cpu.hpp @@ -7,12 +7,23 @@ struct CPU : Processor::TLCS900H, Thread { auto step(uint clocks) -> void override; auto power() -> void; + auto setInterruptHblank(boolean line) -> void; + auto setInterruptVblank(boolean line) -> void; + //memory.cpp auto read(uint24 address) -> uint8 override; auto write(uint24 address, uint8 data) -> void override; //serialization.cpp auto serialize(serializer&) -> void; + +private: + struct IO { + struct IRQ { + boolean hblank; + boolean vblank; + } irq; + } io; }; extern CPU cpu; diff --git a/higan/ngp/interface/interface.cpp b/higan/ngp/interface/interface.cpp index c3d5217b..ed4ba344 100644 --- a/higan/ngp/interface/interface.cpp +++ b/higan/ngp/interface/interface.cpp @@ -15,7 +15,6 @@ auto Interface::display() -> Display { display.internalWidth = 160; display.internalHeight = 152; display.aspectCorrection = 1.0; - display.refreshRate = 60.0; return display; } diff --git a/higan/ngp/vpu/vpu.cpp b/higan/ngp/vpu/vpu.cpp index 74a7872c..505cb2f4 100644 --- a/higan/ngp/vpu/vpu.cpp +++ b/higan/ngp/vpu/vpu.cpp @@ -10,8 +10,34 @@ auto VPU::Enter() -> void { } auto VPU::main() -> void { - step(system.frequency() / 60.0); - scheduler.exit(Scheduler::Event::Frame); + cpu.setInterruptHblank(0); + for(uint hclock : range(480)) { + io.hcounter++; + step(1); + } + if(io.vcounter <= 150) { + if(ram[0x0000].bit(6)) cpu.setInterruptHblank(1); + } + for(uint hclock : range(35)) { + io.hcounter++; + step(1); + } + cpu.setInterruptHblank(0); + io.hcounter = 0; + io.vcounter++; + if(io.vcounter == 152) { + ram[0x0010].bit(6) = 1; + if(ram[0x0000].bit(7)) cpu.setInterruptVblank(1); + scheduler.exit(Scheduler::Event::Frame); + } + if(io.vcounter == 198) { + if(ram[0x0000].bit(6)) cpu.setInterruptHblank(1); + } + if(io.vcounter == 199) { + ram[0x0010].bit(6) = 0; + cpu.setInterruptVblank(0); + io.vcounter = 0; + } } auto VPU::step(uint clocks) -> void { @@ -20,12 +46,15 @@ auto VPU::step(uint clocks) -> void { } auto VPU::refresh() -> void { + for(uint address : range(0x4000)) buffer[address] = ram[address]; + for(uint address : range(0x1f00)) buffer[address + 0x4000] = cpu.ram[address + 0x3000 - 0x1f00]; Emulator::video.refresh(buffer, 160 * sizeof(uint32), 160, 152); } auto VPU::power() -> void { create(VPU::Enter, system.frequency()); ram.allocate(0x4000); + io = {}; } } diff --git a/higan/ngp/vpu/vpu.hpp b/higan/ngp/vpu/vpu.hpp index db64a926..f9fa3de5 100644 --- a/higan/ngp/vpu/vpu.hpp +++ b/higan/ngp/vpu/vpu.hpp @@ -16,6 +16,11 @@ struct VPU : Thread { private: uint32 buffer[160 * 152]; + + struct IO { + uint8 vcounter; + uint10 hcounter; + } io; }; extern VPU vpu; diff --git a/higan/pce/interface/interface.cpp b/higan/pce/interface/interface.cpp index 021e44fe..9cf4f42e 100644 --- a/higan/pce/interface/interface.cpp +++ b/higan/pce/interface/interface.cpp @@ -16,7 +16,6 @@ auto Interface::display() -> Display { display.internalWidth = 1120; display.internalHeight = 240; display.aspectCorrection = 8.0 / 7.0; - display.refreshRate = (system.colorburst() * 6.0) / (262.0 * 1365.0); return display; } diff --git a/higan/processor/tlcs900h/disassembler.cpp b/higan/processor/tlcs900h/disassembler.cpp index f685eaa2..c0362887 100644 --- a/higan/processor/tlcs900h/disassembler.cpp +++ b/higan/processor/tlcs900h/disassembler.cpp @@ -98,10 +98,10 @@ auto TLCS900H::disassemble() -> string { #define opSize opSizes[fetch.bits(4,5)] //extract the size from the opcode fetch switch(auto fetch = read8()) { case 0x00: name = "nop"; break; - case 0x01: break; + case 0x01: break; //"normal" (not present on 900/H) case 0x02: name = "push"; lhs.text("sr"); break; case 0x03: name = "pop"; lhs.text("sr"); break; - case 0x04: break; + case 0x04: break; //"max" or "min" (not present on 900/H) case 0x05: name = "halt"; break; case 0x06: name = "ei"; lhs.immediate(3, (uint3)read8()); if(lhs.immediate() == 7) name = "di", lhs.null(); break; case 0x07: name = "reti"; break; diff --git a/higan/processor/tlcs900h/instruction.cpp b/higan/processor/tlcs900h/instruction.cpp index 5db33d61..9face372 100644 --- a/higan/processor/tlcs900h/instruction.cpp +++ b/higan/processor/tlcs900h/instruction.cpp @@ -17,7 +17,7 @@ template auto TLCS900H::toRegister8(uint8 code) const -> Register template auto TLCS900H::toControlRegister(uint8 code) const -> ControlRegister { return {code}; } template auto TLCS900H::toMemory(uint32 address) const -> Memory { return {address}; } template auto TLCS900H::toImmediate(uint32 constant) const -> Immediate { return {constant}; } -template auto TLCS900H::toImmediate3(natural constant) const -> Immediate { return {constant.clip(3).orElse(8)}; } +template auto TLCS900H::toImmediate3(natural constant) const -> Immediate { return {constant.clip(3) ? constant.clip(3) : 8}; } //note: much of this code is split to multiple statements due to C++ not guaranteeing //the order of evaluations of function arguments. fetch() ordering is critical. @@ -27,16 +27,16 @@ auto TLCS900H::instruction() -> void { switch(r.prefix = data) { case 0x00: return instructionNoOperation(); - case 0x01: return (void)Undefined; + case 0x01: return (void)Undefined; //NORMAL (not present on 900/H) case 0x02: return instructionPush(SR); case 0x03: return instructionPop(SR); - case 0x04: return (void)Undefined; + case 0x04: return (void)Undefined; //MAX or MIN (not present on 900/H) case 0x05: return instructionHalt(); case 0x06: return instructionSetInterruptFlipFlop((uint3)fetch()); case 0x07: return instructionReturnInterrupt(); case 0x08: { auto memory = fetchMemory(); - return instructionLoad(memory, fetchImmediate()); } + return instructionLoad(memory, fetchImmediate()); } case 0x09: return instructionPush(fetchImmediate()); case 0x0a: { auto memory = fetchMemory(); diff --git a/higan/processor/tlcs900h/instructions.cpp b/higan/processor/tlcs900h/instructions.cpp index 6c1eae1a..97d1af1f 100644 --- a/higan/processor/tlcs900h/instructions.cpp +++ b/higan/processor/tlcs900h/instructions.cpp @@ -351,7 +351,8 @@ auto TLCS900H::instructionRotateLeftDigit(LHS lhs, RHS rhs) -> void { template auto TLCS900H::instructionRotateLeft(Target target, Amount amount) -> void { auto result = load(target); - for(uint n : range(load(amount).clip(4).orElse(16))) { + auto length = load(amount).clip(4); + for(uint n : range(length ? length : 16)) { uint cf = result.bit(-1); result = result << 1 | CF; CF = cf; @@ -362,7 +363,8 @@ auto TLCS900H::instructionRotateLeft(Target target, Amount amount) -> void { template auto TLCS900H::instructionRotateLeftWithoutCarry(Target target, Amount amount) -> void { auto result = load(target); - for(uint n : range(load(amount).clip(4).orElse(16))) { + auto length = load(amount).clip(4); + for(uint n : range(length ? length : 16)) { CF = result.bit(-1); result = result << 1 | CF; } @@ -389,7 +391,8 @@ auto TLCS900H::instructionRotateRightDigit(LHS lhs, RHS rhs) -> void { template auto TLCS900H::instructionRotateRight(Target target, Amount amount) -> void { auto result = load(target); - for(uint n : range(load(amount).clip(4).orElse(16))) { + auto length = load(amount).clip(4); + for(uint n : range(length ? length : 16)) { uint cf = result.bit(0); result = CF << Target::bits - 1 | result >> 1; CF = cf; @@ -400,7 +403,8 @@ auto TLCS900H::instructionRotateRight(Target target, Amount amount) -> void { template auto TLCS900H::instructionRotateRightWithoutCarry(Target target, Amount amount) -> void { auto result = load(target); - for(uint n : range(load(amount).clip(4).orElse(16))) { + auto length = load(amount).clip(4); + for(uint n : range(length ? length : 16)) { CF = result.bit(0); result = CF << Target::bits - 1 | result >> 1; } @@ -434,7 +438,8 @@ auto TLCS900H::instructionSetRegisterFilePointer(uint2 value) -> void { template auto TLCS900H::instructionShiftLeftArithmetic(Target target, Amount amount) -> void { auto result = load(target); - for(uint n : range(load(amount).clip(4).orElse(16))) { + auto length = load(amount).clip(4); + for(uint n : range(length ? length : 16)) { CF = result.bit(-1); result = result << 1; } @@ -444,7 +449,8 @@ auto TLCS900H::instructionShiftLeftArithmetic(Target target, Amount amount) -> v template auto TLCS900H::instructionShiftLeftLogical(Target target, Amount amount) -> void { auto result = load(target); - for(uint n : range(load(amount).clip(4).orElse(16))) { + auto length = load(amount).clip(4); + for(uint n : range(length ? length : 16)) { CF = result.bit(-1); result = result << 1; } @@ -454,7 +460,8 @@ auto TLCS900H::instructionShiftLeftLogical(Target target, Amount amount) -> void template auto TLCS900H::instructionShiftRightArithmetic(Target target, Amount amount) -> void { auto result = load(target); - for(uint n : range(load(amount).clip(4).orElse(16))) { + auto length = load(amount).clip(4); + for(uint n : range(length ? length : 16)) { CF = result.bit(0); result = result >> 1; result.bit(-1) = result.bit(-2); @@ -465,7 +472,8 @@ auto TLCS900H::instructionShiftRightArithmetic(Target target, Amount amount) -> template auto TLCS900H::instructionShiftRightLogical(Target target, Amount amount) -> void { auto result = load(target); - for(uint n : range(load(amount).clip(4).orElse(16))) { + auto length = load(amount).clip(4); + for(uint n : range(length ? length : 16)) { CF = result.bit(0); result = result >> 1; } diff --git a/higan/processor/tlcs900h/registers.cpp b/higan/processor/tlcs900h/registers.cpp index e69ffc61..92c73f7b 100644 --- a/higan/processor/tlcs900h/registers.cpp +++ b/higan/processor/tlcs900h/registers.cpp @@ -50,8 +50,8 @@ template<> auto TLCS900H::map(Register register) const -> maybe r(0x38, xde[3].w.w0) r(0x3a, xde[3].w.w1) r(0x3c, xhl[3].w.w0) r(0x3e, xhl[3].w.w1) r(0xd0, xwa[p].w.w0) r(0xd2, xwa[p].w.w1) r(0xd4, xbc[p].w.w0) r(0xd6, xbc[p].w.w1) r(0xd8, xde[p].w.w0) r(0xda, xde[p].w.w1) r(0xdc, xhl[p].w.w0) r(0xde, xhl[p].w.w1) - r(0xe0, xwa[p].w.w0) r(0xe2, xwa[p].w.w1) r(0xe4, xbc[p].w.w0) r(0xe6, xbc[p].w.w1) - r(0xe8, xde[p].w.w0) r(0xea, xde[p].w.w1) r(0xec, xhl[p].w.w0) r(0xee, xhl[p].w.w1) + r(0xe0, xwa[a].w.w0) r(0xe2, xwa[a].w.w1) r(0xe4, xbc[a].w.w0) r(0xe6, xbc[a].w.w1) + r(0xe8, xde[a].w.w0) r(0xea, xde[a].w.w1) r(0xec, xhl[a].w.w0) r(0xee, xhl[a].w.w1) r(0xf0, xix .w.w0) r(0xf2, xix .w.w1) r(0xf4, xiy .w.w0) r(0xf6, xiy .w.w1) r(0xf8, xiz .w.w0) r(0xfa, xiz .w.w1) r(0xfc, xsp .w.w0) r(0xfe, xsp .w.w0) #undef r @@ -106,12 +106,13 @@ auto TLCS900H::store(FlagRegister f, uint8 data) -> void { } auto TLCS900H::load(StatusRegister) const -> uint16 { - return load(F) | r.rfp << 8 | 1 << 11 | r.iff << 12 | 1 << 15; + //900/H: d10 = RFP2 (always 0); d11 = MAX (always 1); d15 = SYSM (always 1) + return load(F) | r.rfp << 8 | 0 << 10 | 1 << 11 | r.iff << 12 | 1 << 15; } auto TLCS900H::store(StatusRegister, uint16 data) -> void { - store(F, data); - r.rfp = data.bits( 8, 9); + store(F, data.bits(0,7)); + r.rfp = data.bits(8,9); r.iff = data.bits(12,14); } diff --git a/higan/processor/tlcs900h/tlcs900h.cpp b/higan/processor/tlcs900h/tlcs900h.cpp index e00b2488..17150030 100644 --- a/higan/processor/tlcs900h/tlcs900h.cpp +++ b/higan/processor/tlcs900h/tlcs900h.cpp @@ -33,6 +33,7 @@ auto TLCS900H::interrupt(uint24 address) -> void { auto TLCS900H::power() -> void { r = {}; + r.xsp.l.l0 = 0x100; } } diff --git a/higan/processor/tlcs900h/tlcs900h.hpp b/higan/processor/tlcs900h/tlcs900h.hpp index 12b9b614..a1840992 100644 --- a/higan/processor/tlcs900h/tlcs900h.hpp +++ b/higan/processor/tlcs900h/tlcs900h.hpp @@ -191,14 +191,14 @@ struct TLCS900H { DataRegister dmam[4]; DataRegister intnest; //16-bit - uint1 c, cp; //carry - uint1 n, np; //negative - uint1 v, vp; //overflow or parity - uint1 h, hp; //half carry - uint1 z, zp; //zero - uint1 s, sp; //sign - uint2 rfp; //register file pointer - uint3 iff = 7; //interrupt mask flip-flop + uint1 c, cp; //carry + uint1 n, np; //negative + uint1 v, vp; //overflow or parity + uint1 h, hp; //half carry + uint1 z, zp; //zero + uint1 s, sp; //sign + uint2 rfp; //register file pointer + uint3 iff = 7; //interrupt mask flip-flop uint1 halted; //set if halt instruction executed; waits for an interrupt to resume uint8 prefix; //first opcode byte; needed for [CP|LD][ID](R) instructions diff --git a/higan/sfc/interface/interface.cpp b/higan/sfc/interface/interface.cpp index ee17c0e6..f11824c6 100644 --- a/higan/sfc/interface/interface.cpp +++ b/higan/sfc/interface/interface.cpp @@ -23,8 +23,6 @@ auto Interface::display() -> Display { display.internalWidth = 512; display.internalHeight = 480; display.aspectCorrection = 8.0 / 7.0; - if(Region::NTSC()) display.refreshRate = system.cpuFrequency() / (262.0 * 1364.0); - if(Region::PAL()) display.refreshRate = system.cpuFrequency() / (312.0 * 1364.0); return display; } diff --git a/higan/ws/interface/interface.cpp b/higan/ws/interface/interface.cpp index abaeb33c..9c0378a8 100644 --- a/higan/ws/interface/interface.cpp +++ b/higan/ws/interface/interface.cpp @@ -16,7 +16,6 @@ auto Interface::display() -> Display { display.internalWidth = 224; display.internalHeight = 144; display.aspectCorrection = 1.0; - display.refreshRate = 3'072'000.0 / (159.0 * 256.0); if(settings.rotateLeft) { swap(display.width, display.height); swap(display.internalWidth, display.internalHeight); diff --git a/nall/primitives.hpp b/nall/primitives.hpp index f954e4e0..a1fc8fd4 100644 --- a/nall/primitives.hpp +++ b/nall/primitives.hpp @@ -5,8 +5,9 @@ namespace nall { struct Boolean; - template struct Natural; - template struct Integer; + template struct Natural; + template struct Integer; + template struct Real; } #include diff --git a/nall/primitives/bit-range.hpp b/nall/primitives/bit-range.hpp index 80b1be8d..f0f418ec 100644 --- a/nall/primitives/bit-range.hpp +++ b/nall/primitives/bit-range.hpp @@ -2,15 +2,18 @@ namespace nall { +//warning: so that BitRange can modify the underlying number directly, it must bind a reference. +//as a result, auto value = number.bits() will capture by-reference, rather than by-value. + template struct BitRange { static_assert(Precision >= 1 && Precision <= 64); static inline constexpr auto bits() -> uint { return Precision; } using utype = - typename conditional::type>::type>::type>::type; + conditional_t>>>; static inline constexpr auto mask() -> utype { return ~0ull >> 64 - bits(); } inline BitRange(utype& source, int lo, int hi) : source(source) { @@ -22,13 +25,14 @@ template struct BitRange { } inline auto& operator=(BitRange& source) { return set(source.get()); } + inline operator utype() const { return get(); } + inline auto operator++(int) { auto value = get(); set(value + 1); return value; } inline auto operator--(int) { auto value = get(); set(value - 1); return value; } inline auto& operator++() { return set(get() + 1); } inline auto& operator--() { return set(get() - 1); } - inline operator utype() const { return get(); } template inline auto& operator =(const T& value) { return set( value); } template inline auto& operator *=(const T& value) { return set(get() * value); } template inline auto& operator /=(const T& value) { return set(get() / value); } diff --git a/nall/primitives/boolean.hpp b/nall/primitives/boolean.hpp index f5832d26..78cbee87 100644 --- a/nall/primitives/boolean.hpp +++ b/nall/primitives/boolean.hpp @@ -4,7 +4,7 @@ namespace nall { struct Boolean { static inline constexpr auto bits() -> uint { return 1; } - using type = bool; + using btype = bool; inline Boolean() : data(false) {} template inline Boolean(const T& value) : data(value) {} @@ -23,7 +23,7 @@ struct Boolean { inline auto serialize(serializer& s) { s(data); } private: - type data; + btype data; }; } diff --git a/nall/primitives/integer.hpp b/nall/primitives/integer.hpp index 6b44c68a..c61c9fe1 100644 --- a/nall/primitives/integer.hpp +++ b/nall/primitives/integer.hpp @@ -2,7 +2,7 @@ namespace nall { -template struct Integer { +template struct Integer { static_assert(Precision >= 1 && Precision <= 64); static inline constexpr auto bits() -> uint { return Precision; } using stype = @@ -16,11 +16,10 @@ template struct Integer { static inline constexpr auto sign() -> utype { return 1ull << Precision - 1; } inline Integer() : data(0) {} - template inline Integer(Integer value) { data = mask(value); } + template inline Integer(Integer value) { data = mask(value); } template inline Integer(const T& value) { data = mask(value); } - explicit inline operator bool() const { return data; } - inline operator int64_t() const { return data; } + inline operator stype() const { return data; } inline auto operator++(int) { auto value = *this; data = mask(data + 1); return value; } inline auto operator--(int) { auto value = *this; data = mask(data - 1); return value; } @@ -28,29 +27,17 @@ template struct Integer { inline auto& operator++() { data = mask(data + 1); return *this; } inline auto& operator--() { data = mask(data - 1); return *this; } - inline auto operator!() const { return !data; } - inline auto operator~() const { return Integer<>{mask(~data)}; } - inline auto operator+() const { return Integer<>{+data}; } - inline auto operator-() const { return Integer<>{data == sign() ? data : -data}; } - - #define lhs data - #define rhs value - template inline auto& operator =(const T& value) { lhs = mask( rhs); return *this; } - template inline auto& operator *=(const T& value) { lhs = mask(lhs * rhs); return *this; } - template inline auto& operator /=(const T& value) { lhs = mask(lhs / rhs); return *this; } - template inline auto& operator %=(const T& value) { lhs = mask(lhs % rhs); return *this; } - template inline auto& operator +=(const T& value) { lhs = mask(lhs + rhs); return *this; } - template inline auto& operator -=(const T& value) { lhs = mask(lhs - rhs); return *this; } - template inline auto& operator<<=(const T& value) { lhs = mask(lhs << rhs); return *this; } - template inline auto& operator>>=(const T& value) { lhs = mask(lhs >> rhs); return *this; } - template inline auto& operator &=(const T& value) { lhs = mask(lhs & rhs); return *this; } - template inline auto& operator ^=(const T& value) { lhs = mask(lhs ^ rhs); return *this; } - template inline auto& operator |=(const T& value) { lhs = mask(lhs | rhs); return *this; } - #undef lhs - #undef rhs - - //warning: this does not and cannot short-circuit; value is always evaluated - template inline auto orElse(const T& value) { return Integer<>{data ? data : value}; } + template inline auto& operator =(const T& value) { data = mask( value); return *this; } + template inline auto& operator *=(const T& value) { data = mask(data * value); return *this; } + template inline auto& operator /=(const T& value) { data = mask(data / value); return *this; } + template inline auto& operator %=(const T& value) { data = mask(data % value); return *this; } + template inline auto& operator +=(const T& value) { data = mask(data + value); return *this; } + template inline auto& operator -=(const T& value) { data = mask(data - value); return *this; } + template inline auto& operator<<=(const T& value) { data = mask(data << value); return *this; } + template inline auto& operator>>=(const T& value) { data = mask(data >> value); return *this; } + template inline auto& operator &=(const T& value) { data = mask(data & value); return *this; } + template inline auto& operator ^=(const T& value) { data = mask(data ^ value); return *this; } + template inline auto& operator |=(const T& value) { data = mask(data | value); return *this; } inline auto bits(int lo, int hi) -> BitRange { return {(utype&)data, lo, hi}; } inline auto bit(int index) -> BitRange { return {(utype&)data, index, index}; } @@ -63,16 +50,16 @@ template struct Integer { inline auto slice(int index) const { return Natural<>{bit(index)}; } inline auto slice(int lo, int hi) const { return Natural<>{bit(lo, hi)}; } - inline auto clamp(uint bits) { + inline auto clamp(uint bits) -> stype { const int64_t b = 1ull << (bits - 1); const int64_t m = b - 1; - return Integer<>{data > m ? m : data < -b ? -b : data}; + return data > m ? m : data < -b ? -b : data; } - inline auto clip(uint bits) { + inline auto clip(uint bits) -> stype { const uint64_t b = 1ull << (bits - 1); const uint64_t m = b * 2 - 1; - return Integer<>{(data & m ^ b) - b}; + return (data & m ^ b) - b; } inline auto serialize(serializer& s) { s(data); } @@ -86,19 +73,4 @@ private: stype data; }; -#define lhs (int64_t)l -#define rhs r -template inline auto operator *(Integer l, Integer r) { return Integer{lhs * rhs}; } -template inline auto operator /(Integer l, Integer r) { return Integer{lhs / rhs}; } -template inline auto operator %(Integer l, Integer r) { return Integer{lhs % rhs}; } -template inline auto operator +(Integer l, Integer r) { return Integer{lhs + rhs}; } -template inline auto operator -(Integer l, Integer r) { return Integer{lhs - rhs}; } -template inline auto operator<<(Integer l, Integer r) { return Integer{lhs << rhs}; } -template inline auto operator>>(Integer l, Integer r) { return Integer{lhs >> rhs}; } -template inline auto operator &(Integer l, Integer r) { return Integer{lhs & rhs}; } -template inline auto operator ^(Integer l, Integer r) { return Integer{lhs ^ rhs}; } -template inline auto operator |(Integer l, Integer r) { return Integer{lhs | rhs}; } -#undef lhs -#undef rhs - } diff --git a/nall/primitives/natural.hpp b/nall/primitives/natural.hpp index 1a663abb..b609c5e7 100644 --- a/nall/primitives/natural.hpp +++ b/nall/primitives/natural.hpp @@ -2,7 +2,7 @@ namespace nall { -template struct Natural { +template struct Natural { static_assert(Precision >= 1 && Precision <= 64); static inline constexpr auto bits() -> uint { return Precision; } using utype = @@ -14,11 +14,10 @@ template struct Natural { static inline constexpr auto mask() -> utype { return ~0ull >> 64 - bits(); } inline Natural() : data(0) {} - template inline Natural(Natural value) { data = mask(value); } + template inline Natural(Natural value) { data = mask(value); } template inline Natural(const T& value) { data = mask(value); } - explicit inline operator bool() const { return data; } - inline operator uint64_t() const { return data; } + inline operator utype() const { return data; } inline auto operator++(int) { auto value = *this; data = mask(data + 1); return value; } inline auto operator--(int) { auto value = *this; data = mask(data - 1); return value; } @@ -26,29 +25,17 @@ template struct Natural { inline auto& operator++() { data = mask(data + 1); return *this; } inline auto& operator--() { data = mask(data - 1); return *this; } - inline auto operator!() const { return !data; } - inline auto operator~() const { return Natural<>{mask(~data)}; } - inline auto operator+() const { return Natural<>{+data}; } - inline auto operator-() const { return Natural<>{-(uint64_t)data}; } - - #define lhs data - #define rhs value - template inline auto& operator =(const T& value) { lhs = mask( rhs); return *this; } - template inline auto& operator *=(const T& value) { lhs = mask(lhs * rhs); return *this; } - template inline auto& operator /=(const T& value) { lhs = mask(lhs / rhs); return *this; } - template inline auto& operator %=(const T& value) { lhs = mask(lhs % rhs); return *this; } - template inline auto& operator +=(const T& value) { lhs = mask(lhs + rhs); return *this; } - template inline auto& operator -=(const T& value) { lhs = mask(lhs - rhs); return *this; } - template inline auto& operator<<=(const T& value) { lhs = mask(lhs << rhs); return *this; } - template inline auto& operator>>=(const T& value) { lhs = mask(lhs >> rhs); return *this; } - template inline auto& operator &=(const T& value) { lhs = mask(lhs & rhs); return *this; } - template inline auto& operator ^=(const T& value) { lhs = mask(lhs ^ rhs); return *this; } - template inline auto& operator |=(const T& value) { lhs = mask(lhs | rhs); return *this; } - #undef lhs - #undef rhs - - //warning: this does not and cannot short-circuit; value is always evaluated - template inline auto orElse(const T& value) { return Natural<>{data ? data : value}; } + template inline auto& operator =(const T& value) { data = mask( value); return *this; } + template inline auto& operator *=(const T& value) { data = mask(data * value); return *this; } + template inline auto& operator /=(const T& value) { data = mask(data / value); return *this; } + template inline auto& operator %=(const T& value) { data = mask(data % value); return *this; } + template inline auto& operator +=(const T& value) { data = mask(data + value); return *this; } + template inline auto& operator -=(const T& value) { data = mask(data - value); return *this; } + template inline auto& operator<<=(const T& value) { data = mask(data << value); return *this; } + template inline auto& operator>>=(const T& value) { data = mask(data >> value); return *this; } + template inline auto& operator &=(const T& value) { data = mask(data & value); return *this; } + template inline auto& operator ^=(const T& value) { data = mask(data ^ value); return *this; } + template inline auto& operator |=(const T& value) { data = mask(data | value); return *this; } inline auto bits(int lo, int hi) -> BitRange { return {(utype&)data, lo, hi}; } inline auto bit(int index) -> BitRange { return {(utype&)data, index, index}; } @@ -61,16 +48,16 @@ template struct Natural { inline auto slice(int index) const { return Natural<>{bit(index)}; } inline auto slice(int lo, int hi) const { return Natural<>{bits(lo, hi)}; } - inline auto clamp(uint bits) { + inline auto clamp(uint bits) -> utype { const uint64_t b = 1ull << (bits - 1); const uint64_t m = b * 2 - 1; - return Natural<>{data < m ? data : m}; + return data < m ? data : m; } - inline auto clip(uint bits) { + inline auto clip(uint bits) -> utype { const uint64_t b = 1ull << (bits - 1); const uint64_t m = b * 2 - 1; - return Natural<>{data & m}; + return data & m; } inline auto serialize(serializer& s) { s(data); } @@ -84,19 +71,4 @@ private: utype data; }; -#define lhs (uint64_t)l -#define rhs r -template inline auto operator *(Natural l, Natural r) { return Natural{lhs * rhs}; } -template inline auto operator /(Natural l, Natural r) { return Natural{lhs / rhs}; } -template inline auto operator %(Natural l, Natural r) { return Natural{lhs % rhs}; } -template inline auto operator +(Natural l, Natural r) { return Natural{lhs + rhs}; } -template inline auto operator -(Natural l, Natural r) { return Natural{lhs - rhs}; } -template inline auto operator<<(Natural l, Natural r) { return Natural{lhs << rhs}; } -template inline auto operator>>(Natural l, Natural r) { return Natural{lhs >> rhs}; } -template inline auto operator &(Natural l, Natural r) { return Natural{lhs & rhs}; } -template inline auto operator ^(Natural l, Natural r) { return Natural{lhs ^ rhs}; } -template inline auto operator |(Natural l, Natural r) { return Natural{lhs | rhs}; } -#undef lhs -#undef rhs - } diff --git a/nall/primitives/real.hpp b/nall/primitives/real.hpp index 99870024..1a5fe21e 100644 --- a/nall/primitives/real.hpp +++ b/nall/primitives/real.hpp @@ -2,7 +2,7 @@ namespace nall { -template struct Real { +template struct Real { static_assert(Precision == 32 || Precision == 64); static inline constexpr auto bits() -> uint { return Precision; } using ftype = @@ -14,8 +14,7 @@ template struct Real { template inline Real(Real value) : data((ftype)value) {} template inline Real(const T& value) : data((ftype)value) {} - explicit inline operator bool() const { return data; } - inline operator float64_t() const { return data; } + inline operator ftype() const { return data; } inline auto operator++(int) { auto value = *this; ++data; return value; } inline auto operator--(int) { auto value = *this; --data; return value; } @@ -36,14 +35,4 @@ private: ftype data; }; -#define lhs (float64_t)(typename Real::type)l -#define rhs (typename Real::type)r -template inline auto operator*(Real l, Real r) { return Real<>{lhs * rhs}; } -template inline auto operator/(Real l, Real r) { return Real<>{lhs / rhs}; } -template inline auto operator%(Real l, Real r) { return Real<>{lhs % rhs}; } -template inline auto operator+(Real l, Real r) { return Real<>{lhs + rhs}; } -template inline auto operator-(Real l, Real r) { return Real<>{lhs - rhs}; } -#undef lhs -#undef rhs - }