mirror of https://github.com/bsnes-emu/bsnes.git
Update to v103r02 release.
byuu says: Changelog: - fc/apu: improved phase duty cycle emulation (mode 3 is 25% phase inverted; counter decrements) - md/apu: power/reset do not cancel 68K bus requests - md/apu: 68K is not granted bus access on Z80 power/reset - md/controller: replaced System::Peripherals with ControllerPort concept - md/controller: CTRL port is now read-write, maintains value across controller changes (and soon, soft resets) - md/psg: PSG sampling rate unintentionally modified¹ - processor/spc700: improve cycle timing of (indirect),y instructions [Overload] - processor/spc700: idle() cycles actually read from the program counter; much like the 6502 [Overload] - some of the idle() cycles should read from other addresses; this still needs to be supported - processor/spc700: various cleanups to instruction function naming - processor/z80: prefix state (HL→IX,IY override) can now be serialized - icarus: fix install rule for certain platforms (it wasn't buggy on FreeBSD, but was on Linux?) ¹: the clock speed of the PSG is oscillator/15. But I was setting the sampling rate to oscillator/15/16, which was around 223KHz. I am not sure whether the PSG should be outputting at 3MHz or 223KHz. Amazingly ... I don't really hear a difference either way `o_O` I didn't actually mean to make this change; I just noticed it after comparing the diff between r01 and r02. If this turns out to be wrong, set stream = Emulator::audio.createStream(1, frequency() / 16.0); in md/psg.cpp to revert this change.
This commit is contained in:
parent
ecc7e899e0
commit
3517d5c4a4
|
@ -12,7 +12,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "103.01";
|
||||
static const string Version = "103.02";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
|
|
@ -8,13 +8,18 @@ auto APU::Pulse::clock() -> uint8 {
|
|||
if(!sweep.checkPeriod()) return 0;
|
||||
if(lengthCounter == 0) return 0;
|
||||
|
||||
static const uint dutyTable[] = {1, 2, 4, 6};
|
||||
uint8 result = (dutyCounter < dutyTable[duty]) ? envelope.volume() : 0;
|
||||
static const uint dutyTable[4][8] = {
|
||||
{0, 1, 0, 0, 0, 0, 0, 0}, //12.5%
|
||||
{0, 1, 1, 0, 0, 0, 0, 0}, //25.0%
|
||||
{0, 1, 1, 1, 1, 0, 0, 0}, //50.0%
|
||||
{1, 0, 0, 1, 1, 1, 1, 1}, //25.0% (inverted)
|
||||
};
|
||||
uint8 result = dutyTable[duty][dutyCounter] ? envelope.volume() : 0;
|
||||
if(sweep.pulsePeriod < 0x008) result = 0;
|
||||
|
||||
if(--periodCounter == 0) {
|
||||
periodCounter = (sweep.pulsePeriod + 1) * 2;
|
||||
dutyCounter++;
|
||||
dutyCounter--;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -54,14 +54,16 @@ auto APU::enable(bool value) -> void {
|
|||
auto APU::power() -> void {
|
||||
Z80::bus = &busAPU;
|
||||
Z80::power();
|
||||
create(APU::Enter, system.colorburst());
|
||||
memory::fill(&state, sizeof(State));
|
||||
bus->grant(false);
|
||||
create(APU::Enter, system.frequency() / 15.0);
|
||||
state = {};
|
||||
}
|
||||
|
||||
auto APU::reset() -> void {
|
||||
create(APU::Enter, system.colorburst());
|
||||
memory::fill(&r, sizeof(Registers));
|
||||
memory::fill(&state, sizeof(State));
|
||||
Z80::power();
|
||||
bus->grant(false);
|
||||
create(APU::Enter, system.frequency() / 15.0);
|
||||
state = {};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -73,13 +73,13 @@ auto BusCPU::readIO(uint24 addr) -> uint16 {
|
|||
| 0 << 0 //0 = Model 1; 1 = Model 2+
|
||||
);
|
||||
|
||||
case 0xa10002: return peripherals.controllerPort1->readData();
|
||||
case 0xa10004: return peripherals.controllerPort2->readData();
|
||||
case 0xa10006: return peripherals.extensionPort->readData();
|
||||
case 0xa10002: return controllerPort1.readData();
|
||||
case 0xa10004: return controllerPort2.readData();
|
||||
case 0xa10006: return extensionPort.readData();
|
||||
|
||||
case 0xa10008: return peripherals.controllerPort1->readControl();
|
||||
case 0xa1000a: return peripherals.controllerPort2->readControl();
|
||||
case 0xa1000c: return peripherals.extensionPort->readControl();
|
||||
case 0xa10008: return controllerPort1.readControl();
|
||||
case 0xa1000a: return controllerPort2.readControl();
|
||||
case 0xa1000c: return extensionPort.readControl();
|
||||
|
||||
case 0xa11100: return !busAPU.granted();
|
||||
}
|
||||
|
@ -89,13 +89,13 @@ auto BusCPU::readIO(uint24 addr) -> uint16 {
|
|||
|
||||
auto BusCPU::writeIO(uint24 addr, uint16 data) -> void {
|
||||
switch(addr & ~1) {
|
||||
case 0xa10002: return peripherals.controllerPort1->writeData(data);
|
||||
case 0xa10004: return peripherals.controllerPort2->writeData(data);
|
||||
case 0xa10006: return peripherals.extensionPort->writeData(data);
|
||||
case 0xa10002: return controllerPort1.writeData(data);
|
||||
case 0xa10004: return controllerPort2.writeData(data);
|
||||
case 0xa10006: return extensionPort.writeData(data);
|
||||
|
||||
case 0xa10008: return peripherals.controllerPort1->writeControl(data);
|
||||
case 0xa1000a: return peripherals.controllerPort2->writeControl(data);
|
||||
case 0xa1000c: return peripherals.extensionPort->writeControl(data);
|
||||
case 0xa10008: return controllerPort1.writeControl(data);
|
||||
case 0xa1000a: return controllerPort2.writeControl(data);
|
||||
case 0xa1000c: return extensionPort.writeControl(data);
|
||||
|
||||
case 0xa11100: return busAPU.request(data.bit(0));
|
||||
case 0xa11200: return apu.enable(data.bit(0));
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
namespace MegaDrive {
|
||||
|
||||
ControllerPort controllerPort1;
|
||||
ControllerPort controllerPort2;
|
||||
ControllerPort extensionPort;
|
||||
#include "gamepad/gamepad.cpp"
|
||||
|
||||
Controller::Controller(uint port) : port(port) {
|
||||
|
@ -15,9 +18,9 @@ Controller::~Controller() {
|
|||
auto Controller::Enter() -> void {
|
||||
while(true) {
|
||||
scheduler.synchronize();
|
||||
if(peripherals.controllerPort1->active()) peripherals.controllerPort1->main();
|
||||
if(peripherals.controllerPort2->active()) peripherals.controllerPort2->main();
|
||||
if(peripherals.extensionPort->active()) peripherals.extensionPort->main();
|
||||
if(controllerPort1.controller->active()) controllerPort1.controller->main();
|
||||
if(controllerPort2.controller->active()) controllerPort2.controller->main();
|
||||
if(extensionPort.controller->active()) extensionPort.controller->main();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,4 +29,51 @@ auto Controller::main() -> void {
|
|||
synchronize(cpu);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
auto ControllerPort::connect(uint device) -> void {
|
||||
if(!system.loaded()) return;
|
||||
delete controller;
|
||||
|
||||
switch(device) { default:
|
||||
case ID::Device::None: controller = new Controller(port); break;
|
||||
case ID::Device::Gamepad: controller = new Gamepad(port); break;
|
||||
}
|
||||
|
||||
cpu.peripherals.reset();
|
||||
cpu.peripherals.append(controllerPort1.controller);
|
||||
cpu.peripherals.append(controllerPort2.controller);
|
||||
cpu.peripherals.append(extensionPort.controller);
|
||||
}
|
||||
|
||||
auto ControllerPort::readData() -> uint8 {
|
||||
return controller->readData();
|
||||
}
|
||||
|
||||
auto ControllerPort::writeData(uint8 data) -> void {
|
||||
return controller->writeData(data);
|
||||
}
|
||||
|
||||
auto ControllerPort::readControl() -> uint8 {
|
||||
return control;
|
||||
}
|
||||
|
||||
auto ControllerPort::writeControl(uint8 data) -> void {
|
||||
control = data;
|
||||
}
|
||||
|
||||
auto ControllerPort::power(uint port) -> void {
|
||||
this->port = port;
|
||||
control = 0x00;
|
||||
}
|
||||
|
||||
auto ControllerPort::unload() -> void {
|
||||
delete controller;
|
||||
controller = nullptr;
|
||||
}
|
||||
|
||||
auto ControllerPort::serialize(serializer& s) -> void {
|
||||
s.integer(control);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,10 +8,29 @@ struct Controller : Thread {
|
|||
virtual auto readData() -> uint8 { return 0xff; }
|
||||
virtual auto writeData(uint8 data) -> void {}
|
||||
|
||||
virtual auto readControl() -> uint8 { return 0x00; }
|
||||
virtual auto writeControl(uint8 data) -> void {}
|
||||
|
||||
const uint port;
|
||||
};
|
||||
|
||||
struct ControllerPort {
|
||||
auto connect(uint device) -> void;
|
||||
|
||||
auto readData() -> uint8;
|
||||
auto writeData(uint8 data) -> void;
|
||||
|
||||
auto readControl() -> uint8;
|
||||
auto writeControl(uint8 data) -> void;
|
||||
|
||||
auto power(uint port) -> void;
|
||||
auto unload() -> void;
|
||||
auto serialize(serializer&) -> void;
|
||||
|
||||
uint port;
|
||||
uint8 control;
|
||||
Controller* controller = nullptr;
|
||||
};
|
||||
|
||||
extern ControllerPort controllerPort1;
|
||||
extern ControllerPort controllerPort2;
|
||||
extern ControllerPort extensionPort;
|
||||
|
||||
#include "gamepad/gamepad.hpp"
|
||||
|
|
|
@ -68,9 +68,9 @@ auto CPU::lower(Interrupt interrupt) -> void {
|
|||
auto CPU::power() -> void {
|
||||
M68K::bus = &busCPU;
|
||||
M68K::power();
|
||||
create(CPU::Enter, system.colorburst() * 15.0 / 7.0);
|
||||
create(CPU::Enter, system.frequency() / 7.0);
|
||||
|
||||
memory::fill(&state, sizeof(State));
|
||||
state = {};
|
||||
state.interruptPending.bit((uint)Interrupt::Reset) = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,9 @@ auto Interface::unload() -> void {
|
|||
}
|
||||
|
||||
auto Interface::connect(uint port, uint device) -> void {
|
||||
peripherals.connect(port, device);
|
||||
if(port == ID::Port::Controller1) controllerPort1.connect(settings.controllerPort1 = device);
|
||||
if(port == ID::Port::Controller2) controllerPort2.connect(settings.controllerPort2 = device);
|
||||
if(port == ID::Port::Extension) extensionPort.connect(settings.extensionPort = device);
|
||||
}
|
||||
|
||||
auto Interface::power() -> void {
|
||||
|
|
|
@ -35,7 +35,7 @@ auto PSG::step(uint clocks) -> void {
|
|||
}
|
||||
|
||||
auto PSG::power() -> void {
|
||||
create(PSG::Enter, system.colorburst() / 16.0);
|
||||
create(PSG::Enter, system.frequency() / 15.0);
|
||||
stream = Emulator::audio.createStream(1, frequency());
|
||||
stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 20.0);
|
||||
stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::LowPass, 2840.0);
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
Peripherals peripherals;
|
||||
|
||||
auto Peripherals::unload() -> void {
|
||||
delete controllerPort1;
|
||||
delete controllerPort2;
|
||||
delete extensionPort;
|
||||
controllerPort1 = nullptr;
|
||||
controllerPort2 = nullptr;
|
||||
extensionPort = nullptr;
|
||||
}
|
||||
|
||||
auto Peripherals::reset() -> void {
|
||||
connect(ID::Port::Controller1, settings.controllerPort1);
|
||||
connect(ID::Port::Controller2, settings.controllerPort2);
|
||||
connect(ID::Port::Extension, settings.extensionPort);
|
||||
}
|
||||
|
||||
auto Peripherals::connect(uint port, uint device) -> void {
|
||||
if(port == ID::Port::Controller1) {
|
||||
settings.controllerPort1 = device;
|
||||
if(!system.loaded()) return;
|
||||
|
||||
delete controllerPort1;
|
||||
switch(device) { default:
|
||||
case ID::Device::None: controllerPort1 = new Controller(0); break;
|
||||
case ID::Device::Gamepad: controllerPort1 = new Gamepad(0); break;
|
||||
}
|
||||
}
|
||||
|
||||
if(port == ID::Port::Controller2) {
|
||||
settings.controllerPort2 = device;
|
||||
if(!system.loaded()) return;
|
||||
|
||||
delete controllerPort2;
|
||||
switch(device) { default:
|
||||
case ID::Device::None: controllerPort2 = new Controller(1); break;
|
||||
case ID::Device::Gamepad: controllerPort2 = new Gamepad(1); break;
|
||||
}
|
||||
}
|
||||
|
||||
if(port == ID::Port::Extension) {
|
||||
settings.extensionPort = device;
|
||||
if(!system.loaded()) return;
|
||||
|
||||
delete extensionPort;
|
||||
switch(device) { default:
|
||||
case ID::Device::None: extensionPort = new Controller(2); break;
|
||||
}
|
||||
}
|
||||
|
||||
cpu.peripherals.reset();
|
||||
cpu.peripherals.append(controllerPort1);
|
||||
cpu.peripherals.append(controllerPort2);
|
||||
cpu.peripherals.append(extensionPort);
|
||||
}
|
|
@ -63,6 +63,9 @@ auto System::serializeAll(serializer& s) -> void {
|
|||
vdp.serialize(s);
|
||||
psg.serialize(s);
|
||||
ym2612.serialize(s);
|
||||
controllerPort1.serialize(s);
|
||||
controllerPort2.serialize(s);
|
||||
extensionPort.serialize(s);
|
||||
}
|
||||
|
||||
auto System::serialize(serializer& s) -> void {
|
||||
|
|
|
@ -5,7 +5,6 @@ namespace MegaDrive {
|
|||
System system;
|
||||
Scheduler scheduler;
|
||||
Cheat cheat;
|
||||
#include "peripherals.cpp"
|
||||
#include "serialization.cpp"
|
||||
|
||||
auto System::run() -> void {
|
||||
|
@ -32,15 +31,15 @@ auto System::load(Emulator::Interface* interface, maybe<Region> region) -> bool
|
|||
|
||||
if(cartridge.region() == "NTSC-J") {
|
||||
information.region = Region::NTSCJ;
|
||||
information.colorburst = Emulator::Constants::Colorburst::NTSC;
|
||||
information.frequency = Emulator::Constants::Colorburst::NTSC * 15.0;
|
||||
}
|
||||
if(cartridge.region() == "NTSC-U") {
|
||||
information.region = Region::NTSCU;
|
||||
information.colorburst = Emulator::Constants::Colorburst::NTSC;
|
||||
information.frequency = Emulator::Constants::Colorburst::NTSC * 15.0;
|
||||
}
|
||||
if(cartridge.region() == "PAL") {
|
||||
information.region = Region::PAL;
|
||||
information.colorburst = Emulator::Constants::Colorburst::PAL * 4.0 / 5.0;
|
||||
information.frequency = Emulator::Constants::Colorburst::PAL * 12.0;
|
||||
}
|
||||
|
||||
serializeInit();
|
||||
|
@ -53,7 +52,9 @@ auto System::save() -> void {
|
|||
}
|
||||
|
||||
auto System::unload() -> void {
|
||||
peripherals.unload();
|
||||
controllerPort1.unload();
|
||||
controllerPort2.unload();
|
||||
extensionPort.unload();
|
||||
cartridge.unload();
|
||||
}
|
||||
|
||||
|
@ -74,7 +75,13 @@ auto System::power() -> void {
|
|||
ym2612.power();
|
||||
scheduler.primary(cpu);
|
||||
|
||||
peripherals.reset();
|
||||
controllerPort1.power(ID::Port::Controller1);
|
||||
controllerPort2.power(ID::Port::Controller2);
|
||||
extensionPort.power(ID::Port::Extension);
|
||||
|
||||
controllerPort1.connect(settings.controllerPort1);
|
||||
controllerPort2.connect(settings.controllerPort2);
|
||||
extensionPort.connect(settings.extensionPort);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ struct System {
|
|||
|
||||
auto loaded() const -> bool { return information.loaded; }
|
||||
auto region() const -> Region { return information.region; }
|
||||
auto colorburst() const -> double { return information.colorburst; }
|
||||
auto frequency() const -> double { return information.frequency; }
|
||||
|
||||
auto run() -> void;
|
||||
auto runToSave() -> void;
|
||||
|
@ -31,23 +31,12 @@ private:
|
|||
string manifest;
|
||||
bool loaded = false;
|
||||
Region region = Region::NTSCJ;
|
||||
double colorburst = Emulator::Constants::Colorburst::NTSC;
|
||||
double frequency = Emulator::Constants::Colorburst::NTSC * 15.0;
|
||||
uint serializeSize = 0;
|
||||
} information;
|
||||
};
|
||||
|
||||
struct Peripherals {
|
||||
auto unload() -> void;
|
||||
auto reset() -> void;
|
||||
auto connect(uint port, uint device) -> void;
|
||||
|
||||
Controller* controllerPort1 = nullptr;
|
||||
Controller* controllerPort2 = nullptr;
|
||||
Controller* extensionPort = nullptr;
|
||||
};
|
||||
|
||||
extern System system;
|
||||
extern Peripherals peripherals;
|
||||
|
||||
auto Region::NTSCJ() -> bool { return system.region() == System::Region::NTSCJ; }
|
||||
auto Region::NTSCU() -> bool { return system.region() == System::Region::NTSCU; }
|
||||
|
|
|
@ -68,7 +68,7 @@ auto VDP::refresh() -> void {
|
|||
}
|
||||
|
||||
auto VDP::power() -> void {
|
||||
create(VDP::Enter, system.colorburst() * 15.0 / 2.0);
|
||||
create(VDP::Enter, system.frequency() / 2.0);
|
||||
|
||||
memory::fill(&io, sizeof(IO));
|
||||
memory::fill(&latch, sizeof(Latch));
|
||||
|
|
|
@ -155,7 +155,7 @@ auto YM2612::step(uint clocks) -> void {
|
|||
}
|
||||
|
||||
auto YM2612::power() -> void {
|
||||
create(YM2612::Enter, system.colorburst() * 15.0 / 7.0);
|
||||
create(YM2612::Enter, system.frequency() / 7.0);
|
||||
stream = Emulator::audio.createStream(2, frequency() / 144.0);
|
||||
stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 20.0);
|
||||
stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::LowPass, 2840.0);
|
||||
|
|
|
@ -7,14 +7,14 @@ auto SPC700::instruction() -> void {
|
|||
op(0x01, JST, 0)
|
||||
op(0x02, SET, 0)
|
||||
op(0x03, BBS, 0)
|
||||
op(0x04, DirectPageRead, fp(OR), A)
|
||||
op(0x04, DirectRead, fp(OR), A)
|
||||
op(0x05, AbsoluteRead, fp(OR), A)
|
||||
op(0x06, IndirectXRead, fp(OR))
|
||||
op(0x07, IndirectPageXRead, fp(OR))
|
||||
op(0x07, IndexedIndirectRead, fp(OR), X)
|
||||
op(0x08, ImmediateRead, fp(OR), A)
|
||||
op(0x09, DirectPageWriteDirectPage, fp(OR))
|
||||
op(0x0a, AbsoluteModifyBit, 0)
|
||||
op(0x0b, DirectPageModify, fp(ASL))
|
||||
op(0x09, DirectWriteDirect, fp(OR))
|
||||
op(0x0a, AbsoluteBitModify, 0)
|
||||
op(0x0b, DirectModify, fp(ASL))
|
||||
op(0x0c, AbsoluteModify, fp(ASL))
|
||||
op(0x0d, Push, P)
|
||||
op(0x0e, TSBAbsolute)
|
||||
|
@ -23,78 +23,78 @@ auto SPC700::instruction() -> void {
|
|||
op(0x11, JST, 1)
|
||||
op(0x12, CLR, 0)
|
||||
op(0x13, BBC, 0)
|
||||
op(0x14, DirectPageIndexedRead, fp(OR), A, X)
|
||||
op(0x14, DirectIndexedRead, fp(OR), A, X)
|
||||
op(0x15, AbsoluteIndexedRead, fp(OR), X)
|
||||
op(0x16, AbsoluteIndexedRead, fp(OR), Y)
|
||||
op(0x17, IndirectPageYRead, fp(OR))
|
||||
op(0x18, DirectPageWriteImmediate, fp(OR))
|
||||
op(0x17, IndirectIndexedRead, fp(OR), Y)
|
||||
op(0x18, DirectWriteImmediate, fp(OR))
|
||||
op(0x19, IndirectXWriteIndirectY, fp(OR))
|
||||
op(0x1a, DirectPageModifyWord, -1)
|
||||
op(0x1b, DirectPageXModify, fp(ASL))
|
||||
op(0x1a, DirectModifyWord, -1)
|
||||
op(0x1b, DirectIndexedModify, fp(ASL), X)
|
||||
op(0x1c, ImpliedModify, fp(ASL), A)
|
||||
op(0x1d, ImpliedModify, fp(DEC), X)
|
||||
op(0x1e, AbsoluteRead, fp(CMP), X)
|
||||
op(0x1f, JMPIndirectAbsoluteX)
|
||||
op(0x1f, JMPIndirectX)
|
||||
op(0x20, FlagClear, PF)
|
||||
op(0x21, JST, 2)
|
||||
op(0x22, SET, 1)
|
||||
op(0x23, BBS, 1)
|
||||
op(0x24, DirectPageRead, fp(AND), A)
|
||||
op(0x24, DirectRead, fp(AND), A)
|
||||
op(0x25, AbsoluteRead, fp(AND), A)
|
||||
op(0x26, IndirectXRead, fp(AND))
|
||||
op(0x27, IndirectPageXRead, fp(AND))
|
||||
op(0x27, IndexedIndirectRead, fp(AND), X)
|
||||
op(0x28, ImmediateRead, fp(AND), A)
|
||||
op(0x29, DirectPageWriteDirectPage, fp(AND))
|
||||
op(0x2a, AbsoluteModifyBit, 1)
|
||||
op(0x2b, DirectPageModify, fp(ROL))
|
||||
op(0x29, DirectWriteDirect, fp(AND))
|
||||
op(0x2a, AbsoluteBitModify, 1)
|
||||
op(0x2b, DirectModify, fp(ROL))
|
||||
op(0x2c, AbsoluteModify, fp(ROL))
|
||||
op(0x2d, Push, A)
|
||||
op(0x2e, BNEDirectPage)
|
||||
op(0x2e, BNEDirect)
|
||||
op(0x2f, Branch, true)
|
||||
op(0x30, Branch, NF == 1)
|
||||
op(0x31, JST, 3)
|
||||
op(0x32, CLR, 1)
|
||||
op(0x33, BBC, 1)
|
||||
op(0x34, DirectPageIndexedRead, fp(AND), A, X)
|
||||
op(0x34, DirectIndexedRead, fp(AND), A, X)
|
||||
op(0x35, AbsoluteIndexedRead, fp(AND), X)
|
||||
op(0x36, AbsoluteIndexedRead, fp(AND), Y)
|
||||
op(0x37, IndirectPageYRead, fp(AND))
|
||||
op(0x38, DirectPageWriteImmediate, fp(AND))
|
||||
op(0x37, IndirectIndexedRead, fp(AND), Y)
|
||||
op(0x38, DirectWriteImmediate, fp(AND))
|
||||
op(0x39, IndirectXWriteIndirectY, fp(AND))
|
||||
op(0x3a, DirectPageModifyWord, +1)
|
||||
op(0x3b, DirectPageXModify, fp(ROL))
|
||||
op(0x3a, DirectModifyWord, +1)
|
||||
op(0x3b, DirectIndexedModify, fp(ROL), A)
|
||||
op(0x3c, ImpliedModify, fp(ROL), A)
|
||||
op(0x3d, ImpliedModify, fp(INC), X)
|
||||
op(0x3e, DirectPageRead, fp(CMP), X)
|
||||
op(0x3e, DirectRead, fp(CMP), X)
|
||||
op(0x3f, JSRAbsolute)
|
||||
op(0x40, FlagSet, PF)
|
||||
op(0x41, JST, 4)
|
||||
op(0x42, SET, 2)
|
||||
op(0x43, BBS, 2)
|
||||
op(0x44, DirectPageRead, fp(EOR), A)
|
||||
op(0x44, DirectRead, fp(EOR), A)
|
||||
op(0x45, AbsoluteRead, fp(EOR), A)
|
||||
op(0x46, IndirectXRead, fp(EOR))
|
||||
op(0x47, IndirectPageXRead, fp(EOR))
|
||||
op(0x47, IndexedIndirectRead, fp(EOR), X)
|
||||
op(0x48, ImmediateRead, fp(EOR), A)
|
||||
op(0x49, DirectPageWriteDirectPage, fp(EOR))
|
||||
op(0x4a, AbsoluteModifyBit, 2)
|
||||
op(0x4b, DirectPageModify, fp(LSR))
|
||||
op(0x49, DirectWriteDirect, fp(EOR))
|
||||
op(0x4a, AbsoluteBitModify, 2)
|
||||
op(0x4b, DirectModify, fp(LSR))
|
||||
op(0x4c, AbsoluteModify, fp(LSR))
|
||||
op(0x4d, Push, X)
|
||||
op(0x4e, TRBAbsolute)
|
||||
op(0x4f, JSPDirectPage)
|
||||
op(0x4f, JSPDirect)
|
||||
op(0x50, Branch, VF == 0)
|
||||
op(0x51, JST, 5)
|
||||
op(0x52, CLR, 2)
|
||||
op(0x53, BBC, 2)
|
||||
op(0x54, DirectPageIndexedRead, fp(EOR), A, X)
|
||||
op(0x54, DirectIndexedRead, fp(EOR), A, X)
|
||||
op(0x55, AbsoluteIndexedRead, fp(EOR), X)
|
||||
op(0x56, AbsoluteIndexedRead, fp(EOR), Y)
|
||||
op(0x57, IndirectPageYRead, fp(EOR))
|
||||
op(0x58, DirectPageWriteImmediate, fp(EOR))
|
||||
op(0x57, IndirectIndexedRead, fp(EOR), Y)
|
||||
op(0x58, DirectWriteImmediate, fp(EOR))
|
||||
op(0x59, IndirectXWriteIndirectY, fp(EOR))
|
||||
op(0x5a, DirectPageReadWord, fp(CPW))
|
||||
op(0x5b, DirectPageXModify, fp(LSR))
|
||||
op(0x5a, DirectReadWord, fp(CPW))
|
||||
op(0x5b, DirectIndexedModify, fp(LSR), X)
|
||||
op(0x5c, ImpliedModify, fp(LSR), A)
|
||||
op(0x5d, Transfer, A, X)
|
||||
op(0x5e, AbsoluteRead, fp(CMP), Y)
|
||||
|
@ -103,62 +103,62 @@ auto SPC700::instruction() -> void {
|
|||
op(0x61, JST, 6)
|
||||
op(0x62, SET, 3)
|
||||
op(0x63, BBS, 3)
|
||||
op(0x64, DirectPageRead, fp(CMP), A)
|
||||
op(0x64, DirectRead, fp(CMP), A)
|
||||
op(0x65, AbsoluteRead, fp(CMP), A)
|
||||
op(0x66, IndirectXRead, fp(CMP))
|
||||
op(0x67, IndirectPageXRead, fp(CMP))
|
||||
op(0x67, IndexedIndirectRead, fp(CMP), X)
|
||||
op(0x68, ImmediateRead, fp(CMP), A)
|
||||
op(0x69, DirectPageWriteDirectPage, fp(CMP))
|
||||
op(0x6a, AbsoluteModifyBit, 3)
|
||||
op(0x6b, DirectPageModify, fp(ROR))
|
||||
op(0x69, DirectWriteDirect, fp(CMP))
|
||||
op(0x6a, AbsoluteBitModify, 3)
|
||||
op(0x6b, DirectModify, fp(ROR))
|
||||
op(0x6c, AbsoluteModify, fp(ROR))
|
||||
op(0x6d, Push, Y)
|
||||
op(0x6e, BNEDirectPageDecrement)
|
||||
op(0x6e, BNEDirectDecrement)
|
||||
op(0x6f, RTS)
|
||||
op(0x70, Branch, VF == 1)
|
||||
op(0x71, JST, 7)
|
||||
op(0x72, CLR, 3)
|
||||
op(0x73, BBC, 3)
|
||||
op(0x74, DirectPageIndexedRead, fp(CMP), A, X)
|
||||
op(0x74, DirectIndexedRead, fp(CMP), A, X)
|
||||
op(0x75, AbsoluteIndexedRead, fp(CMP), X)
|
||||
op(0x76, AbsoluteIndexedRead, fp(CMP), Y)
|
||||
op(0x77, IndirectPageYRead, fp(CMP))
|
||||
op(0x78, DirectPageWriteImmediate, fp(CMP))
|
||||
op(0x77, IndirectIndexedRead, fp(CMP), Y)
|
||||
op(0x78, DirectWriteImmediate, fp(CMP))
|
||||
op(0x79, IndirectXWriteIndirectY, fp(CMP))
|
||||
op(0x7a, DirectPageReadWord, fp(ADW))
|
||||
op(0x7b, DirectPageXModify, fp(ROR))
|
||||
op(0x7a, DirectReadWord, fp(ADW))
|
||||
op(0x7b, DirectIndexedModify, fp(ROR), X)
|
||||
op(0x7c, ImpliedModify, fp(ROR), A)
|
||||
op(0x7d, Transfer, X, A)
|
||||
op(0x7e, DirectPageRead, fp(CMP), Y)
|
||||
op(0x7e, DirectRead, fp(CMP), Y)
|
||||
op(0x7f, RTI)
|
||||
op(0x80, FlagSet, CF)
|
||||
op(0x81, JST, 8)
|
||||
op(0x82, SET, 4)
|
||||
op(0x83, BBS, 4)
|
||||
op(0x84, DirectPageRead, fp(ADC), A)
|
||||
op(0x84, DirectRead, fp(ADC), A)
|
||||
op(0x85, AbsoluteRead, fp(ADC), A)
|
||||
op(0x86, IndirectXRead, fp(ADC))
|
||||
op(0x87, IndirectPageXRead, fp(ADC))
|
||||
op(0x87, IndexedIndirectRead, fp(ADC), X)
|
||||
op(0x88, ImmediateRead, fp(ADC), A)
|
||||
op(0x89, DirectPageWriteDirectPage, fp(ADC))
|
||||
op(0x8a, AbsoluteModifyBit, 4)
|
||||
op(0x8b, DirectPageModify, fp(DEC))
|
||||
op(0x89, DirectWriteDirect, fp(ADC))
|
||||
op(0x8a, AbsoluteBitModify, 4)
|
||||
op(0x8b, DirectModify, fp(DEC))
|
||||
op(0x8c, AbsoluteModify, fp(DEC))
|
||||
op(0x8d, ImmediateRead, fp(LD), Y)
|
||||
op(0x8e, PLP)
|
||||
op(0x8f, DirectPageWriteImmediate, fp(ST))
|
||||
op(0x8f, DirectWriteImmediate, fp(ST))
|
||||
op(0x90, Branch, CF == 0)
|
||||
op(0x91, JST, 9)
|
||||
op(0x92, CLR, 4)
|
||||
op(0x93, BBC, 4)
|
||||
op(0x94, DirectPageIndexedRead, fp(ADC), A, X)
|
||||
op(0x94, DirectIndexedRead, fp(ADC), A, X)
|
||||
op(0x95, AbsoluteIndexedRead, fp(ADC), X)
|
||||
op(0x96, AbsoluteIndexedRead, fp(ADC), Y)
|
||||
op(0x97, IndirectPageYRead, fp(ADC))
|
||||
op(0x98, DirectPageWriteImmediate, fp(ADC))
|
||||
op(0x97, IndirectIndexedRead, fp(ADC), Y)
|
||||
op(0x98, DirectWriteImmediate, fp(ADC))
|
||||
op(0x99, IndirectXWriteIndirectY, fp(ADC))
|
||||
op(0x9a, DirectPageReadWord, fp(SBW))
|
||||
op(0x9b, DirectPageXModify, fp(DEC))
|
||||
op(0x9a, DirectReadWord, fp(SBW))
|
||||
op(0x9b, DirectIndexedModify, fp(DEC), X)
|
||||
op(0x9c, ImpliedModify, fp(DEC), A)
|
||||
op(0x9d, Transfer, S, X)
|
||||
op(0x9e, DIV)
|
||||
|
@ -167,46 +167,46 @@ auto SPC700::instruction() -> void {
|
|||
op(0xa1, JST, 10)
|
||||
op(0xa2, SET, 5)
|
||||
op(0xa3, BBS, 5)
|
||||
op(0xa4, DirectPageRead, fp(SBC), A)
|
||||
op(0xa4, DirectRead, fp(SBC), A)
|
||||
op(0xa5, AbsoluteRead, fp(SBC), A)
|
||||
op(0xa6, IndirectXRead, fp(SBC))
|
||||
op(0xa7, IndirectPageXRead, fp(SBC))
|
||||
op(0xa7, IndexedIndirectRead, fp(SBC), X)
|
||||
op(0xa8, ImmediateRead, fp(SBC), A)
|
||||
op(0xa9, DirectPageWriteDirectPage, fp(SBC))
|
||||
op(0xaa, AbsoluteModifyBit, 5)
|
||||
op(0xab, DirectPageModify, fp(INC))
|
||||
op(0xa9, DirectWriteDirect, fp(SBC))
|
||||
op(0xaa, AbsoluteBitModify, 5)
|
||||
op(0xab, DirectModify, fp(INC))
|
||||
op(0xac, AbsoluteModify, fp(INC))
|
||||
op(0xad, ImmediateRead, fp(CMP), Y)
|
||||
op(0xae, Pull, A)
|
||||
op(0xaf, STAIndirectXIncrement)
|
||||
op(0xaf, IndirectXIncrementWrite, A)
|
||||
op(0xb0, Branch, CF == 1)
|
||||
op(0xb1, JST, 11)
|
||||
op(0xb2, CLR, 5)
|
||||
op(0xb3, BBC, 5)
|
||||
op(0xb4, DirectPageIndexedRead, fp(SBC), A, X)
|
||||
op(0xb4, DirectIndexedRead, fp(SBC), A, X)
|
||||
op(0xb5, AbsoluteIndexedRead, fp(SBC), X)
|
||||
op(0xb6, AbsoluteIndexedRead, fp(SBC), Y)
|
||||
op(0xb7, IndirectPageYRead, fp(SBC))
|
||||
op(0xb8, DirectPageWriteImmediate, fp(SBC))
|
||||
op(0xb7, IndirectIndexedRead, fp(SBC), Y)
|
||||
op(0xb8, DirectWriteImmediate, fp(SBC))
|
||||
op(0xb9, IndirectXWriteIndirectY, fp(SBC))
|
||||
op(0xba, DirectPageReadWord, fp(LDW))
|
||||
op(0xbb, DirectPageXModify, fp(INC))
|
||||
op(0xba, DirectReadWord, fp(LDW))
|
||||
op(0xbb, DirectIndexedModify, fp(INC), X)
|
||||
op(0xbc, ImpliedModify, fp(INC), A)
|
||||
op(0xbd, Transfer, X, S)
|
||||
op(0xbe, DAS)
|
||||
op(0xbf, LDAIndirectXIncrement)
|
||||
op(0xbf, IndirectXIncrementRead, A)
|
||||
op(0xc0, FlagClear, IF)
|
||||
op(0xc1, JST, 12)
|
||||
op(0xc2, SET, 6)
|
||||
op(0xc3, BBS, 6)
|
||||
op(0xc4, DirectPageWrite, A)
|
||||
op(0xc4, DirectWrite, A)
|
||||
op(0xc5, AbsoluteWrite, A)
|
||||
op(0xc6, STAIndirectX)
|
||||
op(0xc7, STAIndirectPageX)
|
||||
op(0xc6, IndirectXWrite, A)
|
||||
op(0xc7, IndexedIndirectWrite, A, X)
|
||||
op(0xc8, ImmediateRead, fp(CMP), X)
|
||||
op(0xc9, AbsoluteWrite, X)
|
||||
op(0xca, AbsoluteModifyBit, 6)
|
||||
op(0xcb, DirectPageWrite, Y)
|
||||
op(0xca, AbsoluteBitModify, 6)
|
||||
op(0xcb, DirectWrite, Y)
|
||||
op(0xcc, AbsoluteWrite, Y)
|
||||
op(0xcd, ImmediateRead, fp(LD), X)
|
||||
op(0xce, Pull, X)
|
||||
|
@ -215,30 +215,30 @@ auto SPC700::instruction() -> void {
|
|||
op(0xd1, JST, 13)
|
||||
op(0xd2, CLR, 6)
|
||||
op(0xd3, BBC, 6)
|
||||
op(0xd4, DirectPageIndexedWrite, A, X)
|
||||
op(0xd4, DirectIndexedWrite, A, X)
|
||||
op(0xd5, AbsoluteIndexedWrite, X)
|
||||
op(0xd6, AbsoluteIndexedWrite, Y)
|
||||
op(0xd7, STAIndirectPageY)
|
||||
op(0xd8, DirectPageWrite, X)
|
||||
op(0xd9, DirectPageIndexedWrite, X, Y)
|
||||
op(0xda, STWDirectPage)
|
||||
op(0xdb, DirectPageIndexedWrite, Y, X)
|
||||
op(0xd7, IndirectIndexedWrite, A, Y)
|
||||
op(0xd8, DirectWrite, X)
|
||||
op(0xd9, DirectIndexedWrite, X, Y)
|
||||
op(0xda, STWDirect)
|
||||
op(0xdb, DirectIndexedWrite, Y, X)
|
||||
op(0xdc, ImpliedModify, fp(DEC), Y)
|
||||
op(0xdd, Transfer, Y, A)
|
||||
op(0xde, BNEDirectPageX)
|
||||
op(0xde, BNEDirectX)
|
||||
op(0xdf, DAA)
|
||||
op(0xe0, CLV)
|
||||
op(0xe1, JST, 14)
|
||||
op(0xe2, SET, 7)
|
||||
op(0xe3, BBS, 7)
|
||||
op(0xe4, DirectPageRead, fp(LD), A)
|
||||
op(0xe4, DirectRead, fp(LD), A)
|
||||
op(0xe5, AbsoluteRead, fp(LD), A)
|
||||
op(0xe6, IndirectXRead, fp(LD))
|
||||
op(0xe7, IndirectPageXRead, fp(LD))
|
||||
op(0xe7, IndexedIndirectRead, fp(LD), X)
|
||||
op(0xe8, ImmediateRead, fp(LD), A)
|
||||
op(0xe9, AbsoluteRead, fp(LD), X)
|
||||
op(0xea, AbsoluteModifyBit, 7)
|
||||
op(0xeb, DirectPageRead, fp(LD), Y)
|
||||
op(0xea, AbsoluteBitModify, 7)
|
||||
op(0xeb, DirectRead, fp(LD), Y)
|
||||
op(0xec, AbsoluteRead, fp(LD), Y)
|
||||
op(0xed, CMC)
|
||||
op(0xee, Pull, Y)
|
||||
|
@ -247,14 +247,14 @@ auto SPC700::instruction() -> void {
|
|||
op(0xf1, JST, 15)
|
||||
op(0xf2, CLR, 7)
|
||||
op(0xf3, BBC, 7)
|
||||
op(0xf4, DirectPageIndexedRead, fp(LD), A, X)
|
||||
op(0xf4, DirectIndexedRead, fp(LD), A, X)
|
||||
op(0xf5, AbsoluteIndexedRead, fp(LD), X)
|
||||
op(0xf6, AbsoluteIndexedRead, fp(LD), Y)
|
||||
op(0xf7, IndirectPageYRead, fp(LD))
|
||||
op(0xf8, DirectPageRead, fp(LD), X)
|
||||
op(0xf9, DirectPageIndexedRead, fp(LD), X, Y)
|
||||
op(0xfa, DirectPageWriteDirectPage, fp(ST))
|
||||
op(0xfb, DirectPageIndexedRead, fp(LD), Y, X)
|
||||
op(0xf7, IndirectIndexedRead, fp(LD), Y)
|
||||
op(0xf8, DirectRead, fp(LD), X)
|
||||
op(0xf9, DirectIndexedRead, fp(LD), X, Y)
|
||||
op(0xfa, DirectWriteDirect, fp(ST))
|
||||
op(0xfb, DirectIndexedRead, fp(LD), Y, X)
|
||||
op(0xfc, ImpliedModify, fp(INC), Y)
|
||||
op(0xfd, Transfer, A, Y)
|
||||
op(0xfe, BNEYDecrement)
|
||||
|
|
|
@ -1,124 +1,4 @@
|
|||
auto SPC700::instructionImpliedModify(fps op, uint8& target) -> void {
|
||||
idle();
|
||||
target = alu(target);
|
||||
}
|
||||
|
||||
auto SPC700::instructionAbsoluteModify(fps op) -> void {
|
||||
uint16 absolute = fetch();
|
||||
absolute |= fetch() << 8;
|
||||
uint8 data = read(absolute);
|
||||
write(absolute, alu(data));
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectPageModify(fps op) -> void {
|
||||
uint8 direct = fetch();
|
||||
uint8 data = load(direct);
|
||||
store(direct, alu(data));
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectPageModifyWord(int adjust) -> void {
|
||||
uint8 direct = fetch();
|
||||
uint16 data = load(direct) + adjust;
|
||||
store(direct++, data >> 0);
|
||||
data += load(direct) << 8;
|
||||
store(direct++, data >> 8);
|
||||
ZF = data == 0;
|
||||
NF = data & 0x8000;
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectPageXModify(fps op) -> void {
|
||||
uint8 direct = fetch();
|
||||
idle();
|
||||
uint8 data = load(direct + X);
|
||||
store(direct + X, alu(data));
|
||||
}
|
||||
|
||||
auto SPC700::instructionBranch(bool take) -> void {
|
||||
uint8 data = fetch();
|
||||
if(!take) return;
|
||||
idle();
|
||||
idle();
|
||||
PC += (int8)data;
|
||||
}
|
||||
|
||||
auto SPC700::instructionPull(uint8& data) -> void {
|
||||
idle();
|
||||
idle();
|
||||
data = pull();
|
||||
}
|
||||
|
||||
auto SPC700::instructionPush(uint8 data) -> void {
|
||||
idle();
|
||||
idle();
|
||||
push(data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionAbsoluteRead(fpb op, uint8& target) -> void {
|
||||
uint16 absolute = fetch();
|
||||
absolute |= fetch() << 8;
|
||||
uint8 data = read(absolute);
|
||||
target = alu(target, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionAbsoluteIndexedRead(fpb op, uint8& index) -> void {
|
||||
uint16 absolute = fetch();
|
||||
absolute |= fetch() << 8;
|
||||
idle();
|
||||
uint8 data = read(absolute + index);
|
||||
A = alu(A, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionImmediateRead(fpb op, uint8& target) -> void {
|
||||
uint8 data = fetch();
|
||||
target = alu(target, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectPageRead(fpb op, uint8& target) -> void {
|
||||
uint8 direct = fetch();
|
||||
uint8 data = load(direct);
|
||||
target = alu(target, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectPageIndexedRead(fpb op, uint8& target, uint8& index) -> void {
|
||||
uint8 direct = fetch();
|
||||
idle();
|
||||
uint8 data = load(direct + index);
|
||||
target = alu(target, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectPageReadWord(fpw op) -> void {
|
||||
uint8 direct = fetch();
|
||||
uint16 data = load(direct++);
|
||||
if(op != &SPC700::algorithmCPW) idle();
|
||||
data |= load(direct++) << 8;
|
||||
YA = alu(YA, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionIndirectPageXRead(fpb op) -> void {
|
||||
uint8 direct = fetch() + X;
|
||||
idle();
|
||||
uint16 absolute = load(direct++);
|
||||
absolute |= load(direct++) << 8;
|
||||
uint8 data = read(absolute);
|
||||
A = alu(A, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionIndirectPageYRead(fpb op) -> void {
|
||||
uint8 direct = fetch();
|
||||
idle();
|
||||
uint16 absolute = load(direct++);
|
||||
absolute |= load(direct++) << 8;
|
||||
uint8 data = read(absolute + Y);
|
||||
A = alu(A, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionIndirectXRead(fpb op) -> void {
|
||||
idle();
|
||||
uint8 data = load(X);
|
||||
A = alu(A, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionAbsoluteModifyBit(uint3 mode) -> void {
|
||||
auto SPC700::instructionAbsoluteBitModify(uint3 mode) -> void {
|
||||
uint16 absolute = fetch();
|
||||
absolute |= fetch() << 8;
|
||||
uint3 bit = absolute >> 13;
|
||||
|
@ -158,6 +38,127 @@ auto SPC700::instructionAbsoluteModifyBit(uint3 mode) -> void {
|
|||
}
|
||||
}
|
||||
|
||||
auto SPC700::instructionAbsoluteRead(fpb op, uint8& target) -> void {
|
||||
uint16 absolute = fetch();
|
||||
absolute |= fetch() << 8;
|
||||
uint8 data = read(absolute);
|
||||
target = alu(target, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionAbsoluteModify(fps op) -> void {
|
||||
uint16 absolute = fetch();
|
||||
absolute |= fetch() << 8;
|
||||
uint8 data = read(absolute);
|
||||
write(absolute, alu(data));
|
||||
}
|
||||
|
||||
auto SPC700::instructionAbsoluteWrite(uint8& data) -> void {
|
||||
uint16 absolute = fetch();
|
||||
absolute |= fetch() << 8;
|
||||
read(absolute);
|
||||
write(absolute, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionAbsoluteIndexedRead(fpb op, uint8& index) -> void {
|
||||
uint16 absolute = fetch();
|
||||
absolute |= fetch() << 8;
|
||||
idle();
|
||||
uint8 data = read(absolute + index);
|
||||
A = alu(A, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionAbsoluteIndexedWrite(uint8& index) -> void {
|
||||
uint16 absolute = fetch();
|
||||
absolute |= fetch() << 8;
|
||||
idle();
|
||||
absolute += index;
|
||||
read(absolute);
|
||||
write(absolute, A);
|
||||
}
|
||||
|
||||
auto SPC700::instructionBranch(bool take) -> void {
|
||||
uint8 data = fetch();
|
||||
if(!take) return;
|
||||
idle();
|
||||
idle();
|
||||
PC += (int8)data;
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectRead(fpb op, uint8& target) -> void {
|
||||
uint8 direct = fetch();
|
||||
uint8 data = load(direct);
|
||||
target = alu(target, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectModify(fps op) -> void {
|
||||
uint8 direct = fetch();
|
||||
uint8 data = load(direct);
|
||||
store(direct, alu(data));
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectWrite(uint8& data) -> void {
|
||||
uint8 direct = fetch();
|
||||
load(direct);
|
||||
store(direct, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectWriteDirect(fpb op) -> void {
|
||||
uint8 source = fetch();
|
||||
uint8 rhs = load(source);
|
||||
uint8 target = fetch();
|
||||
uint8 lhs;
|
||||
if(op != &SPC700::algorithmST) lhs = load(target);
|
||||
lhs = alu(lhs, rhs);
|
||||
op != &SPC700::algorithmCMP ? store(target, lhs) : idle();
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectWriteImmediate(fpb op) -> void {
|
||||
uint8 immediate = fetch();
|
||||
uint8 direct = fetch();
|
||||
uint8 data = load(direct);
|
||||
data = alu(data, immediate);
|
||||
op != &SPC700::algorithmCMP ? store(direct, data) : idle();
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectReadWord(fpw op) -> void {
|
||||
uint8 direct = fetch();
|
||||
uint16 data = load(direct++);
|
||||
if(op != &SPC700::algorithmCPW) idle();
|
||||
data |= load(direct++) << 8;
|
||||
YA = alu(YA, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectModifyWord(int adjust) -> void {
|
||||
uint8 direct = fetch();
|
||||
uint16 data = load(direct) + adjust;
|
||||
store(direct++, data >> 0);
|
||||
data += load(direct) << 8;
|
||||
store(direct++, data >> 8);
|
||||
ZF = data == 0;
|
||||
NF = data & 0x8000;
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectIndexedRead(fpb op, uint8& target, uint8& index) -> void {
|
||||
uint8 direct = fetch();
|
||||
idle();
|
||||
uint8 data = load(direct + index);
|
||||
target = alu(target, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectIndexedModify(fps op, uint8& index) -> void {
|
||||
uint8 direct = fetch();
|
||||
idle();
|
||||
uint8 data = load(direct + index);
|
||||
store(direct + index, alu(data));
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectIndexedWrite(uint8& data, uint8& index) -> void {
|
||||
uint8 direct = fetch() + index;
|
||||
idle();
|
||||
load(direct);
|
||||
store(direct, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionFlagClear(bool& flag) -> void {
|
||||
idle();
|
||||
if(&flag == &IF) idle();
|
||||
|
@ -170,59 +171,76 @@ auto SPC700::instructionFlagSet(bool& flag) -> void {
|
|||
flag = 1;
|
||||
}
|
||||
|
||||
auto SPC700::instructionTransfer(uint8& from, uint8& to) -> void {
|
||||
idle();
|
||||
to = from;
|
||||
if(&to == &S) return;
|
||||
ZF = to == 0;
|
||||
NF = to & 0x80;
|
||||
auto SPC700::instructionImmediateRead(fpb op, uint8& target) -> void {
|
||||
uint8 data = fetch();
|
||||
target = alu(target, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionAbsoluteWrite(uint8& data) -> void {
|
||||
uint16 absolute = fetch();
|
||||
absolute |= fetch() << 8;
|
||||
auto SPC700::instructionImpliedModify(fps op, uint8& target) -> void {
|
||||
idle();
|
||||
target = alu(target);
|
||||
}
|
||||
|
||||
auto SPC700::instructionIndexedIndirectRead(fpb op, uint8& index) -> void {
|
||||
uint8 direct = fetch() + index;
|
||||
idle();
|
||||
uint16 absolute = load(direct++);
|
||||
absolute |= load(direct++) << 8;
|
||||
uint8 data = read(absolute);
|
||||
A = alu(A, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionIndexedIndirectWrite(uint8& data, uint8& index) -> void {
|
||||
uint8 direct = fetch() + index;
|
||||
idle();
|
||||
uint16 absolute = load(direct++);
|
||||
absolute |= load(direct++) << 8;
|
||||
read(absolute);
|
||||
write(absolute, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionAbsoluteIndexedWrite(uint8& index) -> void {
|
||||
uint16 absolute = fetch();
|
||||
absolute |= fetch() << 8;
|
||||
idle();
|
||||
absolute += index;
|
||||
read(absolute);
|
||||
write(absolute, A);
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectPageWrite(uint8& data) -> void {
|
||||
auto SPC700::instructionIndirectIndexedRead(fpb op, uint8& index) -> void {
|
||||
uint8 direct = fetch();
|
||||
load(direct);
|
||||
store(direct, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectPageIndexedWrite(uint8& data, uint8& index) -> void {
|
||||
uint8 direct = fetch() + index;
|
||||
uint16 absolute = load(direct++);
|
||||
absolute |= load(direct++) << 8;
|
||||
idle();
|
||||
load(direct);
|
||||
store(direct, data);
|
||||
uint8 data = read(absolute + index);
|
||||
A = alu(A, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectPageWriteImmediate(fpb op) -> void {
|
||||
uint8 immediate = fetch();
|
||||
auto SPC700::instructionIndirectIndexedWrite(uint8& data, uint8& index) -> void {
|
||||
uint8 direct = fetch();
|
||||
uint8 data = load(direct);
|
||||
data = alu(data, immediate);
|
||||
op != &SPC700::algorithmCMP ? store(direct, data) : idle();
|
||||
uint16 absolute = load(direct++);
|
||||
absolute |= load(direct++) << 8;
|
||||
idle();
|
||||
read(absolute + index);
|
||||
write(absolute + index, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionDirectPageWriteDirectPage(fpb op) -> void {
|
||||
uint8 source = fetch();
|
||||
uint8 rhs = load(source);
|
||||
uint8 target = fetch();
|
||||
uint8 lhs;
|
||||
if(op != &SPC700::algorithmST) lhs = load(target);
|
||||
lhs = alu(lhs, rhs);
|
||||
op != &SPC700::algorithmCMP ? store(target, lhs) : idle();
|
||||
auto SPC700::instructionIndirectXRead(fpb op) -> void {
|
||||
idle();
|
||||
uint8 data = load(X);
|
||||
A = alu(A, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionIndirectXWrite(uint8& data) -> void {
|
||||
idle();
|
||||
load(X);
|
||||
store(X, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionIndirectXIncrementRead(uint8& data) -> void {
|
||||
idle();
|
||||
data = load(X++);
|
||||
idle();
|
||||
ZF = data == 0;
|
||||
NF = data & 0x80;
|
||||
}
|
||||
|
||||
auto SPC700::instructionIndirectXIncrementWrite(uint8& data) -> void {
|
||||
idle();
|
||||
idle();
|
||||
store(X++, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionIndirectXWriteIndirectY(fpb op) -> void {
|
||||
|
@ -233,6 +251,26 @@ auto SPC700::instructionIndirectXWriteIndirectY(fpb op) -> void {
|
|||
op != &SPC700::algorithmCMP ? store(X, lhs) : idle();
|
||||
}
|
||||
|
||||
auto SPC700::instructionPull(uint8& data) -> void {
|
||||
idle();
|
||||
idle();
|
||||
data = pull();
|
||||
}
|
||||
|
||||
auto SPC700::instructionPush(uint8 data) -> void {
|
||||
idle();
|
||||
idle();
|
||||
push(data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionTransfer(uint8& from, uint8& to) -> void {
|
||||
idle();
|
||||
to = from;
|
||||
if(&to == &S) return;
|
||||
ZF = to == 0;
|
||||
NF = to & 0x80;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
auto SPC700::instructionBBC(uint3 bit) -> void {
|
||||
|
@ -257,7 +295,7 @@ auto SPC700::instructionBBS(uint3 bit) -> void {
|
|||
PC += (int8)displacement;
|
||||
}
|
||||
|
||||
auto SPC700::instructionBNEDirectPage() -> void {
|
||||
auto SPC700::instructionBNEDirect() -> void {
|
||||
uint8 direct = fetch();
|
||||
uint8 data = load(direct);
|
||||
uint8 displacement = fetch();
|
||||
|
@ -268,7 +306,7 @@ auto SPC700::instructionBNEDirectPage() -> void {
|
|||
PC += (int8)displacement;
|
||||
}
|
||||
|
||||
auto SPC700::instructionBNEDirectPageDecrement() -> void {
|
||||
auto SPC700::instructionBNEDirectDecrement() -> void {
|
||||
uint8 direct = fetch();
|
||||
uint8 data = load(direct);
|
||||
store(direct, --data);
|
||||
|
@ -279,7 +317,7 @@ auto SPC700::instructionBNEDirectPageDecrement() -> void {
|
|||
PC += (int8)displacement;
|
||||
}
|
||||
|
||||
auto SPC700::instructionBNEDirectPageX() -> void {
|
||||
auto SPC700::instructionBNEDirectX() -> void {
|
||||
uint8 direct = fetch();
|
||||
idle();
|
||||
uint8 data = load(direct + X);
|
||||
|
@ -398,7 +436,7 @@ auto SPC700::instructionJMPAbsolute() -> void {
|
|||
PC = absolute;
|
||||
}
|
||||
|
||||
auto SPC700::instructionJMPIndirectAbsoluteX() -> void {
|
||||
auto SPC700::instructionJMPIndirectX() -> void {
|
||||
uint16 absolute = fetch();
|
||||
absolute |= fetch() << 8;
|
||||
idle();
|
||||
|
@ -408,7 +446,7 @@ auto SPC700::instructionJMPIndirectAbsoluteX() -> void {
|
|||
PC = pc;
|
||||
}
|
||||
|
||||
auto SPC700::instructionJSPDirectPage() -> void {
|
||||
auto SPC700::instructionJSPDirect() -> void {
|
||||
uint8 direct = fetch();
|
||||
idle();
|
||||
idle();
|
||||
|
@ -440,14 +478,6 @@ auto SPC700::instructionJST(uint4 vector) -> void {
|
|||
PC = pc;
|
||||
}
|
||||
|
||||
auto SPC700::instructionLDAIndirectXIncrement() -> void {
|
||||
idle();
|
||||
A = load(X++);
|
||||
idle();
|
||||
ZF = A == 0;
|
||||
NF = A & 0x80;
|
||||
}
|
||||
|
||||
auto SPC700::instructionMUL() -> void {
|
||||
idle();
|
||||
idle();
|
||||
|
@ -499,37 +529,6 @@ auto SPC700::instructionSET(uint3 bit) -> void {
|
|||
store(direct, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionSTAIndirectPageX() -> void {
|
||||
uint8 direct = fetch() + X;
|
||||
idle();
|
||||
uint16 absolute = load(direct++);
|
||||
absolute |= load(direct++) << 8;
|
||||
read(absolute);
|
||||
write(absolute, A);
|
||||
}
|
||||
|
||||
auto SPC700::instructionSTAIndirectPageY() -> void {
|
||||
uint8 direct = fetch();
|
||||
uint16 absolute = load(direct++);
|
||||
absolute |= load(direct++) << 8;
|
||||
idle();
|
||||
absolute += Y;
|
||||
read(absolute);
|
||||
write(absolute, A);
|
||||
}
|
||||
|
||||
auto SPC700::instructionSTAIndirectX() -> void {
|
||||
idle();
|
||||
load(X);
|
||||
store(X, A);
|
||||
}
|
||||
|
||||
auto SPC700::instructionSTAIndirectXIncrement() -> void {
|
||||
idle();
|
||||
idle();
|
||||
store(X++, A);
|
||||
}
|
||||
|
||||
auto SPC700::instructionSTP() -> void {
|
||||
r.stp = true;
|
||||
while(r.stp && !synchronizing()) {
|
||||
|
@ -538,7 +537,7 @@ auto SPC700::instructionSTP() -> void {
|
|||
}
|
||||
}
|
||||
|
||||
auto SPC700::instructionSTWDirectPage() -> void {
|
||||
auto SPC700::instructionSTWDirect() -> void {
|
||||
uint8 direct = fetch();
|
||||
load(direct);
|
||||
store(direct++, A);
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
auto SPC700::idle() -> void {
|
||||
read(PC);
|
||||
}
|
||||
|
||||
auto SPC700::fetch() -> uint8 {
|
||||
return read(PC++);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
namespace Processor {
|
||||
|
||||
struct SPC700 {
|
||||
virtual auto idle() -> void = 0;
|
||||
virtual auto read(uint16 addr) -> uint8 = 0;
|
||||
virtual auto write(uint16 addr, uint8 data) -> void = 0;
|
||||
virtual auto synchronizing() const -> bool = 0;
|
||||
|
@ -17,6 +16,7 @@ struct SPC700 {
|
|||
auto instruction() -> void;
|
||||
|
||||
//memory.cpp
|
||||
auto idle() -> void;
|
||||
auto fetch() -> uint8;
|
||||
auto pull() -> uint8;
|
||||
auto push(uint8 data) -> void;
|
||||
|
@ -48,40 +48,45 @@ struct SPC700 {
|
|||
using fpb = auto (SPC700::*)(uint8, uint8) -> uint8;
|
||||
using fpw = auto (SPC700::*)(uint16, uint16) -> uint16;
|
||||
|
||||
auto instructionImpliedModify(fps, uint8&) -> void;
|
||||
auto instructionAbsoluteModify(fps) -> void;
|
||||
auto instructionDirectPageModify(fps) -> void;
|
||||
auto instructionDirectPageModifyWord(int) -> void;
|
||||
auto instructionDirectPageXModify(fps) -> void;
|
||||
auto instructionBranch(bool) -> void;
|
||||
auto instructionPull(uint8&) -> void;
|
||||
auto instructionPush(uint8) -> void;
|
||||
auto instructionAbsoluteBitModify(uint3) -> void;
|
||||
auto instructionAbsoluteRead(fpb, uint8&) -> void;
|
||||
auto instructionAbsoluteModify(fps) -> void;
|
||||
auto instructionAbsoluteWrite(uint8&) -> void;
|
||||
auto instructionAbsoluteIndexedRead(fpb, uint8&) -> void;
|
||||
auto instructionImmediateRead(fpb, uint8&) -> void;
|
||||
auto instructionDirectPageRead(fpb, uint8&) -> void;
|
||||
auto instructionDirectPageIndexedRead(fpb, uint8&, uint8&) -> void;
|
||||
auto instructionDirectPageReadWord(fpw) -> void;
|
||||
auto instructionIndirectPageXRead(fpb) -> void;
|
||||
auto instructionIndirectPageYRead(fpb) -> void;
|
||||
auto instructionIndirectXRead(fpb) -> void;
|
||||
auto instructionAbsoluteModifyBit(uint3) -> void;
|
||||
auto instructionAbsoluteIndexedWrite(uint8&) -> void;
|
||||
auto instructionBranch(bool) -> void;
|
||||
auto instructionDirectRead(fpb, uint8&) -> void;
|
||||
auto instructionDirectModify(fps) -> void;
|
||||
auto instructionDirectWrite(uint8&) -> void;
|
||||
auto instructionDirectWriteDirect(fpb) -> void;
|
||||
auto instructionDirectWriteImmediate(fpb) -> void;
|
||||
auto instructionDirectReadWord(fpw) -> void;
|
||||
auto instructionDirectModifyWord(int) -> void;
|
||||
auto instructionDirectIndexedRead(fpb, uint8&, uint8&) -> void;
|
||||
auto instructionDirectIndexedModify(fps, uint8&) -> void;
|
||||
auto instructionDirectIndexedWrite(uint8&, uint8&) -> void;
|
||||
auto instructionFlagClear(bool&) -> void;
|
||||
auto instructionFlagSet(bool&) -> void;
|
||||
auto instructionTransfer(uint8&, uint8&) -> void;
|
||||
auto instructionAbsoluteWrite(uint8&) -> void;
|
||||
auto instructionAbsoluteIndexedWrite(uint8&) -> void;
|
||||
auto instructionDirectPageWrite(uint8&) -> void;
|
||||
auto instructionDirectPageIndexedWrite(uint8&, uint8&) -> void;
|
||||
auto instructionDirectPageWriteImmediate(fpb) -> void;
|
||||
auto instructionDirectPageWriteDirectPage(fpb) -> void;
|
||||
auto instructionImmediateRead(fpb, uint8&) -> void;
|
||||
auto instructionImpliedModify(fps, uint8&) -> void;
|
||||
auto instructionIndexedIndirectRead(fpb, uint8&) -> void;
|
||||
auto instructionIndexedIndirectWrite(uint8&, uint8&) -> void;
|
||||
auto instructionIndirectIndexedRead(fpb, uint8&) -> void;
|
||||
auto instructionIndirectIndexedWrite(uint8&, uint8&) -> void;
|
||||
auto instructionIndirectXRead(fpb) -> void;
|
||||
auto instructionIndirectXWrite(uint8&) -> void;
|
||||
auto instructionIndirectXIncrementRead(uint8&) -> void;
|
||||
auto instructionIndirectXIncrementWrite(uint8&) -> void;
|
||||
auto instructionIndirectXWriteIndirectY(fpb) -> void;
|
||||
auto instructionPull(uint8&) -> void;
|
||||
auto instructionPush(uint8) -> void;
|
||||
auto instructionTransfer(uint8&, uint8&) -> void;
|
||||
|
||||
auto instructionBBC(uint3) -> void;
|
||||
auto instructionBBS(uint3) -> void;
|
||||
auto instructionBNEDirectPage() -> void;
|
||||
auto instructionBNEDirectPageDecrement() -> void;
|
||||
auto instructionBNEDirectPageX() -> void;
|
||||
auto instructionBNEDirect() -> void;
|
||||
auto instructionBNEDirectDecrement() -> void;
|
||||
auto instructionBNEDirectX() -> void;
|
||||
auto instructionBNEYDecrement() -> void;
|
||||
auto instructionBRK() -> void;
|
||||
auto instructionCLR(uint3) -> void;
|
||||
|
@ -91,23 +96,18 @@ struct SPC700 {
|
|||
auto instructionDAS() -> void;
|
||||
auto instructionDIV() -> void;
|
||||
auto instructionJMPAbsolute() -> void;
|
||||
auto instructionJMPIndirectAbsoluteX() -> void;
|
||||
auto instructionJSPDirectPage() -> void;
|
||||
auto instructionJMPIndirectX() -> void;
|
||||
auto instructionJSPDirect() -> void;
|
||||
auto instructionJSRAbsolute() -> void;
|
||||
auto instructionJST(uint4) -> void;
|
||||
auto instructionLDAIndirectXIncrement() -> void;
|
||||
auto instructionMUL() -> void;
|
||||
auto instructionNOP() -> void;
|
||||
auto instructionPLP() -> void;
|
||||
auto instructionRTI() -> void;
|
||||
auto instructionRTS() -> void;
|
||||
auto instructionSET(uint3) -> void;
|
||||
auto instructionSTAIndirectPageX() -> void;
|
||||
auto instructionSTAIndirectPageY() -> void;
|
||||
auto instructionSTAIndirectX() -> void;
|
||||
auto instructionSTAIndirectXIncrement() -> void;
|
||||
auto instructionSTP() -> void;
|
||||
auto instructionSTWDirectPage() -> void;
|
||||
auto instructionSTWDirect() -> void;
|
||||
auto instructionTRBAbsolute() -> void;
|
||||
auto instructionTSBAbsolute() -> void;
|
||||
auto instructionWAI() -> void;
|
||||
|
|
|
@ -2,8 +2,8 @@ auto Z80::instruction() -> void {
|
|||
//todo: return instruction() could cause stack crash from recursion
|
||||
//but this is needed to prevent IRQs from firing between prefixes and opcodes
|
||||
auto code = opcode();
|
||||
if(code == 0xdd) { r.hlp = &r.ix; return instruction(); }
|
||||
if(code == 0xfd) { r.hlp = &r.iy; return instruction(); }
|
||||
if(code == 0xdd) { prefix = Prefix::ix; return instruction(); }
|
||||
if(code == 0xfd) { prefix = Prefix::iy; return instruction(); }
|
||||
|
||||
if(r.ei) {
|
||||
r.ei = 0;
|
||||
|
@ -11,7 +11,7 @@ auto Z80::instruction() -> void {
|
|||
r.iff2 = 1;
|
||||
}
|
||||
|
||||
if(code == 0xcb && r.hlp != &r.hl) {
|
||||
if(code == 0xcb && prefix != Prefix::hl) {
|
||||
uint16 addr = HL + (int8)operand();
|
||||
wait(1);
|
||||
instructionCBd(addr, opcode());
|
||||
|
@ -23,7 +23,7 @@ auto Z80::instruction() -> void {
|
|||
instruction(code);
|
||||
}
|
||||
|
||||
r.hlp = &r.hl;
|
||||
prefix = Prefix::hl;
|
||||
}
|
||||
|
||||
#define op(id, name, ...) case id: return instruction##name(__VA_ARGS__);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#define AF r.af.word
|
||||
#define BC r.bc.word
|
||||
#define DE r.de.word
|
||||
#define HL r.hlp->word //virtual HL (overridden by IX/IY prefixes)
|
||||
#define HL (prefix == Prefix::ix ? r.ix.word : prefix == Prefix::iy ? r.iy.word : r.hl.word)
|
||||
|
||||
#define A r.af.byte.hi
|
||||
#define F r.af.byte.lo
|
||||
|
@ -9,8 +9,8 @@
|
|||
#define C r.bc.byte.lo
|
||||
#define D r.de.byte.hi
|
||||
#define E r.de.byte.lo
|
||||
#define H r.hlp->byte.hi
|
||||
#define L r.hlp->byte.lo
|
||||
#define H (prefix == Prefix::ix ? r.ix.byte.hi : prefix == Prefix::iy ? r.iy.byte.hi : r.hl.byte.hi)
|
||||
#define L (prefix == Prefix::ix ? r.ix.byte.lo : prefix == Prefix::iy ? r.iy.byte.lo : r.hl.byte.lo)
|
||||
|
||||
#define _HL r.hl.word //true HL (ignores IX/IY prefixes)
|
||||
#define _H r.hl.byte.hi
|
||||
|
|
|
@ -17,8 +17,7 @@ auto Z80::serialize(serializer& s) -> void {
|
|||
s.integer(r.iff1);
|
||||
s.integer(r.iff2);
|
||||
s.integer(r.im);
|
||||
|
||||
//todo: r.hlp is not serializable
|
||||
s.integer((uint&)prefix);
|
||||
}
|
||||
|
||||
auto Z80::Bus::serialize(serializer& s) -> void {
|
||||
|
|
|
@ -12,10 +12,8 @@ namespace Processor {
|
|||
#include "serialization.cpp"
|
||||
|
||||
auto Z80::power() -> void {
|
||||
memory::fill(&r, sizeof(Registers));
|
||||
r.hlp = &r.hl;
|
||||
bus->request(false);
|
||||
bus->grant(true);
|
||||
r = {};
|
||||
prefix = Prefix::hl;
|
||||
}
|
||||
|
||||
auto Z80::irq(bool maskable, uint16 pc, uint8 extbus) -> bool {
|
||||
|
|
|
@ -242,10 +242,10 @@ struct Z80 {
|
|||
bool iff1; //interrupt flip-flop 1
|
||||
bool iff2; //interrupt flip-flop 2
|
||||
uint2 im; //interrupt mode (0-2)
|
||||
|
||||
Pair* hlp = nullptr;
|
||||
} r;
|
||||
|
||||
enum class Prefix : uint { hl, ix, iy } prefix = Prefix::hl;
|
||||
|
||||
Bus* bus = nullptr;
|
||||
};
|
||||
|
||||
|
|
|
@ -173,11 +173,6 @@ auto SMP::writeBus(uint16 addr, uint8 data) -> void {
|
|||
writeRAM(addr, data); //all writes, even to MMIO registers, appear on bus
|
||||
}
|
||||
|
||||
auto SMP::idle() -> void {
|
||||
step(24);
|
||||
cycleEdge();
|
||||
}
|
||||
|
||||
auto SMP::read(uint16 addr) -> uint8 {
|
||||
step(12);
|
||||
uint8 data = readBus(addr);
|
||||
|
|
|
@ -52,7 +52,6 @@ private:
|
|||
auto readBus(uint16 addr) -> uint8;
|
||||
auto writeBus(uint16 addr, uint8 data) -> void;
|
||||
|
||||
auto idle() -> void override;
|
||||
auto read(uint16 addr) -> uint8 override;
|
||||
auto write(uint16 addr, uint8 data) -> void override;
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ ifeq ($(platform),macosx)
|
|||
else ifneq ($(filter $(platform),linux bsd),)
|
||||
mkdir -p $(prefix)/share/$(name)/Database/
|
||||
if [ -f out/$(name) ]; then cp out/$(name) $(prefix)/bin/$(name); fi
|
||||
cp -R Database/ $(prefix)/share/$(name)/Database/
|
||||
cp -R Database/* $(prefix)/share/$(name)/Database/
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
|
|
Loading…
Reference in New Issue