From b03563426f8705f75ebe51597bc51d0c1da09be3 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Thu, 19 Jan 2017 19:38:57 +1100 Subject: [PATCH] Update to v101r35 release. byuu says: Changelog: - PCE: added 384KB HuCard ROM mirroring mode - PCE: corrected D-pad polling order - PCE: corrected palette color ordering (GRB, not RGB -- yes, seriously) - PCE: corrected SATB DMA -- should write to SATB, not to VRAM - PCE: broke out Background, Sprite VDC settings to separate subclasses - PCE: emulated VDC backgrounds - PCE: emulated VDC sprites - PCE: emulated VDC sprite overflow, collision interrupts - HuC6280: fixed disassembler output for STi instructions - HuC6280: added missing LastCycle check to interrupt() - HuC6280: fixed BIT, CMP, CPX, CPY, TRB, TSB, TST flag testing and result - HuC6280: added extra cycle delays to the block move instructions - HuC6280: fixed ordering for flag set/clear instructions (happens after LastCycle check) - HuC6280: removed extra cycle from immediate instructions - HuC6280: fixed indirectLoad, indirectYStore absolute addressing - HuC6280: fixed BBR, BBS zeropage value testing - HuC6280: fixed stack push/pull direction Neutopia looks okay until the main title screen, then there's some gibberish on the bottom. The game also locks up with some gibberish once you actually start a new game. So, still not playable just yet =( --- higan/emulator/emulator.hpp | 2 +- higan/pce/cartridge/cartridge.cpp | 6 ++ higan/pce/controller/gamepad/gamepad.cpp | 26 ++++--- higan/pce/cpu/cpu.cpp | 9 +-- higan/pce/interface/interface.cpp | 8 +- higan/pce/vdc/background.cpp | 29 +++++++ higan/pce/vdc/dma.cpp | 9 ++- higan/pce/vdc/io.cpp | 20 ++--- higan/pce/vdc/sprite.cpp | 88 +++++++++++++++++++++ higan/pce/vdc/vdc.cpp | 24 +++++- higan/pce/vdc/vdc.hpp | 51 +++++++++--- higan/processor/huc6280/disassembler.cpp | 6 +- higan/processor/huc6280/instruction.cpp | 4 +- higan/processor/huc6280/instructions.cpp | 98 ++++++++++++++---------- higan/processor/huc6280/memory.cpp | 4 +- 15 files changed, 287 insertions(+), 97 deletions(-) create mode 100644 higan/pce/vdc/background.cpp create mode 100644 higan/pce/vdc/sprite.cpp diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 7c241d4a..823cc30c 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -12,7 +12,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "101.34"; + static const string Version = "101.35"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/pce/cartridge/cartridge.cpp b/higan/pce/cartridge/cartridge.cpp index ae14be59..9638cf02 100644 --- a/higan/pce/cartridge/cartridge.cpp +++ b/higan/pce/cartridge/cartridge.cpp @@ -54,6 +54,12 @@ auto Cartridge::write(uint20 addr, uint8 data) -> void { } auto Cartridge::mirror(uint addr, uint size) -> uint { + //384KB games have unusual mirroring (only second ROM repeats) + if(size == 0x60000) { + if(addr <= 0x3ffff) return addr; + return 0x40000 + (addr & 0x1ffff); + } + uint base = 0; uint mask = 1 << 20; while(addr >= size) { diff --git a/higan/pce/controller/gamepad/gamepad.cpp b/higan/pce/controller/gamepad/gamepad.cpp index 898bcc6c..c2fbf782 100644 --- a/higan/pce/controller/gamepad/gamepad.cpp +++ b/higan/pce/controller/gamepad/gamepad.cpp @@ -7,17 +7,23 @@ auto Gamepad::readData() -> uint4 { uint4 data; if(sel) { - data.bit(0) = !platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, Up); - data.bit(1) = !platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, Down); - data.bit(2) = !platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, Right); - data.bit(3) = !platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, Left); - if(data.bits(0,1) == 0) data.bits(0,1) = 3; //disallow up+down at the same time - if(data.bits(2,3) == 0) data.bits(2,3) = 3; //disallow left+right at the same time + bool up = platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, Up); + bool right = platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, Right); + bool down = platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, Down); + bool left = platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, Left); + data.bit(0) = !(up & !down); + data.bit(1) = !(right & !left); + data.bit(2) = !(down & !up); + data.bit(3) = !(left & !right); } else { - data.bit(0) = !platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, One); - data.bit(1) = !platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, Two); - data.bit(2) = !platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, Select); - data.bit(3) = !platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, Run); + bool one = platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, One); + bool two = platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, Two); + bool select = platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, Select); + bool run = platform->inputPoll(ID::Port::Controller, ID::Device::Gamepad, Run); + data.bit(0) = !one; + data.bit(1) = !two; + data.bit(2) = !select; + data.bit(3) = !run; } return data; diff --git a/higan/pce/cpu/cpu.cpp b/higan/pce/cpu/cpu.cpp index ed41bc73..a84e827a 100644 --- a/higan/pce/cpu/cpu.cpp +++ b/higan/pce/cpu/cpu.cpp @@ -12,14 +12,7 @@ auto CPU::Enter() -> void { } auto CPU::main() -> void { - #if 1 - static uint counter = 0; - if(counter++ < 40) { - print(disassemble(r.pc), "\n"); - } - #endif - - if(irq.pending()) interrupt(irq.vector()); + if(irq.pending()) return interrupt(irq.vector()); instruction(); } diff --git a/higan/pce/interface/interface.cpp b/higan/pce/interface/interface.cpp index fff0fcfc..4b4f2a88 100644 --- a/higan/pce/interface/interface.cpp +++ b/higan/pce/interface/interface.cpp @@ -45,13 +45,13 @@ auto Interface::title() -> string { } auto Interface::videoSize() -> VideoSize { - return {512, 484}; + return {256, 240}; } auto Interface::videoSize(uint width, uint height, bool arc) -> VideoSize { auto a = arc ? 8.0 / 7.0 : 1.0; uint w = 256; - uint h = 242; + uint h = 240; uint m = min(width / (w * a), height / h); return {uint(w * a * m), uint(h * m)}; } @@ -66,8 +66,8 @@ auto Interface::videoColors() -> uint32 { auto Interface::videoColor(uint32 color) -> uint64 { uint3 B = color.bits(0,2); - uint3 G = color.bits(3,5); - uint3 R = color.bits(6,8); + uint3 R = color.bits(3,5); + uint3 G = color.bits(6,8); uint64 r = image::normalize(R, 3, 16); uint64 g = image::normalize(G, 3, 16); diff --git a/higan/pce/vdc/background.cpp b/higan/pce/vdc/background.cpp new file mode 100644 index 00000000..9fa364d3 --- /dev/null +++ b/higan/pce/vdc/background.cpp @@ -0,0 +1,29 @@ +auto VDC::Background::scanline(uint y) -> void { +} + +auto VDC::Background::run(uint x, uint y) -> void { + color = nothing; +//if(blank) return; + + uint10 hoffset = x + hscroll; + uint9 voffset = y + vscroll; + + uint16 batAddress = (voffset >> 3) * width + (hoffset >> 3); + uint16 tiledata = vdc.vramRead(batAddress); + uint16 patternAddress = tiledata.bits(0,11) << 4; + patternAddress += (voffset & 7); + uint4 palette = tiledata.bits(12,15); + + uint16 d0 = vdc.vramRead(patternAddress + 0); + uint16 d1 = vdc.vramRead(patternAddress + 8); + + uint3 index = 7 - (hoffset & 7); + uint4 output; + output.bit(0) = d0.bit(0 + index); + output.bit(1) = d0.bit(8 + index); + output.bit(2) = d1.bit(0 + index); + output.bit(3) = d1.bit(8 + index); + + if(output == 0) return; + color = vdc.cram[palette << 4 | output]; +} diff --git a/higan/pce/vdc/dma.cpp b/higan/pce/vdc/dma.cpp index 93cef630..dc49c168 100644 --- a/higan/pce/vdc/dma.cpp +++ b/higan/pce/vdc/dma.cpp @@ -12,10 +12,11 @@ auto VDC::DMA::step(uint clocks) -> void { } if(satbActive) { - uint16 data = vdc.vramRead(satbSource + satbTarget); - vdc.vramWrite(satbTarget++, data); - if(satbTarget == 256) { + uint16 data = vdc.vramRead(satbSource + satbOffset); + vdc.satb[satbOffset] = data; + if(++satbOffset == 256) { satbActive = false; + satbOffset = 0; satbPending = satbRepeat; vdc.irq.raise(VDC::IRQ::Line::TransferSATB); } @@ -30,7 +31,7 @@ auto VDC::DMA::vramStart() -> void { auto VDC::DMA::satbStart() -> void { if(!satbPending) return; satbActive = true; - satbTarget = 0; + satbOffset = 0; } auto VDC::DMA::satbQueue() -> void { diff --git a/higan/pce/vdc/io.cpp b/higan/pce/vdc/io.cpp index ce6b5dbb..52eca957 100644 --- a/higan/pce/vdc/io.cpp +++ b/higan/pce/vdc/io.cpp @@ -99,8 +99,8 @@ auto VDC::write(uint11 addr, uint8 data) -> void { irq.enableLineCoincidence = data.bit(2); irq.enableVblank = data.bit(3); io.externalSync = data.bits(4,5); - io.spriteBlank = data.bit(6); - io.backgroundBlank = data.bit(7); + sprite.blank = data.bit(6); + background.blank = data.bit(7); } else { io.displayOutput = data.bits(0,1); io.dramRefresh = data.bit(2); @@ -120,13 +120,13 @@ auto VDC::write(uint11 addr, uint8 data) -> void { if(io.address == 0x07) { //BXR - io.backgroundHscroll.byte(a0) = data; + background.hscroll.byte(a0) = data; return; } if(io.address == 0x08) { //BYR - io.backgroundVscroll.byte(a0) = data; + background.vscroll.byte(a0) = data; return; } @@ -135,12 +135,12 @@ auto VDC::write(uint11 addr, uint8 data) -> void { if(a0) return; io.vramAccess = data.bits(0,1); io.spriteAccess = data.bits(2,3); - if(data.bits(4,5) == 0) io.backgroundWidth = 32; - if(data.bits(4,5) == 1) io.backgroundWidth = 64; - if(data.bits(4,5) == 2) io.backgroundWidth = 128; - if(data.bits(4,5) == 3) io.backgroundWidth = 128; - if(data.bit(6) == 0) io.backgroundHeight = 32; - if(data.bit(6) == 1) io.backgroundHeight = 64; + if(data.bits(4,5) == 0) background.width = 32; + if(data.bits(4,5) == 1) background.width = 64; + if(data.bits(4,5) == 2) background.width = 128; + if(data.bits(4,5) == 3) background.width = 128; + if(data.bit(6) == 0) background.height = 32; + if(data.bit(6) == 1) background.height = 64; io.cgMode = data.bit(7); return; } diff --git a/higan/pce/vdc/sprite.cpp b/higan/pce/vdc/sprite.cpp new file mode 100644 index 00000000..c87f2eb3 --- /dev/null +++ b/higan/pce/vdc/sprite.cpp @@ -0,0 +1,88 @@ +auto VDC::Sprite::scanline(uint y) -> void { + y += 64; + objects.reset(); + + static const uint width[] = {15, 31}; + static const uint height[] = {15, 31, 63, 63}; + + uint count = 0; + for(uint index : range(64)) { + uint16 d0 = vdc.satb[index << 2 | 0]; + uint16 d1 = vdc.satb[index << 2 | 1]; + uint16 d2 = vdc.satb[index << 2 | 2]; + uint16 d3 = vdc.satb[index << 2 | 3]; + + Object object; + object.y = d0.bits(0,9); + object.height = height[d3.bits(12,13)]; + if(y < object.y) continue; + if(y > object.y + object.height) continue; + + object.x = d1.bits(0,9); + object.mode = d2.bit(0); + object.pattern = d2.bits(1,10); + object.palette = d3.bits(0,3); + object.priority = d3.bit(7); + object.width = width[d3.bit(8)]; + object.hflip = d3.bit(11); + object.vflip = d3.bit(15); + objects.append(object); + + count += 1 + d3.bit(8); //32-width sprites consume two slots + if(count >= 16) { + vdc.irq.raise(VDC::IRQ::Line::Overflow); + break; + } + } +} + +auto VDC::Sprite::run(uint x, uint y) -> void { + x += 32; + y += 64; + color = nothing; + + bool zero = 0; + uint index = 0; + for(auto& object : objects) { + uint id = index++; + if(x < object.x) continue; + if(x > object.x + object.width) continue; + + uint10 hoffset = x - object.x; + uint10 voffset = y - object.y; + if(object.hflip) hoffset ^= object.width; + if(object.vflip) voffset ^= object.height; + + uint10 pattern = object.pattern; + if(object.width == 31) pattern.bit(0) = 0; + if(object.height == 31) pattern.bit(1) = 0; + if(object.height == 63) pattern.bits(1,2) = 0; + + uint16 patternAddress = pattern << 6; + patternAddress += (voffset >> 4) << (6 + (object.height == 31)); + patternAddress += (hoffset >> 4) << 6; + patternAddress += (voffset & 15); + + uint16 d0 = vdc.vramRead(patternAddress + 0); + uint16 d1 = vdc.vramRead(patternAddress + 16); + uint16 d2 = vdc.vramRead(patternAddress + 32); + uint16 d3 = vdc.vramRead(patternAddress + 48); + + uint4 index = 15 - (hoffset & 15); + uint4 output; + output.bit(0) = d0.bit(index); + output.bit(1) = d1.bit(index); + output.bit(2) = d2.bit(index); + output.bit(3) = d3.bit(index); + if(output == 0) continue; + + if(color) { + if(zero) vdc.irq.raise(VDC::IRQ::Line::Collision); + break; + } + + color = vdc.cram[1 << 8 | object.palette << 4 | output]; + priority = object.priority; + if(id == 0) zero = 1; + } +} diff --git a/higan/pce/vdc/vdc.cpp b/higan/pce/vdc/vdc.cpp index 8c341872..fd8a8375 100644 --- a/higan/pce/vdc/vdc.cpp +++ b/higan/pce/vdc/vdc.cpp @@ -6,6 +6,8 @@ VDC vdc; #include "io.cpp" #include "irq.cpp" #include "dma.cpp" +#include "background.cpp" +#include "sprite.cpp" auto VDC::Enter() -> void { while(true) scheduler.synchronize(), vdc.main(); @@ -13,7 +15,25 @@ auto VDC::Enter() -> void { auto VDC::main() -> void { //1365 cycles/scanline + uint y = state.y; + auto output = buffer + y * 512; + background.scanline(y); + sprite.scanline(y); for(uint x : range(256)) { + if(y < 240) { + background.run(x, y); + sprite.run(x, y); + + if(sprite.color && sprite.priority) { + *output++ = sprite.color(); + } else if(background.color) { + *output++ = background.color(); + } else if(sprite.color) { + *output++ = sprite.color(); + } else { + *output++ = cram[0]; + } + } step(4); } step(341); @@ -41,7 +61,7 @@ auto VDC::step(uint clocks) -> void { } auto VDC::refresh() -> void { - Emulator::video.refresh(buffer, 512 * sizeof(uint32), 512, 484); + Emulator::video.refresh(buffer, 512 * sizeof(uint32), 256, 240); } auto VDC::power() -> void { @@ -55,6 +75,8 @@ auto VDC::power() -> void { memory::fill(&irq, sizeof(IRQ)); memory::fill(&dma, sizeof(DMA)); memory::fill(&io, sizeof(IO)); + memory::fill(&background, sizeof(Background)); + memory::fill(&sprite, sizeof(Sprite)); } } diff --git a/higan/pce/vdc/vdc.hpp b/higan/pce/vdc/vdc.hpp index 8d699e7e..ee9709a8 100644 --- a/higan/pce/vdc/vdc.hpp +++ b/higan/pce/vdc/vdc.hpp @@ -77,9 +77,48 @@ private: bool vramActive; bool satbActive; bool satbPending; - uint16 satbTarget; + uint16 satbOffset; } dma; + struct Background { + //background.cpp + auto scanline(uint y) -> void; + auto run(uint x, uint y) -> void; + + bool blank; + uint10 hscroll; + uint9 vscroll; + uint8 width; + uint8 height; + + maybe color; + } background; + + struct Sprite { + //sprite.cpp + auto scanline(uint y) -> void; + auto run(uint x, uint y) -> void; + + bool blank; + + struct Object { + uint10 y; + uint10 x; + bool mode; + uint10 pattern; + uint4 palette; + bool priority; + uint width; + bool hflip; + uint height; + bool vflip; + }; + array objects; + + maybe color; + bool priority; + } sprite; + struct IO { uint5 address; @@ -98,8 +137,6 @@ private: //$05 CR (W) uint2 externalSync; - bool spriteBlank; - bool backgroundBlank; uint2 displayOutput; bool dramRefresh; uint vramAddressIncrement; @@ -107,17 +144,9 @@ private: //$06 RCR uint10 lineCoincidence; - //$07 BXR - uint10 backgroundHscroll; - - //$08 BYR - uint9 backgroundVscroll; - //$09 MWR uint2 vramAccess; uint2 spriteAccess; - uint backgroundWidth; - uint backgroundHeight; bool cgMode; //$0a HSR diff --git a/higan/processor/huc6280/disassembler.cpp b/higan/processor/huc6280/disassembler.cpp index 556438ca..1a4cf369 100644 --- a/higan/processor/huc6280/disassembler.cpp +++ b/higan/processor/huc6280/disassembler.cpp @@ -75,7 +75,7 @@ auto HuC6280::disassemble(uint16 pc_) -> string { op(0x00, "brk") op(0x01, "ora", indirectX()) op(0x02, "sxy") - op(0x03, "st0") + op(0x03, "st0", immediate()) op(0x04, "tsb", zeropage()) op(0x05, "ora", zeropage()) op(0x06, "asl", zeropage()) @@ -91,7 +91,7 @@ U op(0x0b, "nop", "$0b") op(0x10, "bpl", relative()) op(0x11, "ora", indirectY()) op(0x12, "ora", indirect()) - op(0x13, "st1") + op(0x13, "st1", immediate()) op(0x14, "trb", zeropage()) op(0x15, "ora", zeropageX()) op(0x16, "asl", zeropageX()) @@ -107,7 +107,7 @@ U op(0x1b, "nop", "$1b") op(0x20, "jsr", absolute()) op(0x21, "and", indirectX()) op(0x22, "sax") - op(0x23, "st2") + op(0x23, "st2", immediate()) op(0x24, "bit", zeropage()) op(0x25, "and", zeropage()) op(0x26, "rol", zeropage()) diff --git a/higan/processor/huc6280/instruction.cpp b/higan/processor/huc6280/instruction.cpp index 07d155a7..0d95b63e 100644 --- a/higan/processor/huc6280/instruction.cpp +++ b/higan/processor/huc6280/instruction.cpp @@ -7,10 +7,10 @@ auto HuC6280::interrupt(uint16 vector) -> void { push(PC >> 8); push(PC >> 0); push(P); - PC.byte(0) = load(vector + 0); - PC.byte(1) = load(vector + 1); D = 0; I = 1; + PC.byte(0) = load(vector + 0); +L PC.byte(1) = load(vector + 1); } auto HuC6280::instruction() -> void { diff --git a/higan/processor/huc6280/instructions.cpp b/higan/processor/huc6280/instructions.cpp index b3dea4f6..04bbbc69 100644 --- a/higan/processor/huc6280/instructions.cpp +++ b/higan/processor/huc6280/instructions.cpp @@ -23,34 +23,34 @@ auto HuC6280::ASL(uint8 i) -> uint8 { } auto HuC6280::BIT(uint8 i) -> uint8 { - Z = i == 0; + Z = (A & i) == 0; V = i.bit(6); N = i.bit(7); - return i; + return A; } auto HuC6280::CMP(uint8 i) -> uint8 { uint9 o = A - i; - C = o.bit(8); + C = !o.bit(8); Z = uint8(o) == 0; N = o.bit(7); - return i; + return A; } auto HuC6280::CPX(uint8 i) -> uint8 { uint9 o = X - i; - C = o.bit(8); + C = !o.bit(8); Z = uint8(o) == 0; N = o.bit(7); - return i; + return X; } auto HuC6280::CPY(uint8 i) -> uint8 { uint9 o = Y - i; - C = o.bit(8); + C = !o.bit(8); Z = uint8(o) == 0; N = o.bit(7); - return i; + return Y; } auto HuC6280::DEC(uint8 i) -> uint8 { @@ -114,23 +114,26 @@ auto HuC6280::ROR(uint8 i) -> uint8 { } auto HuC6280::SBC(uint8 i) -> uint8 { - return ADC(~i); + uint9 o = A - i - !C; + C = !o.bit(8); + Z = uint8(o) == 0; + V = (A ^ i) & (A ^ o) & 0x80; + N = o.bit(7); + return o; } auto HuC6280::TRB(uint8 i) -> uint8 { - uint8 o = i & A; - Z = o == 0; - V = o.bit(6); - N = o.bit(7); - return i & ~A; + Z = (A & i) == 0; + V = i.bit(6); + N = i.bit(7); + return ~A & i; } auto HuC6280::TSB(uint8 i) -> uint8 { - uint8 o = i & A; - Z = o == 0; - V = o.bit(6); - N = o.bit(7); - return i | A; + Z = (A & i) == 0; + V = i.bit(6); + N = i.bit(7); + return A | i; } // @@ -187,15 +190,29 @@ L store(absolute + index, data); auto HuC6280::instruction_blockmove(bp alu) -> void { uint16 source = operand(); source |= operand() << 8; + io(); + io(); + io(); uint16 target = operand(); target |= operand() << 8; + io(); + io(); + io(); uint16 length = operand(); length |= operand() << 8; + io(); + io(); + io(); do { auto data = load(source); store(target, data); ALU(source, target); + io(); + io(); + io(); + io(); } while(--length); + io(); L io(); } @@ -211,23 +228,22 @@ auto HuC6280::instruction_branch(bool take) -> void { } auto HuC6280::instruction_clear(uint8& data) -> void { - data = 0; L io(); + data = 0; } auto HuC6280::instruction_clear(bool& flag) -> void { - flag = 0; L io(); + flag = 0; } auto HuC6280::instruction_immediate(fp alu, uint8& data) -> void { - data = ALU(operand()); -L io(); +L data = ALU(operand()); } auto HuC6280::instruction_implied(fp alu, uint8& data) -> void { - data = ALU(data); L io(); + data = ALU(data); } auto HuC6280::instruction_indirectLoad(fp alu, uint8& data, uint8 index) -> void { @@ -242,7 +258,7 @@ L data = ALU(load(absolute)); auto HuC6280::instruction_indirectStore(uint8 data, uint8 index) -> void { auto zeropage = operand(); io(); - auto absolute = load(0x2000 + zeropage + index); + uint16 absolute = load(0x2000 + zeropage + index); absolute |= load(0x2001 + zeropage + index) << 8; L store(absolute, data); } @@ -259,7 +275,7 @@ L data = ALU(load(absolute + Y)); auto HuC6280::instruction_indirectYStore(uint8 data) -> void { auto zeropage = operand(); io(); - auto absolute = load(0x2000 + zeropage); + uint16 absolute = load(0x2000 + zeropage); absolute |= load(0x2001 + zeropage) << 8; L store(absolute + Y, data); } @@ -289,19 +305,19 @@ L push(data); } auto HuC6280::instruction_set(bool& flag) -> void { - flag = 1; L io(); + flag = 1; } auto HuC6280::instruction_swap(uint8& lhs, uint8& rhs) -> void { - swap(lhs, rhs); io(); L io(); + swap(lhs, rhs); } auto HuC6280::instruction_transfer(uint8& source, uint8& target) -> void { - target = source; L io(); + target = source; Z = target == 0; N = target.bit(7); } @@ -333,8 +349,8 @@ auto HuC6280::instruction_BBR(uint3 index) -> void { auto displacement = operand(); io(); io(); -L io(); - if(zeropage.bit(index) == 0) { +L auto data = load(0x2000 + zeropage); + if(data.bit(index) == 0) { PC += (int8)displacement; } } @@ -344,8 +360,8 @@ auto HuC6280::instruction_BBS(uint3 index) -> void { auto displacement = operand(); io(); io(); -L io(); - if(zeropage.bit(index) == 1) { +L auto data = load(0x2000 + zeropage); + if(data.bit(index) == 1) { PC += (int8)displacement; } } @@ -357,8 +373,8 @@ auto HuC6280::instruction_BRK() -> void { push(PC >> 0); uint8 p = P; push(p | 0x10); //B flag set on push - I = 1; D = 0; + I = 1; PC.byte(0) = load(0xfff6); L PC.byte(1) = load(0xfff7); } @@ -375,13 +391,13 @@ L push((PC - 1) >> 0); } auto HuC6280::instruction_CSL() -> void { - r.cs = 4; L io(); + r.cs = 4; } auto HuC6280::instruction_CSH() -> void { - r.cs = 1; L io(); + r.cs = 1; } auto HuC6280::instruction_JMP_absolute() -> void { @@ -486,8 +502,8 @@ auto HuC6280::instruction_TST_absolute(uint8 index) -> void { io(); io(); io(); -L uint8 data = load(absolute + index) & mask; - Z = data == 0; +L uint8 data = load(absolute + index); + Z = (data & mask) == 0; V = data.bit(6); N = data.bit(7); } @@ -498,13 +514,13 @@ auto HuC6280::instruction_TST_zeropage(uint8 index) -> void { io(); io(); io(); -L uint8 data = load(0x2000 + zeropage + index) & mask; - Z = data == 0; +L uint8 data = load(0x2000 + zeropage + index); + Z = (data & mask) == 0; V = data.bit(6); N = data.bit(7); } auto HuC6280::instruction_TXS() -> void { - S = X; L io(); + S = X; } diff --git a/higan/processor/huc6280/memory.cpp b/higan/processor/huc6280/memory.cpp index d70f8bb4..126c0226 100644 --- a/higan/processor/huc6280/memory.cpp +++ b/higan/processor/huc6280/memory.cpp @@ -31,9 +31,9 @@ auto HuC6280::operand() -> uint8 { // auto HuC6280::push(uint8 data) -> void { - store(0x2100 + ++S, data); + store(0x2100 + (S--), data); } auto HuC6280::pull() -> uint8 { - return load(0x2100 + S--); + return load(0x2100 + (++S)); }