mirror of
https://github.com/libretro/bsnes-libretro.git
synced 2024-11-23 08:59:40 +00:00
Update to v098r11 release.
byuu says: Changelog: - fixed nall/path.hpp compilation issue - fixed ruby/audio/xaudio header declaration compilation issue (again) - cleaned up xaudio2.hpp file to match my coding syntax (12.5% of the file was whitespace overkill) - added null terminator entry to nall/windows/utf8.hpp argc[] array - nall/windows/guid.hpp uses the Windows API for generating the GUID - this should stop all the bug reports where two nall users were generating GUIDs at the exact same second - fixed hiro/cocoa compilation issue with uint# types - fixed major higan/sfc Super Game Boy audio latency issue - fixed higan/sfc CPU core bug with pei, [dp], [dp]+y instructions - major cleanups to higan/processor/r65816 core - merged emulation/native-mode opcodes - use camel-case naming on memory.hpp functions - simplify address masking code for memory.hpp functions - simplify a few opcodes themselves (avoid redundant copies, etc) - rename regs.* to r.* to match modern convention of other CPU cores - removed device.order<> concept from Emulator::Interface - cores will now do the translation to make the job of the UI easier - fixed plurality naming of arrays in Emulator::Interface - example: emulator.ports[p].devices[d].inputs[i] - example: vector<Medium> media - probably more surprises Major show-stoppers to the next official release: - we need to work on GB core improvements: LY=153/0 case, multiple STAT IRQs case, GBC audio output regs, etc. - we need to re-add software cursors for light guns (Super Scope, Justifier) - after the above, we need to fix the turbo button for the Super Scope I really have no idea how I want to implement the light guns. Ideally, we'd want it in higan/video, so we can support the NES Zapper with the same code. But this isn't going to be easy, because only the SNES knows when its output is interlaced, and its resolutions can vary as {256,512}x{224,240,448,480} which requires pixel doubling that was hard-coded to the SNES-specific behavior, but isn't appropriate to be exposed in higan/video.
This commit is contained in:
parent
3ebc77c148
commit
ae5d380d06
@ -8,7 +8,7 @@ using namespace nall;
|
||||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "098.10";
|
||||
static const string Version = "098.11";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
@ -17,13 +17,13 @@ struct Interface {
|
||||
} capability;
|
||||
} information;
|
||||
|
||||
struct Media {
|
||||
struct Medium {
|
||||
uint id;
|
||||
string name;
|
||||
string type;
|
||||
bool bootable; //false for cartridge slots (eg Sufami Turbo cartridges)
|
||||
};
|
||||
vector<Media> media;
|
||||
vector<Medium> media;
|
||||
|
||||
struct Device {
|
||||
uint id;
|
||||
@ -35,16 +35,15 @@ struct Interface {
|
||||
string name;
|
||||
uintptr guid; //user data field
|
||||
};
|
||||
vector<Input> input;
|
||||
vector<uint> order;
|
||||
vector<Input> inputs;
|
||||
};
|
||||
|
||||
struct Port {
|
||||
uint id;
|
||||
string name;
|
||||
vector<Device> device;
|
||||
vector<Device> devices;
|
||||
};
|
||||
vector<Port> port;
|
||||
vector<Port> ports;
|
||||
|
||||
struct Bind {
|
||||
virtual auto loadRequest(uint, string, string, bool) -> void {}
|
||||
|
@ -15,12 +15,15 @@ auto Input::latch(bool data) -> void {
|
||||
}
|
||||
|
||||
auto Input::data(bool port) -> bool {
|
||||
//table to convert native button ordering to Emulator::Interface ordering
|
||||
static const uint lookup[] = {5, 4, 6, 7, 0, 1, 2, 3};
|
||||
|
||||
bool result = 0;
|
||||
|
||||
if(port == 0) {
|
||||
if(port1 == Device::Joypad) {
|
||||
if(counter1 >= 8) return 1;
|
||||
result = interface->inputPoll(0, 0u, counter1);
|
||||
result = interface->inputPoll(0, 0u, lookup[counter1]);
|
||||
if(latchdata == 0) counter1++;
|
||||
}
|
||||
}
|
||||
@ -28,7 +31,7 @@ auto Input::data(bool port) -> bool {
|
||||
if(port == 1) {
|
||||
if(port2 == Device::Joypad) {
|
||||
if(counter2 >= 8) return 1;
|
||||
result = interface->inputPoll(1, 0u, counter2);
|
||||
result = interface->inputPoll(1, 0u, lookup[counter2]);
|
||||
if(latchdata == 0) counter2++;
|
||||
}
|
||||
}
|
||||
|
@ -22,25 +22,24 @@ Interface::Interface() {
|
||||
media.append({ID::Famicom, "Famicom", "fc", true});
|
||||
|
||||
{ Device device{0, ID::Port1 | ID::Port2, "Controller"};
|
||||
device.input.append({0, 0, "A" });
|
||||
device.input.append({1, 0, "B" });
|
||||
device.input.append({2, 0, "Select"});
|
||||
device.input.append({3, 0, "Start" });
|
||||
device.input.append({4, 0, "Up" });
|
||||
device.input.append({5, 0, "Down" });
|
||||
device.input.append({6, 0, "Left" });
|
||||
device.input.append({7, 0, "Right" });
|
||||
device.order = {4, 5, 6, 7, 1, 0, 2, 3};
|
||||
this->device.append(device);
|
||||
device.inputs.append({0, 0, "Up" });
|
||||
device.inputs.append({1, 0, "Down" });
|
||||
device.inputs.append({2, 0, "Left" });
|
||||
device.inputs.append({3, 0, "Right" });
|
||||
device.inputs.append({4, 0, "B" });
|
||||
device.inputs.append({5, 0, "A" });
|
||||
device.inputs.append({6, 0, "Select"});
|
||||
device.inputs.append({7, 0, "Start" });
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
port.append({0, "Port 1"});
|
||||
port.append({1, "Port 2"});
|
||||
ports.append({0, "Port 1"});
|
||||
ports.append({1, "Port 2"});
|
||||
|
||||
for(auto& device : this->device) {
|
||||
for(auto& port : this->port) {
|
||||
for(auto& device : devices) {
|
||||
for(auto& port : ports) {
|
||||
if(device.portmask & (1 << port.id)) {
|
||||
port.device.append(device);
|
||||
port.devices.append(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -98,14 +97,14 @@ auto Interface::videoColor(uint32 n) -> uint64 {
|
||||
v *= brightness / 12.0;
|
||||
|
||||
y += v;
|
||||
i += v * std::cos((3.141592653 / 6.0) * (p + hue));
|
||||
q += v * std::sin((3.141592653 / 6.0) * (p + hue));
|
||||
i += v * cos((3.141592653 / 6.0) * (p + hue));
|
||||
q += v * sin((3.141592653 / 6.0) * (p + hue));
|
||||
}
|
||||
|
||||
i *= saturation;
|
||||
q *= saturation;
|
||||
|
||||
auto gammaAdjust = [=](double f) { return f < 0.0 ? 0.0 : std::pow(f, 2.2 / gamma); };
|
||||
auto gammaAdjust = [=](double f) { return f < 0.0 ? 0.0 : pow(f, 2.2 / gamma); };
|
||||
uint64 r = uclamp<16>(65535.0 * gammaAdjust(y + 0.946882 * i + 0.623557 * q));
|
||||
uint64 g = uclamp<16>(65535.0 * gammaAdjust(y + -0.274788 * i + -0.635691 * q));
|
||||
uint64 b = uclamp<16>(65535.0 * gammaAdjust(y + -1.108545 * i + 1.709007 * q));
|
||||
|
@ -55,7 +55,7 @@ struct Interface : Emulator::Interface {
|
||||
auto set(const string& name, const any& value) -> bool override;
|
||||
|
||||
private:
|
||||
vector<Device> device;
|
||||
vector<Device> devices;
|
||||
};
|
||||
|
||||
struct Settings {
|
||||
|
@ -25,19 +25,18 @@ Interface::Interface() {
|
||||
|
||||
{
|
||||
Device device{0, ID::Device, "Controller"};
|
||||
device.input.append({0, 0, "Up" });
|
||||
device.input.append({1, 0, "Down" });
|
||||
device.input.append({2, 0, "Left" });
|
||||
device.input.append({3, 0, "Right" });
|
||||
device.input.append({4, 0, "B" });
|
||||
device.input.append({5, 0, "A" });
|
||||
device.input.append({6, 0, "Select"});
|
||||
device.input.append({7, 0, "Start" });
|
||||
device.order = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||
this->device.append(device);
|
||||
device.inputs.append({0, 0, "Up" });
|
||||
device.inputs.append({1, 0, "Down" });
|
||||
device.inputs.append({2, 0, "Left" });
|
||||
device.inputs.append({3, 0, "Right" });
|
||||
device.inputs.append({4, 0, "B" });
|
||||
device.inputs.append({5, 0, "A" });
|
||||
device.inputs.append({6, 0, "Select"});
|
||||
device.inputs.append({7, 0, "Start" });
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
port.append({0, "Device", {device[0]}});
|
||||
ports.append({0, "Device", {devices[0]}});
|
||||
}
|
||||
|
||||
auto Interface::manifest() -> string {
|
||||
|
@ -69,7 +69,7 @@ struct Interface : Emulator::Interface {
|
||||
auto joypWrite(bool p15, bool p14) -> void;
|
||||
|
||||
private:
|
||||
vector<Device> device;
|
||||
vector<Device> devices;
|
||||
};
|
||||
|
||||
struct Settings {
|
||||
|
@ -91,12 +91,15 @@ auto CPU::sync_step(uint clocks) -> void {
|
||||
}
|
||||
|
||||
auto CPU::keypad_run() -> void {
|
||||
if(regs.keypad.control.enable == false) return;
|
||||
//lookup table to convert button indexes to Emulator::Interface indexes
|
||||
static const uint lookup[] = {5, 4, 8, 9, 3, 2, 0, 1, 7, 6};
|
||||
|
||||
if(!regs.keypad.control.enable) return;
|
||||
|
||||
bool test = regs.keypad.control.condition; //0 = OR, 1 = AND
|
||||
for(auto n : range(10)) {
|
||||
if(regs.keypad.control.flag[n] == false) continue;
|
||||
bool input = interface->inputPoll(0, 0, n);
|
||||
if(!regs.keypad.control.flag[n]) continue;
|
||||
bool input = interface->inputPoll(0, 0, lookup[n]);
|
||||
if(regs.keypad.control.condition == 0) test |= input;
|
||||
if(regs.keypad.control.condition == 1) test &= input;
|
||||
}
|
||||
|
@ -61,9 +61,10 @@ auto CPU::read(uint32 addr) -> uint8 {
|
||||
|
||||
//KEYINPUT
|
||||
case 0x04000130: {
|
||||
static const uint lookup[] = {5, 4, 8, 9, 3, 2, 0, 1};
|
||||
if(auto result = player.keyinput()) return result() >> 0;
|
||||
uint8 result = 0;
|
||||
for(uint n = 0; n < 8; n++) result |= interface->inputPoll(0, 0, n) << n;
|
||||
for(uint n = 0; n < 8; n++) result |= interface->inputPoll(0, 0, lookup[n]) << n;
|
||||
if((result & 0xc0) == 0xc0) result &= (uint8)~0xc0; //up+down cannot be pressed simultaneously
|
||||
if((result & 0x30) == 0x30) result &= (uint8)~0x30; //left+right cannot be pressed simultaneously
|
||||
return result ^ 0xff;
|
||||
@ -71,8 +72,8 @@ auto CPU::read(uint32 addr) -> uint8 {
|
||||
case 0x04000131: {
|
||||
if(auto result = player.keyinput()) return result() >> 8;
|
||||
uint8 result = 0;
|
||||
result |= interface->inputPoll(0, 0, 8) << 0;
|
||||
result |= interface->inputPoll(0, 0, 9) << 1;
|
||||
result |= interface->inputPoll(0, 0, 7) << 0;
|
||||
result |= interface->inputPoll(0, 0, 6) << 1;
|
||||
return result ^ 0x03;
|
||||
}
|
||||
|
||||
|
@ -22,22 +22,21 @@ Interface::Interface() {
|
||||
media.append({ID::GameBoyAdvance, "Game Boy Advance", "gba", true});
|
||||
|
||||
{ Device device{0, ID::Device, "Controller"};
|
||||
device.input.append({ 0, 0, "A" });
|
||||
device.input.append({ 1, 0, "B" });
|
||||
device.input.append({ 2, 0, "Select"});
|
||||
device.input.append({ 3, 0, "Start" });
|
||||
device.input.append({ 4, 0, "Right" });
|
||||
device.input.append({ 5, 0, "Left" });
|
||||
device.input.append({ 6, 0, "Up" });
|
||||
device.input.append({ 7, 0, "Down" });
|
||||
device.input.append({ 8, 0, "R" });
|
||||
device.input.append({ 9, 0, "L" });
|
||||
device.input.append({10, 2, "Rumble"});
|
||||
device.order = {6, 7, 5, 4, 1, 0, 9, 8, 2, 3, 10};
|
||||
this->device.append(device);
|
||||
device.inputs.append({ 0, 0, "Up" });
|
||||
device.inputs.append({ 1, 0, "Down" });
|
||||
device.inputs.append({ 2, 0, "Left" });
|
||||
device.inputs.append({ 3, 0, "Right" });
|
||||
device.inputs.append({ 4, 0, "B" });
|
||||
device.inputs.append({ 5, 0, "A" });
|
||||
device.inputs.append({ 6, 0, "L" });
|
||||
device.inputs.append({ 7, 0, "R" });
|
||||
device.inputs.append({ 8, 0, "Select"});
|
||||
device.inputs.append({ 9, 0, "Start" });
|
||||
device.inputs.append({10, 2, "Rumble"});
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
port.append({0, "Device", {device[0]}});
|
||||
ports.append({0, "Device", {devices[0]}});
|
||||
}
|
||||
|
||||
auto Interface::manifest() -> string {
|
||||
|
@ -52,7 +52,7 @@ struct Interface : Emulator::Interface {
|
||||
auto set(const string& name, const any& value) -> bool override;
|
||||
|
||||
private:
|
||||
vector<Device> device;
|
||||
vector<Device> devices;
|
||||
};
|
||||
|
||||
struct Settings {
|
||||
|
@ -1,327 +1,327 @@
|
||||
auto R65816::op_adc_b() {
|
||||
int result;
|
||||
|
||||
if(!regs.p.d) {
|
||||
result = regs.a.l + rd.l + regs.p.c;
|
||||
if(!r.p.d) {
|
||||
result = r.a.l + rd.l + r.p.c;
|
||||
} else {
|
||||
result = (regs.a.l & 0x0f) + (rd.l & 0x0f) + (regs.p.c << 0);
|
||||
result = (r.a.l & 0x0f) + (rd.l & 0x0f) + (r.p.c << 0);
|
||||
if(result > 0x09) result += 0x06;
|
||||
regs.p.c = result > 0x0f;
|
||||
result = (regs.a.l & 0xf0) + (rd.l & 0xf0) + (regs.p.c << 4) + (result & 0x0f);
|
||||
r.p.c = result > 0x0f;
|
||||
result = (r.a.l & 0xf0) + (rd.l & 0xf0) + (r.p.c << 4) + (result & 0x0f);
|
||||
}
|
||||
|
||||
regs.p.v = ~(regs.a.l ^ rd.l) & (regs.a.l ^ result) & 0x80;
|
||||
if(regs.p.d && result > 0x9f) result += 0x60;
|
||||
regs.p.c = result > 0xff;
|
||||
regs.p.n = result & 0x80;
|
||||
regs.p.z = (uint8_t)result == 0;
|
||||
r.p.v = ~(r.a.l ^ rd.l) & (r.a.l ^ result) & 0x80;
|
||||
if(r.p.d && result > 0x9f) result += 0x60;
|
||||
r.p.c = result > 0xff;
|
||||
r.p.n = result & 0x80;
|
||||
r.p.z = (uint8)result == 0;
|
||||
|
||||
regs.a.l = result;
|
||||
r.a.l = result;
|
||||
}
|
||||
|
||||
auto R65816::op_adc_w() {
|
||||
int result;
|
||||
|
||||
if(!regs.p.d) {
|
||||
result = regs.a.w + rd.w + regs.p.c;
|
||||
if(!r.p.d) {
|
||||
result = r.a.w + rd.w + r.p.c;
|
||||
} else {
|
||||
result = (regs.a.w & 0x000f) + (rd.w & 0x000f) + (regs.p.c << 0);
|
||||
result = (r.a.w & 0x000f) + (rd.w & 0x000f) + (r.p.c << 0);
|
||||
if(result > 0x0009) result += 0x0006;
|
||||
regs.p.c = result > 0x000f;
|
||||
result = (regs.a.w & 0x00f0) + (rd.w & 0x00f0) + (regs.p.c << 4) + (result & 0x000f);
|
||||
r.p.c = result > 0x000f;
|
||||
result = (r.a.w & 0x00f0) + (rd.w & 0x00f0) + (r.p.c << 4) + (result & 0x000f);
|
||||
if(result > 0x009f) result += 0x0060;
|
||||
regs.p.c = result > 0x00ff;
|
||||
result = (regs.a.w & 0x0f00) + (rd.w & 0x0f00) + (regs.p.c << 8) + (result & 0x00ff);
|
||||
r.p.c = result > 0x00ff;
|
||||
result = (r.a.w & 0x0f00) + (rd.w & 0x0f00) + (r.p.c << 8) + (result & 0x00ff);
|
||||
if(result > 0x09ff) result += 0x0600;
|
||||
regs.p.c = result > 0x0fff;
|
||||
result = (regs.a.w & 0xf000) + (rd.w & 0xf000) + (regs.p.c << 12) + (result & 0x0fff);
|
||||
r.p.c = result > 0x0fff;
|
||||
result = (r.a.w & 0xf000) + (rd.w & 0xf000) + (r.p.c << 12) + (result & 0x0fff);
|
||||
}
|
||||
|
||||
regs.p.v = ~(regs.a.w ^ rd.w) & (regs.a.w ^ result) & 0x8000;
|
||||
if(regs.p.d && result > 0x9fff) result += 0x6000;
|
||||
regs.p.c = result > 0xffff;
|
||||
regs.p.n = result & 0x8000;
|
||||
regs.p.z = (uint16_t)result == 0;
|
||||
r.p.v = ~(r.a.w ^ rd.w) & (r.a.w ^ result) & 0x8000;
|
||||
if(r.p.d && result > 0x9fff) result += 0x6000;
|
||||
r.p.c = result > 0xffff;
|
||||
r.p.n = result & 0x8000;
|
||||
r.p.z = (uint16)result == 0;
|
||||
|
||||
regs.a.w = result;
|
||||
r.a.w = result;
|
||||
}
|
||||
|
||||
auto R65816::op_and_b() {
|
||||
regs.a.l &= rd.l;
|
||||
regs.p.n = regs.a.l & 0x80;
|
||||
regs.p.z = regs.a.l == 0;
|
||||
r.a.l &= rd.l;
|
||||
r.p.n = r.a.l & 0x80;
|
||||
r.p.z = r.a.l == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_and_w() {
|
||||
regs.a.w &= rd.w;
|
||||
regs.p.n = regs.a.w & 0x8000;
|
||||
regs.p.z = regs.a.w == 0;
|
||||
r.a.w &= rd.w;
|
||||
r.p.n = r.a.w & 0x8000;
|
||||
r.p.z = r.a.w == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_bit_b() {
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.v = rd.l & 0x40;
|
||||
regs.p.z = (rd.l & regs.a.l) == 0;
|
||||
r.p.n = rd.l & 0x80;
|
||||
r.p.v = rd.l & 0x40;
|
||||
r.p.z = (rd.l & r.a.l) == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_bit_w() {
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.v = rd.w & 0x4000;
|
||||
regs.p.z = (rd.w & regs.a.w) == 0;
|
||||
r.p.n = rd.w & 0x8000;
|
||||
r.p.v = rd.w & 0x4000;
|
||||
r.p.z = (rd.w & r.a.w) == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_cmp_b() {
|
||||
int r = regs.a.l - rd.l;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
int result = r.a.l - rd.l;
|
||||
r.p.n = result & 0x80;
|
||||
r.p.z = (uint8)result == 0;
|
||||
r.p.c = result >= 0;
|
||||
}
|
||||
|
||||
auto R65816::op_cmp_w() {
|
||||
int r = regs.a.w - rd.w;
|
||||
regs.p.n = r & 0x8000;
|
||||
regs.p.z = (uint16)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
int result = r.a.w - rd.w;
|
||||
r.p.n = result & 0x8000;
|
||||
r.p.z = (uint16)result == 0;
|
||||
r.p.c = result >= 0;
|
||||
}
|
||||
|
||||
auto R65816::op_cpx_b() {
|
||||
int r = regs.x.l - rd.l;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
int result = r.x.l - rd.l;
|
||||
r.p.n = result & 0x80;
|
||||
r.p.z = (uint8)result == 0;
|
||||
r.p.c = result >= 0;
|
||||
}
|
||||
|
||||
auto R65816::op_cpx_w() {
|
||||
int r = regs.x.w - rd.w;
|
||||
regs.p.n = r & 0x8000;
|
||||
regs.p.z = (uint16)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
int result = r.x.w - rd.w;
|
||||
r.p.n = result & 0x8000;
|
||||
r.p.z = (uint16)result == 0;
|
||||
r.p.c = result >= 0;
|
||||
}
|
||||
|
||||
auto R65816::op_cpy_b() {
|
||||
int r = regs.y.l - rd.l;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
int result = r.y.l - rd.l;
|
||||
r.p.n = result & 0x80;
|
||||
r.p.z = (uint8)result == 0;
|
||||
r.p.c = result >= 0;
|
||||
}
|
||||
|
||||
auto R65816::op_cpy_w() {
|
||||
int r = regs.y.w - rd.w;
|
||||
regs.p.n = r & 0x8000;
|
||||
regs.p.z = (uint16)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
int result = r.y.w - rd.w;
|
||||
r.p.n = result & 0x8000;
|
||||
r.p.z = (uint16)result == 0;
|
||||
r.p.c = result >= 0;
|
||||
}
|
||||
|
||||
auto R65816::op_eor_b() {
|
||||
regs.a.l ^= rd.l;
|
||||
regs.p.n = regs.a.l & 0x80;
|
||||
regs.p.z = regs.a.l == 0;
|
||||
r.a.l ^= rd.l;
|
||||
r.p.n = r.a.l & 0x80;
|
||||
r.p.z = r.a.l == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_eor_w() {
|
||||
regs.a.w ^= rd.w;
|
||||
regs.p.n = regs.a.w & 0x8000;
|
||||
regs.p.z = regs.a.w == 0;
|
||||
r.a.w ^= rd.w;
|
||||
r.p.n = r.a.w & 0x8000;
|
||||
r.p.z = r.a.w == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_lda_b() {
|
||||
regs.a.l = rd.l;
|
||||
regs.p.n = regs.a.l & 0x80;
|
||||
regs.p.z = regs.a.l == 0;
|
||||
r.a.l = rd.l;
|
||||
r.p.n = r.a.l & 0x80;
|
||||
r.p.z = r.a.l == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_lda_w() {
|
||||
regs.a.w = rd.w;
|
||||
regs.p.n = regs.a.w & 0x8000;
|
||||
regs.p.z = regs.a.w == 0;
|
||||
r.a.w = rd.w;
|
||||
r.p.n = r.a.w & 0x8000;
|
||||
r.p.z = r.a.w == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_ldx_b() {
|
||||
regs.x.l = rd.l;
|
||||
regs.p.n = regs.x.l & 0x80;
|
||||
regs.p.z = regs.x.l == 0;
|
||||
r.x.l = rd.l;
|
||||
r.p.n = r.x.l & 0x80;
|
||||
r.p.z = r.x.l == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_ldx_w() {
|
||||
regs.x.w = rd.w;
|
||||
regs.p.n = regs.x.w & 0x8000;
|
||||
regs.p.z = regs.x.w == 0;
|
||||
r.x.w = rd.w;
|
||||
r.p.n = r.x.w & 0x8000;
|
||||
r.p.z = r.x.w == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_ldy_b() {
|
||||
regs.y.l = rd.l;
|
||||
regs.p.n = regs.y.l & 0x80;
|
||||
regs.p.z = regs.y.l == 0;
|
||||
r.y.l = rd.l;
|
||||
r.p.n = r.y.l & 0x80;
|
||||
r.p.z = r.y.l == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_ldy_w() {
|
||||
regs.y.w = rd.w;
|
||||
regs.p.n = regs.y.w & 0x8000;
|
||||
regs.p.z = regs.y.w == 0;
|
||||
r.y.w = rd.w;
|
||||
r.p.n = r.y.w & 0x8000;
|
||||
r.p.z = r.y.w == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_ora_b() {
|
||||
regs.a.l |= rd.l;
|
||||
regs.p.n = regs.a.l & 0x80;
|
||||
regs.p.z = regs.a.l == 0;
|
||||
r.a.l |= rd.l;
|
||||
r.p.n = r.a.l & 0x80;
|
||||
r.p.z = r.a.l == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_ora_w() {
|
||||
regs.a.w |= rd.w;
|
||||
regs.p.n = regs.a.w & 0x8000;
|
||||
regs.p.z = regs.a.w == 0;
|
||||
r.a.w |= rd.w;
|
||||
r.p.n = r.a.w & 0x8000;
|
||||
r.p.z = r.a.w == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_sbc_b() {
|
||||
int result;
|
||||
rd.l ^= 0xff;
|
||||
|
||||
if(!regs.p.d) {
|
||||
result = regs.a.l + rd.l + regs.p.c;
|
||||
if(!r.p.d) {
|
||||
result = r.a.l + rd.l + r.p.c;
|
||||
} else {
|
||||
result = (regs.a.l & 0x0f) + (rd.l & 0x0f) + (regs.p.c << 0);
|
||||
result = (r.a.l & 0x0f) + (rd.l & 0x0f) + (r.p.c << 0);
|
||||
if(result <= 0x0f) result -= 0x06;
|
||||
regs.p.c = result > 0x0f;
|
||||
result = (regs.a.l & 0xf0) + (rd.l & 0xf0) + (regs.p.c << 4) + (result & 0x0f);
|
||||
r.p.c = result > 0x0f;
|
||||
result = (r.a.l & 0xf0) + (rd.l & 0xf0) + (r.p.c << 4) + (result & 0x0f);
|
||||
}
|
||||
|
||||
regs.p.v = ~(regs.a.l ^ rd.l) & (regs.a.l ^ result) & 0x80;
|
||||
if(regs.p.d && result <= 0xff) result -= 0x60;
|
||||
regs.p.c = result > 0xff;
|
||||
regs.p.n = result & 0x80;
|
||||
regs.p.z = (uint8_t)result == 0;
|
||||
r.p.v = ~(r.a.l ^ rd.l) & (r.a.l ^ result) & 0x80;
|
||||
if(r.p.d && result <= 0xff) result -= 0x60;
|
||||
r.p.c = result > 0xff;
|
||||
r.p.n = result & 0x80;
|
||||
r.p.z = (uint8_t)result == 0;
|
||||
|
||||
regs.a.l = result;
|
||||
r.a.l = result;
|
||||
}
|
||||
|
||||
auto R65816::op_sbc_w() {
|
||||
int result;
|
||||
rd.w ^= 0xffff;
|
||||
|
||||
if(!regs.p.d) {
|
||||
result = regs.a.w + rd.w + regs.p.c;
|
||||
if(!r.p.d) {
|
||||
result = r.a.w + rd.w + r.p.c;
|
||||
} else {
|
||||
result = (regs.a.w & 0x000f) + (rd.w & 0x000f) + (regs.p.c << 0);
|
||||
result = (r.a.w & 0x000f) + (rd.w & 0x000f) + (r.p.c << 0);
|
||||
if(result <= 0x000f) result -= 0x0006;
|
||||
regs.p.c = result > 0x000f;
|
||||
result = (regs.a.w & 0x00f0) + (rd.w & 0x00f0) + (regs.p.c << 4) + (result & 0x000f);
|
||||
r.p.c = result > 0x000f;
|
||||
result = (r.a.w & 0x00f0) + (rd.w & 0x00f0) + (r.p.c << 4) + (result & 0x000f);
|
||||
if(result <= 0x00ff) result -= 0x0060;
|
||||
regs.p.c = result > 0x00ff;
|
||||
result = (regs.a.w & 0x0f00) + (rd.w & 0x0f00) + (regs.p.c << 8) + (result & 0x00ff);
|
||||
r.p.c = result > 0x00ff;
|
||||
result = (r.a.w & 0x0f00) + (rd.w & 0x0f00) + (r.p.c << 8) + (result & 0x00ff);
|
||||
if(result <= 0x0fff) result -= 0x0600;
|
||||
regs.p.c = result > 0x0fff;
|
||||
result = (regs.a.w & 0xf000) + (rd.w & 0xf000) + (regs.p.c << 12) + (result & 0x0fff);
|
||||
r.p.c = result > 0x0fff;
|
||||
result = (r.a.w & 0xf000) + (rd.w & 0xf000) + (r.p.c << 12) + (result & 0x0fff);
|
||||
}
|
||||
|
||||
regs.p.v = ~(regs.a.w ^ rd.w) & (regs.a.w ^ result) & 0x8000;
|
||||
if(regs.p.d && result <= 0xffff) result -= 0x6000;
|
||||
regs.p.c = result > 0xffff;
|
||||
regs.p.n = result & 0x8000;
|
||||
regs.p.z = (uint16_t)result == 0;
|
||||
r.p.v = ~(r.a.w ^ rd.w) & (r.a.w ^ result) & 0x8000;
|
||||
if(r.p.d && result <= 0xffff) result -= 0x6000;
|
||||
r.p.c = result > 0xffff;
|
||||
r.p.n = result & 0x8000;
|
||||
r.p.z = (uint16_t)result == 0;
|
||||
|
||||
regs.a.w = result;
|
||||
r.a.w = result;
|
||||
}
|
||||
|
||||
auto R65816::op_inc_b() {
|
||||
rd.l++;
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.z = rd.l == 0;
|
||||
r.p.n = rd.l & 0x80;
|
||||
r.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_inc_w() {
|
||||
rd.w++;
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.z = rd.w == 0;
|
||||
r.p.n = rd.w & 0x8000;
|
||||
r.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_dec_b() {
|
||||
rd.l--;
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.z = rd.l == 0;
|
||||
r.p.n = rd.l & 0x80;
|
||||
r.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_dec_w() {
|
||||
rd.w--;
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.z = rd.w == 0;
|
||||
r.p.n = rd.w & 0x8000;
|
||||
r.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_asl_b() {
|
||||
regs.p.c = rd.l & 0x80;
|
||||
r.p.c = rd.l & 0x80;
|
||||
rd.l <<= 1;
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.z = rd.l == 0;
|
||||
r.p.n = rd.l & 0x80;
|
||||
r.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_asl_w() {
|
||||
regs.p.c = rd.w & 0x8000;
|
||||
r.p.c = rd.w & 0x8000;
|
||||
rd.w <<= 1;
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.z = rd.w == 0;
|
||||
r.p.n = rd.w & 0x8000;
|
||||
r.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_lsr_b() {
|
||||
regs.p.c = rd.l & 1;
|
||||
r.p.c = rd.l & 1;
|
||||
rd.l >>= 1;
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.z = rd.l == 0;
|
||||
r.p.n = rd.l & 0x80;
|
||||
r.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_lsr_w() {
|
||||
regs.p.c = rd.w & 1;
|
||||
r.p.c = rd.w & 1;
|
||||
rd.w >>= 1;
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.z = rd.w == 0;
|
||||
r.p.n = rd.w & 0x8000;
|
||||
r.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_rol_b() {
|
||||
unsigned carry = (unsigned)regs.p.c;
|
||||
regs.p.c = rd.l & 0x80;
|
||||
auto carry = (uint)r.p.c;
|
||||
r.p.c = rd.l & 0x80;
|
||||
rd.l = (rd.l << 1) | carry;
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.z = rd.l == 0;
|
||||
r.p.n = rd.l & 0x80;
|
||||
r.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_rol_w() {
|
||||
unsigned carry = (unsigned)regs.p.c;
|
||||
regs.p.c = rd.w & 0x8000;
|
||||
auto carry = (uint)r.p.c;
|
||||
r.p.c = rd.w & 0x8000;
|
||||
rd.w = (rd.w << 1) | carry;
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.z = rd.w == 0;
|
||||
r.p.n = rd.w & 0x8000;
|
||||
r.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_ror_b() {
|
||||
unsigned carry = (unsigned)regs.p.c << 7;
|
||||
regs.p.c = rd.l & 1;
|
||||
auto carry = (uint)r.p.c << 7;
|
||||
r.p.c = rd.l & 1;
|
||||
rd.l = carry | (rd.l >> 1);
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.z = rd.l == 0;
|
||||
r.p.n = rd.l & 0x80;
|
||||
r.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_ror_w() {
|
||||
unsigned carry = (unsigned)regs.p.c << 15;
|
||||
regs.p.c = rd.w & 1;
|
||||
auto carry = (uint)r.p.c << 15;
|
||||
r.p.c = rd.w & 1;
|
||||
rd.w = carry | (rd.w >> 1);
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.z = rd.w == 0;
|
||||
r.p.n = rd.w & 0x8000;
|
||||
r.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
auto R65816::op_trb_b() {
|
||||
regs.p.z = (rd.l & regs.a.l) == 0;
|
||||
rd.l &= ~regs.a.l;
|
||||
r.p.z = (rd.l & r.a.l) == 0;
|
||||
rd.l &= ~r.a.l;
|
||||
}
|
||||
|
||||
auto R65816::op_trb_w() {
|
||||
regs.p.z = (rd.w & regs.a.w) == 0;
|
||||
rd.w &= ~regs.a.w;
|
||||
r.p.z = (rd.w & r.a.w) == 0;
|
||||
rd.w &= ~r.a.w;
|
||||
}
|
||||
|
||||
auto R65816::op_tsb_b() {
|
||||
regs.p.z = (rd.l & regs.a.l) == 0;
|
||||
rd.l |= regs.a.l;
|
||||
r.p.z = (rd.l & r.a.l) == 0;
|
||||
rd.l |= r.a.l;
|
||||
}
|
||||
|
||||
auto R65816::op_tsb_w() {
|
||||
regs.p.z = (rd.w & regs.a.w) == 0;
|
||||
rd.w |= regs.a.w;
|
||||
r.p.z = (rd.w & r.a.w) == 0;
|
||||
rd.w |= r.a.w;
|
||||
}
|
||||
|
@ -23,93 +23,93 @@ auto R65816::dreadl(uint24 addr) -> uint24 {
|
||||
}
|
||||
|
||||
auto R65816::decode(uint8 mode, uint24 addr) -> uint24 {
|
||||
uint24 r = 0;
|
||||
uint24 a = 0;
|
||||
|
||||
switch(mode) {
|
||||
case OPTYPE_DP:
|
||||
r = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
a = (r.d + (addr & 0xffff)) & 0xffff;
|
||||
break;
|
||||
case OPTYPE_DPX:
|
||||
r = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
|
||||
a = (r.d + r.x + (addr & 0xffff)) & 0xffff;
|
||||
break;
|
||||
case OPTYPE_DPY:
|
||||
r = (regs.d + regs.y + (addr & 0xffff)) & 0xffff;
|
||||
a = (r.d + r.y + (addr & 0xffff)) & 0xffff;
|
||||
break;
|
||||
case OPTYPE_IDP:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = (regs.db << 16) + dreadw(addr);
|
||||
addr = (r.d + (addr & 0xffff)) & 0xffff;
|
||||
a = (r.db << 16) + dreadw(addr);
|
||||
break;
|
||||
case OPTYPE_IDPX:
|
||||
addr = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
|
||||
r = (regs.db << 16) + dreadw(addr);
|
||||
addr = (r.d + r.x + (addr & 0xffff)) & 0xffff;
|
||||
a = (r.db << 16) + dreadw(addr);
|
||||
break;
|
||||
case OPTYPE_IDPY:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = (regs.db << 16) + dreadw(addr) + regs.y;
|
||||
addr = (r.d + (addr & 0xffff)) & 0xffff;
|
||||
a = (r.db << 16) + dreadw(addr) + r.y;
|
||||
break;
|
||||
case OPTYPE_ILDP:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = dreadl(addr);
|
||||
addr = (r.d + (addr & 0xffff)) & 0xffff;
|
||||
a = dreadl(addr);
|
||||
break;
|
||||
case OPTYPE_ILDPY:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = dreadl(addr) + regs.y;
|
||||
addr = (r.d + (addr & 0xffff)) & 0xffff;
|
||||
a = dreadl(addr) + r.y;
|
||||
break;
|
||||
case OPTYPE_ADDR:
|
||||
r = (regs.db << 16) + (addr & 0xffff);
|
||||
a = (r.db << 16) + (addr & 0xffff);
|
||||
break;
|
||||
case OPTYPE_ADDR_PC:
|
||||
r = (regs.pc.b << 16) + (addr & 0xffff);
|
||||
a = (r.pc.b << 16) + (addr & 0xffff);
|
||||
break;
|
||||
case OPTYPE_ADDRX:
|
||||
r = (regs.db << 16) + (addr & 0xffff) + regs.x;
|
||||
a = (r.db << 16) + (addr & 0xffff) + r.x;
|
||||
break;
|
||||
case OPTYPE_ADDRY:
|
||||
r = (regs.db << 16) + (addr & 0xffff) + regs.y;
|
||||
a = (r.db << 16) + (addr & 0xffff) + r.y;
|
||||
break;
|
||||
case OPTYPE_IADDR_PC:
|
||||
r = (regs.pc.b << 16) + (addr & 0xffff);
|
||||
a = (r.pc.b << 16) + (addr & 0xffff);
|
||||
break;
|
||||
case OPTYPE_IADDRX:
|
||||
r = (regs.pc.b << 16) + ((addr + regs.x) & 0xffff);
|
||||
a = (r.pc.b << 16) + ((addr + r.x) & 0xffff);
|
||||
break;
|
||||
case OPTYPE_ILADDR:
|
||||
r = addr;
|
||||
a = addr;
|
||||
break;
|
||||
case OPTYPE_LONG:
|
||||
r = addr;
|
||||
a = addr;
|
||||
break;
|
||||
case OPTYPE_LONGX:
|
||||
r = (addr + regs.x);
|
||||
a = (addr + r.x);
|
||||
break;
|
||||
case OPTYPE_SR:
|
||||
r = (regs.s + (addr & 0xff)) & 0xffff;
|
||||
a = (r.s + (addr & 0xff)) & 0xffff;
|
||||
break;
|
||||
case OPTYPE_ISRY:
|
||||
addr = (regs.s + (addr & 0xff)) & 0xffff;
|
||||
r = (regs.db << 16) + dreadw(addr) + regs.y;
|
||||
addr = (r.s + (addr & 0xff)) & 0xffff;
|
||||
a = (r.db << 16) + dreadw(addr) + r.y;
|
||||
break;
|
||||
case OPTYPE_RELB:
|
||||
r = (regs.pc.b << 16) + ((regs.pc.w + 2) & 0xffff);
|
||||
r += int8(addr);
|
||||
a = (r.pc.b << 16) + ((r.pc.w + 2) & 0xffff);
|
||||
a += int8(addr);
|
||||
break;
|
||||
case OPTYPE_RELW:
|
||||
r = (regs.pc.b << 16) + ((regs.pc.w + 3) & 0xffff);
|
||||
r += (int16)addr;
|
||||
a = (r.pc.b << 16) + ((r.pc.w + 3) & 0xffff);
|
||||
a += (int16)addr;
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
return a;
|
||||
}
|
||||
|
||||
auto R65816::disassemble() -> string {
|
||||
return disassemble(regs.pc.d, regs.e, regs.p.m, regs.p.x);
|
||||
return disassemble(r.pc.d, r.e, r.p.m, r.p.x);
|
||||
}
|
||||
|
||||
auto R65816::disassemble(uint24 addr, bool e, bool m, bool x) -> string {
|
||||
string s;
|
||||
|
||||
reg24_t pc;
|
||||
reg24 pc;
|
||||
pc.d = addr;
|
||||
s = {hex(pc, 6), " "};
|
||||
|
||||
@ -403,23 +403,23 @@ auto R65816::disassemble(uint24 addr, bool e, bool m, bool x) -> string {
|
||||
#undef x8
|
||||
|
||||
s.append(t, " A:{0} X:{1} Y:{2} S:{3} D:{4} B:{5} ", format{
|
||||
hex(regs.a.w, 4), hex(regs.x.w, 4), hex(regs.y.w, 4),
|
||||
hex(regs.s.w, 4), hex(regs.d.w, 4), hex(regs.db, 2)
|
||||
hex(r.a.w, 4), hex(r.x.w, 4), hex(r.y.w, 4),
|
||||
hex(r.s.w, 4), hex(r.d.w, 4), hex(r.db, 2)
|
||||
});
|
||||
|
||||
if(regs.e) {
|
||||
if(r.e) {
|
||||
s.append(
|
||||
regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v',
|
||||
regs.p.m ? '1' : '0', regs.p.x ? 'B' : 'b',
|
||||
regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i',
|
||||
regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c'
|
||||
r.p.n ? 'N' : 'n', r.p.v ? 'V' : 'v',
|
||||
r.p.m ? '1' : '0', r.p.x ? 'B' : 'b',
|
||||
r.p.d ? 'D' : 'd', r.p.i ? 'I' : 'i',
|
||||
r.p.z ? 'Z' : 'z', r.p.c ? 'C' : 'c'
|
||||
);
|
||||
} else {
|
||||
s.append(
|
||||
regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v',
|
||||
regs.p.m ? 'M' : 'm', regs.p.x ? 'X' : 'x',
|
||||
regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i',
|
||||
regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c'
|
||||
r.p.n ? 'N' : 'n', r.p.v ? 'V' : 'v',
|
||||
r.p.m ? 'M' : 'm', r.p.x ? 'X' : 'x',
|
||||
r.p.d ? 'D' : 'd', r.p.i ? 'I' : 'i',
|
||||
r.p.z ? 'Z' : 'z', r.p.c ? 'C' : 'c'
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,77 +1,81 @@
|
||||
alwaysinline auto readpc() -> uint8 {
|
||||
return read((regs.pc.b << 16) + regs.pc.w++);
|
||||
alwaysinline auto readPC() -> uint8 {
|
||||
return read(r.pc.b << 16 | uint16(r.pc.w++));
|
||||
}
|
||||
|
||||
alwaysinline auto readstack() -> uint8 {
|
||||
regs.e ? regs.s.l++ : regs.s.w++;
|
||||
return read(regs.s.w);
|
||||
alwaysinline auto readSP() -> uint8 {
|
||||
r.e ? r.s.l++ : r.s.w++;
|
||||
return read(r.s.w);
|
||||
}
|
||||
|
||||
alwaysinline auto readstackn() -> uint8 {
|
||||
return read(++regs.s.w);
|
||||
alwaysinline auto readSPn() -> uint8 {
|
||||
return read(++r.s.w);
|
||||
}
|
||||
|
||||
alwaysinline auto readaddr(uint32 addr) -> uint8 {
|
||||
return read(addr & 0xffff);
|
||||
alwaysinline auto readAddr(uint addr) -> uint8 {
|
||||
return read(uint16(addr));
|
||||
}
|
||||
|
||||
alwaysinline auto readlong(uint32 addr) -> uint8 {
|
||||
return read(addr & 0xffffff);
|
||||
alwaysinline auto readLong(uint addr) -> uint8 {
|
||||
return read(uint24(addr));
|
||||
}
|
||||
|
||||
alwaysinline auto readdbr(uint32 addr) -> uint8 {
|
||||
return read(((regs.db << 16) + addr) & 0xffffff);
|
||||
alwaysinline auto readDB(uint addr) -> uint8 {
|
||||
return read(r.db << 16 | uint16(addr));
|
||||
}
|
||||
|
||||
alwaysinline auto readpbr(uint32 addr) -> uint8 {
|
||||
return read((regs.pc.b << 16) + (addr & 0xffff));
|
||||
alwaysinline auto readPB(uint addr) -> uint8 {
|
||||
return read(r.pc.b << 16 | uint16(addr));
|
||||
}
|
||||
|
||||
alwaysinline auto readdp(uint32 addr) -> uint8 {
|
||||
if(regs.e && regs.d.l == 0x00) {
|
||||
return read((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff));
|
||||
alwaysinline auto readDP(uint addr) -> uint8 {
|
||||
if(r.e && r.d.l == 0x00) {
|
||||
return read(r.d | uint8(addr));
|
||||
} else {
|
||||
return read((regs.d + (addr & 0xffff)) & 0xffff);
|
||||
return read(uint16(r.d + addr));
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline auto readsp(uint32 addr) -> uint8 {
|
||||
return read((regs.s + (addr & 0xffff)) & 0xffff);
|
||||
alwaysinline auto readDPn(uint addr) -> uint8 {
|
||||
return read(uint16(r.d + addr));
|
||||
}
|
||||
|
||||
alwaysinline auto writestack(uint8 data) -> void {
|
||||
write(regs.s.w, data);
|
||||
regs.e ? regs.s.l-- : regs.s.w--;
|
||||
alwaysinline auto readSP(uint addr) -> uint8 {
|
||||
return read(uint16(r.s + addr));
|
||||
}
|
||||
|
||||
alwaysinline auto writestackn(uint8 data) -> void {
|
||||
write(regs.s.w--, data);
|
||||
alwaysinline auto writeSP(uint8 data) -> void {
|
||||
write(r.s.w, data);
|
||||
r.e ? r.s.l-- : r.s.w--;
|
||||
}
|
||||
|
||||
alwaysinline auto writeaddr(uint32 addr, uint8 data) -> void {
|
||||
write(addr & 0xffff, data);
|
||||
alwaysinline auto writeSPn(uint8 data) -> void {
|
||||
write(r.s.w--, data);
|
||||
}
|
||||
|
||||
alwaysinline auto writelong(uint32 addr, uint8 data) -> void {
|
||||
write(addr & 0xffffff, data);
|
||||
alwaysinline auto writeAddr(uint addr, uint8 data) -> void {
|
||||
write(uint16(addr), data);
|
||||
}
|
||||
|
||||
alwaysinline auto writedbr(uint32 addr, uint8 data) -> void {
|
||||
write(((regs.db << 16) + addr) & 0xffffff, data);
|
||||
alwaysinline auto writeLong(uint addr, uint8 data) -> void {
|
||||
write(uint24(addr), data);
|
||||
}
|
||||
|
||||
alwaysinline auto writepbr(uint32 addr, uint8 data) -> void {
|
||||
write((regs.pc.b << 16) + (addr & 0xffff), data);
|
||||
alwaysinline auto writeDB(uint addr, uint8 data) -> void {
|
||||
write(r.db << 16 | uint16(addr), data);
|
||||
}
|
||||
|
||||
alwaysinline auto writedp(uint32 addr, uint8 data) -> void {
|
||||
if(regs.e && regs.d.l == 0x00) {
|
||||
write((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff), data);
|
||||
alwaysinline auto writePB(uint addr, uint8 data) -> void {
|
||||
write(r.pc.b << 16 | uint16(addr), data);
|
||||
}
|
||||
|
||||
alwaysinline auto writeDP(uint addr, uint8 data) -> void {
|
||||
if(r.e && r.d.l == 0x00) {
|
||||
write(r.d | uint8(addr), data);
|
||||
} else {
|
||||
write((regs.d + (addr & 0xffff)) & 0xffff, data);
|
||||
write(uint16(r.d + addr), data);
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline auto writesp(uint32 addr, uint8 data) -> void {
|
||||
write((regs.s + (addr & 0xffff)) & 0xffff, data);
|
||||
alwaysinline auto writeSP(uint addr, uint8 data) -> void {
|
||||
write(uint16(r.s + addr), data);
|
||||
}
|
||||
|
@ -3,81 +3,65 @@ L ioIRQ();
|
||||
}
|
||||
|
||||
auto R65816::op_wdm() {
|
||||
L readpc();
|
||||
L readPC();
|
||||
}
|
||||
|
||||
auto R65816::op_xba() {
|
||||
io();
|
||||
L io();
|
||||
regs.a.l ^= regs.a.h;
|
||||
regs.a.h ^= regs.a.l;
|
||||
regs.a.l ^= regs.a.h;
|
||||
regs.p.n = (regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
swap(r.a.l, r.a.h);
|
||||
r.p.n = (r.a.l & 0x80);
|
||||
r.p.z = (r.a.l == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_move_b(signed adjust) {
|
||||
dp = readpc();
|
||||
sp = readpc();
|
||||
regs.db = dp;
|
||||
rd.l = readlong((sp << 16) | regs.x.w);
|
||||
writelong((dp << 16) | regs.y.w, rd.l);
|
||||
auto R65816::op_move_b(int adjust) {
|
||||
dp = readPC();
|
||||
sp = readPC();
|
||||
r.db = dp;
|
||||
rd.l = readLong(sp << 16 | r.x.w);
|
||||
writeLong(dp << 16 | r.y.w, rd.l);
|
||||
io();
|
||||
regs.x.l += adjust;
|
||||
regs.y.l += adjust;
|
||||
r.x.l += adjust;
|
||||
r.y.l += adjust;
|
||||
L io();
|
||||
if(regs.a.w--) regs.pc.w -= 3;
|
||||
if(r.a.w--) r.pc.w -= 3;
|
||||
}
|
||||
|
||||
auto R65816::op_move_w(signed adjust) {
|
||||
dp = readpc();
|
||||
sp = readpc();
|
||||
regs.db = dp;
|
||||
rd.l = readlong((sp << 16) | regs.x.w);
|
||||
writelong((dp << 16) | regs.y.w, rd.l);
|
||||
auto R65816::op_move_w(int adjust) {
|
||||
dp = readPC();
|
||||
sp = readPC();
|
||||
r.db = dp;
|
||||
rd.l = readLong(sp << 16 | r.x.w);
|
||||
writeLong(dp << 16 | r.y.w, rd.l);
|
||||
io();
|
||||
regs.x.w += adjust;
|
||||
regs.y.w += adjust;
|
||||
r.x.w += adjust;
|
||||
r.y.w += adjust;
|
||||
L io();
|
||||
if(regs.a.w--) regs.pc.w -= 3;
|
||||
if(r.a.w--) r.pc.w -= 3;
|
||||
}
|
||||
|
||||
auto R65816::op_interrupt_e(uint16 vector) {
|
||||
readpc();
|
||||
writestack(regs.pc.h);
|
||||
writestack(regs.pc.l);
|
||||
writestack(regs.p);
|
||||
rd.l = readlong(vector + 0);
|
||||
regs.pc.b = 0;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
L rd.h = readlong(vector + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
auto R65816::op_interrupt_n(uint16 vector) {
|
||||
readpc();
|
||||
writestack(regs.pc.b);
|
||||
writestack(regs.pc.h);
|
||||
writestack(regs.pc.l);
|
||||
writestack(regs.p);
|
||||
rd.l = readlong(vector + 0);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
L rd.h = readlong(vector + 1);
|
||||
regs.pc.w = rd.w;
|
||||
auto R65816::op_interrupt(uint16 vector) {
|
||||
readPC();
|
||||
N writeSP(r.pc.b);
|
||||
writeSP(r.pc.h);
|
||||
writeSP(r.pc.l);
|
||||
writeSP(r.p);
|
||||
r.pc.l = readLong(vector + 0);
|
||||
r.p.i = 1;
|
||||
r.p.d = 0;
|
||||
L r.pc.h = readLong(vector + 1);
|
||||
r.pc.b = 0x00;
|
||||
}
|
||||
|
||||
auto R65816::op_stp() {
|
||||
while(regs.wai = true) {
|
||||
while(r.wai = true) {
|
||||
L io();
|
||||
}
|
||||
}
|
||||
|
||||
auto R65816::op_wai() {
|
||||
regs.wai = true;
|
||||
while(regs.wai) {
|
||||
r.wai = true;
|
||||
while(r.wai) {
|
||||
L io();
|
||||
}
|
||||
io();
|
||||
@ -85,15 +69,15 @@ L io();
|
||||
|
||||
auto R65816::op_xce() {
|
||||
L ioIRQ();
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = regs.e;
|
||||
regs.e = carry;
|
||||
if(regs.e) {
|
||||
regs.p.m = 1;
|
||||
regs.p.x = 1;
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
regs.s.h = 0x01;
|
||||
bool carry = r.p.c;
|
||||
r.p.c = r.e;
|
||||
r.e = carry;
|
||||
if(r.e) {
|
||||
r.p.m = 1;
|
||||
r.p.x = 1;
|
||||
r.x.h = 0x00;
|
||||
r.y.h = 0x00;
|
||||
r.s.h = 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,226 +86,160 @@ L ioIRQ();
|
||||
flag = value;
|
||||
}
|
||||
|
||||
auto R65816::op_pflag_e(bool mode) {
|
||||
rd.l = readpc();
|
||||
auto R65816::op_pflag(bool mode) {
|
||||
rd.l = readPC();
|
||||
L io();
|
||||
regs.p = (mode ? regs.p | rd.l : regs.p & ~rd.l);
|
||||
regs.p.m = 1;
|
||||
regs.p.x = 1;
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
|
||||
auto R65816::op_pflag_n(bool mode) {
|
||||
rd.l = readpc();
|
||||
L io();
|
||||
regs.p = (mode ? regs.p | rd.l : regs.p & ~rd.l);
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
r.p = (mode ? r.p | rd.l : r.p & ~rd.l);
|
||||
E r.p.m = 1, r.p.x = 1;
|
||||
if(r.p.x) {
|
||||
r.x.h = 0x00;
|
||||
r.y.h = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
auto R65816::op_transfer_b(reg16_t& from, reg16_t& to) {
|
||||
auto R65816::op_transfer_b(reg16& from, reg16& to) {
|
||||
L ioIRQ();
|
||||
to.l = from.l;
|
||||
regs.p.n = (to.l & 0x80);
|
||||
regs.p.z = (to.l == 0);
|
||||
r.p.n = (to.l & 0x80);
|
||||
r.p.z = (to.l == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_transfer_w(reg16_t& from, reg16_t& to) {
|
||||
auto R65816::op_transfer_w(reg16& from, reg16& to) {
|
||||
L ioIRQ();
|
||||
to.w = from.w;
|
||||
regs.p.n = (to.w & 0x8000);
|
||||
regs.p.z = (to.w == 0);
|
||||
r.p.n = (to.w & 0x8000);
|
||||
r.p.z = (to.w == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_tcs_e() {
|
||||
auto R65816::op_tcs() {
|
||||
L ioIRQ();
|
||||
regs.s.l = regs.a.l;
|
||||
}
|
||||
|
||||
auto R65816::op_tcs_n() {
|
||||
L ioIRQ();
|
||||
regs.s.w = regs.a.w;
|
||||
r.s.w = r.a.w;
|
||||
E r.s.h = 0x01;
|
||||
}
|
||||
|
||||
auto R65816::op_tsx_b() {
|
||||
L ioIRQ();
|
||||
regs.x.l = regs.s.l;
|
||||
regs.p.n = (regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
r.x.l = r.s.l;
|
||||
r.p.n = (r.x.l & 0x80);
|
||||
r.p.z = (r.x.l == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_tsx_w() {
|
||||
L ioIRQ();
|
||||
regs.x.w = regs.s.w;
|
||||
regs.p.n = (regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
r.x.w = r.s.w;
|
||||
r.p.n = (r.x.w & 0x8000);
|
||||
r.p.z = (r.x.w == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_txs_e() {
|
||||
auto R65816::op_txs() {
|
||||
L ioIRQ();
|
||||
regs.s.l = regs.x.l;
|
||||
E r.s.l = r.x.l;
|
||||
N r.s.w = r.x.w;
|
||||
}
|
||||
|
||||
auto R65816::op_txs_n() {
|
||||
L ioIRQ();
|
||||
regs.s.w = regs.x.w;
|
||||
}
|
||||
|
||||
auto R65816::op_push_b(reg16_t& reg) {
|
||||
auto R65816::op_push_b(reg16& reg) {
|
||||
io();
|
||||
L writestack(reg.l);
|
||||
L writeSP(reg.l);
|
||||
}
|
||||
|
||||
auto R65816::op_push_w(reg16_t& reg) {
|
||||
auto R65816::op_push_w(reg16& reg) {
|
||||
io();
|
||||
writestack(reg.h);
|
||||
L writestack(reg.l);
|
||||
writeSP(reg.h);
|
||||
L writeSP(reg.l);
|
||||
}
|
||||
|
||||
auto R65816::op_phd_e() {
|
||||
auto R65816::op_phd() {
|
||||
io();
|
||||
writestackn(regs.d.h);
|
||||
L writestackn(regs.d.l);
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
auto R65816::op_phd_n() {
|
||||
io();
|
||||
writestackn(regs.d.h);
|
||||
L writestackn(regs.d.l);
|
||||
writeSPn(r.d.h);
|
||||
L writeSPn(r.d.l);
|
||||
E r.s.h = 0x01;
|
||||
}
|
||||
|
||||
auto R65816::op_phb() {
|
||||
io();
|
||||
L writestack(regs.db);
|
||||
L writeSP(r.db);
|
||||
}
|
||||
|
||||
auto R65816::op_phk() {
|
||||
io();
|
||||
L writestack(regs.pc.b);
|
||||
L writeSP(r.pc.b);
|
||||
}
|
||||
|
||||
auto R65816::op_php() {
|
||||
io();
|
||||
L writestack(regs.p);
|
||||
L writeSP(r.p);
|
||||
}
|
||||
|
||||
auto R65816::op_pull_b(reg16_t& reg) {
|
||||
auto R65816::op_pull_b(reg16& reg) {
|
||||
io();
|
||||
io();
|
||||
L reg.l = readstack();
|
||||
regs.p.n = (reg.l & 0x80);
|
||||
regs.p.z = (reg.l == 0);
|
||||
L reg.l = readSP();
|
||||
r.p.n = (reg.l & 0x80);
|
||||
r.p.z = (reg.l == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_pull_w(reg16_t& reg) {
|
||||
auto R65816::op_pull_w(reg16& reg) {
|
||||
io();
|
||||
io();
|
||||
reg.l = readstack();
|
||||
L reg.h = readstack();
|
||||
regs.p.n = (reg.w & 0x8000);
|
||||
regs.p.z = (reg.w == 0);
|
||||
reg.l = readSP();
|
||||
L reg.h = readSP();
|
||||
r.p.n = (reg.w & 0x8000);
|
||||
r.p.z = (reg.w == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_pld_e() {
|
||||
auto R65816::op_pld() {
|
||||
io();
|
||||
io();
|
||||
regs.d.l = readstackn();
|
||||
L regs.d.h = readstackn();
|
||||
regs.p.n = (regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
auto R65816::op_pld_n() {
|
||||
io();
|
||||
io();
|
||||
regs.d.l = readstackn();
|
||||
L regs.d.h = readstackn();
|
||||
regs.p.n = (regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
r.d.l = readSPn();
|
||||
L r.d.h = readSPn();
|
||||
r.p.n = (r.d.w & 0x8000);
|
||||
r.p.z = (r.d.w == 0);
|
||||
E r.s.h = 0x01;
|
||||
}
|
||||
|
||||
auto R65816::op_plb() {
|
||||
io();
|
||||
io();
|
||||
L regs.db = readstack();
|
||||
regs.p.n = (regs.db & 0x80);
|
||||
regs.p.z = (regs.db == 0);
|
||||
L r.db = readSP();
|
||||
r.p.n = (r.db & 0x80);
|
||||
r.p.z = (r.db == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_plp_e() {
|
||||
auto R65816::op_plp() {
|
||||
io();
|
||||
io();
|
||||
L regs.p = readstack() | 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
L r.p = readSP();
|
||||
E r.p.m = 1, r.p.x = 1;
|
||||
if(r.p.x) {
|
||||
r.x.h = 0x00;
|
||||
r.y.h = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
auto R65816::op_plp_n() {
|
||||
io();
|
||||
io();
|
||||
L regs.p = readstack();
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
auto R65816::op_pea() {
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
writeSPn(aa.h);
|
||||
L writeSPn(aa.l);
|
||||
E r.s.h = 0x01;
|
||||
}
|
||||
|
||||
auto R65816::op_pea_e() {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
writestackn(aa.h);
|
||||
L writestackn(aa.l);
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
auto R65816::op_pea_n() {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
writestackn(aa.h);
|
||||
L writestackn(aa.l);
|
||||
}
|
||||
|
||||
auto R65816::op_pei_e() {
|
||||
dp = readpc();
|
||||
auto R65816::op_pei() {
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
writestackn(aa.h);
|
||||
L writestackn(aa.l);
|
||||
regs.s.h = 0x01;
|
||||
aa.l = readDPn(dp + 0);
|
||||
aa.h = readDPn(dp + 1);
|
||||
writeSPn(aa.h);
|
||||
L writeSPn(aa.l);
|
||||
E r.s.h = 0x01;
|
||||
}
|
||||
|
||||
auto R65816::op_pei_n() {
|
||||
dp = readpc();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
writestackn(aa.h);
|
||||
L writestackn(aa.l);
|
||||
}
|
||||
|
||||
auto R65816::op_per_e() {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
auto R65816::op_per() {
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
io();
|
||||
rd.w = regs.pc.d + (int16)aa.w;
|
||||
writestackn(rd.h);
|
||||
L writestackn(rd.l);
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
auto R65816::op_per_n() {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
io();
|
||||
rd.w = regs.pc.d + (int16)aa.w;
|
||||
writestackn(rd.h);
|
||||
L writestackn(rd.l);
|
||||
rd.w = r.pc.d + (int16)aa.w;
|
||||
writeSPn(rd.h);
|
||||
L writeSPn(rd.l);
|
||||
E r.s.h = 0x01;
|
||||
}
|
||||
|
@ -1,176 +1,138 @@
|
||||
auto R65816::op_branch(bool flag, bool value) {
|
||||
if(flag != value) {
|
||||
L rd.l = readpc();
|
||||
L rd.l = readPC();
|
||||
} else {
|
||||
rd.l = readpc();
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
rd.l = readPC();
|
||||
aa.w = r.pc.d + (int8)rd.l;
|
||||
io6(aa.w);
|
||||
L io();
|
||||
regs.pc.w = aa.w;
|
||||
r.pc.w = aa.w;
|
||||
}
|
||||
}
|
||||
|
||||
auto R65816::op_bra() {
|
||||
rd.l = readpc();
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
rd.l = readPC();
|
||||
aa.w = r.pc.d + (int8)rd.l;
|
||||
io6(aa.w);
|
||||
L io();
|
||||
regs.pc.w = aa.w;
|
||||
r.pc.w = aa.w;
|
||||
}
|
||||
|
||||
auto R65816::op_brl() {
|
||||
rd.l = readpc();
|
||||
rd.h = readpc();
|
||||
rd.l = readPC();
|
||||
rd.h = readPC();
|
||||
L io();
|
||||
regs.pc.w = regs.pc.d + (int16)rd.w;
|
||||
r.pc.w = r.pc.d + (int16)rd.w;
|
||||
}
|
||||
|
||||
auto R65816::op_jmp_addr() {
|
||||
rd.l = readpc();
|
||||
L rd.h = readpc();
|
||||
regs.pc.w = rd.w;
|
||||
rd.l = readPC();
|
||||
L rd.h = readPC();
|
||||
r.pc.w = rd.w;
|
||||
}
|
||||
|
||||
auto R65816::op_jmp_long() {
|
||||
rd.l = readpc();
|
||||
rd.h = readpc();
|
||||
L rd.b = readpc();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
rd.l = readPC();
|
||||
rd.h = readPC();
|
||||
L rd.b = readPC();
|
||||
r.pc.d = rd.d;
|
||||
}
|
||||
|
||||
auto R65816::op_jmp_iaddr() {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
rd.l = readaddr(aa.w + 0);
|
||||
L rd.h = readaddr(aa.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
rd.l = readAddr(aa.w + 0);
|
||||
L rd.h = readAddr(aa.w + 1);
|
||||
r.pc.w = rd.w;
|
||||
}
|
||||
|
||||
auto R65816::op_jmp_iaddrx() {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
io();
|
||||
rd.l = readpbr(aa.w + regs.x.w + 0);
|
||||
L rd.h = readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
rd.l = readPB(aa.w + r.x.w + 0);
|
||||
L rd.h = readPB(aa.w + r.x.w + 1);
|
||||
r.pc.w = rd.w;
|
||||
}
|
||||
|
||||
auto R65816::op_jmp_iladdr() {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
rd.l = readaddr(aa.w + 0);
|
||||
rd.h = readaddr(aa.w + 1);
|
||||
L rd.b = readaddr(aa.w + 2);
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
rd.l = readAddr(aa.w + 0);
|
||||
rd.h = readAddr(aa.w + 1);
|
||||
L rd.b = readAddr(aa.w + 2);
|
||||
r.pc.d = rd.d;
|
||||
}
|
||||
|
||||
auto R65816::op_jsr_addr() {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
io();
|
||||
regs.pc.w--;
|
||||
writestack(regs.pc.h);
|
||||
L writestack(regs.pc.l);
|
||||
regs.pc.w = aa.w;
|
||||
r.pc.w--;
|
||||
writeSP(r.pc.h);
|
||||
L writeSP(r.pc.l);
|
||||
r.pc.w = aa.w;
|
||||
}
|
||||
|
||||
auto R65816::op_jsr_long_e() {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
writestackn(regs.pc.b);
|
||||
auto R65816::op_jsr_long() {
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
writeSPn(r.pc.b);
|
||||
io();
|
||||
aa.b = readpc();
|
||||
regs.pc.w--;
|
||||
writestackn(regs.pc.h);
|
||||
L writestackn(regs.pc.l);
|
||||
regs.pc.d = aa.d & 0xffffff;
|
||||
regs.s.h = 0x01;
|
||||
aa.b = readPC();
|
||||
r.pc.w--;
|
||||
writeSPn(r.pc.h);
|
||||
L writeSPn(r.pc.l);
|
||||
r.pc.d = aa.d;
|
||||
E r.s.h = 0x01;
|
||||
}
|
||||
|
||||
auto R65816::op_jsr_long_n() {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
writestackn(regs.pc.b);
|
||||
auto R65816::op_jsr_iaddrx() {
|
||||
aa.l = readPC();
|
||||
writeSPn(r.pc.h);
|
||||
writeSPn(r.pc.l);
|
||||
aa.h = readPC();
|
||||
io();
|
||||
aa.b = readpc();
|
||||
regs.pc.w--;
|
||||
writestackn(regs.pc.h);
|
||||
L writestackn(regs.pc.l);
|
||||
regs.pc.d = aa.d & 0xffffff;
|
||||
rd.l = readPB(aa.w + r.x.w + 0);
|
||||
L rd.h = readPB(aa.w + r.x.w + 1);
|
||||
r.pc.w = rd.w;
|
||||
E r.s.h = 0x01;
|
||||
}
|
||||
|
||||
auto R65816::op_jsr_iaddrx_e() {
|
||||
aa.l = readpc();
|
||||
writestackn(regs.pc.h);
|
||||
writestackn(regs.pc.l);
|
||||
aa.h = readpc();
|
||||
io();
|
||||
rd.l = readpbr(aa.w + regs.x.w + 0);
|
||||
L rd.h = readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
auto R65816::op_jsr_iaddrx_n() {
|
||||
aa.l = readpc();
|
||||
writestackn(regs.pc.h);
|
||||
writestackn(regs.pc.l);
|
||||
aa.h = readpc();
|
||||
io();
|
||||
rd.l = readpbr(aa.w + regs.x.w + 0);
|
||||
L rd.h = readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
auto R65816::op_rti_e() {
|
||||
auto R65816::op_rti() {
|
||||
io();
|
||||
io();
|
||||
regs.p = readstack() | 0x30;
|
||||
rd.l = readstack();
|
||||
L rd.h = readstack();
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
auto R65816::op_rti_n() {
|
||||
io();
|
||||
io();
|
||||
regs.p = readstack();
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
r.p = readSP();
|
||||
E r.p.m = 1, r.p.x = 1;
|
||||
if(r.p.x) {
|
||||
r.x.h = 0x00;
|
||||
r.y.h = 0x00;
|
||||
}
|
||||
r.pc.l = readSP();
|
||||
if(r.e) {
|
||||
L r.pc.h = readSP();
|
||||
} else {
|
||||
r.pc.h = readSP();
|
||||
L r.pc.b = readSP();
|
||||
}
|
||||
rd.l = readstack();
|
||||
rd.h = readstack();
|
||||
L rd.b = readstack();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
|
||||
auto R65816::op_rts() {
|
||||
io();
|
||||
io();
|
||||
rd.l = readstack();
|
||||
rd.h = readstack();
|
||||
rd.l = readSP();
|
||||
rd.h = readSP();
|
||||
L io();
|
||||
regs.pc.w = ++rd.w;
|
||||
r.pc.w = ++rd.w;
|
||||
}
|
||||
|
||||
auto R65816::op_rtl_e() {
|
||||
auto R65816::op_rtl() {
|
||||
io();
|
||||
io();
|
||||
rd.l = readstackn();
|
||||
rd.h = readstackn();
|
||||
L rd.b = readstackn();
|
||||
regs.pc.b = rd.b;
|
||||
regs.pc.w = ++rd.w;
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
auto R65816::op_rtl_n() {
|
||||
io();
|
||||
io();
|
||||
rd.l = readstackn();
|
||||
rd.h = readstackn();
|
||||
L rd.b = readstackn();
|
||||
regs.pc.b = rd.b;
|
||||
regs.pc.w = ++rd.w;
|
||||
rd.l = readSPn();
|
||||
rd.h = readSPn();
|
||||
L rd.b = readSPn();
|
||||
r.pc.b = rd.b;
|
||||
r.pc.w = ++rd.w;
|
||||
E r.s.h = 0x01;
|
||||
}
|
||||
|
@ -1,275 +1,275 @@
|
||||
auto R65816::op_read_const_b(fp op) {
|
||||
L rd.l = readpc();
|
||||
L rd.l = readPC();
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_const_w(fp op) {
|
||||
rd.l = readpc();
|
||||
L rd.h = readpc();
|
||||
rd.l = readPC();
|
||||
L rd.h = readPC();
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_bit_const_b() {
|
||||
L rd.l = readpc();
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
L rd.l = readPC();
|
||||
r.p.z = ((rd.l & r.a.l) == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_read_bit_const_w() {
|
||||
rd.l = readpc();
|
||||
L rd.h = readpc();
|
||||
regs.p.z = ((rd.w & regs.a.w) == 0);
|
||||
rd.l = readPC();
|
||||
L rd.h = readPC();
|
||||
r.p.z = ((rd.w & r.a.w) == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_read_addr_b(fp op) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
L rd.l = readdbr(aa.w);
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
L rd.l = readDB(aa.w);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_addr_w(fp op) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
rd.l = readdbr(aa.w + 0);
|
||||
L rd.h = readdbr(aa.w + 1);
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
rd.l = readDB(aa.w + 0);
|
||||
L rd.h = readDB(aa.w + 1);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_addrx_b(fp op) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
io4(aa.w, aa.w + regs.x.w);
|
||||
L rd.l = readdbr(aa.w + regs.x.w);
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
io4(aa.w, aa.w + r.x.w);
|
||||
L rd.l = readDB(aa.w + r.x.w);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_addrx_w(fp op) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
io4(aa.w, aa.w + regs.x.w);
|
||||
rd.l = readdbr(aa.w + regs.x.w + 0);
|
||||
L rd.h = readdbr(aa.w + regs.x.w + 1);
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
io4(aa.w, aa.w + r.x.w);
|
||||
rd.l = readDB(aa.w + r.x.w + 0);
|
||||
L rd.h = readDB(aa.w + r.x.w + 1);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_addry_b(fp op) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
io4(aa.w, aa.w + regs.y.w);
|
||||
L rd.l = readdbr(aa.w + regs.y.w);
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
io4(aa.w, aa.w + r.y.w);
|
||||
L rd.l = readDB(aa.w + r.y.w);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_addry_w(fp op) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
io4(aa.w, aa.w + regs.y.w);
|
||||
rd.l = readdbr(aa.w + regs.y.w + 0);
|
||||
L rd.h = readdbr(aa.w + regs.y.w + 1);
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
io4(aa.w, aa.w + r.y.w);
|
||||
rd.l = readDB(aa.w + r.y.w + 0);
|
||||
L rd.h = readDB(aa.w + r.y.w + 1);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_long_b(fp op) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
aa.b = readpc();
|
||||
L rd.l = readlong(aa.d);
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
aa.b = readPC();
|
||||
L rd.l = readLong(aa.d);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_long_w(fp op) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
aa.b = readpc();
|
||||
rd.l = readlong(aa.d + 0);
|
||||
L rd.h = readlong(aa.d + 1);
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
aa.b = readPC();
|
||||
rd.l = readLong(aa.d + 0);
|
||||
L rd.h = readLong(aa.d + 1);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_longx_b(fp op) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
aa.b = readpc();
|
||||
L rd.l = readlong(aa.d + regs.x.w);
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
aa.b = readPC();
|
||||
L rd.l = readLong(aa.d + r.x.w);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_longx_w(fp op) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
aa.b = readpc();
|
||||
rd.l = readlong(aa.d + regs.x.w + 0);
|
||||
L rd.h = readlong(aa.d + regs.x.w + 1);
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
aa.b = readPC();
|
||||
rd.l = readLong(aa.d + r.x.w + 0);
|
||||
L rd.h = readLong(aa.d + r.x.w + 1);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_dp_b(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
L rd.l = readdp(dp);
|
||||
L rd.l = readDP(dp);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_dp_w(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
rd.l = readdp(dp + 0);
|
||||
L rd.h = readdp(dp + 1);
|
||||
rd.l = readDP(dp + 0);
|
||||
L rd.h = readDP(dp + 1);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_dpr_b(fp op, reg16_t& reg) {
|
||||
dp = readpc();
|
||||
auto R65816::op_read_dpr_b(fp op, reg16& reg) {
|
||||
dp = readPC();
|
||||
io2();
|
||||
io();
|
||||
L rd.l = readdp(dp + reg.w);
|
||||
L rd.l = readDP(dp + reg.w);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_dpr_w(fp op, reg16_t& reg) {
|
||||
dp = readpc();
|
||||
auto R65816::op_read_dpr_w(fp op, reg16& reg) {
|
||||
dp = readPC();
|
||||
io2();
|
||||
io();
|
||||
rd.l = readdp(dp + reg.w + 0);
|
||||
L rd.h = readdp(dp + reg.w + 1);
|
||||
rd.l = readDP(dp + reg.w + 0);
|
||||
L rd.h = readDP(dp + reg.w + 1);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_idp_b(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
L rd.l = readdbr(aa.w);
|
||||
aa.l = readDP(dp + 0);
|
||||
aa.h = readDP(dp + 1);
|
||||
L rd.l = readDB(aa.w);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_idp_w(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
rd.l = readdbr(aa.w + 0);
|
||||
L rd.h = readdbr(aa.w + 1);
|
||||
aa.l = readDP(dp + 0);
|
||||
aa.h = readDP(dp + 1);
|
||||
rd.l = readDB(aa.w + 0);
|
||||
L rd.h = readDB(aa.w + 1);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_idpx_b(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
io();
|
||||
aa.l = readdp(dp + regs.x.w + 0);
|
||||
aa.h = readdp(dp + regs.x.w + 1);
|
||||
L rd.l = readdbr(aa.w);
|
||||
aa.l = readDP(dp + r.x.w + 0);
|
||||
aa.h = readDP(dp + r.x.w + 1);
|
||||
L rd.l = readDB(aa.w);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_idpx_w(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
io();
|
||||
aa.l = readdp(dp + regs.x.w + 0);
|
||||
aa.h = readdp(dp + regs.x.w + 1);
|
||||
rd.l = readdbr(aa.w + 0);
|
||||
L rd.h = readdbr(aa.w + 1);
|
||||
aa.l = readDP(dp + r.x.w + 0);
|
||||
aa.h = readDP(dp + r.x.w + 1);
|
||||
rd.l = readDB(aa.w + 0);
|
||||
L rd.h = readDB(aa.w + 1);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_idpy_b(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
io4(aa.w, aa.w + regs.y.w);
|
||||
L rd.l = readdbr(aa.w + regs.y.w);
|
||||
aa.l = readDP(dp + 0);
|
||||
aa.h = readDP(dp + 1);
|
||||
io4(aa.w, aa.w + r.y.w);
|
||||
L rd.l = readDB(aa.w + r.y.w);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_idpy_w(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
io4(aa.w, aa.w + regs.y.w);
|
||||
rd.l = readdbr(aa.w + regs.y.w + 0);
|
||||
L rd.h = readdbr(aa.w + regs.y.w + 1);
|
||||
aa.l = readDP(dp + 0);
|
||||
aa.h = readDP(dp + 1);
|
||||
io4(aa.w, aa.w + r.y.w);
|
||||
rd.l = readDB(aa.w + r.y.w + 0);
|
||||
L rd.h = readDB(aa.w + r.y.w + 1);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_ildp_b(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
aa.b = readdp(dp + 2);
|
||||
L rd.l = readlong(aa.d);
|
||||
aa.l = readDPn(dp + 0);
|
||||
aa.h = readDPn(dp + 1);
|
||||
aa.b = readDPn(dp + 2);
|
||||
L rd.l = readLong(aa.d);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_ildp_w(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
aa.b = readdp(dp + 2);
|
||||
rd.l = readlong(aa.d + 0);
|
||||
L rd.h = readlong(aa.d + 1);
|
||||
aa.l = readDPn(dp + 0);
|
||||
aa.h = readDPn(dp + 1);
|
||||
aa.b = readDPn(dp + 2);
|
||||
rd.l = readLong(aa.d + 0);
|
||||
L rd.h = readLong(aa.d + 1);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_ildpy_b(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
aa.b = readdp(dp + 2);
|
||||
L rd.l = readlong(aa.d + regs.y.w);
|
||||
aa.l = readDPn(dp + 0);
|
||||
aa.h = readDPn(dp + 1);
|
||||
aa.b = readDPn(dp + 2);
|
||||
L rd.l = readLong(aa.d + r.y.w);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_ildpy_w(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
aa.b = readdp(dp + 2);
|
||||
rd.l = readlong(aa.d + regs.y.w + 0);
|
||||
L rd.h = readlong(aa.d + regs.y.w + 1);
|
||||
aa.l = readDPn(dp + 0);
|
||||
aa.h = readDPn(dp + 1);
|
||||
aa.b = readDPn(dp + 2);
|
||||
rd.l = readLong(aa.d + r.y.w + 0);
|
||||
L rd.h = readLong(aa.d + r.y.w + 1);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_sr_b(fp op) {
|
||||
sp = readpc();
|
||||
sp = readPC();
|
||||
io();
|
||||
L rd.l = readsp(sp);
|
||||
L rd.l = readSP(sp);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_sr_w(fp op) {
|
||||
sp = readpc();
|
||||
sp = readPC();
|
||||
io();
|
||||
rd.l = readsp(sp + 0);
|
||||
L rd.h = readsp(sp + 1);
|
||||
rd.l = readSP(sp + 0);
|
||||
L rd.h = readSP(sp + 1);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_isry_b(fp op) {
|
||||
sp = readpc();
|
||||
sp = readPC();
|
||||
io();
|
||||
aa.l = readsp(sp + 0);
|
||||
aa.h = readsp(sp + 1);
|
||||
aa.l = readSP(sp + 0);
|
||||
aa.h = readSP(sp + 1);
|
||||
io();
|
||||
L rd.l = readdbr(aa.w + regs.y.w);
|
||||
L rd.l = readDB(aa.w + r.y.w);
|
||||
call(op);
|
||||
}
|
||||
|
||||
auto R65816::op_read_isry_w(fp op) {
|
||||
sp = readpc();
|
||||
sp = readPC();
|
||||
io();
|
||||
aa.l = readsp(sp + 0);
|
||||
aa.h = readsp(sp + 1);
|
||||
aa.l = readSP(sp + 0);
|
||||
aa.h = readSP(sp + 1);
|
||||
io();
|
||||
rd.l = readdbr(aa.w + regs.y.w + 0);
|
||||
L rd.h = readdbr(aa.w + regs.y.w + 1);
|
||||
rd.l = readDB(aa.w + r.y.w + 0);
|
||||
L rd.h = readDB(aa.w + r.y.w + 1);
|
||||
call(op);
|
||||
}
|
||||
|
@ -1,165 +1,165 @@
|
||||
auto R65816::op_adjust_imm_b(reg16_t& reg, signed adjust) {
|
||||
auto R65816::op_adjust_imm_b(reg16& reg, int adjust) {
|
||||
L ioIRQ();
|
||||
reg.l += adjust;
|
||||
regs.p.n = (reg.l & 0x80);
|
||||
regs.p.z = (reg.l == 0);
|
||||
r.p.n = (reg.l & 0x80);
|
||||
r.p.z = (reg.l == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_adjust_imm_w(reg16_t& reg, signed adjust) {
|
||||
auto R65816::op_adjust_imm_w(reg16& reg, int adjust) {
|
||||
L ioIRQ();
|
||||
reg.w += adjust;
|
||||
regs.p.n = (reg.w & 0x8000);
|
||||
regs.p.z = (reg.w == 0);
|
||||
r.p.n = (reg.w & 0x8000);
|
||||
r.p.z = (reg.w == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_asl_imm_b() {
|
||||
L ioIRQ();
|
||||
regs.p.c = (regs.a.l & 0x80);
|
||||
regs.a.l <<= 1;
|
||||
regs.p.n = (regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
r.p.c = (r.a.l & 0x80);
|
||||
r.a.l <<= 1;
|
||||
r.p.n = (r.a.l & 0x80);
|
||||
r.p.z = (r.a.l == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_asl_imm_w() {
|
||||
L ioIRQ();
|
||||
regs.p.c = (regs.a.w & 0x8000);
|
||||
regs.a.w <<= 1;
|
||||
regs.p.n = (regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
r.p.c = (r.a.w & 0x8000);
|
||||
r.a.w <<= 1;
|
||||
r.p.n = (r.a.w & 0x8000);
|
||||
r.p.z = (r.a.w == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_lsr_imm_b() {
|
||||
L ioIRQ();
|
||||
regs.p.c = (regs.a.l & 0x01);
|
||||
regs.a.l >>= 1;
|
||||
regs.p.n = (regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
r.p.c = (r.a.l & 0x01);
|
||||
r.a.l >>= 1;
|
||||
r.p.n = (r.a.l & 0x80);
|
||||
r.p.z = (r.a.l == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_lsr_imm_w() {
|
||||
L ioIRQ();
|
||||
regs.p.c = (regs.a.w & 0x0001);
|
||||
regs.a.w >>= 1;
|
||||
regs.p.n = (regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
r.p.c = (r.a.w & 0x0001);
|
||||
r.a.w >>= 1;
|
||||
r.p.n = (r.a.w & 0x8000);
|
||||
r.p.z = (r.a.w == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_rol_imm_b() {
|
||||
L ioIRQ();
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = (regs.a.l & 0x80);
|
||||
regs.a.l = (regs.a.l << 1) | carry;
|
||||
regs.p.n = (regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
bool carry = r.p.c;
|
||||
r.p.c = (r.a.l & 0x80);
|
||||
r.a.l = (r.a.l << 1) | carry;
|
||||
r.p.n = (r.a.l & 0x80);
|
||||
r.p.z = (r.a.l == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_rol_imm_w() {
|
||||
L ioIRQ();
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = (regs.a.w & 0x8000);
|
||||
regs.a.w = (regs.a.w << 1) | carry;
|
||||
regs.p.n = (regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
bool carry = r.p.c;
|
||||
r.p.c = (r.a.w & 0x8000);
|
||||
r.a.w = (r.a.w << 1) | carry;
|
||||
r.p.n = (r.a.w & 0x8000);
|
||||
r.p.z = (r.a.w == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_ror_imm_b() {
|
||||
L ioIRQ();
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = (regs.a.l & 0x01);
|
||||
regs.a.l = (carry << 7) | (regs.a.l >> 1);
|
||||
regs.p.n = (regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
bool carry = r.p.c;
|
||||
r.p.c = (r.a.l & 0x01);
|
||||
r.a.l = (carry << 7) | (r.a.l >> 1);
|
||||
r.p.n = (r.a.l & 0x80);
|
||||
r.p.z = (r.a.l == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_ror_imm_w() {
|
||||
L ioIRQ();
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = (regs.a.w & 0x0001);
|
||||
regs.a.w = (carry << 15) | (regs.a.w >> 1);
|
||||
regs.p.n = (regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
bool carry = r.p.c;
|
||||
r.p.c = (r.a.w & 0x0001);
|
||||
r.a.w = (carry << 15) | (r.a.w >> 1);
|
||||
r.p.n = (r.a.w & 0x8000);
|
||||
r.p.z = (r.a.w == 0);
|
||||
}
|
||||
|
||||
auto R65816::op_adjust_addr_b(fp op) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
rd.l = readdbr(aa.w);
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
rd.l = readDB(aa.w);
|
||||
io();
|
||||
call(op);
|
||||
L writedbr(aa.w, rd.l);
|
||||
L writeDB(aa.w, rd.l);
|
||||
}
|
||||
|
||||
auto R65816::op_adjust_addr_w(fp op) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
rd.l = readdbr(aa.w + 0);
|
||||
rd.h = readdbr(aa.w + 1);
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
rd.l = readDB(aa.w + 0);
|
||||
rd.h = readDB(aa.w + 1);
|
||||
io();
|
||||
call(op);
|
||||
writedbr(aa.w + 1, rd.h);
|
||||
L writedbr(aa.w + 0, rd.l);
|
||||
writeDB(aa.w + 1, rd.h);
|
||||
L writeDB(aa.w + 0, rd.l);
|
||||
}
|
||||
|
||||
auto R65816::op_adjust_addrx_b(fp op) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
io();
|
||||
rd.l = readdbr(aa.w + regs.x.w);
|
||||
rd.l = readDB(aa.w + r.x.w);
|
||||
io();
|
||||
call(op);
|
||||
L writedbr(aa.w + regs.x.w, rd.l);
|
||||
L writeDB(aa.w + r.x.w, rd.l);
|
||||
}
|
||||
|
||||
auto R65816::op_adjust_addrx_w(fp op) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
io();
|
||||
rd.l = readdbr(aa.w + regs.x.w + 0);
|
||||
rd.h = readdbr(aa.w + regs.x.w + 1);
|
||||
rd.l = readDB(aa.w + r.x.w + 0);
|
||||
rd.h = readDB(aa.w + r.x.w + 1);
|
||||
io();
|
||||
call(op);
|
||||
writedbr(aa.w + regs.x.w + 1, rd.h);
|
||||
L writedbr(aa.w + regs.x.w + 0, rd.l);
|
||||
writeDB(aa.w + r.x.w + 1, rd.h);
|
||||
L writeDB(aa.w + r.x.w + 0, rd.l);
|
||||
}
|
||||
|
||||
auto R65816::op_adjust_dp_b(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
rd.l = readdp(dp);
|
||||
rd.l = readDP(dp);
|
||||
io();
|
||||
call(op);
|
||||
L writedp(dp, rd.l);
|
||||
L writeDP(dp, rd.l);
|
||||
}
|
||||
|
||||
auto R65816::op_adjust_dp_w(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
rd.l = readdp(dp + 0);
|
||||
rd.h = readdp(dp + 1);
|
||||
rd.l = readDP(dp + 0);
|
||||
rd.h = readDP(dp + 1);
|
||||
io();
|
||||
call(op);
|
||||
writedp(dp + 1, rd.h);
|
||||
L writedp(dp + 0, rd.l);
|
||||
writeDP(dp + 1, rd.h);
|
||||
L writeDP(dp + 0, rd.l);
|
||||
}
|
||||
|
||||
auto R65816::op_adjust_dpx_b(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
io();
|
||||
rd.l = readdp(dp + regs.x.w);
|
||||
rd.l = readDP(dp + r.x.w);
|
||||
io();
|
||||
call(op);
|
||||
L writedp(dp + regs.x.w, rd.l);
|
||||
L writeDP(dp + r.x.w, rd.l);
|
||||
}
|
||||
|
||||
auto R65816::op_adjust_dpx_w(fp op) {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
io();
|
||||
rd.l = readdp(dp + regs.x.w + 0);
|
||||
rd.h = readdp(dp + regs.x.w + 1);
|
||||
rd.l = readDP(dp + r.x.w + 0);
|
||||
rd.h = readDP(dp + r.x.w + 1);
|
||||
io();
|
||||
call(op);
|
||||
writedp(dp + regs.x.w + 1, rd.h);
|
||||
L writedp(dp + regs.x.w + 0, rd.l);
|
||||
writeDP(dp + r.x.w + 1, rd.h);
|
||||
L writeDP(dp + r.x.w + 0, rd.l);
|
||||
}
|
||||
|
@ -1,195 +1,195 @@
|
||||
auto R65816::op_write_addr_b(reg16_t& reg) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
L writedbr(aa.w, reg);
|
||||
auto R65816::op_write_addr_b(reg16& reg) {
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
L writeDB(aa.w, reg);
|
||||
}
|
||||
|
||||
auto R65816::op_write_addr_w(reg16_t& reg) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
writedbr(aa.w + 0, reg >> 0);
|
||||
L writedbr(aa.w + 1, reg >> 8);
|
||||
auto R65816::op_write_addr_w(reg16& reg) {
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
writeDB(aa.w + 0, reg >> 0);
|
||||
L writeDB(aa.w + 1, reg >> 8);
|
||||
}
|
||||
|
||||
auto R65816::op_write_addrr_b(reg16_t& reg, reg16_t& idx) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
auto R65816::op_write_addrr_b(reg16& reg, reg16& idx) {
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
io();
|
||||
L writedbr(aa.w + idx, reg);
|
||||
L writeDB(aa.w + idx, reg);
|
||||
}
|
||||
|
||||
auto R65816::op_write_addrr_w(reg16_t& reg, reg16_t& idx) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
auto R65816::op_write_addrr_w(reg16& reg, reg16& idx) {
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
io();
|
||||
writedbr(aa.w + idx + 0, reg >> 0);
|
||||
L writedbr(aa.w + idx + 1, reg >> 8);
|
||||
writeDB(aa.w + idx + 0, reg >> 0);
|
||||
L writeDB(aa.w + idx + 1, reg >> 8);
|
||||
}
|
||||
|
||||
auto R65816::op_write_longr_b(reg16_t& idx) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
aa.b = readpc();
|
||||
L writelong(aa.d + idx, regs.a.l);
|
||||
auto R65816::op_write_longr_b(reg16& idx) {
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
aa.b = readPC();
|
||||
L writeLong(aa.d + idx, r.a.l);
|
||||
}
|
||||
|
||||
auto R65816::op_write_longr_w(reg16_t& idx) {
|
||||
aa.l = readpc();
|
||||
aa.h = readpc();
|
||||
aa.b = readpc();
|
||||
writelong(aa.d + idx + 0, regs.a.l);
|
||||
L writelong(aa.d + idx + 1, regs.a.h);
|
||||
auto R65816::op_write_longr_w(reg16& idx) {
|
||||
aa.l = readPC();
|
||||
aa.h = readPC();
|
||||
aa.b = readPC();
|
||||
writeLong(aa.d + idx + 0, r.a.l);
|
||||
L writeLong(aa.d + idx + 1, r.a.h);
|
||||
}
|
||||
|
||||
auto R65816::op_write_dp_b(reg16_t& reg) {
|
||||
dp = readpc();
|
||||
auto R65816::op_write_dp_b(reg16& reg) {
|
||||
dp = readPC();
|
||||
io2();
|
||||
L writedp(dp, reg);
|
||||
L writeDP(dp, reg);
|
||||
}
|
||||
|
||||
auto R65816::op_write_dp_w(reg16_t& reg) {
|
||||
dp = readpc();
|
||||
auto R65816::op_write_dp_w(reg16& reg) {
|
||||
dp = readPC();
|
||||
io2();
|
||||
writedp(dp + 0, reg >> 0);
|
||||
L writedp(dp + 1, reg >> 8);
|
||||
writeDP(dp + 0, reg >> 0);
|
||||
L writeDP(dp + 1, reg >> 8);
|
||||
}
|
||||
|
||||
auto R65816::op_write_dpr_b(reg16_t& reg, reg16_t& idx) {
|
||||
dp = readpc();
|
||||
auto R65816::op_write_dpr_b(reg16& reg, reg16& idx) {
|
||||
dp = readPC();
|
||||
io2();
|
||||
io();
|
||||
L writedp(dp + idx, reg);
|
||||
L writeDP(dp + idx, reg);
|
||||
}
|
||||
|
||||
auto R65816::op_write_dpr_w(reg16_t& reg, reg16_t& idx) {
|
||||
dp = readpc();
|
||||
auto R65816::op_write_dpr_w(reg16& reg, reg16& idx) {
|
||||
dp = readPC();
|
||||
io2();
|
||||
io();
|
||||
writedp(dp + idx + 0, reg >> 0);
|
||||
L writedp(dp + idx + 1, reg >> 8);
|
||||
writeDP(dp + idx + 0, reg >> 0);
|
||||
L writeDP(dp + idx + 1, reg >> 8);
|
||||
}
|
||||
|
||||
auto R65816::op_sta_idp_b() {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
L writedbr(aa.w, regs.a.l);
|
||||
aa.l = readDP(dp + 0);
|
||||
aa.h = readDP(dp + 1);
|
||||
L writeDB(aa.w, r.a.l);
|
||||
}
|
||||
|
||||
auto R65816::op_sta_idp_w() {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
writedbr(aa.w + 0, regs.a.l);
|
||||
L writedbr(aa.w + 1, regs.a.h);
|
||||
aa.l = readDP(dp + 0);
|
||||
aa.h = readDP(dp + 1);
|
||||
writeDB(aa.w + 0, r.a.l);
|
||||
L writeDB(aa.w + 1, r.a.h);
|
||||
}
|
||||
|
||||
auto R65816::op_sta_ildp_b() {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
aa.b = readdp(dp + 2);
|
||||
L writelong(aa.d, regs.a.l);
|
||||
aa.l = readDPn(dp + 0);
|
||||
aa.h = readDPn(dp + 1);
|
||||
aa.b = readDPn(dp + 2);
|
||||
L writeLong(aa.d, r.a.l);
|
||||
}
|
||||
|
||||
auto R65816::op_sta_ildp_w() {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
aa.b = readdp(dp + 2);
|
||||
writelong(aa.d + 0, regs.a.l);
|
||||
L writelong(aa.d + 1, regs.a.h);
|
||||
aa.l = readDPn(dp + 0);
|
||||
aa.h = readDPn(dp + 1);
|
||||
aa.b = readDPn(dp + 2);
|
||||
writeLong(aa.d + 0, r.a.l);
|
||||
L writeLong(aa.d + 1, r.a.h);
|
||||
}
|
||||
|
||||
auto R65816::op_sta_idpx_b() {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
io();
|
||||
aa.l = readdp(dp + regs.x.w + 0);
|
||||
aa.h = readdp(dp + regs.x.w + 1);
|
||||
L writedbr(aa.w, regs.a.l);
|
||||
aa.l = readDP(dp + r.x.w + 0);
|
||||
aa.h = readDP(dp + r.x.w + 1);
|
||||
L writeDB(aa.w, r.a.l);
|
||||
}
|
||||
|
||||
auto R65816::op_sta_idpx_w() {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
io();
|
||||
aa.l = readdp(dp + regs.x.w + 0);
|
||||
aa.h = readdp(dp + regs.x.w + 1);
|
||||
writedbr(aa.w + 0, regs.a.l);
|
||||
L writedbr(aa.w + 1, regs.a.h);
|
||||
aa.l = readDP(dp + r.x.w + 0);
|
||||
aa.h = readDP(dp + r.x.w + 1);
|
||||
writeDB(aa.w + 0, r.a.l);
|
||||
L writeDB(aa.w + 1, r.a.h);
|
||||
}
|
||||
|
||||
auto R65816::op_sta_idpy_b() {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
aa.l = readDP(dp + 0);
|
||||
aa.h = readDP(dp + 1);
|
||||
io();
|
||||
L writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
L writeDB(aa.w + r.y.w, r.a.l);
|
||||
}
|
||||
|
||||
auto R65816::op_sta_idpy_w() {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
aa.l = readDP(dp + 0);
|
||||
aa.h = readDP(dp + 1);
|
||||
io();
|
||||
writedbr(aa.w + regs.y.w + 0, regs.a.l);
|
||||
L writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
writeDB(aa.w + r.y.w + 0, r.a.l);
|
||||
L writeDB(aa.w + r.y.w + 1, r.a.h);
|
||||
}
|
||||
|
||||
auto R65816::op_sta_ildpy_b() {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
aa.b = readdp(dp + 2);
|
||||
L writelong(aa.d + regs.y.w, regs.a.l);
|
||||
aa.l = readDPn(dp + 0);
|
||||
aa.h = readDPn(dp + 1);
|
||||
aa.b = readDPn(dp + 2);
|
||||
L writeLong(aa.d + r.y.w, r.a.l);
|
||||
}
|
||||
|
||||
auto R65816::op_sta_ildpy_w() {
|
||||
dp = readpc();
|
||||
dp = readPC();
|
||||
io2();
|
||||
aa.l = readdp(dp + 0);
|
||||
aa.h = readdp(dp + 1);
|
||||
aa.b = readdp(dp + 2);
|
||||
writelong(aa.d + regs.y.w + 0, regs.a.l);
|
||||
L writelong(aa.d + regs.y.w + 1, regs.a.h);
|
||||
aa.l = readDPn(dp + 0);
|
||||
aa.h = readDPn(dp + 1);
|
||||
aa.b = readDPn(dp + 2);
|
||||
writeLong(aa.d + r.y.w + 0, r.a.l);
|
||||
L writeLong(aa.d + r.y.w + 1, r.a.h);
|
||||
}
|
||||
|
||||
auto R65816::op_sta_sr_b() {
|
||||
sp = readpc();
|
||||
sp = readPC();
|
||||
io();
|
||||
L writesp(sp, regs.a.l);
|
||||
L writeSP(sp, r.a.l);
|
||||
}
|
||||
|
||||
auto R65816::op_sta_sr_w() {
|
||||
sp = readpc();
|
||||
sp = readPC();
|
||||
io();
|
||||
writesp(sp + 0, regs.a.l);
|
||||
L writesp(sp + 1, regs.a.h);
|
||||
writeSP(sp + 0, r.a.l);
|
||||
L writeSP(sp + 1, r.a.h);
|
||||
}
|
||||
|
||||
auto R65816::op_sta_isry_b() {
|
||||
sp = readpc();
|
||||
sp = readPC();
|
||||
io();
|
||||
aa.l = readsp(sp + 0);
|
||||
aa.h = readsp(sp + 1);
|
||||
aa.l = readSP(sp + 0);
|
||||
aa.h = readSP(sp + 1);
|
||||
io();
|
||||
L writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
L writeDB(aa.w + r.y.w, r.a.l);
|
||||
}
|
||||
|
||||
auto R65816::op_sta_isry_w() {
|
||||
sp = readpc();
|
||||
sp = readPC();
|
||||
io();
|
||||
aa.l = readsp(sp + 0);
|
||||
aa.h = readsp(sp + 1);
|
||||
aa.l = readSP(sp + 0);
|
||||
aa.h = readSP(sp + 1);
|
||||
io();
|
||||
writedbr(aa.w + regs.y.w + 0, regs.a.l);
|
||||
L writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
writeDB(aa.w + r.y.w + 0, r.a.l);
|
||||
L writeDB(aa.w + r.y.w + 1, r.a.h);
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ namespace Processor {
|
||||
#include "disassembler.cpp"
|
||||
#include "serialization.cpp"
|
||||
|
||||
#define E if(r.e)
|
||||
#define N if(!r.e)
|
||||
#define L lastCycle();
|
||||
#define call(op) (this->*op)()
|
||||
|
||||
@ -17,9 +19,6 @@ namespace Processor {
|
||||
#include "opcode_misc.cpp"
|
||||
#include "switch.cpp"
|
||||
|
||||
#undef L
|
||||
#undef call
|
||||
|
||||
//immediate, 2-cycle opcodes with I/O cycle will become bus read
|
||||
//when an IRQ is to be triggered immediately after opcode completion.
|
||||
//this affects the following opcodes:
|
||||
@ -31,43 +30,47 @@ namespace Processor {
|
||||
auto R65816::ioIRQ() -> void {
|
||||
if(interruptPending()) {
|
||||
//modify I/O cycle to bus read cycle, do not increment PC
|
||||
read(regs.pc.d);
|
||||
read(r.pc.d);
|
||||
} else {
|
||||
io();
|
||||
}
|
||||
}
|
||||
|
||||
auto R65816::io2() -> void {
|
||||
if(regs.d.l != 0x00) {
|
||||
if(r.d.l != 0x00) {
|
||||
io();
|
||||
}
|
||||
}
|
||||
|
||||
auto R65816::io4(uint16 x, uint16 y) -> void {
|
||||
if(!regs.p.x || (x & 0xff00) != (y & 0xff00)) {
|
||||
if(!r.p.x || (x & 0xff00) != (y & 0xff00)) {
|
||||
io();
|
||||
}
|
||||
}
|
||||
|
||||
auto R65816::io6(uint16 addr) -> void {
|
||||
if(regs.e && (regs.pc.w & 0xff00) != (addr & 0xff00)) {
|
||||
if(r.e && (r.pc.w & 0xff00) != (addr & 0xff00)) {
|
||||
io();
|
||||
}
|
||||
}
|
||||
|
||||
auto R65816::interrupt() -> void {
|
||||
read(regs.pc.d);
|
||||
read(r.pc.d);
|
||||
io();
|
||||
if(!regs.e) writestack(regs.pc.b);
|
||||
writestack(regs.pc.h);
|
||||
writestack(regs.pc.l);
|
||||
writestack(regs.e ? (regs.p & ~0x10) : regs.p);
|
||||
rd.l = read(regs.vector + 0);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
rd.h = read(regs.vector + 1);
|
||||
regs.pc.w = rd.w;
|
||||
N writeSP(r.pc.b);
|
||||
writeSP(r.pc.h);
|
||||
writeSP(r.pc.l);
|
||||
writeSP(r.e ? (r.p & ~0x10) : r.p);
|
||||
r.pc.l = read(r.vector + 0);
|
||||
r.p.i = 1;
|
||||
r.p.d = 0;
|
||||
r.pc.h = read(r.vector + 1);
|
||||
r.pc.b = 0x00;
|
||||
}
|
||||
|
||||
#undef E
|
||||
#undef N
|
||||
#undef L
|
||||
#undef call
|
||||
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ struct R65816 {
|
||||
virtual auto interruptPending() const -> bool = 0;
|
||||
virtual auto interrupt() -> void;
|
||||
|
||||
virtual auto disassemblerRead(uint24 addr) -> uint8 { return 0u; }
|
||||
virtual auto disassemblerRead(uint24 addr) -> uint8 { return 0; }
|
||||
|
||||
//r65816.cpp
|
||||
alwaysinline auto ioIRQ() -> void;
|
||||
@ -88,8 +88,8 @@ struct R65816 {
|
||||
auto op_read_longx_w(fp);
|
||||
auto op_read_dp_b(fp);
|
||||
auto op_read_dp_w(fp);
|
||||
auto op_read_dpr_b(fp, reg16_t&);
|
||||
auto op_read_dpr_w(fp, reg16_t&);
|
||||
auto op_read_dpr_b(fp, reg16&);
|
||||
auto op_read_dpr_w(fp, reg16&);
|
||||
auto op_read_idp_b(fp);
|
||||
auto op_read_idp_w(fp);
|
||||
auto op_read_idpx_b(fp);
|
||||
@ -106,16 +106,16 @@ struct R65816 {
|
||||
auto op_read_isry_w(fp);
|
||||
|
||||
//opcode_write.cpp
|
||||
auto op_write_addr_b(reg16_t&);
|
||||
auto op_write_addr_w(reg16_t&);
|
||||
auto op_write_addrr_b(reg16_t&, reg16_t&);
|
||||
auto op_write_addrr_w(reg16_t&, reg16_t&);
|
||||
auto op_write_longr_b(reg16_t&);
|
||||
auto op_write_longr_w(reg16_t&);
|
||||
auto op_write_dp_b(reg16_t&);
|
||||
auto op_write_dp_w(reg16_t&);
|
||||
auto op_write_dpr_b(reg16_t&, reg16_t&);
|
||||
auto op_write_dpr_w(reg16_t&, reg16_t&);
|
||||
auto op_write_addr_b(reg16&);
|
||||
auto op_write_addr_w(reg16&);
|
||||
auto op_write_addrr_b(reg16&, reg16&);
|
||||
auto op_write_addrr_w(reg16&, reg16&);
|
||||
auto op_write_longr_b(reg16&);
|
||||
auto op_write_longr_w(reg16&);
|
||||
auto op_write_dp_b(reg16&);
|
||||
auto op_write_dp_w(reg16&);
|
||||
auto op_write_dpr_b(reg16&, reg16&);
|
||||
auto op_write_dpr_w(reg16&, reg16&);
|
||||
auto op_sta_idp_b();
|
||||
auto op_sta_idp_w();
|
||||
auto op_sta_ildp_b();
|
||||
@ -132,8 +132,8 @@ struct R65816 {
|
||||
auto op_sta_isry_w();
|
||||
|
||||
//opcode_rmw.cpp
|
||||
auto op_adjust_imm_b(reg16_t&, signed);
|
||||
auto op_adjust_imm_w(reg16_t&, signed);
|
||||
auto op_adjust_imm_b(reg16&, int);
|
||||
auto op_adjust_imm_w(reg16&, int);
|
||||
auto op_asl_imm_b();
|
||||
auto op_asl_imm_w();
|
||||
auto op_lsr_imm_b();
|
||||
@ -161,58 +161,44 @@ struct R65816 {
|
||||
auto op_jmp_iaddrx();
|
||||
auto op_jmp_iladdr();
|
||||
auto op_jsr_addr();
|
||||
auto op_jsr_long_e();
|
||||
auto op_jsr_long_n();
|
||||
auto op_jsr_iaddrx_e();
|
||||
auto op_jsr_iaddrx_n();
|
||||
auto op_rti_e();
|
||||
auto op_rti_n();
|
||||
auto op_jsr_long();
|
||||
auto op_jsr_iaddrx();
|
||||
auto op_rti();
|
||||
auto op_rts();
|
||||
auto op_rtl_e();
|
||||
auto op_rtl_n();
|
||||
auto op_rtl();
|
||||
|
||||
//opcode_misc.cpp
|
||||
auto op_nop();
|
||||
auto op_wdm();
|
||||
auto op_xba();
|
||||
auto op_move_b(signed adjust);
|
||||
auto op_move_w(signed adjust);
|
||||
auto op_interrupt_e(uint16);
|
||||
auto op_interrupt_n(uint16);
|
||||
auto op_move_b(int adjust);
|
||||
auto op_move_w(int adjust);
|
||||
auto op_interrupt(uint16);
|
||||
auto op_stp();
|
||||
auto op_wai();
|
||||
auto op_xce();
|
||||
auto op_flag(bool& flag, bool value);
|
||||
auto op_pflag_e(bool);
|
||||
auto op_pflag_n(bool);
|
||||
auto op_transfer_b(reg16_t&, reg16_t&);
|
||||
auto op_transfer_w(reg16_t&, reg16_t&);
|
||||
auto op_tcs_e();
|
||||
auto op_tcs_n();
|
||||
auto op_pflag(bool);
|
||||
auto op_transfer_b(reg16&, reg16&);
|
||||
auto op_transfer_w(reg16&, reg16&);
|
||||
auto op_tcs();
|
||||
auto op_tsx_b();
|
||||
auto op_tsx_w();
|
||||
auto op_txs_e();
|
||||
auto op_txs_n();
|
||||
auto op_push_b(reg16_t&);
|
||||
auto op_push_w(reg16_t&);
|
||||
auto op_phd_e();
|
||||
auto op_phd_n();
|
||||
auto op_txs();
|
||||
auto op_push_b(reg16&);
|
||||
auto op_push_w(reg16&);
|
||||
auto op_phd();
|
||||
auto op_phb();
|
||||
auto op_phk();
|
||||
auto op_php();
|
||||
auto op_pull_b(reg16_t&);
|
||||
auto op_pull_w(reg16_t&);
|
||||
auto op_pld_e();
|
||||
auto op_pld_n();
|
||||
auto op_pull_b(reg16&);
|
||||
auto op_pull_w(reg16&);
|
||||
auto op_pld();
|
||||
auto op_plb();
|
||||
auto op_plp_e();
|
||||
auto op_plp_n();
|
||||
auto op_pea_e();
|
||||
auto op_pea_n();
|
||||
auto op_pei_e();
|
||||
auto op_pei_n();
|
||||
auto op_per_e();
|
||||
auto op_per_n();
|
||||
auto op_plp();
|
||||
auto op_pea();
|
||||
auto op_pei();
|
||||
auto op_per();
|
||||
|
||||
//switch.cpp
|
||||
auto instruction() -> void;
|
||||
@ -220,8 +206,8 @@ struct R65816 {
|
||||
//serialization.cpp
|
||||
auto serialize(serializer&) -> void;
|
||||
|
||||
regs_t regs;
|
||||
reg24_t aa, rd;
|
||||
Registers r;
|
||||
reg24 aa, rd;
|
||||
uint8 sp, dp;
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
struct flag_t {
|
||||
struct Flags {
|
||||
bool n{0};
|
||||
bool v{0};
|
||||
bool m{0};
|
||||
@ -8,68 +8,68 @@ struct flag_t {
|
||||
bool z{0};
|
||||
bool c{0};
|
||||
|
||||
inline operator unsigned() const {
|
||||
inline operator uint() const {
|
||||
return (n << 7) + (v << 6) + (m << 5) + (x << 4)
|
||||
+ (d << 3) + (i << 2) + (z << 1) + (c << 0);
|
||||
}
|
||||
|
||||
inline auto operator=(uint8 data) -> unsigned {
|
||||
inline auto operator=(uint8 data) -> uint {
|
||||
n = data & 0x80; v = data & 0x40; m = data & 0x20; x = data & 0x10;
|
||||
d = data & 0x08; i = data & 0x04; z = data & 0x02; c = data & 0x01;
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
struct reg16_t {
|
||||
struct reg16 {
|
||||
union {
|
||||
uint16_t w = 0;
|
||||
struct { uint8_t order_lsb2(l, h); };
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return w; }
|
||||
inline auto operator = (unsigned i) -> unsigned { return w = i; }
|
||||
inline auto operator |= (unsigned i) -> unsigned { return w |= i; }
|
||||
inline auto operator ^= (unsigned i) -> unsigned { return w ^= i; }
|
||||
inline auto operator &= (unsigned i) -> unsigned { return w &= i; }
|
||||
inline auto operator <<= (unsigned i) -> unsigned { return w <<= i; }
|
||||
inline auto operator >>= (unsigned i) -> unsigned { return w >>= i; }
|
||||
inline auto operator += (unsigned i) -> unsigned { return w += i; }
|
||||
inline auto operator -= (unsigned i) -> unsigned { return w -= i; }
|
||||
inline auto operator *= (unsigned i) -> unsigned { return w *= i; }
|
||||
inline auto operator /= (unsigned i) -> unsigned { return w /= i; }
|
||||
inline auto operator %= (unsigned i) -> unsigned { return w %= i; }
|
||||
inline operator uint() const { return w; }
|
||||
inline auto operator =(uint i) -> uint { return w = i; }
|
||||
inline auto operator |=(uint i) -> uint { return w |= i; }
|
||||
inline auto operator ^=(uint i) -> uint { return w ^= i; }
|
||||
inline auto operator &=(uint i) -> uint { return w &= i; }
|
||||
inline auto operator<<=(uint i) -> uint { return w <<= i; }
|
||||
inline auto operator>>=(uint i) -> uint { return w >>= i; }
|
||||
inline auto operator +=(uint i) -> uint { return w += i; }
|
||||
inline auto operator -=(uint i) -> uint { return w -= i; }
|
||||
inline auto operator *=(uint i) -> uint { return w *= i; }
|
||||
inline auto operator /=(uint i) -> uint { return w /= i; }
|
||||
inline auto operator %=(uint i) -> uint { return w %= i; }
|
||||
};
|
||||
|
||||
struct reg24_t {
|
||||
struct reg24 {
|
||||
union {
|
||||
uint32_t d = 0;
|
||||
struct { uint16_t order_lsb2(w, wh); };
|
||||
struct { uint8_t order_lsb4(l, h, b, bh); };
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return d; }
|
||||
inline auto operator = (unsigned i) -> unsigned { return d = uclip<24>(i); }
|
||||
inline auto operator |= (unsigned i) -> unsigned { return d = uclip<24>(d | i); }
|
||||
inline auto operator ^= (unsigned i) -> unsigned { return d = uclip<24>(d ^ i); }
|
||||
inline auto operator &= (unsigned i) -> unsigned { return d = uclip<24>(d & i); }
|
||||
inline auto operator <<= (unsigned i) -> unsigned { return d = uclip<24>(d << i); }
|
||||
inline auto operator >>= (unsigned i) -> unsigned { return d = uclip<24>(d >> i); }
|
||||
inline auto operator += (unsigned i) -> unsigned { return d = uclip<24>(d + i); }
|
||||
inline auto operator -= (unsigned i) -> unsigned { return d = uclip<24>(d - i); }
|
||||
inline auto operator *= (unsigned i) -> unsigned { return d = uclip<24>(d * i); }
|
||||
inline auto operator /= (unsigned i) -> unsigned { return d = uclip<24>(d / i); }
|
||||
inline auto operator %= (unsigned i) -> unsigned { return d = uclip<24>(d % i); }
|
||||
inline operator uint() const { return d; }
|
||||
inline auto operator =(uint i) -> uint { return d = uclip<24>(i); }
|
||||
inline auto operator |=(uint i) -> uint { return d = uclip<24>(d | i); }
|
||||
inline auto operator ^=(uint i) -> uint { return d = uclip<24>(d ^ i); }
|
||||
inline auto operator &=(uint i) -> uint { return d = uclip<24>(d & i); }
|
||||
inline auto operator<<=(uint i) -> uint { return d = uclip<24>(d << i); }
|
||||
inline auto operator>>=(uint i) -> uint { return d = uclip<24>(d >> i); }
|
||||
inline auto operator +=(uint i) -> uint { return d = uclip<24>(d + i); }
|
||||
inline auto operator -=(uint i) -> uint { return d = uclip<24>(d - i); }
|
||||
inline auto operator *=(uint i) -> uint { return d = uclip<24>(d * i); }
|
||||
inline auto operator /=(uint i) -> uint { return d = uclip<24>(d / i); }
|
||||
inline auto operator %=(uint i) -> uint { return d = uclip<24>(d % i); }
|
||||
};
|
||||
|
||||
struct regs_t {
|
||||
reg24_t pc;
|
||||
reg16_t a;
|
||||
reg16_t x;
|
||||
reg16_t y;
|
||||
reg16_t z; //pseudo-register (zero register)
|
||||
reg16_t s;
|
||||
reg16_t d;
|
||||
flag_t p;
|
||||
struct Registers {
|
||||
reg24 pc;
|
||||
reg16 a;
|
||||
reg16 x;
|
||||
reg16 y;
|
||||
reg16 z; //pseudo-register (zero register)
|
||||
reg16 s;
|
||||
reg16 d;
|
||||
Flags p;
|
||||
uint8 db{0};
|
||||
bool e{0};
|
||||
|
||||
|
@ -1,28 +1,28 @@
|
||||
auto R65816::serialize(serializer& s) -> void {
|
||||
s.integer(regs.pc.d);
|
||||
s.integer(r.pc.d);
|
||||
|
||||
s.integer(regs.a.w);
|
||||
s.integer(regs.x.w);
|
||||
s.integer(regs.y.w);
|
||||
s.integer(regs.z.w);
|
||||
s.integer(regs.s.w);
|
||||
s.integer(regs.d.w);
|
||||
s.integer(r.a.w);
|
||||
s.integer(r.x.w);
|
||||
s.integer(r.y.w);
|
||||
s.integer(r.z.w);
|
||||
s.integer(r.s.w);
|
||||
s.integer(r.d.w);
|
||||
|
||||
s.integer(regs.p.n);
|
||||
s.integer(regs.p.v);
|
||||
s.integer(regs.p.m);
|
||||
s.integer(regs.p.x);
|
||||
s.integer(regs.p.d);
|
||||
s.integer(regs.p.i);
|
||||
s.integer(regs.p.z);
|
||||
s.integer(regs.p.c);
|
||||
s.integer(r.p.n);
|
||||
s.integer(r.p.v);
|
||||
s.integer(r.p.m);
|
||||
s.integer(r.p.x);
|
||||
s.integer(r.p.d);
|
||||
s.integer(r.p.i);
|
||||
s.integer(r.p.z);
|
||||
s.integer(r.p.c);
|
||||
|
||||
s.integer(regs.db);
|
||||
s.integer(regs.e);
|
||||
s.integer(regs.irq);
|
||||
s.integer(regs.wai);
|
||||
s.integer(regs.mdr);
|
||||
s.integer(regs.vector);
|
||||
s.integer(r.db);
|
||||
s.integer(r.e);
|
||||
s.integer(r.irq);
|
||||
s.integer(r.wai);
|
||||
s.integer(r.mdr);
|
||||
s.integer(r.vector);
|
||||
|
||||
s.integer(aa.d);
|
||||
s.integer(rd.d);
|
||||
|
@ -1,24 +1,22 @@
|
||||
auto R65816::instruction() -> void {
|
||||
#define opA( n, o ) case n: return op_##o();
|
||||
#define opAI( n, o, i ) case n: return op_##o(i);
|
||||
#define opAII(n, o, i, j) case n: return op_##o(i, j);
|
||||
#define opE( n, o ) case n: return regs.e ? op_##o##_e() : op_##o##_n();
|
||||
#define opEI( n, o, i ) case n: return regs.e ? op_##o##_e(i) : op_##o##_n(i);
|
||||
#define opEII(n, o, i, j) case n: return regs.e ? op_##o##_e(i) : op_##o##_n(j);
|
||||
#define opM( n, o ) case n: return regs.p.m ? op_##o##_b() : op_##o##_w();
|
||||
#define opMF( n, o, f ) case n: return regs.p.m ? op_##o##_b(&R65816::op_##f##_b) : op_##o##_w(&R65816::op_##f##_w);
|
||||
#define opMFI(n, o, f, i) case n: return regs.p.m ? op_##o##_b(&R65816::op_##f##_b, i) : op_##o##_w(&R65816::op_##f##_w, i);
|
||||
#define opMI( n, o, i ) case n: return regs.p.m ? op_##o##_b(i) : op_##o##_w(i);
|
||||
#define opMII(n, o, i, j) case n: return regs.p.m ? op_##o##_b(i, j) : op_##o##_w(i, j);
|
||||
#define opX( n, o) case n: return regs.p.x ? op_##o##_b() : op_##o##_w();
|
||||
#define opXF( n, o, f ) case n: return regs.p.x ? op_##o##_b(&R65816::op_##f##_b) : op_##o##_w(&R65816::op_##f##_w);
|
||||
#define opXFI(n, o, f, i) case n: return regs.p.x ? op_##o##_b(&R65816::op_##f##_b, i) : op_##o##_w(&R65816::op_##f##_w, i);
|
||||
#define opXI( n, o, i ) case n: return regs.p.x ? op_##o##_b(i) : op_##o##_w(i);
|
||||
#define opXII(n, o, i, j) case n: return regs.p.x ? op_##o##_b(i, j) : op_##o##_w(i, j);
|
||||
#define opM( n, o ) case n: return r.p.m ? op_##o##_b() : op_##o##_w();
|
||||
#define opMF( n, o, f ) case n: return r.p.m ? op_##o##_b(&R65816::op_##f##_b) : op_##o##_w(&R65816::op_##f##_w);
|
||||
#define opMFI(n, o, f, i) case n: return r.p.m ? op_##o##_b(&R65816::op_##f##_b, i) : op_##o##_w(&R65816::op_##f##_w, i);
|
||||
#define opMI( n, o, i ) case n: return r.p.m ? op_##o##_b(i) : op_##o##_w(i);
|
||||
#define opMII(n, o, i, j) case n: return r.p.m ? op_##o##_b(i, j) : op_##o##_w(i, j);
|
||||
#define opX( n, o) case n: return r.p.x ? op_##o##_b() : op_##o##_w();
|
||||
#define opXF( n, o, f ) case n: return r.p.x ? op_##o##_b(&R65816::op_##f##_b) : op_##o##_w(&R65816::op_##f##_w);
|
||||
#define opXFI(n, o, f, i) case n: return r.p.x ? op_##o##_b(&R65816::op_##f##_b, i) : op_##o##_w(&R65816::op_##f##_w, i);
|
||||
#define opXI( n, o, i ) case n: return r.p.x ? op_##o##_b(i) : op_##o##_w(i);
|
||||
#define opXII(n, o, i, j) case n: return r.p.x ? op_##o##_b(i, j) : op_##o##_w(i, j);
|
||||
|
||||
switch(readpc()) {
|
||||
opEII(0x00, interrupt, 0xfffe, 0xffe6)
|
||||
switch(readPC()) {
|
||||
opAI (0x00, interrupt, r.e ? 0xffe6 : 0xfffe)
|
||||
opMF (0x01, read_idpx, ora)
|
||||
opEII(0x02, interrupt, 0xfff4, 0xffe4)
|
||||
opAI (0x02, interrupt, r.e ? 0xffe4 : 0xfff4)
|
||||
opMF (0x03, read_sr, ora)
|
||||
opMF (0x04, adjust_dp, tsb)
|
||||
opMF (0x05, read_dp, ora)
|
||||
@ -27,60 +25,60 @@ auto R65816::instruction() -> void {
|
||||
opA (0x08, php)
|
||||
opMF (0x09, read_const, ora)
|
||||
opM (0x0a, asl_imm)
|
||||
opE (0x0b, phd)
|
||||
opA (0x0b, phd)
|
||||
opMF (0x0c, adjust_addr, tsb)
|
||||
opMF (0x0d, read_addr, ora)
|
||||
opMF (0x0e, adjust_addr, asl)
|
||||
opMF (0x0f, read_long, ora)
|
||||
opAII(0x10, branch, regs.p.n, 0)
|
||||
opAII(0x10, branch, r.p.n, 0)
|
||||
opMF (0x11, read_idpy, ora)
|
||||
opMF (0x12, read_idp, ora)
|
||||
opMF (0x13, read_isry, ora)
|
||||
opMF (0x14, adjust_dp, trb)
|
||||
opMFI(0x15, read_dpr, ora, regs.x)
|
||||
opMFI(0x15, read_dpr, ora, r.x)
|
||||
opMF (0x16, adjust_dpx, asl)
|
||||
opMF (0x17, read_ildpy, ora)
|
||||
opAII(0x18, flag, regs.p.c, 0)
|
||||
opAII(0x18, flag, r.p.c, 0)
|
||||
opMF (0x19, read_addry, ora)
|
||||
opMII(0x1a, adjust_imm, regs.a, +1)
|
||||
opE (0x1b, tcs)
|
||||
opMII(0x1a, adjust_imm, r.a, +1)
|
||||
opA (0x1b, tcs)
|
||||
opMF (0x1c, adjust_addr, trb)
|
||||
opMF (0x1d, read_addrx, ora)
|
||||
opMF (0x1e, adjust_addrx, asl)
|
||||
opMF (0x1f, read_longx, ora)
|
||||
opA (0x20, jsr_addr)
|
||||
opMF (0x21, read_idpx, and)
|
||||
opE (0x22, jsr_long)
|
||||
opA (0x22, jsr_long)
|
||||
opMF (0x23, read_sr, and)
|
||||
opMF (0x24, read_dp, bit)
|
||||
opMF (0x25, read_dp, and)
|
||||
opMF (0x26, adjust_dp, rol)
|
||||
opMF (0x27, read_ildp, and)
|
||||
opE (0x28, plp)
|
||||
opA (0x28, plp)
|
||||
opMF (0x29, read_const, and)
|
||||
opM (0x2a, rol_imm)
|
||||
opE (0x2b, pld)
|
||||
opA (0x2b, pld)
|
||||
opMF (0x2c, read_addr, bit)
|
||||
opMF (0x2d, read_addr, and)
|
||||
opMF (0x2e, adjust_addr, rol)
|
||||
opMF (0x2f, read_long, and)
|
||||
opAII(0x30, branch, regs.p.n, 1)
|
||||
opAII(0x30, branch, r.p.n, 1)
|
||||
opMF (0x31, read_idpy, and)
|
||||
opMF (0x32, read_idp, and)
|
||||
opMF (0x33, read_isry, and)
|
||||
opMFI(0x34, read_dpr, bit, regs.x)
|
||||
opMFI(0x35, read_dpr, and, regs.x)
|
||||
opMFI(0x34, read_dpr, bit, r.x)
|
||||
opMFI(0x35, read_dpr, and, r.x)
|
||||
opMF (0x36, adjust_dpx, rol)
|
||||
opMF (0x37, read_ildpy, and)
|
||||
opAII(0x38, flag, regs.p.c, 1)
|
||||
opAII(0x38, flag, r.p.c, 1)
|
||||
opMF (0x39, read_addry, and)
|
||||
opMII(0x3a, adjust_imm, regs.a, -1)
|
||||
opAII(0x3b, transfer_w, regs.s, regs.a)
|
||||
opMII(0x3a, adjust_imm, r.a, -1)
|
||||
opAII(0x3b, transfer_w, r.s, r.a)
|
||||
opMF (0x3c, read_addrx, bit)
|
||||
opMF (0x3d, read_addrx, and)
|
||||
opMF (0x3e, adjust_addrx, rol)
|
||||
opMF (0x3f, read_longx, and)
|
||||
opE (0x40, rti)
|
||||
opA (0x40, rti)
|
||||
opMF (0x41, read_idpx, eor)
|
||||
opA (0x42, wdm)
|
||||
opMF (0x43, read_sr, eor)
|
||||
@ -88,7 +86,7 @@ auto R65816::instruction() -> void {
|
||||
opMF (0x45, read_dp, eor)
|
||||
opMF (0x46, adjust_dp, lsr)
|
||||
opMF (0x47, read_ildp, eor)
|
||||
opMI (0x48, push, regs.a)
|
||||
opMI (0x48, push, r.a)
|
||||
opMF (0x49, read_const, eor)
|
||||
opM (0x4a, lsr_imm)
|
||||
opA (0x4b, phk)
|
||||
@ -96,50 +94,50 @@ auto R65816::instruction() -> void {
|
||||
opMF (0x4d, read_addr, eor)
|
||||
opMF (0x4e, adjust_addr, lsr)
|
||||
opMF (0x4f, read_long, eor)
|
||||
opAII(0x50, branch, regs.p.v, 0)
|
||||
opAII(0x50, branch, r.p.v, 0)
|
||||
opMF (0x51, read_idpy, eor)
|
||||
opMF (0x52, read_idp, eor)
|
||||
opMF (0x53, read_isry, eor)
|
||||
opXI (0x54, move, +1)
|
||||
opMFI(0x55, read_dpr, eor, regs.x)
|
||||
opMFI(0x55, read_dpr, eor, r.x)
|
||||
opMF (0x56, adjust_dpx, lsr)
|
||||
opMF (0x57, read_ildpy, eor)
|
||||
opAII(0x58, flag, regs.p.i, 0)
|
||||
opAII(0x58, flag, r.p.i, 0)
|
||||
opMF (0x59, read_addry, eor)
|
||||
opXI (0x5a, push, regs.y)
|
||||
opAII(0x5b, transfer_w, regs.a, regs.d)
|
||||
opXI (0x5a, push, r.y)
|
||||
opAII(0x5b, transfer_w, r.a, r.d)
|
||||
opA (0x5c, jmp_long)
|
||||
opMF (0x5d, read_addrx, eor)
|
||||
opMF (0x5e, adjust_addrx, lsr)
|
||||
opMF (0x5f, read_longx, eor)
|
||||
opA (0x60, rts)
|
||||
opMF (0x61, read_idpx, adc)
|
||||
opE (0x62, per)
|
||||
opA (0x62, per)
|
||||
opMF (0x63, read_sr, adc)
|
||||
opMI (0x64, write_dp, regs.z)
|
||||
opMI (0x64, write_dp, r.z)
|
||||
opMF (0x65, read_dp, adc)
|
||||
opMF (0x66, adjust_dp, ror)
|
||||
opMF (0x67, read_ildp, adc)
|
||||
opMI (0x68, pull, regs.a)
|
||||
opMI (0x68, pull, r.a)
|
||||
opMF (0x69, read_const, adc)
|
||||
opM (0x6a, ror_imm)
|
||||
opE (0x6b, rtl)
|
||||
opA (0x6b, rtl)
|
||||
opA (0x6c, jmp_iaddr)
|
||||
opMF (0x6d, read_addr, adc)
|
||||
opMF (0x6e, adjust_addr, ror)
|
||||
opMF (0x6f, read_long, adc)
|
||||
opAII(0x70, branch, regs.p.v, 1)
|
||||
opAII(0x70, branch, r.p.v, 1)
|
||||
opMF (0x71, read_idpy, adc)
|
||||
opMF (0x72, read_idp, adc)
|
||||
opMF (0x73, read_isry, adc)
|
||||
opMII(0x74, write_dpr, regs.z, regs.x)
|
||||
opMFI(0x75, read_dpr, adc, regs.x)
|
||||
opMII(0x74, write_dpr, r.z, r.x)
|
||||
opMFI(0x75, read_dpr, adc, r.x)
|
||||
opMF (0x76, adjust_dpx, ror)
|
||||
opMF (0x77, read_ildpy, adc)
|
||||
opAII(0x78, flag, regs.p.i, 1)
|
||||
opAII(0x78, flag, r.p.i, 1)
|
||||
opMF (0x79, read_addry, adc)
|
||||
opXI (0x7a, pull, regs.y)
|
||||
opAII(0x7b, transfer_w, regs.d, regs.a)
|
||||
opXI (0x7a, pull, r.y)
|
||||
opAII(0x7b, transfer_w, r.d, r.a)
|
||||
opA (0x7c, jmp_iaddrx)
|
||||
opMF (0x7d, read_addrx, adc)
|
||||
opMF (0x7e, adjust_addrx, ror)
|
||||
@ -148,34 +146,34 @@ auto R65816::instruction() -> void {
|
||||
opM (0x81, sta_idpx)
|
||||
opA (0x82, brl)
|
||||
opM (0x83, sta_sr)
|
||||
opXI (0x84, write_dp, regs.y)
|
||||
opMI (0x85, write_dp, regs.a)
|
||||
opXI (0x86, write_dp, regs.x)
|
||||
opXI (0x84, write_dp, r.y)
|
||||
opMI (0x85, write_dp, r.a)
|
||||
opXI (0x86, write_dp, r.x)
|
||||
opM (0x87, sta_ildp)
|
||||
opXII(0x88, adjust_imm, regs.y, -1)
|
||||
opXII(0x88, adjust_imm, r.y, -1)
|
||||
opM (0x89, read_bit_const)
|
||||
opMII(0x8a, transfer, regs.x, regs.a)
|
||||
opMII(0x8a, transfer, r.x, r.a)
|
||||
opA (0x8b, phb)
|
||||
opXI (0x8c, write_addr, regs.y)
|
||||
opMI (0x8d, write_addr, regs.a)
|
||||
opXI (0x8e, write_addr, regs.x)
|
||||
opMI (0x8f, write_longr, regs.z)
|
||||
opAII(0x90, branch, regs.p.c, 0)
|
||||
opXI (0x8c, write_addr, r.y)
|
||||
opMI (0x8d, write_addr, r.a)
|
||||
opXI (0x8e, write_addr, r.x)
|
||||
opMI (0x8f, write_longr, r.z)
|
||||
opAII(0x90, branch, r.p.c, 0)
|
||||
opM (0x91, sta_idpy)
|
||||
opM (0x92, sta_idp)
|
||||
opM (0x93, sta_isry)
|
||||
opXII(0x94, write_dpr, regs.y, regs.x)
|
||||
opMII(0x95, write_dpr, regs.a, regs.x)
|
||||
opXII(0x96, write_dpr, regs.x, regs.y)
|
||||
opXII(0x94, write_dpr, r.y, r.x)
|
||||
opMII(0x95, write_dpr, r.a, r.x)
|
||||
opXII(0x96, write_dpr, r.x, r.y)
|
||||
opM (0x97, sta_ildpy)
|
||||
opMII(0x98, transfer, regs.y, regs.a)
|
||||
opMII(0x99, write_addrr, regs.a, regs.y)
|
||||
opE (0x9a, txs)
|
||||
opXII(0x9b, transfer, regs.x, regs.y)
|
||||
opMI (0x9c, write_addr, regs.z)
|
||||
opMII(0x9d, write_addrr, regs.a, regs.x)
|
||||
opMII(0x9e, write_addrr, regs.z, regs.x)
|
||||
opMI (0x9f, write_longr, regs.x)
|
||||
opMII(0x98, transfer, r.y, r.a)
|
||||
opMII(0x99, write_addrr, r.a, r.y)
|
||||
opA (0x9a, txs)
|
||||
opXII(0x9b, transfer, r.x, r.y)
|
||||
opMI (0x9c, write_addr, r.z)
|
||||
opMII(0x9d, write_addrr, r.a, r.x)
|
||||
opMII(0x9e, write_addrr, r.z, r.x)
|
||||
opMI (0x9f, write_longr, r.x)
|
||||
opXF (0xa0, read_const, ldy)
|
||||
opMF (0xa1, read_idpx, lda)
|
||||
opXF (0xa2, read_const, ldx)
|
||||
@ -184,57 +182,57 @@ auto R65816::instruction() -> void {
|
||||
opMF (0xa5, read_dp, lda)
|
||||
opXF (0xa6, read_dp, ldx)
|
||||
opMF (0xa7, read_ildp, lda)
|
||||
opXII(0xa8, transfer, regs.a, regs.y)
|
||||
opXII(0xa8, transfer, r.a, r.y)
|
||||
opMF (0xa9, read_const, lda)
|
||||
opXII(0xaa, transfer, regs.a, regs.x)
|
||||
opXII(0xaa, transfer, r.a, r.x)
|
||||
opA (0xab, plb)
|
||||
opXF (0xac, read_addr, ldy)
|
||||
opMF (0xad, read_addr, lda)
|
||||
opXF (0xae, read_addr, ldx)
|
||||
opMF (0xaf, read_long, lda)
|
||||
opAII(0xb0, branch, regs.p.c, 1)
|
||||
opAII(0xb0, branch, r.p.c, 1)
|
||||
opMF (0xb1, read_idpy, lda)
|
||||
opMF (0xb2, read_idp, lda)
|
||||
opMF (0xb3, read_isry, lda)
|
||||
opXFI(0xb4, read_dpr, ldy, regs.x)
|
||||
opMFI(0xb5, read_dpr, lda, regs.x)
|
||||
opXFI(0xb6, read_dpr, ldx, regs.y)
|
||||
opXFI(0xb4, read_dpr, ldy, r.x)
|
||||
opMFI(0xb5, read_dpr, lda, r.x)
|
||||
opXFI(0xb6, read_dpr, ldx, r.y)
|
||||
opMF (0xb7, read_ildpy, lda)
|
||||
opAII(0xb8, flag, regs.p.v, 0)
|
||||
opAII(0xb8, flag, r.p.v, 0)
|
||||
opMF (0xb9, read_addry, lda)
|
||||
opX (0xba, tsx)
|
||||
opXII(0xbb, transfer, regs.y, regs.x)
|
||||
opXII(0xbb, transfer, r.y, r.x)
|
||||
opXF (0xbc, read_addrx, ldy)
|
||||
opMF (0xbd, read_addrx, lda)
|
||||
opXF (0xbe, read_addry, ldx)
|
||||
opMF (0xbf, read_longx, lda)
|
||||
opXF (0xc0, read_const, cpy)
|
||||
opMF (0xc1, read_idpx, cmp)
|
||||
opEI (0xc2, pflag, 0)
|
||||
opAI (0xc2, pflag, 0)
|
||||
opMF (0xc3, read_sr, cmp)
|
||||
opXF (0xc4, read_dp, cpy)
|
||||
opMF (0xc5, read_dp, cmp)
|
||||
opMF (0xc6, adjust_dp, dec)
|
||||
opMF (0xc7, read_ildp, cmp)
|
||||
opXII(0xc8, adjust_imm, regs.y, +1)
|
||||
opXII(0xc8, adjust_imm, r.y, +1)
|
||||
opMF (0xc9, read_const, cmp)
|
||||
opXII(0xca, adjust_imm, regs.x, -1)
|
||||
opXII(0xca, adjust_imm, r.x, -1)
|
||||
opA (0xcb, wai)
|
||||
opXF (0xcc, read_addr, cpy)
|
||||
opMF (0xcd, read_addr, cmp)
|
||||
opMF (0xce, adjust_addr, dec)
|
||||
opMF (0xcf, read_long, cmp)
|
||||
opAII(0xd0, branch, regs.p.z, 0)
|
||||
opAII(0xd0, branch, r.p.z, 0)
|
||||
opMF (0xd1, read_idpy, cmp)
|
||||
opMF (0xd2, read_idp, cmp)
|
||||
opMF (0xd3, read_isry, cmp)
|
||||
opE (0xd4, pei)
|
||||
opMFI(0xd5, read_dpr, cmp, regs.x)
|
||||
opA (0xd4, pei)
|
||||
opMFI(0xd5, read_dpr, cmp, r.x)
|
||||
opMF (0xd6, adjust_dpx, dec)
|
||||
opMF (0xd7, read_ildpy, cmp)
|
||||
opAII(0xd8, flag, regs.p.d, 0)
|
||||
opAII(0xd8, flag, r.p.d, 0)
|
||||
opMF (0xd9, read_addry, cmp)
|
||||
opXI (0xda, push, regs.x)
|
||||
opXI (0xda, push, r.x)
|
||||
opA (0xdb, stp)
|
||||
opA (0xdc, jmp_iladdr)
|
||||
opMF (0xdd, read_addrx, cmp)
|
||||
@ -242,13 +240,13 @@ auto R65816::instruction() -> void {
|
||||
opMF (0xdf, read_longx, cmp)
|
||||
opXF (0xe0, read_const, cpx)
|
||||
opMF (0xe1, read_idpx, sbc)
|
||||
opEI (0xe2, pflag, 1)
|
||||
opAI (0xe2, pflag, 1)
|
||||
opMF (0xe3, read_sr, sbc)
|
||||
opXF (0xe4, read_dp, cpx)
|
||||
opMF (0xe5, read_dp, sbc)
|
||||
opMF (0xe6, adjust_dp, inc)
|
||||
opMF (0xe7, read_ildp, sbc)
|
||||
opXII(0xe8, adjust_imm, regs.x, +1)
|
||||
opXII(0xe8, adjust_imm, r.x, +1)
|
||||
opMF (0xe9, read_const, sbc)
|
||||
opA (0xea, nop)
|
||||
opA (0xeb, xba)
|
||||
@ -256,29 +254,27 @@ auto R65816::instruction() -> void {
|
||||
opMF (0xed, read_addr, sbc)
|
||||
opMF (0xee, adjust_addr, inc)
|
||||
opMF (0xef, read_long, sbc)
|
||||
opAII(0xf0, branch, regs.p.z, 1)
|
||||
opAII(0xf0, branch, r.p.z, 1)
|
||||
opMF (0xf1, read_idpy, sbc)
|
||||
opMF (0xf2, read_idp, sbc)
|
||||
opMF (0xf3, read_isry, sbc)
|
||||
opE (0xf4, pea)
|
||||
opMFI(0xf5, read_dpr, sbc, regs.x)
|
||||
opA (0xf4, pea)
|
||||
opMFI(0xf5, read_dpr, sbc, r.x)
|
||||
opMF (0xf6, adjust_dpx, inc)
|
||||
opMF (0xf7, read_ildpy, sbc)
|
||||
opAII(0xf8, flag, regs.p.d, 1)
|
||||
opAII(0xf8, flag, r.p.d, 1)
|
||||
opMF (0xf9, read_addry, sbc)
|
||||
opXI (0xfa, pull, regs.x)
|
||||
opXI (0xfa, pull, r.x)
|
||||
opA (0xfb, xce)
|
||||
opE (0xfc, jsr_iaddrx)
|
||||
opA (0xfc, jsr_iaddrx)
|
||||
opMF (0xfd, read_addrx, sbc)
|
||||
opMF (0xfe, adjust_addrx, inc)
|
||||
opMF (0xff, read_longx, sbc)
|
||||
}
|
||||
|
||||
#undef opA
|
||||
#undef opAI
|
||||
#undef opAII
|
||||
#undef opE
|
||||
#undef opEI
|
||||
#undef opEII
|
||||
#undef opM
|
||||
#undef opMF
|
||||
#undef opMFI
|
||||
|
@ -1,6 +1,6 @@
|
||||
struct Gamepad : Controller {
|
||||
enum : uint {
|
||||
B, Y, Select, Start, Up, Down, Left, Right, A, X, L, R,
|
||||
Up, Down, Left, Right, B, A, Y, X, L, R, Select, Start,
|
||||
};
|
||||
|
||||
Gamepad(bool port);
|
||||
|
@ -25,7 +25,7 @@ auto ICD2::main() -> void {
|
||||
GameBoy::system._clocksExecuted = 0;
|
||||
} else { //DMG halted
|
||||
stream->sample(0, 0);
|
||||
step(1);
|
||||
step(2); //two clocks per audio sample
|
||||
}
|
||||
synchronizeCPU();
|
||||
}
|
||||
@ -54,7 +54,7 @@ auto ICD2::power() -> void {
|
||||
|
||||
auto ICD2::reset(bool soft) -> void {
|
||||
create(ICD2::Enter, cpu.frequency / 5);
|
||||
if(!soft) stream = Emulator::audio.createStream(2, 4194304.0 / 2.0);
|
||||
if(!soft) stream = Emulator::audio.createStream(2, cpu.frequency / 10);
|
||||
|
||||
r6003 = 0x00;
|
||||
r6004 = 0xff;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
auto SA1::dma_normal() -> void {
|
||||
while(mmio.dtc--) {
|
||||
uint8 data = regs.mdr;
|
||||
uint8 data = r.mdr;
|
||||
uint32 dsa = mmio.dsa++;
|
||||
uint32 dda = mmio.dda++;
|
||||
|
||||
@ -61,7 +61,7 @@ auto SA1::dma_cc1() -> void {
|
||||
mmio.chdma_irqfl = true;
|
||||
if(mmio.chdma_irqen) {
|
||||
mmio.chdma_irqcl = 0;
|
||||
cpu.regs.irq = 1;
|
||||
cpu.r.irq = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,13 +115,13 @@ auto SA1::io() -> void {
|
||||
auto SA1::read(uint24 addr) -> uint8 {
|
||||
tick();
|
||||
if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick();
|
||||
return bus_read(addr, regs.mdr);
|
||||
return bus_read(addr, r.mdr);
|
||||
}
|
||||
|
||||
auto SA1::write(uint24 addr, uint8 data) -> void {
|
||||
tick();
|
||||
if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick();
|
||||
bus_write(addr, regs.mdr = data);
|
||||
bus_write(addr, r.mdr = data);
|
||||
}
|
||||
|
||||
//note: addresses are translated prior to invoking this function:
|
||||
|
@ -2,8 +2,8 @@
|
||||
auto SA1::mmio_w2200(uint8 data) -> void {
|
||||
if(mmio.sa1_resb && !(data & 0x80)) {
|
||||
//reset SA-1 CPU
|
||||
regs.pc.w = mmio.crv;
|
||||
regs.pc.b = 0x00;
|
||||
r.pc.w = mmio.crv;
|
||||
r.pc.b = 0x00;
|
||||
}
|
||||
|
||||
mmio.sa1_irq = (data & 0x80);
|
||||
@ -28,14 +28,14 @@ auto SA1::mmio_w2201(uint8 data) -> void {
|
||||
if(!mmio.cpu_irqen && (data & 0x80)) {
|
||||
if(mmio.cpu_irqfl) {
|
||||
mmio.cpu_irqcl = 0;
|
||||
cpu.regs.irq = 1;
|
||||
cpu.r.irq = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(!mmio.chdma_irqen && (data & 0x20)) {
|
||||
if(mmio.chdma_irqfl) {
|
||||
mmio.chdma_irqcl = 0;
|
||||
cpu.regs.irq = 1;
|
||||
cpu.r.irq = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ auto SA1::mmio_w2202(uint8 data) -> void {
|
||||
if(mmio.cpu_irqcl ) mmio.cpu_irqfl = false;
|
||||
if(mmio.chdma_irqcl) mmio.chdma_irqfl = false;
|
||||
|
||||
if(!mmio.cpu_irqfl && !mmio.chdma_irqfl) cpu.regs.irq = 0;
|
||||
if(!mmio.cpu_irqfl && !mmio.chdma_irqfl) cpu.r.irq = 0;
|
||||
}
|
||||
|
||||
//(CRV) SA-1 reset vector
|
||||
@ -77,7 +77,7 @@ auto SA1::mmio_w2209(uint8 data) -> void {
|
||||
mmio.cpu_irqfl = true;
|
||||
if(mmio.cpu_irqen) {
|
||||
mmio.cpu_irqcl = 0;
|
||||
cpu.regs.irq = 1;
|
||||
cpu.r.irq = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,41 +32,41 @@ auto SA1::main() -> void {
|
||||
}
|
||||
|
||||
auto SA1::interrupt() -> void {
|
||||
read(regs.pc.d);
|
||||
read(r.pc.d);
|
||||
io();
|
||||
if(!regs.e) writestack(regs.pc.b);
|
||||
writestack(regs.pc.h);
|
||||
writestack(regs.pc.l);
|
||||
writestack(regs.e ? (regs.p & ~0x10) : regs.p);
|
||||
regs.pc.w = regs.vector;
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
if(!r.e) writeSP(r.pc.b);
|
||||
writeSP(r.pc.h);
|
||||
writeSP(r.pc.l);
|
||||
writeSP(r.e ? (r.p & ~0x10) : r.p);
|
||||
r.pc.w = r.vector;
|
||||
r.pc.b = 0x00;
|
||||
r.p.i = 1;
|
||||
r.p.d = 0;
|
||||
}
|
||||
|
||||
auto SA1::lastCycle() -> void {
|
||||
if(mmio.sa1_nmi && !mmio.sa1_nmicl) {
|
||||
status.interrupt_pending = true;
|
||||
regs.vector = mmio.cnv;
|
||||
r.vector = mmio.cnv;
|
||||
mmio.sa1_nmifl = true;
|
||||
mmio.sa1_nmicl = 1;
|
||||
regs.wai = false;
|
||||
} else if(!regs.p.i) {
|
||||
r.wai = false;
|
||||
} else if(!r.p.i) {
|
||||
if(mmio.timer_irqen && !mmio.timer_irqcl) {
|
||||
status.interrupt_pending = true;
|
||||
regs.vector = mmio.civ;
|
||||
r.vector = mmio.civ;
|
||||
mmio.timer_irqfl = true;
|
||||
regs.wai = false;
|
||||
r.wai = false;
|
||||
} else if(mmio.dma_irqen && !mmio.dma_irqcl) {
|
||||
status.interrupt_pending = true;
|
||||
regs.vector = mmio.civ;
|
||||
r.vector = mmio.civ;
|
||||
mmio.dma_irqfl = true;
|
||||
regs.wai = false;
|
||||
r.wai = false;
|
||||
} else if(mmio.sa1_irq && !mmio.sa1_irqcl) {
|
||||
status.interrupt_pending = true;
|
||||
regs.vector = mmio.civ;
|
||||
r.vector = mmio.civ;
|
||||
mmio.sa1_irqfl = true;
|
||||
regs.wai = false;
|
||||
r.wai = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,8 +124,10 @@ auto SA1::unload() -> void {
|
||||
}
|
||||
|
||||
auto SA1::power() -> void {
|
||||
regs.a = regs.x = regs.y = 0x0000;
|
||||
regs.s = 0x01ff;
|
||||
r.a = 0x0000;
|
||||
r.x = 0x0000;
|
||||
r.y = 0x0000;
|
||||
r.s = 0x01ff;
|
||||
}
|
||||
|
||||
auto SA1::reset() -> void {
|
||||
@ -136,17 +138,17 @@ auto SA1::reset() -> void {
|
||||
iram.write(addr, 0x00);
|
||||
}
|
||||
|
||||
regs.pc.d = 0x000000;
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
regs.s.h = 0x01;
|
||||
regs.d = 0x0000;
|
||||
regs.db = 0x00;
|
||||
regs.p = 0x34;
|
||||
regs.e = 1;
|
||||
regs.mdr = 0x00;
|
||||
regs.wai = false;
|
||||
regs.vector = 0x0000;
|
||||
r.pc.d = 0x000000;
|
||||
r.x.h = 0x00;
|
||||
r.y.h = 0x00;
|
||||
r.s.h = 0x01;
|
||||
r.d = 0x0000;
|
||||
r.db = 0x00;
|
||||
r.p = 0x34;
|
||||
r.e = 1;
|
||||
r.mdr = 0x00;
|
||||
r.wai = false;
|
||||
r.vector = 0x0000;
|
||||
|
||||
status.tick_counter = 0;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
auto SuperFX::stop() -> void {
|
||||
cpu.regs.irq = 1;
|
||||
cpu.r.irq = 1;
|
||||
}
|
||||
|
||||
auto SuperFX::color(uint8 source) -> uint8 {
|
||||
|
@ -18,7 +18,7 @@ auto SuperFX::mmio_read(uint24 addr, uint8) -> uint8 {
|
||||
case 0x3031: {
|
||||
uint8 r = regs.sfr >> 8;
|
||||
regs.sfr.irq = 0;
|
||||
cpu.regs.irq = 0;
|
||||
cpu.r.irq = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -60,28 +60,28 @@ auto CPU::main() -> void {
|
||||
status.interrupt_pending = false;
|
||||
if(status.nmi_pending) {
|
||||
status.nmi_pending = false;
|
||||
regs.vector = !regs.e ? 0xffea : 0xfffa;
|
||||
r.vector = r.e ? 0xfffa : 0xffea;
|
||||
interrupt();
|
||||
debugger.op_nmi();
|
||||
} else if(status.irq_pending) {
|
||||
status.irq_pending = false;
|
||||
regs.vector = !regs.e ? 0xffee : 0xfffe;
|
||||
r.vector = r.e ? 0xfffe : 0xffee;
|
||||
interrupt();
|
||||
debugger.op_irq();
|
||||
} else if(status.reset_pending) {
|
||||
status.reset_pending = false;
|
||||
addClocks(132);
|
||||
regs.vector = 0xfffc;
|
||||
r.vector = 0xfffc;
|
||||
interrupt();
|
||||
} else if(status.power_pending) {
|
||||
status.power_pending = false;
|
||||
addClocks(186);
|
||||
regs.pc.l = bus.read(0xfffc, regs.mdr);
|
||||
regs.pc.h = bus.read(0xfffd, regs.mdr);
|
||||
r.pc.l = bus.read(0xfffc, r.mdr);
|
||||
r.pc.h = bus.read(0xfffd, r.mdr);
|
||||
}
|
||||
}
|
||||
|
||||
debugger.op_exec(regs.pc.d);
|
||||
debugger.op_exec(r.pc.d);
|
||||
instruction();
|
||||
}
|
||||
|
||||
@ -89,8 +89,10 @@ auto CPU::power() -> void {
|
||||
for(auto& byte : wram) byte = random(0x55);
|
||||
|
||||
//CPU
|
||||
regs.a = regs.x = regs.y = 0x0000;
|
||||
regs.s = 0x01ff;
|
||||
r.a = 0x0000;
|
||||
r.x = 0x0000;
|
||||
r.y = 0x0000;
|
||||
r.s = 0x01ff;
|
||||
|
||||
//DMA
|
||||
for(auto& channel : this->channel) {
|
||||
@ -144,17 +146,17 @@ auto CPU::reset() -> void {
|
||||
bus.map(reader, writer, "7e-7f:0000-ffff", 0x20000);
|
||||
|
||||
//CPU
|
||||
regs.pc = 0x000000;
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
regs.s.h = 0x01;
|
||||
regs.d = 0x0000;
|
||||
regs.db = 0x00;
|
||||
regs.p = 0x34;
|
||||
regs.e = 1;
|
||||
regs.mdr = 0x00;
|
||||
regs.wai = false;
|
||||
regs.vector = 0xfffc; //reset vector address
|
||||
r.pc = 0x000000;
|
||||
r.x.h = 0x00;
|
||||
r.y.h = 0x00;
|
||||
r.s.h = 0x01;
|
||||
r.d = 0x0000;
|
||||
r.db = 0x00;
|
||||
r.p = 0x34;
|
||||
r.e = 1;
|
||||
r.mdr = 0x00;
|
||||
r.wai = false;
|
||||
r.vector = 0xfffc; //reset vector address
|
||||
|
||||
//$2140-217f
|
||||
for(auto& port : status.port) port = 0x00;
|
||||
|
@ -24,7 +24,7 @@ auto CPU::dmaAddressValid(uint24 abus) -> bool {
|
||||
|
||||
auto CPU::dmaRead(uint24 abus) -> uint8 {
|
||||
if(!dmaAddressValid(abus)) return 0x00;
|
||||
return bus.read(abus, regs.mdr);
|
||||
return bus.read(abus, r.mdr);
|
||||
}
|
||||
|
||||
//simulate two-stage pipeline for DMA transfers; example:
|
||||
@ -42,14 +42,14 @@ auto CPU::dmaWrite(bool valid, uint addr, uint8 data) -> void {
|
||||
auto CPU::dmaTransfer(bool direction, uint8 bbus, uint24 abus) -> void {
|
||||
if(direction == 0) {
|
||||
dmaAddClocks(4);
|
||||
regs.mdr = dmaRead(abus);
|
||||
r.mdr = dmaRead(abus);
|
||||
dmaAddClocks(4);
|
||||
dmaWrite(dmaTransferValid(bbus, abus), 0x2100 | bbus, regs.mdr);
|
||||
dmaWrite(dmaTransferValid(bbus, abus), 0x2100 | bbus, r.mdr);
|
||||
} else {
|
||||
dmaAddClocks(4);
|
||||
regs.mdr = dmaTransferValid(bbus, abus) ? bus.read(0x2100 | bbus, regs.mdr) : (uint8)0x00;
|
||||
r.mdr = dmaTransferValid(bbus, abus) ? bus.read(0x2100 | bbus, r.mdr) : (uint8)0x00;
|
||||
dmaAddClocks(4);
|
||||
dmaWrite(dmaAddressValid(abus), abus, regs.mdr);
|
||||
dmaWrite(dmaAddressValid(abus), abus, r.mdr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,12 +155,12 @@ auto CPU::dmaRun() -> void {
|
||||
|
||||
auto CPU::hdmaUpdate(uint n) -> void {
|
||||
dmaAddClocks(4);
|
||||
regs.mdr = dmaRead(channel[n].source_bank << 16 | channel[n].hdma_addr);
|
||||
r.mdr = dmaRead(channel[n].source_bank << 16 | channel[n].hdma_addr);
|
||||
dmaAddClocks(4);
|
||||
dmaWrite(false);
|
||||
|
||||
if((channel[n].line_counter & 0x7f) == 0) {
|
||||
channel[n].line_counter = regs.mdr;
|
||||
channel[n].line_counter = r.mdr;
|
||||
channel[n].hdma_addr++;
|
||||
|
||||
channel[n].hdma_completed = channel[n].line_counter == 0;
|
||||
@ -168,16 +168,16 @@ auto CPU::hdmaUpdate(uint n) -> void {
|
||||
|
||||
if(channel[n].indirect) {
|
||||
dmaAddClocks(4);
|
||||
regs.mdr = dmaRead(hdmaAddress(n));
|
||||
channel[n].indirect_addr = regs.mdr << 8;
|
||||
r.mdr = dmaRead(hdmaAddress(n));
|
||||
channel[n].indirect_addr = r.mdr << 8;
|
||||
dmaAddClocks(4);
|
||||
dmaWrite(false);
|
||||
|
||||
if(!channel[n].hdma_completed || hdmaActiveAfter(n)) {
|
||||
dmaAddClocks(4);
|
||||
regs.mdr = dmaRead(hdmaAddress(n));
|
||||
r.mdr = dmaRead(hdmaAddress(n));
|
||||
channel[n].indirect_addr >>= 8;
|
||||
channel[n].indirect_addr |= regs.mdr << 8;
|
||||
channel[n].indirect_addr |= r.mdr << 8;
|
||||
dmaAddClocks(4);
|
||||
dmaWrite(false);
|
||||
}
|
||||
|
@ -90,13 +90,13 @@ auto CPU::timeup() -> bool {
|
||||
auto CPU::nmiTest() -> bool {
|
||||
if(!status.nmi_transition) return false;
|
||||
status.nmi_transition = false;
|
||||
regs.wai = false;
|
||||
r.wai = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto CPU::irqTest() -> bool {
|
||||
if(!status.irq_transition && !regs.irq) return false;
|
||||
if(!status.irq_transition && !r.irq) return false;
|
||||
status.irq_transition = false;
|
||||
regs.wai = false;
|
||||
return !regs.p.i;
|
||||
r.wai = false;
|
||||
return !r.p.i;
|
||||
}
|
||||
|
@ -17,11 +17,11 @@ auto CPU::read(uint24 addr) -> uint8 {
|
||||
status.clock_count = speed(addr);
|
||||
dmaEdge();
|
||||
addClocks(status.clock_count - 4);
|
||||
regs.mdr = bus.read(addr, regs.mdr);
|
||||
r.mdr = bus.read(addr, r.mdr);
|
||||
addClocks(4);
|
||||
aluEdge();
|
||||
debugger.op_read(addr, regs.mdr);
|
||||
return regs.mdr;
|
||||
debugger.op_read(addr, r.mdr);
|
||||
return r.mdr;
|
||||
}
|
||||
|
||||
auto CPU::write(uint24 addr, uint8 data) -> void {
|
||||
@ -29,8 +29,8 @@ auto CPU::write(uint24 addr, uint8 data) -> void {
|
||||
status.clock_count = speed(addr);
|
||||
dmaEdge();
|
||||
addClocks(status.clock_count);
|
||||
bus.write(addr, regs.mdr = data);
|
||||
debugger.op_write(addr, regs.mdr);
|
||||
bus.write(addr, r.mdr = data);
|
||||
debugger.op_write(addr, r.mdr);
|
||||
}
|
||||
|
||||
auto CPU::speed(uint24 addr) const -> uint {
|
||||
@ -44,5 +44,5 @@ auto CPU::speed(uint24 addr) const -> uint {
|
||||
}
|
||||
|
||||
auto CPU::disassemblerRead(uint24 addr) -> uint8 {
|
||||
return bus.read(addr, regs.mdr);
|
||||
return bus.read(addr, r.mdr);
|
||||
}
|
||||
|
@ -8,16 +8,16 @@ auto CPU::cpuPortRead(uint24 addr, uint8 data) -> uint8 {
|
||||
|
||||
//WMDATA
|
||||
if(addr == 0x2180) {
|
||||
return bus.read(0x7e0000 | status.wram_addr++, regs.mdr);
|
||||
return bus.read(0x7e0000 | status.wram_addr++, r.mdr);
|
||||
}
|
||||
|
||||
//JOYSER0
|
||||
//7-2 = MDR
|
||||
//1-0 = Joypad serial data
|
||||
if(addr == 0x4016) {
|
||||
uint8 r = regs.mdr & 0xfc;
|
||||
r |= SuperFamicom::peripherals.controllerPort1->data();
|
||||
return r;
|
||||
uint8 v = r.mdr & 0xfc;
|
||||
v |= SuperFamicom::peripherals.controllerPort1->data();
|
||||
return v;
|
||||
}
|
||||
|
||||
//JOYSER1
|
||||
@ -25,9 +25,9 @@ auto CPU::cpuPortRead(uint24 addr, uint8 data) -> uint8 {
|
||||
//7-5 = MDR
|
||||
//4-2 = Always 1 (pins are connected to GND)
|
||||
//1-0 = Joypad serial data
|
||||
uint8 r = (regs.mdr & 0xe0) | 0x1c;
|
||||
r |= SuperFamicom::peripherals.controllerPort2->data();
|
||||
return r;
|
||||
uint8 v = (r.mdr & 0xe0) | 0x1c;
|
||||
v |= SuperFamicom::peripherals.controllerPort2->data();
|
||||
return v;
|
||||
}
|
||||
|
||||
//RDNMI
|
||||
@ -35,19 +35,19 @@ auto CPU::cpuPortRead(uint24 addr, uint8 data) -> uint8 {
|
||||
//7 = NMI acknowledge
|
||||
//6-4 = MDR
|
||||
//3-0 = CPU (5a22) version
|
||||
uint8 r = (regs.mdr & 0x70);
|
||||
r |= (uint8)(rdnmi()) << 7;
|
||||
r |= (cpu_version & 0x0f);
|
||||
return r;
|
||||
uint8 v = (r.mdr & 0x70);
|
||||
v |= (uint8)(rdnmi()) << 7;
|
||||
v |= (cpu_version & 0x0f);
|
||||
return v;
|
||||
}
|
||||
|
||||
//TIMEUP
|
||||
if(addr == 0x4211) {
|
||||
//7 = IRQ acknowledge
|
||||
//6-0 = MDR
|
||||
uint8 r = (regs.mdr & 0x7f);
|
||||
r |= (uint8)(timeup()) << 7;
|
||||
return r;
|
||||
uint8 v = (r.mdr & 0x7f);
|
||||
v |= (uint8)(timeup()) << 7;
|
||||
return v;
|
||||
}
|
||||
|
||||
//HVBJOY
|
||||
@ -56,11 +56,11 @@ auto CPU::cpuPortRead(uint24 addr, uint8 data) -> uint8 {
|
||||
//6 = HBLANK acknowledge
|
||||
//5-1 = MDR
|
||||
//0 = JOYPAD acknowledge
|
||||
uint8 r = (regs.mdr & 0x3e);
|
||||
if(status.auto_joypad_active) r |= 0x01;
|
||||
if(hcounter() <= 2 || hcounter() >= 1096) r |= 0x40; //hblank
|
||||
if(vcounter() >= ppu.vdisp()) r |= 0x80; //vblank
|
||||
return r;
|
||||
uint8 v = (r.mdr & 0x3e);
|
||||
if(status.auto_joypad_active) v |= 0x01;
|
||||
if(hcounter() <= 2 || hcounter() >= 1096) v |= 0x40; //hblank
|
||||
if(vcounter() >= ppu.vdisp()) v |= 0x80; //vblank
|
||||
return v;
|
||||
}
|
||||
|
||||
//RDIO
|
||||
|
@ -28,15 +28,15 @@ auto SuperDisc::Enter() -> void {
|
||||
}
|
||||
|
||||
auto SuperDisc::main() -> void {
|
||||
cpu.regs.irq = 0;
|
||||
cpu.r.irq = 0;
|
||||
|
||||
if(r.irqEnable.bit(3)) {
|
||||
cpu.regs.irq = 1;
|
||||
cpu.r.irq = 1;
|
||||
nec.data = necPollIRQ();
|
||||
}
|
||||
|
||||
if(r.irqEnable.bit(2)) {
|
||||
cpu.regs.irq = 1;
|
||||
cpu.r.irq = 1;
|
||||
sony.data = sonyPollIRQ();
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ auto SuperDisc::read(uint24 addr, uint8 data) -> uint8 {
|
||||
}
|
||||
|
||||
if(addr == 0x21e1) {
|
||||
cpu.regs.irq = 0;
|
||||
cpu.r.irq = 0;
|
||||
data = necReadData();
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ auto SuperDisc::read(uint24 addr, uint8 data) -> uint8 {
|
||||
}
|
||||
|
||||
if(addr == 0x21e3) {
|
||||
cpu.regs.irq = 0;
|
||||
cpu.r.irq = 0;
|
||||
data = sonyReadData();
|
||||
}
|
||||
|
||||
|
@ -26,113 +26,105 @@ Interface::Interface() {
|
||||
media.append({ID::SuperFamicom, "Sufami Turbo", "st", false});
|
||||
|
||||
{ Device device{0, ID::ControllerPort1 | ID::ControllerPort2 | ID::ExpansionPort, "None"};
|
||||
this->device.append(device);
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
{ Device device{1, ID::ControllerPort1 | ID::ControllerPort2, "Gamepad"};
|
||||
device.input.append({ 0, 0, "B" });
|
||||
device.input.append({ 1, 0, "Y" });
|
||||
device.input.append({ 2, 0, "Select"});
|
||||
device.input.append({ 3, 0, "Start" });
|
||||
device.input.append({ 4, 0, "Up" });
|
||||
device.input.append({ 5, 0, "Down" });
|
||||
device.input.append({ 6, 0, "Left" });
|
||||
device.input.append({ 7, 0, "Right" });
|
||||
device.input.append({ 8, 0, "A" });
|
||||
device.input.append({ 9, 0, "X" });
|
||||
device.input.append({10, 0, "L" });
|
||||
device.input.append({11, 0, "R" });
|
||||
device.order = {4, 5, 6, 7, 0, 8, 1, 9, 10, 11, 2, 3};
|
||||
this->device.append(device);
|
||||
device.inputs.append({ 0, 0, "Up" });
|
||||
device.inputs.append({ 1, 0, "Down" });
|
||||
device.inputs.append({ 2, 0, "Left" });
|
||||
device.inputs.append({ 3, 0, "Right" });
|
||||
device.inputs.append({ 4, 0, "B" });
|
||||
device.inputs.append({ 5, 0, "A" });
|
||||
device.inputs.append({ 6, 0, "Y" });
|
||||
device.inputs.append({ 7, 0, "X" });
|
||||
device.inputs.append({ 8, 0, "L" });
|
||||
device.inputs.append({ 9, 0, "R" });
|
||||
device.inputs.append({10, 0, "Select"});
|
||||
device.inputs.append({11, 0, "Start" });
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
{ Device device{2, ID::ControllerPort1 | ID::ControllerPort2, "Multitap"};
|
||||
for(uint p = 1, n = 0; p <= 4; p++, n += 12) {
|
||||
device.input.append({n + 0, 0, {"Port ", p, " - ", "B" }});
|
||||
device.input.append({n + 1, 0, {"Port ", p, " - ", "Y" }});
|
||||
device.input.append({n + 2, 0, {"Port ", p, " - ", "Select"}});
|
||||
device.input.append({n + 3, 0, {"Port ", p, " - ", "Start" }});
|
||||
device.input.append({n + 4, 0, {"Port ", p, " - ", "Up" }});
|
||||
device.input.append({n + 5, 0, {"Port ", p, " - ", "Down" }});
|
||||
device.input.append({n + 6, 0, {"Port ", p, " - ", "Left" }});
|
||||
device.input.append({n + 7, 0, {"Port ", p, " - ", "Right" }});
|
||||
device.input.append({n + 8, 0, {"Port ", p, " - ", "A" }});
|
||||
device.input.append({n + 9, 0, {"Port ", p, " - ", "X" }});
|
||||
device.input.append({n + 10, 0, {"Port ", p, " - ", "L" }});
|
||||
device.input.append({n + 11, 0, {"Port ", p, " - ", "R" }});
|
||||
device.order.append({n + 4, n + 5, n + 6, n + 7, n + 0, n + 8});
|
||||
device.order.append({n + 1, n + 9, n + 10, n + 11, n + 2, n + 3});
|
||||
device.inputs.append({n + 0, 0, {"Port ", p, " - ", "Up" }});
|
||||
device.inputs.append({n + 1, 0, {"Port ", p, " - ", "Down" }});
|
||||
device.inputs.append({n + 2, 0, {"Port ", p, " - ", "Left" }});
|
||||
device.inputs.append({n + 3, 0, {"Port ", p, " - ", "Right" }});
|
||||
device.inputs.append({n + 4, 0, {"Port ", p, " - ", "B" }});
|
||||
device.inputs.append({n + 5, 0, {"Port ", p, " - ", "A" }});
|
||||
device.inputs.append({n + 6, 0, {"Port ", p, " - ", "Y" }});
|
||||
device.inputs.append({n + 7, 0, {"Port ", p, " - ", "X" }});
|
||||
device.inputs.append({n + 8, 0, {"Port ", p, " - ", "L" }});
|
||||
device.inputs.append({n + 9, 0, {"Port ", p, " - ", "R" }});
|
||||
device.inputs.append({n + 10, 0, {"Port ", p, " - ", "Select"}});
|
||||
device.inputs.append({n + 11, 0, {"Port ", p, " - ", "Start" }});
|
||||
}
|
||||
this->device.append(device);
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
{ Device device{3, ID::ControllerPort1 | ID::ControllerPort2, "Mouse"};
|
||||
device.input.append({0, 1, "X-axis"});
|
||||
device.input.append({1, 1, "Y-axis"});
|
||||
device.input.append({2, 0, "Left" });
|
||||
device.input.append({3, 0, "Right" });
|
||||
device.order = {0, 1, 2, 3};
|
||||
this->device.append(device);
|
||||
device.inputs.append({0, 1, "X-axis"});
|
||||
device.inputs.append({1, 1, "Y-axis"});
|
||||
device.inputs.append({2, 0, "Left" });
|
||||
device.inputs.append({3, 0, "Right" });
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
{ Device device{4, ID::ControllerPort2, "Super Scope"};
|
||||
device.input.append({0, 1, "X-axis" });
|
||||
device.input.append({1, 1, "Y-axis" });
|
||||
device.input.append({2, 0, "Trigger"});
|
||||
device.input.append({3, 0, "Cursor" });
|
||||
device.input.append({4, 0, "Turbo" });
|
||||
device.input.append({5, 0, "Pause" });
|
||||
device.order = {0, 1, 2, 3, 4, 5};
|
||||
this->device.append(device);
|
||||
device.inputs.append({0, 1, "X-axis" });
|
||||
device.inputs.append({1, 1, "Y-axis" });
|
||||
device.inputs.append({2, 0, "Trigger"});
|
||||
device.inputs.append({3, 0, "Cursor" });
|
||||
device.inputs.append({4, 0, "Turbo" });
|
||||
device.inputs.append({5, 0, "Pause" });
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
{ Device device{5, ID::ControllerPort2, "Justifier"};
|
||||
device.input.append({0, 1, "X-axis" });
|
||||
device.input.append({1, 1, "Y-axis" });
|
||||
device.input.append({2, 0, "Trigger"});
|
||||
device.input.append({3, 0, "Start" });
|
||||
device.order = {0, 1, 2, 3};
|
||||
this->device.append(device);
|
||||
device.inputs.append({0, 1, "X-axis" });
|
||||
device.inputs.append({1, 1, "Y-axis" });
|
||||
device.inputs.append({2, 0, "Trigger"});
|
||||
device.inputs.append({3, 0, "Start" });
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
{ Device device{6, ID::ControllerPort2, "Justifiers"};
|
||||
device.input.append({0, 1, "Port 1 - X-axis" });
|
||||
device.input.append({1, 1, "Port 1 - Y-axis" });
|
||||
device.input.append({2, 0, "Port 1 - Trigger"});
|
||||
device.input.append({3, 0, "Port 1 - Start" });
|
||||
device.order.append({0, 1, 2, 3});
|
||||
device.input.append({4, 1, "Port 2 - X-axis" });
|
||||
device.input.append({5, 1, "Port 2 - Y-axis" });
|
||||
device.input.append({6, 0, "Port 2 - Trigger"});
|
||||
device.input.append({7, 0, "Port 2 - Start" });
|
||||
device.order.append({4, 5, 6, 7});
|
||||
this->device.append(device);
|
||||
device.inputs.append({0, 1, "Port 1 - X-axis" });
|
||||
device.inputs.append({1, 1, "Port 1 - Y-axis" });
|
||||
device.inputs.append({2, 0, "Port 1 - Trigger"});
|
||||
device.inputs.append({3, 0, "Port 1 - Start" });
|
||||
device.inputs.append({4, 1, "Port 2 - X-axis" });
|
||||
device.inputs.append({5, 1, "Port 2 - Y-axis" });
|
||||
device.inputs.append({6, 0, "Port 2 - Trigger"});
|
||||
device.inputs.append({7, 0, "Port 2 - Start" });
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
{ Device device{7, ID::ControllerPort1, "Serial USART"};
|
||||
this->device.append(device);
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
{ Device device{8, ID::ExpansionPort, "Satellaview"};
|
||||
this->device.append(device);
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
{ Device device{9, ID::ExpansionPort, "Super Disc"};
|
||||
this->device.append(device);
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
{ Device device{10, ID::ExpansionPort, "21fx"};
|
||||
this->device.append(device);
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
port.append({0, "Controller Port 1"});
|
||||
port.append({1, "Controller Port 2"});
|
||||
port.append({2, "Expansion Port"});
|
||||
ports.append({0, "Controller Port 1"});
|
||||
ports.append({1, "Controller Port 2"});
|
||||
ports.append({2, "Expansion Port"});
|
||||
|
||||
for(auto& device : this->device) {
|
||||
for(auto& port : this->port) {
|
||||
for(auto& device : devices) {
|
||||
for(auto& port : ports) {
|
||||
if(device.portmask & (1 << port.id)) {
|
||||
port.device.append(device);
|
||||
port.devices.append(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ struct Interface : Emulator::Interface {
|
||||
auto get(const string& name) -> any override;
|
||||
auto set(const string& name, const any& value) -> bool override;
|
||||
|
||||
vector<Device> device;
|
||||
vector<Device> devices;
|
||||
};
|
||||
|
||||
struct Settings {
|
||||
|
@ -13,21 +13,21 @@ auto PPU::read(uint24 addr, uint8 data) -> uint8 {
|
||||
|
||||
//MPYL
|
||||
case 0x2134: {
|
||||
unsigned result = ((int16)regs.m7a * (int8)(regs.m7b >> 8));
|
||||
uint result = ((int16)regs.m7a * (int8)(regs.m7b >> 8));
|
||||
regs.ppu1_mdr = (result >> 0);
|
||||
return regs.ppu1_mdr;
|
||||
}
|
||||
|
||||
//MPYM
|
||||
case 0x2135: {
|
||||
unsigned result = ((int16)regs.m7a * (int8)(regs.m7b >> 8));
|
||||
uint result = ((int16)regs.m7a * (int8)(regs.m7b >> 8));
|
||||
regs.ppu1_mdr = (result >> 8);
|
||||
return regs.ppu1_mdr;
|
||||
}
|
||||
|
||||
//MPYH
|
||||
case 0x2136: {
|
||||
unsigned result = ((int16)regs.m7a * (int8)(regs.m7b >> 8));
|
||||
uint result = ((int16)regs.m7a * (int8)(regs.m7b >> 8));
|
||||
regs.ppu1_mdr = (result >> 16);
|
||||
return regs.ppu1_mdr;
|
||||
}
|
||||
@ -35,7 +35,7 @@ auto PPU::read(uint24 addr, uint8 data) -> uint8 {
|
||||
//SLHV
|
||||
case 0x2137: {
|
||||
if(cpu.pio() & 0x80) latchCounters();
|
||||
return cpu.regs.mdr;
|
||||
return cpu.r.mdr;
|
||||
}
|
||||
|
||||
//OAMDATAREAD
|
||||
|
@ -6,13 +6,13 @@ auto Program::loadRequest(uint id, string name, string type, bool required) -> v
|
||||
.openFolder();
|
||||
if(!directory::exists(location)) return;
|
||||
|
||||
mediaPaths(id) = location;
|
||||
mediumPaths(id) = location;
|
||||
folderPaths.append(location);
|
||||
emulator->load(id);
|
||||
}
|
||||
|
||||
auto Program::loadRequest(uint id, string filename, bool required) -> void {
|
||||
string pathname = mediaPaths(emulator->group(id));
|
||||
string pathname = mediumPaths(emulator->group(id));
|
||||
string location = {pathname, filename};
|
||||
|
||||
if(filename == "manifest.bml" && pathname && !pathname.endsWith("sys/")) {
|
||||
@ -36,7 +36,7 @@ auto Program::loadRequest(uint id, string filename, bool required) -> void {
|
||||
}
|
||||
|
||||
auto Program::saveRequest(uint id, string filename) -> void {
|
||||
string pathname = mediaPaths(emulator->group(id));
|
||||
string pathname = mediumPaths(emulator->group(id));
|
||||
string location = {pathname, filename};
|
||||
|
||||
//filestream stream{location, file::mode::write};
|
||||
@ -113,7 +113,7 @@ auto Program::dipSettings(const Markup::Node& node) -> uint {
|
||||
}
|
||||
|
||||
auto Program::path(uint group) -> string {
|
||||
return mediaPaths(group);
|
||||
return mediumPaths(group);
|
||||
}
|
||||
|
||||
auto Program::notify(string text) -> void {
|
||||
|
@ -1,21 +1,21 @@
|
||||
auto Program::loadMedia(string location) -> void {
|
||||
auto Program::loadMedium(string location) -> void {
|
||||
location.transform("\\", "/");
|
||||
if(!location.endsWith("/")) location.append("/");
|
||||
if(!directory::exists(location)) return;
|
||||
|
||||
string type = suffixname(location).trimLeft(".", 1L);
|
||||
for(auto& media : emulator->media) {
|
||||
if(!media.bootable) continue;
|
||||
if(media.type != type) continue;
|
||||
return loadMedia(media, location);
|
||||
for(auto& medium : emulator->media) {
|
||||
if(!medium.bootable) continue;
|
||||
if(medium.type != type) continue;
|
||||
return loadMedium(medium, location);
|
||||
}
|
||||
}
|
||||
|
||||
auto Program::loadMedia(Emulator::Interface::Media& media, string location) -> void {
|
||||
unloadMedia();
|
||||
auto Program::loadMedium(Emulator::Interface::Medium& medium, string location) -> void {
|
||||
unloadMedium();
|
||||
|
||||
mediaPaths(0) = locate({media.name, ".sys/"});
|
||||
mediaPaths(media.id) = location;
|
||||
mediumPaths(0) = locate({medium.name, ".sys/"});
|
||||
mediumPaths(medium.id) = location;
|
||||
folderPaths.append(location);
|
||||
|
||||
emulator->set("Blur Emulation", false);
|
||||
@ -28,17 +28,17 @@ auto Program::loadMedia(Emulator::Interface::Media& media, string location) -> v
|
||||
emulator->connect((uint)SFC::Port::Controller2, (uint)SFC::Device::None);
|
||||
emulator->connect((uint)SFC::Port::Expansion, (uint)SFC::Device::None);
|
||||
|
||||
emulator->load(media.id);
|
||||
emulator->load(medium.id);
|
||||
emulator->power();
|
||||
|
||||
presentation->setTitle(emulator->title());
|
||||
}
|
||||
|
||||
auto Program::unloadMedia() -> void {
|
||||
auto Program::unloadMedium() -> void {
|
||||
if(!emulator->loaded()) return;
|
||||
|
||||
emulator->unload();
|
||||
mediaPaths.reset();
|
||||
mediumPaths.reset();
|
||||
folderPaths.reset();
|
||||
|
||||
presentation->setTitle("");
|
@ -1,6 +1,6 @@
|
||||
#include "../loki.hpp"
|
||||
#include "interface.cpp"
|
||||
#include "media.cpp"
|
||||
#include "medium.cpp"
|
||||
unique_pointer<Program> program;
|
||||
|
||||
Program::Program(lstring args) {
|
||||
@ -38,7 +38,7 @@ Program::Program(lstring args) {
|
||||
"Legend of Zelda - A Link to the Past, The (USA) (1.0).sfc/"
|
||||
};
|
||||
|
||||
if(directory::exists(location)) loadMedia(location);
|
||||
if(directory::exists(location)) loadMedium(location);
|
||||
}
|
||||
|
||||
auto Program::main() -> void {
|
||||
@ -52,7 +52,7 @@ auto Program::main() -> void {
|
||||
}
|
||||
|
||||
auto Program::quit() -> void {
|
||||
unloadMedia();
|
||||
unloadMedium();
|
||||
video.reset();
|
||||
audio.reset();
|
||||
input.reset();
|
||||
|
@ -5,9 +5,9 @@ struct Program : Emulator::Interface::Bind {
|
||||
auto quit() -> void;
|
||||
|
||||
//media.cpp
|
||||
auto loadMedia(string location) -> void;
|
||||
auto loadMedia(Emulator::Interface::Media& media, string location) -> void;
|
||||
auto unloadMedia() -> void;
|
||||
auto loadMedium(string location) -> void;
|
||||
auto loadMedium(Emulator::Interface::Medium& medium, string location) -> void;
|
||||
auto unloadMedium() -> void;
|
||||
|
||||
//interface.cpp
|
||||
auto loadRequest(uint id, string name, string type, bool required) -> void override;
|
||||
@ -22,7 +22,7 @@ struct Program : Emulator::Interface::Bind {
|
||||
auto notify(string text) -> void override;
|
||||
|
||||
vector<shared_pointer<HID::Device>> devices;
|
||||
vector<string> mediaPaths;
|
||||
vector<string> mediumPaths;
|
||||
vector<string> folderPaths;
|
||||
};
|
||||
|
||||
|
@ -150,16 +150,15 @@ InputManager::InputManager() {
|
||||
auto& inputEmulator = emulators.right();
|
||||
inputEmulator.name = emulator->information.name;
|
||||
|
||||
for(auto& port : emulator->port) {
|
||||
for(auto& port : emulator->ports) {
|
||||
inputEmulator.ports.append(InputPort());
|
||||
auto& inputPort = inputEmulator.ports.right();
|
||||
inputPort.name = port.name;
|
||||
for(auto& device : port.device) {
|
||||
for(auto& device : port.devices) {
|
||||
inputPort.devices.append(InputDevice());
|
||||
auto& inputDevice = inputPort.devices.right();
|
||||
inputDevice.name = device.name;
|
||||
for(auto number : device.order) {
|
||||
auto& input = device.input[number];
|
||||
for(auto& input : device.inputs) {
|
||||
inputDevice.mappings.append(new InputMapping());
|
||||
auto& inputMapping = inputDevice.mappings.right();
|
||||
inputMapping->name = input.name;
|
||||
|
@ -17,7 +17,7 @@ Presentation::Presentation() {
|
||||
.setFilters(string{media.name, "|*.", media.type})
|
||||
.openFolder();
|
||||
if(directory::exists(location)) {
|
||||
program->loadMedia(location);
|
||||
program->loadMedium(location);
|
||||
}
|
||||
});
|
||||
loadBootableMedia.append(item);
|
||||
@ -29,7 +29,7 @@ Presentation::Presentation() {
|
||||
libraryMenu.append(MenuItem().setText("Load ROM File ...").onActivate([&] {
|
||||
audio->clear();
|
||||
if(auto location = execute("icarus", "--import")) {
|
||||
program->loadMedia(location.output.strip());
|
||||
program->loadMedium(location.output.strip());
|
||||
}
|
||||
}));
|
||||
libraryMenu.append(MenuItem().setText("Import ROM Files ...").onActivate([&] {
|
||||
@ -40,7 +40,7 @@ Presentation::Presentation() {
|
||||
systemMenu.setText("System").setVisible(false);
|
||||
powerSystem.setText("Power").onActivate([&] { program->powerCycle(); });
|
||||
resetSystem.setText("Reset").onActivate([&] { program->softReset(); });
|
||||
unloadSystem.setText("Unload").onActivate([&] { program->unloadMedia(); drawSplashScreen(); });
|
||||
unloadSystem.setText("Unload").onActivate([&] { program->unloadMedium(); drawSplashScreen(); });
|
||||
|
||||
settingsMenu.setText("Settings");
|
||||
videoScaleMenu.setText("Video Scale");
|
||||
@ -173,14 +173,14 @@ auto Presentation::updateEmulator() -> void {
|
||||
inputPort2.setVisible(false).reset();
|
||||
inputPort3.setVisible(false).reset();
|
||||
|
||||
for(auto n : range(emulator->port)) {
|
||||
for(auto n : range(emulator->ports)) {
|
||||
if(n >= 3) break;
|
||||
auto& port = emulator->port[n];
|
||||
auto& port = emulator->ports[n];
|
||||
auto& menu = (n == 0 ? inputPort1 : n == 1 ? inputPort2 : inputPort3);
|
||||
menu.setText(port.name);
|
||||
|
||||
Group devices;
|
||||
for(auto& device : port.device) {
|
||||
for(auto& device : port.devices) {
|
||||
MenuRadioItem item{&menu};
|
||||
item.setText(device.name).onActivate([=] {
|
||||
auto path = string{emulator->information.name, "/", port.name}.replace(" ", "");
|
||||
|
@ -7,14 +7,14 @@ auto Program::loadRequest(uint id, string name, string type, bool required) -> v
|
||||
.openFolder();
|
||||
if(!directory::exists(location)) return;
|
||||
|
||||
mediaPaths(id) = location;
|
||||
mediumPaths(id) = location;
|
||||
folderPaths.append(location);
|
||||
emulator->load(id);
|
||||
}
|
||||
|
||||
//request from emulation core to load non-volatile media file
|
||||
auto Program::loadRequest(uint id, string filename, bool required) -> void {
|
||||
string pathname = mediaPaths(emulator->group(id));
|
||||
string pathname = mediumPaths(emulator->group(id));
|
||||
string location = {pathname, filename};
|
||||
|
||||
if(filename == "manifest.bml" && pathname && !pathname.endsWith(".sys/")) {
|
||||
@ -39,7 +39,7 @@ auto Program::loadRequest(uint id, string filename, bool required) -> void {
|
||||
|
||||
//request from emulation core to save non-volatile media file
|
||||
auto Program::saveRequest(uint id, string filename) -> void {
|
||||
string pathname = mediaPaths(emulator->group(id));
|
||||
string pathname = mediumPaths(emulator->group(id));
|
||||
string location = {pathname, filename};
|
||||
if(!pathname) return; //should never occur
|
||||
|
||||
@ -89,19 +89,13 @@ auto Program::videoRefresh(const uint32* data, uint pitch, uint width, uint heig
|
||||
}
|
||||
}
|
||||
|
||||
auto Program::audioSample(int16 lsample, int16 rsample) -> void {
|
||||
audio->sample(lsample, rsample);
|
||||
//int samples[] = {lsample, rsample};
|
||||
//dsp.sample(samples);
|
||||
//while(dsp.pending()) {
|
||||
// dsp.read(samples);
|
||||
// audio->sample(samples[0], samples[1]);
|
||||
//}
|
||||
auto Program::audioSample(int16 left, int16 right) -> void {
|
||||
audio->sample(left, right);
|
||||
}
|
||||
|
||||
auto Program::inputPoll(uint port, uint device, uint input) -> int16 {
|
||||
if(presentation->focused() || settings["Input/FocusLoss/AllowInput"].boolean()) {
|
||||
auto guid = emulator->port[port].device[device].input[input].guid;
|
||||
auto guid = emulator->ports[port].devices[device].inputs[input].guid;
|
||||
auto mapping = (InputMapping*)guid;
|
||||
if(mapping) return mapping->poll();
|
||||
}
|
||||
@ -110,7 +104,7 @@ auto Program::inputPoll(uint port, uint device, uint input) -> int16 {
|
||||
|
||||
auto Program::inputRumble(uint port, uint device, uint input, bool enable) -> void {
|
||||
if(presentation->focused() || settings["Input/FocusLoss/AllowInput"].boolean() || !enable) {
|
||||
auto guid = emulator->port[port].device[device].input[input].guid;
|
||||
auto guid = emulator->ports[port].devices[device].inputs[input].guid;
|
||||
auto mapping = (InputMapping*)guid;
|
||||
if(mapping) return mapping->rumble(enable);
|
||||
}
|
||||
@ -121,7 +115,7 @@ auto Program::dipSettings(const Markup::Node& node) -> uint {
|
||||
}
|
||||
|
||||
auto Program::path(uint group) -> string {
|
||||
return mediaPaths(group);
|
||||
return mediumPaths(group);
|
||||
}
|
||||
|
||||
auto Program::notify(string text) -> void {
|
||||
|
@ -1,23 +1,23 @@
|
||||
auto Program::loadMedia(string location) -> void {
|
||||
auto Program::loadMedium(string location) -> void {
|
||||
location.transform("\\", "/");
|
||||
if(!location.endsWith("/")) location.append("/");
|
||||
if(!directory::exists(location)) return;
|
||||
|
||||
string type = suffixname(location).trimLeft(".", 1L);
|
||||
for(auto& emulator : emulators) {
|
||||
for(auto& media : emulator->media) {
|
||||
if(!media.bootable) continue;
|
||||
if(media.type != type) continue;
|
||||
return loadMedia(*emulator, media, location);
|
||||
for(auto& medium : emulator->media) {
|
||||
if(!medium.bootable) continue;
|
||||
if(medium.type != type) continue;
|
||||
return loadMedium(*emulator, medium, location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto Program::loadMedia(Emulator::Interface& interface, Emulator::Interface::Media& media, string location) -> void {
|
||||
unloadMedia();
|
||||
auto Program::loadMedium(Emulator::Interface& interface, Emulator::Interface::Medium& medium, string location) -> void {
|
||||
unloadMedium();
|
||||
|
||||
mediaPaths(0) = locate({media.name, ".sys/"});
|
||||
mediaPaths(media.id) = location;
|
||||
mediumPaths(0) = locate({medium.name, ".sys/"});
|
||||
mediumPaths(medium.id) = location;
|
||||
folderPaths.append(location);
|
||||
|
||||
//note: the order of operations in this block of code is critical
|
||||
@ -25,14 +25,14 @@ auto Program::loadMedia(Emulator::Interface& interface, Emulator::Interface::Med
|
||||
Emulator::audio.setFrequency(audio->get(Audio::Frequency).get<uint>());
|
||||
emulator = &interface;
|
||||
connectDevices();
|
||||
emulator->load(media.id);
|
||||
emulator->load(medium.id);
|
||||
updateAudioDriver();
|
||||
updateAudioEffects();
|
||||
emulator->power();
|
||||
|
||||
presentation->resizeViewport();
|
||||
presentation->setTitle(emulator->title());
|
||||
presentation->systemMenu.setText(media.name).setVisible(true);
|
||||
presentation->systemMenu.setText(medium.name).setVisible(true);
|
||||
presentation->toolsMenu.setVisible(true);
|
||||
presentation->updateEmulator();
|
||||
toolsManager->cheatEditor.loadCheats();
|
||||
@ -40,14 +40,14 @@ auto Program::loadMedia(Emulator::Interface& interface, Emulator::Interface::Med
|
||||
toolsManager->manifestViewer.doRefresh();
|
||||
}
|
||||
|
||||
auto Program::unloadMedia() -> void {
|
||||
auto Program::unloadMedium() -> void {
|
||||
if(!emulator) return;
|
||||
|
||||
toolsManager->cheatEditor.saveCheats();
|
||||
emulator->unload();
|
||||
emulator = nullptr;
|
||||
|
||||
mediaPaths.reset();
|
||||
mediumPaths.reset();
|
||||
folderPaths.reset();
|
||||
|
||||
presentation->setTitle({"higan v", Emulator::Version});
|
@ -5,7 +5,7 @@
|
||||
#include <gba/interface/interface.hpp>
|
||||
#include <ws/interface/interface.hpp>
|
||||
#include "interface.cpp"
|
||||
#include "media.cpp"
|
||||
#include "medium.cpp"
|
||||
#include "state.cpp"
|
||||
#include "utility.cpp"
|
||||
unique_pointer<Program> program;
|
||||
@ -64,7 +64,7 @@ Program::Program(lstring args) {
|
||||
|
||||
auto Program::load(string location) -> void {
|
||||
if(directory::exists(location)) {
|
||||
loadMedia(location);
|
||||
loadMedium(location);
|
||||
} else if(file::exists(location)) {
|
||||
//special handling to allow importing the Game Boy Advance BIOS
|
||||
if(file::size(location) == 16384 && file::sha256(location).beginsWith("fd2547724b505f48")) {
|
||||
@ -77,7 +77,7 @@ auto Program::load(string location) -> void {
|
||||
|
||||
//ask icarus to import the game; and play it upon success
|
||||
if(auto result = execute("icarus", "--import", location)) {
|
||||
loadMedia(result.output.strip());
|
||||
loadMedium(result.output.strip());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -96,7 +96,7 @@ auto Program::main() -> void {
|
||||
}
|
||||
|
||||
auto Program::quit() -> void {
|
||||
unloadMedia();
|
||||
unloadMedium();
|
||||
settings.quit();
|
||||
inputManager->quit();
|
||||
Application::quit();
|
||||
|
@ -17,10 +17,10 @@ struct Program : Emulator::Interface::Bind {
|
||||
auto path(uint group) -> string override;
|
||||
auto notify(string text) -> void override;
|
||||
|
||||
//media.cpp
|
||||
auto loadMedia(string location) -> void;
|
||||
auto loadMedia(Emulator::Interface& interface, Emulator::Interface::Media& media, string location) -> void;
|
||||
auto unloadMedia() -> void;
|
||||
//medium.cpp
|
||||
auto loadMedium(string location) -> void;
|
||||
auto loadMedium(Emulator::Interface& interface, Emulator::Interface::Medium& medium, string location) -> void;
|
||||
auto unloadMedium() -> void;
|
||||
|
||||
//state.cpp
|
||||
auto stateName(uint slot, bool manager = false) -> string;
|
||||
@ -42,7 +42,7 @@ struct Program : Emulator::Interface::Bind {
|
||||
|
||||
vector<Emulator::Interface*> emulators;
|
||||
|
||||
vector<string> mediaPaths;
|
||||
vector<string> mediumPaths;
|
||||
vector<string> folderPaths;
|
||||
|
||||
string statusText;
|
||||
|
@ -13,10 +13,10 @@ auto Program::softReset() -> void {
|
||||
|
||||
auto Program::connectDevices() -> void {
|
||||
if(!emulator) return;
|
||||
for(auto& port : emulator->port) {
|
||||
for(auto& port : emulator->ports) {
|
||||
auto path = string{emulator->information.name, "/", port.name}.replace(" ", "");
|
||||
auto name = settings(path).text();
|
||||
for(auto& device : port.device) {
|
||||
for(auto& device : port.devices) {
|
||||
if(device.name == name) {
|
||||
emulator->connect(port.id, device.id);
|
||||
break;
|
||||
|
@ -23,41 +23,39 @@ Interface::Interface() {
|
||||
media.append({ID::WonderSwanColor, "WonderSwan Color", "wsc", true});
|
||||
|
||||
{ Device device{0, ID::DeviceHorizontal, "Controller"};
|
||||
device.input.append({ 0, 0, "Y1"});
|
||||
device.input.append({ 1, 0, "Y2"});
|
||||
device.input.append({ 2, 0, "Y3"});
|
||||
device.input.append({ 3, 0, "Y4"});
|
||||
device.input.append({ 4, 0, "X1"});
|
||||
device.input.append({ 5, 0, "X2"});
|
||||
device.input.append({ 6, 0, "X3"});
|
||||
device.input.append({ 7, 0, "X4"});
|
||||
device.input.append({ 8, 0, "B"});
|
||||
device.input.append({ 9, 0, "A"});
|
||||
device.input.append({10, 0, "Start"});
|
||||
device.input.append({11, 0, "Rotate"});
|
||||
device.order = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
||||
this->device.append(device);
|
||||
device.inputs.append({ 0, 0, "Y1"});
|
||||
device.inputs.append({ 1, 0, "Y2"});
|
||||
device.inputs.append({ 2, 0, "Y3"});
|
||||
device.inputs.append({ 3, 0, "Y4"});
|
||||
device.inputs.append({ 4, 0, "X1"});
|
||||
device.inputs.append({ 5, 0, "X2"});
|
||||
device.inputs.append({ 6, 0, "X3"});
|
||||
device.inputs.append({ 7, 0, "X4"});
|
||||
device.inputs.append({ 8, 0, "B"});
|
||||
device.inputs.append({ 9, 0, "A"});
|
||||
device.inputs.append({10, 0, "Start"});
|
||||
device.inputs.append({11, 0, "Rotate"});
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
{ Device device{1, ID::DeviceVertical, "Controller"};
|
||||
device.input.append({ 0, 0, "Y1"});
|
||||
device.input.append({ 1, 0, "Y2"});
|
||||
device.input.append({ 2, 0, "Y3"});
|
||||
device.input.append({ 3, 0, "Y4"});
|
||||
device.input.append({ 4, 0, "X1"});
|
||||
device.input.append({ 5, 0, "X2"});
|
||||
device.input.append({ 6, 0, "X3"});
|
||||
device.input.append({ 7, 0, "X4"});
|
||||
device.input.append({ 8, 0, "B"});
|
||||
device.input.append({ 9, 0, "A"});
|
||||
device.input.append({10, 0, "Start"});
|
||||
device.input.append({11, 0, "Rotate"});
|
||||
device.order = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
||||
this->device.append(device);
|
||||
device.inputs.append({ 0, 0, "Y1"});
|
||||
device.inputs.append({ 1, 0, "Y2"});
|
||||
device.inputs.append({ 2, 0, "Y3"});
|
||||
device.inputs.append({ 3, 0, "Y4"});
|
||||
device.inputs.append({ 4, 0, "X1"});
|
||||
device.inputs.append({ 5, 0, "X2"});
|
||||
device.inputs.append({ 6, 0, "X3"});
|
||||
device.inputs.append({ 7, 0, "X4"});
|
||||
device.inputs.append({ 8, 0, "B"});
|
||||
device.inputs.append({ 9, 0, "A"});
|
||||
device.inputs.append({10, 0, "Start"});
|
||||
device.inputs.append({11, 0, "Rotate"});
|
||||
devices.append(device);
|
||||
}
|
||||
|
||||
port.append({0, "Horizontal Orientation", {device[0]}});
|
||||
port.append({1, "Vertical Orientation", {device[1]}});
|
||||
ports.append({0, "Horizontal Orientation", {devices[0]}});
|
||||
ports.append({1, "Vertical Orientation", {devices[1]}});
|
||||
}
|
||||
|
||||
auto Interface::manifest() -> string {
|
||||
|
@ -57,7 +57,7 @@ struct Interface : Emulator::Interface {
|
||||
auto set(const string& name, const any& value) -> bool override;
|
||||
|
||||
private:
|
||||
vector<Device> device;
|
||||
vector<Device> devices;
|
||||
};
|
||||
|
||||
struct Settings {
|
||||
|
@ -1,4 +1,8 @@
|
||||
#define decimal decimal_cocoa
|
||||
#define int8 int8_cocoa
|
||||
#define int16 int16_cocoa
|
||||
#define int32 int32_cocoa
|
||||
#define int64 int64_cocoa
|
||||
#define uint8 uint8_cocoa
|
||||
#define uint16 uint16_cocoa
|
||||
#define uint32 uint32_cocoa
|
||||
@ -6,6 +10,10 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
#undef decimal
|
||||
#undef int8
|
||||
#undef int16
|
||||
#undef int32
|
||||
#undef int64
|
||||
#undef uint8
|
||||
#undef uint16
|
||||
#undef uint32
|
||||
|
36
nall/bit.hpp
36
nall/bit.hpp
@ -4,28 +4,28 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
template<unsigned bits> inline auto uclamp(const uintmax_t x) -> uintmax_t {
|
||||
enum : uintmax_t { b = 1ull << (bits - 1), y = b * 2 - 1 };
|
||||
template<uint bits> inline auto uclamp(const uintmax x) -> uintmax {
|
||||
enum : uintmax { b = 1ull << (bits - 1), y = b * 2 - 1 };
|
||||
return y + ((x - y) & -(x < y)); //min(x, y);
|
||||
}
|
||||
|
||||
template<unsigned bits> inline auto uclip(const uintmax_t x) -> uintmax_t {
|
||||
enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 };
|
||||
template<uint bits> inline auto uclip(const uintmax x) -> uintmax {
|
||||
enum : uintmax { b = 1ull << (bits - 1), m = b * 2 - 1 };
|
||||
return (x & m);
|
||||
}
|
||||
|
||||
template<unsigned bits> inline auto sclamp(const intmax_t x) -> intmax_t {
|
||||
enum : intmax_t { b = 1ull << (bits - 1), m = b - 1 };
|
||||
template<uint bits> inline auto sclamp(const intmax x) -> intmax {
|
||||
enum : intmax { b = 1ull << (bits - 1), m = b - 1 };
|
||||
return (x > m) ? m : (x < -b) ? -b : x;
|
||||
}
|
||||
|
||||
template<unsigned bits> inline auto sclip(const intmax_t x) -> intmax_t {
|
||||
enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 };
|
||||
template<uint bits> inline auto sclip(const intmax x) -> intmax {
|
||||
enum : uintmax { b = 1ull << (bits - 1), m = b * 2 - 1 };
|
||||
return ((x & m) ^ b) - b;
|
||||
}
|
||||
|
||||
namespace bit {
|
||||
constexpr inline auto mask(const char* s, uintmax_t sum = 0) -> uintmax_t {
|
||||
constexpr inline auto mask(const char* s, uintmax sum = 0) -> uintmax {
|
||||
return (
|
||||
*s == '0' || *s == '1' ? mask(s + 1, (sum << 1) | 1) :
|
||||
*s == ' ' || *s == '_' ? mask(s + 1, sum) :
|
||||
@ -34,7 +34,7 @@ namespace bit {
|
||||
);
|
||||
}
|
||||
|
||||
constexpr inline auto test(const char* s, uintmax_t sum = 0) -> uintmax_t {
|
||||
constexpr inline auto test(const char* s, uintmax sum = 0) -> uintmax {
|
||||
return (
|
||||
*s == '0' || *s == '1' ? test(s + 1, (sum << 1) | (*s - '0')) :
|
||||
*s == ' ' || *s == '_' ? test(s + 1, sum) :
|
||||
@ -44,38 +44,38 @@ namespace bit {
|
||||
}
|
||||
|
||||
//lowest(0b1110) == 0b0010
|
||||
constexpr inline auto lowest(const uintmax_t x) -> uintmax_t {
|
||||
constexpr inline auto lowest(const uintmax x) -> uintmax {
|
||||
return x & -x;
|
||||
}
|
||||
|
||||
//clear_lowest(0b1110) == 0b1100
|
||||
constexpr inline auto clear_lowest(const uintmax_t x) -> uintmax_t {
|
||||
constexpr inline auto clear_lowest(const uintmax x) -> uintmax {
|
||||
return x & (x - 1);
|
||||
}
|
||||
|
||||
//set_lowest(0b0101) == 0b0111
|
||||
constexpr inline auto set_lowest(const uintmax_t x) -> uintmax_t {
|
||||
constexpr inline auto set_lowest(const uintmax x) -> uintmax {
|
||||
return x | (x + 1);
|
||||
}
|
||||
|
||||
//count number of bits set in a byte
|
||||
inline auto count(uintmax_t x) -> unsigned {
|
||||
unsigned count = 0;
|
||||
inline auto count(uintmax x) -> uint {
|
||||
uint count = 0;
|
||||
do count += x & 1; while(x >>= 1);
|
||||
return count;
|
||||
}
|
||||
|
||||
//return index of the first bit set (or zero of no bits are set)
|
||||
//first(0b1000) == 3
|
||||
inline auto first(uintmax_t x) -> unsigned {
|
||||
unsigned first = 0;
|
||||
inline auto first(uintmax x) -> uint {
|
||||
uint first = 0;
|
||||
while(x) { if(x & 1) break; x >>= 1; first++; }
|
||||
return first;
|
||||
}
|
||||
|
||||
//round up to next highest single bit:
|
||||
//round(15) == 16, round(16) == 16, round(17) == 32
|
||||
inline auto round(uintmax_t x) -> uintmax_t {
|
||||
inline auto round(uintmax x) -> uintmax {
|
||||
if((x & (x - 1)) == 0) return x;
|
||||
while(x & (x - 1)) x &= x - 1;
|
||||
return x << 1;
|
||||
|
@ -10,7 +10,7 @@ namespace Configuration {
|
||||
struct Node {
|
||||
string name;
|
||||
string desc;
|
||||
enum class Type : unsigned { Null, Boolean, Integer, Natural, Double, String } type = Type::Null;
|
||||
enum class Type : uint { Null, Boolean, Integer, Natural, Double, String } type = Type::Null;
|
||||
void* data = nullptr;
|
||||
vector<Node> children;
|
||||
|
||||
@ -74,7 +74,7 @@ struct Node {
|
||||
}
|
||||
}
|
||||
|
||||
auto save(file& fp, unsigned depth = 0) -> void {
|
||||
auto save(file& fp, uint depth = 0) -> void {
|
||||
for(auto& child : children) {
|
||||
if(child.desc) {
|
||||
for(auto n : range(depth)) fp.print(" ");
|
||||
|
@ -65,7 +65,7 @@ inline auto library::close() -> void {
|
||||
inline auto library::open(const string& name, const string& path) -> bool {
|
||||
if(handle) close();
|
||||
if(path) handle = (uintptr_t)dlopen(string(path, "lib", name, ".dylib"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr_t)dlopen(string(userpath(), ".local/lib/lib", name, ".dylib"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr_t)dlopen(string(Path::user(), ".local/lib/lib", name, ".dylib"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".dylib"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr_t)dlopen(string("lib", name, ".dylib"), RTLD_LAZY);
|
||||
return handle;
|
||||
|
@ -7,7 +7,7 @@
|
||||
//remove: O(1) average; O(n) worst
|
||||
//
|
||||
//requirements:
|
||||
// auto T::hash() const -> unsigned;
|
||||
// auto T::hash() const -> uint;
|
||||
// auto T::operator==(const T&) const -> bool;
|
||||
|
||||
namespace nall {
|
||||
@ -15,7 +15,7 @@ namespace nall {
|
||||
template<typename T>
|
||||
struct hashset {
|
||||
hashset() = default;
|
||||
hashset(unsigned length) : length(bit::round(length)) {}
|
||||
hashset(uint length) : length(bit::round(length)) {}
|
||||
hashset(const hashset& source) { operator=(source); }
|
||||
hashset(hashset&& source) { operator=(move(source)); }
|
||||
~hashset() { reset(); }
|
||||
@ -23,7 +23,7 @@ struct hashset {
|
||||
auto operator=(const hashset& source) -> hashset& {
|
||||
reset();
|
||||
if(source.pool) {
|
||||
for(unsigned n = 0; n < source.count; n++) {
|
||||
for(uint n : range(source.count)) {
|
||||
insert(*source.pool[n]);
|
||||
}
|
||||
}
|
||||
@ -42,12 +42,12 @@ struct hashset {
|
||||
}
|
||||
|
||||
explicit operator bool() const { return count; }
|
||||
auto capacity() const -> unsigned { return length; }
|
||||
auto size() const -> unsigned { return count; }
|
||||
auto capacity() const -> uint { return length; }
|
||||
auto size() const -> uint { return count; }
|
||||
|
||||
auto reset() -> void {
|
||||
if(pool) {
|
||||
for(unsigned n = 0; n < length; n++) {
|
||||
for(uint n : range(length)) {
|
||||
if(pool[n]) {
|
||||
delete pool[n];
|
||||
pool[n] = nullptr;
|
||||
@ -60,15 +60,15 @@ struct hashset {
|
||||
count = 0;
|
||||
}
|
||||
|
||||
auto reserve(unsigned size) -> void {
|
||||
auto reserve(uint size) -> void {
|
||||
//ensure all items will fit into pool (with <= 50% load) and amortize growth
|
||||
size = bit::round(max(size, count << 1));
|
||||
T** copy = new T*[size]();
|
||||
|
||||
if(pool) {
|
||||
for(unsigned n = 0; n < length; n++) {
|
||||
for(uint n : range(length)) {
|
||||
if(pool[n]) {
|
||||
unsigned hash = (*pool[n]).hash() & (size - 1);
|
||||
uint hash = (*pool[n]).hash() & (size - 1);
|
||||
while(copy[hash]) if(++hash >= size) hash = 0;
|
||||
copy[hash] = pool[n];
|
||||
pool[n] = nullptr;
|
||||
@ -84,7 +84,7 @@ struct hashset {
|
||||
auto find(const T& value) -> maybe<T&> {
|
||||
if(!pool) return nothing;
|
||||
|
||||
unsigned hash = value.hash() & (length - 1);
|
||||
uint hash = value.hash() & (length - 1);
|
||||
while(pool[hash]) {
|
||||
if(value == *pool[hash]) return *pool[hash];
|
||||
if(++hash >= length) hash = 0;
|
||||
@ -100,7 +100,7 @@ struct hashset {
|
||||
if(count >= (length >> 1)) reserve(length << 1);
|
||||
count++;
|
||||
|
||||
unsigned hash = value.hash() & (length - 1);
|
||||
uint hash = value.hash() & (length - 1);
|
||||
while(pool[hash]) if(++hash >= length) hash = 0;
|
||||
pool[hash] = new T(value);
|
||||
|
||||
@ -110,7 +110,7 @@ struct hashset {
|
||||
auto remove(const T& value) -> bool {
|
||||
if(!pool) return false;
|
||||
|
||||
unsigned hash = value.hash() & (length - 1);
|
||||
uint hash = value.hash() & (length - 1);
|
||||
while(pool[hash]) {
|
||||
if(value == *pool[hash]) {
|
||||
delete pool[hash];
|
||||
@ -126,8 +126,8 @@ struct hashset {
|
||||
|
||||
protected:
|
||||
T** pool = nullptr;
|
||||
unsigned length = 8; //length of pool
|
||||
unsigned count = 0; //number of objects inside of the pool
|
||||
uint length = 8; //length of pool
|
||||
uint count = 0; //number of objects inside of the pool
|
||||
};
|
||||
|
||||
}
|
||||
|
14
nall/hid.hpp
14
nall/hid.hpp
@ -19,10 +19,10 @@ struct Group : vector<Input> {
|
||||
Group(const string& name) : _name(name) {}
|
||||
|
||||
auto name() const -> string { return _name; }
|
||||
auto input(unsigned id) -> Input& { return operator[](id); }
|
||||
auto input(uint id) -> Input& { return operator[](id); }
|
||||
auto append(const string& name) -> void { vector::append(Input{name}); }
|
||||
|
||||
auto find(const string& name) const -> maybe<unsigned> {
|
||||
auto find(const string& name) const -> maybe<uint> {
|
||||
for(auto id : range(size())) {
|
||||
if(operator[](id)._name == name) return id;
|
||||
}
|
||||
@ -50,10 +50,10 @@ struct Device : vector<Group> {
|
||||
auto name() const -> string { return _name; }
|
||||
auto id() const -> uint64_t { return _id; }
|
||||
auto setID(uint64_t id) -> void { _id = id; }
|
||||
auto group(unsigned id) -> Group& { return operator[](id); }
|
||||
auto group(uint id) -> Group& { return operator[](id); }
|
||||
auto append(const string& name) -> void { vector::append(Group{name}); }
|
||||
|
||||
auto find(const string& name) const -> maybe<unsigned> {
|
||||
auto find(const string& name) const -> maybe<uint> {
|
||||
for(auto id : range(size())) {
|
||||
if(operator[](id)._name == name) return id;
|
||||
}
|
||||
@ -71,7 +71,7 @@ struct Null : Device {
|
||||
};
|
||||
|
||||
struct Keyboard : Device {
|
||||
enum GroupID : unsigned { Button };
|
||||
enum GroupID : uint { Button };
|
||||
|
||||
Keyboard() : Device("Keyboard") { append("Button"); }
|
||||
auto isKeyboard() const -> bool { return true; }
|
||||
@ -79,7 +79,7 @@ struct Keyboard : Device {
|
||||
};
|
||||
|
||||
struct Mouse : Device {
|
||||
enum GroupID : unsigned { Axis, Button };
|
||||
enum GroupID : uint { Axis, Button };
|
||||
|
||||
Mouse() : Device("Mouse") { append("Axis"), append("Button"); }
|
||||
auto isMouse() const -> bool { return true; }
|
||||
@ -88,7 +88,7 @@ struct Mouse : Device {
|
||||
};
|
||||
|
||||
struct Joypad : Device {
|
||||
enum GroupID : unsigned { Axis, Hat, Trigger, Button };
|
||||
enum GroupID : uint { Axis, Hat, Trigger, Button };
|
||||
|
||||
Joypad() : Device("Joypad") { append("Axis"), append("Hat"), append("Trigger"), append("Button"); }
|
||||
auto isJoypad() const -> bool { return true; }
|
||||
|
@ -9,7 +9,7 @@
|
||||
namespace nall {
|
||||
|
||||
struct inode {
|
||||
enum class time : unsigned { access, modify };
|
||||
enum class time : uint { access, modify };
|
||||
|
||||
static auto exists(const string& name) -> bool {
|
||||
return access(name, F_OK) == 0;
|
||||
@ -27,19 +27,19 @@ struct inode {
|
||||
return access(name, X_OK) == 0;
|
||||
}
|
||||
|
||||
static auto uid(const string& name) -> unsigned {
|
||||
static auto uid(const string& name) -> uint {
|
||||
struct stat data{0};
|
||||
stat(name, &data);
|
||||
return data.st_uid;
|
||||
}
|
||||
|
||||
static auto gid(const string& name) -> unsigned {
|
||||
static auto gid(const string& name) -> uint {
|
||||
struct stat data{0};
|
||||
stat(name, &data);
|
||||
return data.st_gid;
|
||||
}
|
||||
|
||||
static auto mode(const string& name) -> unsigned {
|
||||
static auto mode(const string& name) -> uint {
|
||||
struct stat data{0};
|
||||
stat(name, &data);
|
||||
return data.st_mode;
|
||||
@ -55,7 +55,7 @@ struct inode {
|
||||
}
|
||||
|
||||
//returns true if 'name' already exists
|
||||
static auto create(const string& name, unsigned permissions = 0755) -> bool {
|
||||
static auto create(const string& name, uint permissions = 0755) -> bool {
|
||||
if(exists(name)) return true;
|
||||
if(name.endsWith("/")) return mkdir(name, permissions) == 0;
|
||||
int fd = open(name, O_CREAT | O_EXCL, permissions);
|
||||
|
@ -1,13 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
namespace nall {
|
||||
using uint = unsigned;
|
||||
|
||||
struct Intrinsics {
|
||||
enum class Compiler : unsigned { Clang, GCC, VisualCPP, Unknown };
|
||||
enum class Platform : unsigned { Windows, MacOSX, Linux, BSD, Unknown };
|
||||
enum class API : unsigned { Windows, Posix, Unknown };
|
||||
enum class Display : unsigned { Windows, Quartz, Xorg, Unknown };
|
||||
enum class Processor : unsigned { x86, amd64, ARM, PPC32, PPC64, Unknown };
|
||||
enum class Endian : unsigned { LSB, MSB, Unknown };
|
||||
enum class Compiler : uint { Clang, GCC, VisualCPP, Unknown };
|
||||
enum class Platform : uint { Windows, MacOSX, Linux, BSD, Unknown };
|
||||
enum class API : uint { Windows, Posix, Unknown };
|
||||
enum class Display : uint { Windows, Quartz, Xorg, Unknown };
|
||||
enum class Processor : uint { x86, amd64, ARM, PPC32, PPC64, Unknown };
|
||||
enum class Endian : uint { LSB, MSB, Unknown };
|
||||
|
||||
static inline auto compiler() -> Compiler;
|
||||
static inline auto platform() -> Platform;
|
||||
|
@ -4,13 +4,13 @@ namespace nall {
|
||||
|
||||
namespace Matrix {
|
||||
|
||||
template<typename T> inline auto Multiply(T* output, const T* xdata, unsigned xrows, unsigned xcols, const T* ydata, unsigned yrows, unsigned ycols) -> void {
|
||||
template<typename T> inline auto Multiply(T* output, const T* xdata, uint xrows, uint xcols, const T* ydata, uint yrows, uint ycols) -> void {
|
||||
if(xcols != yrows) return;
|
||||
|
||||
for(unsigned y = 0; y < xrows; y++) {
|
||||
for(unsigned x = 0; x < ycols; x++) {
|
||||
for(uint y : range(xrows)) {
|
||||
for(uint x : range(ycols)) {
|
||||
T sum = 0;
|
||||
for(unsigned z = 0; z < xcols; z++) {
|
||||
for(uint z : range(xcols)) {
|
||||
sum += xdata[y * xcols + z] * ydata[z * ycols + x];
|
||||
}
|
||||
*output++ = sum;
|
||||
@ -18,7 +18,7 @@ template<typename T> inline auto Multiply(T* output, const T* xdata, unsigned xr
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> inline auto Multiply(const T* xdata, unsigned xrows, unsigned xcols, const T* ydata, unsigned yrows, unsigned ycols) -> vector<T> {
|
||||
template<typename T> inline auto Multiply(const T* xdata, uint xrows, uint xcols, const T* ydata, uint yrows, uint ycols) -> vector<T> {
|
||||
vector<T> output;
|
||||
output.resize(xrows * ycols);
|
||||
Multiply(output.data(), xdata, xrows, xcols, ydata, yrows, ycols);
|
||||
|
@ -30,11 +30,11 @@ inline auto program() -> string {
|
||||
GetModuleFileName(nullptr, path, PATH_MAX);
|
||||
string result = (const char*)utf8_t(path);
|
||||
result.transform("\\", "/");
|
||||
return real(result);
|
||||
return Path::real(result);
|
||||
#else
|
||||
Dl_info info;
|
||||
dladdr((void*)&program, &info);
|
||||
return real(info.dli_fname);
|
||||
return Path::real(info.dli_fname);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -78,9 +78,9 @@ inline auto config() -> string {
|
||||
string result = (const char*)utf8_t(path);
|
||||
result.transform("\\", "/");
|
||||
#elif defined(PLATFORM_MACOSX)
|
||||
string result = {user(), "Library/Application Support/"};
|
||||
string result = {Path::user(), "Library/Application Support/"};
|
||||
#else
|
||||
string result = {user(), ".config/"};
|
||||
string result = {Path::user(), ".config/"};
|
||||
#endif
|
||||
if(!result) result = ".";
|
||||
if(!result.endsWith("/")) result.append("/");
|
||||
@ -96,9 +96,9 @@ inline auto local() -> string {
|
||||
string result = (const char*)utf8_t(path);
|
||||
result.transform("\\", "/");
|
||||
#elif defined(PLATFORM_MACOSX)
|
||||
string result = {user(), "Library/Application Support/"};
|
||||
string result = {Path::user(), "Library/Application Support/"};
|
||||
#else
|
||||
string result = {user(), ".local/share/"};
|
||||
string result = {Path::user(), ".local/share/"};
|
||||
#endif
|
||||
if(!result) result = ".";
|
||||
if(!result.endsWith("/")) result.append("/");
|
||||
|
@ -1,106 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/serializer.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
|
||||
template<typename type_t> auto priority_queue_nocallback(type_t) -> void {}
|
||||
|
||||
//priority queue implementation using binary min-heap array;
|
||||
//does not require normalize() function.
|
||||
//O(1) find (tick)
|
||||
//O(log n) append (enqueue)
|
||||
//O(log n) remove (dequeue)
|
||||
template<typename type_t> struct priority_queue {
|
||||
priority_queue(unsigned size, function<void (type_t)> callback = &priority_queue_nocallback<type_t>) : callback(callback) {
|
||||
heap = new heap_t[size];
|
||||
heapcapacity = size;
|
||||
reset();
|
||||
}
|
||||
|
||||
~priority_queue() {
|
||||
delete[] heap;
|
||||
}
|
||||
|
||||
priority_queue(const priority_queue&) = delete;
|
||||
auto operator=(const priority_queue&) -> priority_queue& = delete;
|
||||
|
||||
inline auto tick(unsigned ticks) -> void {
|
||||
basecounter += ticks;
|
||||
while(heapsize && gte(basecounter, heap[0].counter)) callback(dequeue());
|
||||
}
|
||||
|
||||
//counter is relative to current time (eg enqueue(64, ...) fires in 64 ticks);
|
||||
//counter cannot exceed std::numeric_limits<unsigned>::max() >> 1.
|
||||
auto enqueue(unsigned counter, type_t event) -> void {
|
||||
unsigned child = heapsize++;
|
||||
counter += basecounter;
|
||||
|
||||
while(child) {
|
||||
unsigned parent = (child - 1) >> 1;
|
||||
if(gte(counter, heap[parent].counter)) break;
|
||||
|
||||
heap[child].counter = heap[parent].counter;
|
||||
heap[child].event = heap[parent].event;
|
||||
child = parent;
|
||||
}
|
||||
|
||||
heap[child].counter = counter;
|
||||
heap[child].event = event;
|
||||
}
|
||||
|
||||
auto dequeue() -> type_t {
|
||||
type_t event(heap[0].event);
|
||||
unsigned parent = 0;
|
||||
unsigned counter = heap[--heapsize].counter;
|
||||
|
||||
while(true) {
|
||||
unsigned child = (parent << 1) + 1;
|
||||
if(child >= heapsize) break;
|
||||
if(child + 1 < heapsize && gte(heap[child].counter, heap[child + 1].counter)) child++;
|
||||
if(gte(heap[child].counter, counter)) break;
|
||||
|
||||
heap[parent].counter = heap[child].counter;
|
||||
heap[parent].event = heap[child].event;
|
||||
parent = child;
|
||||
}
|
||||
|
||||
heap[parent].counter = counter;
|
||||
heap[parent].event = heap[heapsize].event;
|
||||
return event;
|
||||
}
|
||||
|
||||
auto reset() -> void {
|
||||
basecounter = 0;
|
||||
heapsize = 0;
|
||||
}
|
||||
|
||||
auto serialize(serializer& s) -> void {
|
||||
s.integer(basecounter);
|
||||
s.integer(heapsize);
|
||||
for(unsigned n = 0; n < heapcapacity; n++) {
|
||||
s.integer(heap[n].counter);
|
||||
s.integer(heap[n].event);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
function<void (type_t)> callback;
|
||||
unsigned basecounter;
|
||||
unsigned heapsize;
|
||||
unsigned heapcapacity;
|
||||
struct heap_t {
|
||||
unsigned counter;
|
||||
type_t event;
|
||||
} *heap;
|
||||
|
||||
//return true if x is greater than or equal to y
|
||||
inline auto gte(unsigned x, unsigned y) -> bool {
|
||||
return x - y < (std::numeric_limits<unsigned>::max() >> 1);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -15,11 +15,11 @@ struct RandomNumberGenerator {
|
||||
struct LinearFeedbackShiftRegisterGenerator : RandomNumberGenerator {
|
||||
auto seed(uint64_t seed) -> void {
|
||||
lfsr = seed;
|
||||
for(unsigned n = 0; n < 8; n++) operator()();
|
||||
for(uint n = 0; n < 8; n++) operator()();
|
||||
}
|
||||
|
||||
auto operator()() -> uint64_t {
|
||||
return lfsr = (lfsr >> 1) ^ (-(lfsr & 1) & crc64jones);
|
||||
return lfsr = (lfsr >> 1) ^ (-(lfsr & 1) & crc64);
|
||||
}
|
||||
|
||||
auto serialize(serializer& s) -> void {
|
||||
@ -27,9 +27,8 @@ struct LinearFeedbackShiftRegisterGenerator : RandomNumberGenerator {
|
||||
}
|
||||
|
||||
private:
|
||||
static const uint64_t crc64ecma = 0x42f0e1eba9ea3693;
|
||||
static const uint64_t crc64jones = 0xad93d23594c935a9;
|
||||
uint64_t lfsr = crc64ecma;
|
||||
static const uint64_t crc64 = 0xc96c'5795'd787'0f42;
|
||||
uint64_t lfsr = crc64;
|
||||
};
|
||||
|
||||
inline auto random() -> uint64_t {
|
||||
|
16
nall/set.hpp
16
nall/set.hpp
@ -26,7 +26,7 @@ template<typename T> struct set {
|
||||
};
|
||||
|
||||
node_t* root = nullptr;
|
||||
unsigned nodes = 0;
|
||||
uint nodes = 0;
|
||||
|
||||
set() = default;
|
||||
set(const set& source) { operator=(source); }
|
||||
@ -50,7 +50,7 @@ template<typename T> struct set {
|
||||
}
|
||||
|
||||
explicit operator bool() const { return nodes; }
|
||||
auto size() const -> unsigned { return nodes; }
|
||||
auto size() const -> uint { return nodes; }
|
||||
|
||||
auto reset() -> void {
|
||||
reset(root);
|
||||
@ -68,7 +68,7 @@ template<typename T> struct set {
|
||||
}
|
||||
|
||||
auto insert(const T& value) -> maybe<T&> {
|
||||
unsigned count = size();
|
||||
uint count = size();
|
||||
node_t* v = insert(root, value);
|
||||
root->red = 0;
|
||||
if(size() == count) return nothing;
|
||||
@ -82,7 +82,7 @@ template<typename T> struct set {
|
||||
}
|
||||
|
||||
auto remove(const T& value) -> bool {
|
||||
unsigned count = size();
|
||||
uint count = size();
|
||||
bool done = 0;
|
||||
remove(root, &value, done);
|
||||
if(root) root->red = 0;
|
||||
@ -112,7 +112,7 @@ template<typename T> struct set {
|
||||
return *this;
|
||||
}
|
||||
|
||||
base_iterator(const set& source, unsigned position) : source(source), position(position) {
|
||||
base_iterator(const set& source, uint position) : source(source), position(position) {
|
||||
node_t* node = source.root;
|
||||
while(node) {
|
||||
stack.append(node);
|
||||
@ -122,12 +122,12 @@ template<typename T> struct set {
|
||||
|
||||
protected:
|
||||
const set& source;
|
||||
unsigned position;
|
||||
uint position;
|
||||
vector<node_t*> stack;
|
||||
};
|
||||
|
||||
struct iterator : base_iterator {
|
||||
iterator(const set& source, unsigned position) : base_iterator(source, position) {}
|
||||
iterator(const set& source, uint position) : base_iterator(source, position) {}
|
||||
auto operator*() const -> T& { return base_iterator::stack.right()->value; }
|
||||
};
|
||||
|
||||
@ -135,7 +135,7 @@ template<typename T> struct set {
|
||||
auto end() -> iterator { return iterator(*this, size()); }
|
||||
|
||||
struct const_iterator : base_iterator {
|
||||
const_iterator(const set& source, unsigned position) : base_iterator(source, position) {}
|
||||
const_iterator(const set& source, uint position) : base_iterator(source, position) {}
|
||||
auto operator*() const -> const T& { return base_iterator::stack.right()->value; }
|
||||
};
|
||||
|
||||
|
@ -18,14 +18,14 @@
|
||||
namespace nall {
|
||||
|
||||
struct SMTP {
|
||||
enum class Format : unsigned { Plain, HTML };
|
||||
enum class Format : uint { Plain, HTML };
|
||||
|
||||
inline auto server(string server, uint16_t port = 25) -> void;
|
||||
inline auto from(string mail, string name = "") -> void;
|
||||
inline auto to(string mail, string name = "") -> void;
|
||||
inline auto cc(string mail, string name = "") -> void;
|
||||
inline auto bcc(string mail, string name = "") -> void;
|
||||
inline auto attachment(const uint8_t* data, unsigned size, string name) -> void;
|
||||
inline auto attachment(const uint8_t* data, uint size, string name) -> void;
|
||||
inline auto attachment(string filename, string name = "") -> bool;
|
||||
inline auto subject(string subject) -> void;
|
||||
inline auto body(string body, Format format = Format::Plain) -> void;
|
||||
@ -94,7 +94,7 @@ auto SMTP::bcc(string mail, string name) -> void {
|
||||
info.bcc.append({mail, name});
|
||||
}
|
||||
|
||||
auto SMTP::attachment(const uint8_t* data, unsigned size, string name) -> void {
|
||||
auto SMTP::attachment(const uint8_t* data, uint size, string name) -> void {
|
||||
vector<uint8_t> buffer;
|
||||
buffer.resize(size);
|
||||
memcpy(buffer.data(), data, size);
|
||||
@ -223,7 +223,7 @@ auto SMTP::response() -> string {
|
||||
|
||||
auto SMTP::send(int sock, const string& text) -> bool {
|
||||
const char* data = text.data();
|
||||
unsigned size = text.size();
|
||||
uint size = text.size();
|
||||
while(size) {
|
||||
int length = ::send(sock, (const char*)data, size, 0);
|
||||
if(length == -1) return false;
|
||||
@ -249,7 +249,7 @@ auto SMTP::boundary() -> string {
|
||||
random_lfsr random;
|
||||
random.seed(time(0));
|
||||
string boundary;
|
||||
for(unsigned n = 0; n < 16; n++) boundary.append(hex<2>(random()));
|
||||
for(uint n = 0; n < 16; n++) boundary.append(hex<2>(random()));
|
||||
return boundary;
|
||||
}
|
||||
|
||||
@ -279,9 +279,9 @@ auto SMTP::contacts(const vector<Information::Contact>& contacts) -> string {
|
||||
auto SMTP::split(const string& text) -> string {
|
||||
string result;
|
||||
|
||||
unsigned offset = 0;
|
||||
uint offset = 0;
|
||||
while(offset < text.size()) {
|
||||
unsigned length = min(76, text.size() - offset);
|
||||
uint length = min(76, text.size() - offset);
|
||||
if(length < 76) {
|
||||
result.append(text.slice(offset));
|
||||
} else {
|
||||
|
@ -19,13 +19,13 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
template<typename T, typename Comparator> auto sort(T list[], unsigned size, const Comparator& lessthan) -> void {
|
||||
template<typename T, typename Comparator> auto sort(T list[], uint size, const Comparator& lessthan) -> void {
|
||||
if(size <= 1) return; //nothing to sort
|
||||
|
||||
//use insertion sort to quickly sort smaller blocks
|
||||
if(size < 64) {
|
||||
#if defined(NALL_SORT_INSERTION)
|
||||
for(signed i = 1, j; i < size; i++) {
|
||||
for(int i = 1, j; i < size; i++) {
|
||||
T copy = std::move(list[i]);
|
||||
for(j = i - 1; j >= 0; j--) {
|
||||
if(!lessthan(copy, list[j])) break;
|
||||
@ -34,9 +34,9 @@ template<typename T, typename Comparator> auto sort(T list[], unsigned size, con
|
||||
list[j + 1] = std::move(copy);
|
||||
}
|
||||
#elif defined(NALL_SORT_SELECTION)
|
||||
for(unsigned i = 0; i < size; i++) {
|
||||
unsigned min = i;
|
||||
for(unsigned j = i + 1; j < size; j++) {
|
||||
for(uint i = 0; i < size; i++) {
|
||||
uint min = i;
|
||||
for(uint j = i + 1; j < size; j++) {
|
||||
if(lessthan(list[j], list[min])) min = j;
|
||||
}
|
||||
if(min != i) std::swap(list[i], list[min]);
|
||||
@ -46,13 +46,13 @@ template<typename T, typename Comparator> auto sort(T list[], unsigned size, con
|
||||
}
|
||||
|
||||
//split list in half and recursively sort both
|
||||
unsigned middle = size / 2;
|
||||
uint middle = size / 2;
|
||||
sort(list, middle, lessthan);
|
||||
sort(list + middle, size - middle, lessthan);
|
||||
|
||||
//left and right are sorted here; perform merge sort
|
||||
T* buffer = new T[size];
|
||||
unsigned offset = 0, left = 0, right = middle;
|
||||
uint offset = 0, left = 0, right = middle;
|
||||
while(left < middle && right < size) {
|
||||
if(!lessthan(list[right], list[left])) {
|
||||
buffer[offset++] = std::move(list[left++]);
|
||||
@ -63,11 +63,11 @@ template<typename T, typename Comparator> auto sort(T list[], unsigned size, con
|
||||
while(left < middle) buffer[offset++] = std::move(list[left++]);
|
||||
while(right < size) buffer[offset++] = std::move(list[right++]);
|
||||
|
||||
for(unsigned i = 0; i < size; i++) list[i] = std::move(buffer[i]);
|
||||
for(uint i = 0; i < size; i++) list[i] = std::move(buffer[i]);
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
template<typename T> auto sort(T list[], unsigned size) -> void {
|
||||
template<typename T> auto sort(T list[], uint size) -> void {
|
||||
return sort(list, size, [](const T& l, const T& r) { return l < r; });
|
||||
}
|
||||
|
||||
|
@ -19,13 +19,13 @@ namespace nall {
|
||||
struct thread {
|
||||
inline auto join() -> void;
|
||||
|
||||
static inline auto create(const function<void (uintptr_t)>& callback, uintptr_t parameter = 0, unsigned stacksize = 0) -> thread;
|
||||
static inline auto create(const function<void (uintptr)>& callback, uintptr parameter = 0, uint stacksize = 0) -> thread;
|
||||
static inline auto detach() -> void;
|
||||
static inline auto exit() -> void;
|
||||
|
||||
struct context {
|
||||
function<void (uintptr_t)> callback;
|
||||
uintptr_t parameter = 0;
|
||||
function<auto (uintptr) -> void> callback;
|
||||
uintptr parameter = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
@ -43,7 +43,7 @@ auto thread::join() -> void {
|
||||
pthread_join(handle, nullptr);
|
||||
}
|
||||
|
||||
auto thread::create(const function<void (uintptr_t)>& callback, uintptr_t parameter, unsigned stacksize) -> thread {
|
||||
auto thread::create(const function<void (uintptr)>& callback, uintptr parameter, uint stacksize) -> thread {
|
||||
thread instance;
|
||||
|
||||
auto context = new thread::context;
|
||||
@ -76,13 +76,13 @@ struct thread {
|
||||
inline ~thread();
|
||||
inline auto join() -> void;
|
||||
|
||||
static inline auto create(const function<void (uintptr_t)>& callback, uintptr_t parameter = 0, unsigned stacksize = 0) -> thread;
|
||||
static inline auto create(const function<void (uintptr)>& callback, uintptr parameter = 0, uint stacksize = 0) -> thread;
|
||||
static inline auto detach() -> void;
|
||||
static inline auto exit() -> void;
|
||||
|
||||
struct context {
|
||||
function<void (uintptr_t)> callback;
|
||||
uintptr_t parameter = 0;
|
||||
function<auto (uintptr) -> void> callback;
|
||||
uintptr parameter = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
@ -111,7 +111,7 @@ auto thread::join() -> void {
|
||||
}
|
||||
}
|
||||
|
||||
auto thread::create(const function<void (uintptr_t)>& callback, uintptr_t parameter, unsigned stacksize) -> thread {
|
||||
auto thread::create(const function<void (uintptr)>& callback, uintptr parameter, uint stacksize) -> thread {
|
||||
thread instance;
|
||||
|
||||
auto context = new thread::context;
|
||||
|
@ -9,9 +9,9 @@ template<typename T> struct base_from_member {
|
||||
T value;
|
||||
};
|
||||
|
||||
template<typename T> inline auto allocate(unsigned size, const T& value) -> T* {
|
||||
template<typename T> inline auto allocate(uint size, const T& value) -> T* {
|
||||
T* array = new T[size];
|
||||
for(unsigned i = 0; i < size; i++) array[i] = value;
|
||||
for(uint i = 0; i < size; i++) array[i] = value;
|
||||
return array;
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,8 @@ struct varint {
|
||||
virtual auto read() -> uint8_t = 0;
|
||||
virtual auto write(uint8_t) -> void = 0;
|
||||
|
||||
auto readvu() -> uintmax_t {
|
||||
uintmax_t data = 0, shift = 1;
|
||||
auto readvu() -> uintmax {
|
||||
uintmax data = 0, shift = 1;
|
||||
while(true) {
|
||||
uint8_t x = read();
|
||||
data += (x & 0x7f) * shift;
|
||||
@ -22,15 +22,15 @@ struct varint {
|
||||
return data;
|
||||
}
|
||||
|
||||
auto readvs() -> intmax_t {
|
||||
uintmax_t data = readvu();
|
||||
auto readvs() -> intmax {
|
||||
uintmax data = readvu();
|
||||
bool negate = data & 1;
|
||||
data >>= 1;
|
||||
if(negate) data = ~data;
|
||||
return data;
|
||||
}
|
||||
|
||||
auto writevu(uintmax_t data) -> void {
|
||||
auto writevu(uintmax data) -> void {
|
||||
while(true) {
|
||||
uint8_t x = data & 0x7f;
|
||||
data >>= 7;
|
||||
@ -40,7 +40,7 @@ struct varint {
|
||||
}
|
||||
}
|
||||
|
||||
auto writevs(intmax_t data) -> void {
|
||||
auto writevs(intmax data) -> void {
|
||||
bool negate = data < 0;
|
||||
if(negate) data = ~data;
|
||||
data = (data << 1) | negate;
|
||||
|
@ -1,27 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <nall/random.hpp>
|
||||
#include <nall/string.hpp>
|
||||
|
||||
namespace nall {
|
||||
|
||||
//generate unique GUID
|
||||
inline auto guid() -> string {
|
||||
LinearFeedbackShiftRegisterGenerator lfsr;
|
||||
lfsr.seed(time(nullptr));
|
||||
for(uint n = 0; n < 256; n++) lfsr();
|
||||
GUID guidInstance;
|
||||
CoCreateGuid(&guidInstance);
|
||||
|
||||
string output;
|
||||
for(uint n = 0; n < 4; n++) output.append(hex(lfsr(), 2L));
|
||||
output.append("-");
|
||||
for(uint n = 0; n < 2; n++) output.append(hex(lfsr(), 2L));
|
||||
output.append("-");
|
||||
for(uint n = 0; n < 2; n++) output.append(hex(lfsr(), 2L));
|
||||
output.append("-");
|
||||
for(uint n = 0; n < 2; n++) output.append(hex(lfsr(), 2L));
|
||||
output.append("-");
|
||||
for(uint n = 0; n < 6; n++) output.append(hex(lfsr(), 2L));
|
||||
return {"{", output, "}"};
|
||||
wchar_t guidString[39];
|
||||
StringFromGUID2(guidInstance, guidString, 39);
|
||||
|
||||
return (char*)utf8_t(guidString);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ namespace nall {
|
||||
|
||||
inline auto utf8_args(int& argc, char**& argv) -> void {
|
||||
wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
argv = new char*[argc];
|
||||
argv = new char*[argc + 1]();
|
||||
for(uint i = 0; i < argc; i++) {
|
||||
argv[i] = new char[PATH_MAX];
|
||||
strcpy(argv[i], nall::utf8_t(wargv[i]));
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "xaudio2.hpp"
|
||||
#include <windows.h>
|
||||
#include <audioclient.h>
|
||||
|
||||
struct AudioXAudio2 : Audio, public IXAudio2VoiceCallback {
|
||||
~AudioXAudio2() { term(); }
|
||||
|
@ -6,14 +6,15 @@
|
||||
#define GUID_EXT EXTERN_C
|
||||
#define GUID_SECT
|
||||
|
||||
#include <BaseTyps.h>
|
||||
#include <audioclient.h>
|
||||
#include <basetyps.h>
|
||||
|
||||
#define DEFINE_GUID_X(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) GUID_EXT const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
|
||||
#define DEFINE_GUID_X(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) GUID_EXT const GUID n GUID_SECT = {l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}}
|
||||
#define DEFINE_CLSID_X(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
DEFINE_GUID_X(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
|
||||
DEFINE_GUID_X(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
|
||||
#define DEFINE_IID_X(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
DEFINE_GUID_X(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
|
||||
#define X2DEFAULT(x) =x
|
||||
DEFINE_GUID_X(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
|
||||
#define X2DEFAULT(x) = x
|
||||
|
||||
DEFINE_CLSID_X(XAudio2, e21a7345, eb21, 468e, be, 50, 80, 4d, b9, 7c, f7, 08);
|
||||
DEFINE_CLSID_X(XAudio2_Debug, f7a76c21, 53d4, 46bb, ac, 53, 8b, 45, 9c, ae, 46, bd);
|
||||
@ -21,299 +22,271 @@ DEFINE_IID_X(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb);
|
||||
|
||||
DECLARE_INTERFACE(IXAudio2Voice);
|
||||
|
||||
#define XAUDIO2_COMMIT_NOW 0
|
||||
#define XAUDIO2_DEFAULT_CHANNELS 0
|
||||
#define XAUDIO2_DEFAULT_SAMPLERATE 0
|
||||
#define XAUDIO2_DEFAULT_FREQ_RATIO 4.0f
|
||||
#define XAUDIO2_DEBUG_ENGINE 0x0001
|
||||
#define XAUDIO2_VOICE_NOSRC 0x0004
|
||||
#define XAUDIO2_COMMIT_NOW 0
|
||||
#define XAUDIO2_DEFAULT_CHANNELS 0
|
||||
#define XAUDIO2_DEFAULT_SAMPLERATE 0
|
||||
#define XAUDIO2_DEFAULT_FREQ_RATIO 4.0f
|
||||
#define XAUDIO2_DEBUG_ENGINE 0x0001
|
||||
#define XAUDIO2_VOICE_NOSRC 0x0004
|
||||
|
||||
typedef enum XAUDIO2_DEVICE_ROLE
|
||||
{
|
||||
NotDefaultDevice = 0x0,
|
||||
DefaultConsoleDevice = 0x1,
|
||||
DefaultMultimediaDevice = 0x2,
|
||||
DefaultCommunicationsDevice = 0x4,
|
||||
DefaultGameDevice = 0x8,
|
||||
GlobalDefaultDevice = 0xf,
|
||||
InvalidDeviceRole = ~GlobalDefaultDevice
|
||||
typedef enum XAUDIO2_DEVICE_ROLE {
|
||||
NotDefaultDevice = 0x0,
|
||||
DefaultConsoleDevice = 0x1,
|
||||
DefaultMultimediaDevice = 0x2,
|
||||
DefaultCommunicationsDevice = 0x4,
|
||||
DefaultGameDevice = 0x8,
|
||||
GlobalDefaultDevice = 0xf,
|
||||
InvalidDeviceRole = ~GlobalDefaultDevice,
|
||||
} XAUDIO2_DEVICE_ROLE;
|
||||
|
||||
typedef struct XAUDIO2_DEVICE_DETAILS
|
||||
{
|
||||
WCHAR DeviceID[256];
|
||||
WCHAR DisplayName[256];
|
||||
XAUDIO2_DEVICE_ROLE Role;
|
||||
WAVEFORMATEXTENSIBLE OutputFormat;
|
||||
typedef struct XAUDIO2_DEVICE_DETAILS {
|
||||
WCHAR DeviceID[256];
|
||||
WCHAR DisplayName[256];
|
||||
XAUDIO2_DEVICE_ROLE Role;
|
||||
WAVEFORMATEXTENSIBLE OutputFormat;
|
||||
} XAUDIO2_DEVICE_DETAILS;
|
||||
|
||||
typedef struct XAUDIO2_VOICE_DETAILS
|
||||
{
|
||||
UINT32 CreationFlags;
|
||||
UINT32 InputChannels;
|
||||
UINT32 InputSampleRate;
|
||||
typedef struct XAUDIO2_VOICE_DETAILS {
|
||||
UINT32 CreationFlags;
|
||||
UINT32 InputChannels;
|
||||
UINT32 InputSampleRate;
|
||||
} XAUDIO2_VOICE_DETAILS;
|
||||
|
||||
typedef enum XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER
|
||||
{
|
||||
Processor1 = 0x00000001,
|
||||
Processor2 = 0x00000002,
|
||||
Processor3 = 0x00000004,
|
||||
Processor4 = 0x00000008,
|
||||
Processor5 = 0x00000010,
|
||||
Processor6 = 0x00000020,
|
||||
Processor7 = 0x00000040,
|
||||
Processor8 = 0x00000080,
|
||||
Processor9 = 0x00000100,
|
||||
Processor10 = 0x00000200,
|
||||
Processor11 = 0x00000400,
|
||||
Processor12 = 0x00000800,
|
||||
Processor13 = 0x00001000,
|
||||
Processor14 = 0x00002000,
|
||||
Processor15 = 0x00004000,
|
||||
Processor16 = 0x00008000,
|
||||
Processor17 = 0x00010000,
|
||||
Processor18 = 0x00020000,
|
||||
Processor19 = 0x00040000,
|
||||
Processor20 = 0x00080000,
|
||||
Processor21 = 0x00100000,
|
||||
Processor22 = 0x00200000,
|
||||
Processor23 = 0x00400000,
|
||||
Processor24 = 0x00800000,
|
||||
Processor25 = 0x01000000,
|
||||
Processor26 = 0x02000000,
|
||||
Processor27 = 0x04000000,
|
||||
Processor28 = 0x08000000,
|
||||
Processor29 = 0x10000000,
|
||||
Processor30 = 0x20000000,
|
||||
Processor31 = 0x40000000,
|
||||
Processor32 = 0x80000000,
|
||||
XAUDIO2_ANY_PROCESSOR = 0xffffffff,
|
||||
XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR
|
||||
typedef enum XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER {
|
||||
Processor1 = 0x00000001,
|
||||
Processor2 = 0x00000002,
|
||||
Processor3 = 0x00000004,
|
||||
Processor4 = 0x00000008,
|
||||
Processor5 = 0x00000010,
|
||||
Processor6 = 0x00000020,
|
||||
Processor7 = 0x00000040,
|
||||
Processor8 = 0x00000080,
|
||||
Processor9 = 0x00000100,
|
||||
Processor10 = 0x00000200,
|
||||
Processor11 = 0x00000400,
|
||||
Processor12 = 0x00000800,
|
||||
Processor13 = 0x00001000,
|
||||
Processor14 = 0x00002000,
|
||||
Processor15 = 0x00004000,
|
||||
Processor16 = 0x00008000,
|
||||
Processor17 = 0x00010000,
|
||||
Processor18 = 0x00020000,
|
||||
Processor19 = 0x00040000,
|
||||
Processor20 = 0x00080000,
|
||||
Processor21 = 0x00100000,
|
||||
Processor22 = 0x00200000,
|
||||
Processor23 = 0x00400000,
|
||||
Processor24 = 0x00800000,
|
||||
Processor25 = 0x01000000,
|
||||
Processor26 = 0x02000000,
|
||||
Processor27 = 0x04000000,
|
||||
Processor28 = 0x08000000,
|
||||
Processor29 = 0x10000000,
|
||||
Processor30 = 0x20000000,
|
||||
Processor31 = 0x40000000,
|
||||
Processor32 = 0x80000000,
|
||||
XAUDIO2_ANY_PROCESSOR = 0xffffffff,
|
||||
XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR,
|
||||
} XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER, XAUDIO2_PROCESSOR;
|
||||
|
||||
typedef struct XAUDIO2_VOICE_SENDS
|
||||
{
|
||||
UINT32 OutputCount;
|
||||
IXAudio2Voice** pOutputVoices;
|
||||
typedef struct XAUDIO2_VOICE_SENDS {
|
||||
UINT32 OutputCount;
|
||||
IXAudio2Voice** pOutputVoices;
|
||||
} XAUDIO2_VOICE_SENDS;
|
||||
|
||||
typedef struct XAUDIO2_EFFECT_DESCRIPTOR
|
||||
{
|
||||
IUnknown* pEffect;
|
||||
BOOL InitialState;
|
||||
UINT32 OutputChannels;
|
||||
typedef struct XAUDIO2_EFFECT_DESCRIPTOR {
|
||||
IUnknown* pEffect;
|
||||
BOOL InitialState;
|
||||
UINT32 OutputChannels;
|
||||
} XAUDIO2_EFFECT_DESCRIPTOR;
|
||||
|
||||
typedef struct XAUDIO2_EFFECT_CHAIN
|
||||
{
|
||||
UINT32 EffectCount;
|
||||
const XAUDIO2_EFFECT_DESCRIPTOR* pEffectDescriptors;
|
||||
typedef struct XAUDIO2_EFFECT_CHAIN {
|
||||
UINT32 EffectCount;
|
||||
const XAUDIO2_EFFECT_DESCRIPTOR* pEffectDescriptors;
|
||||
} XAUDIO2_EFFECT_CHAIN;
|
||||
|
||||
typedef enum XAUDIO2_FILTER_TYPE
|
||||
{
|
||||
LowPassFilter,
|
||||
BandPassFilter,
|
||||
HighPassFilter
|
||||
typedef enum XAUDIO2_FILTER_TYPE {
|
||||
LowPassFilter,
|
||||
BandPassFilter,
|
||||
HighPassFilter,
|
||||
} XAUDIO2_FILTER_TYPE;
|
||||
|
||||
typedef struct XAUDIO2_FILTER_PARAMETERS
|
||||
{
|
||||
XAUDIO2_FILTER_TYPE Type;
|
||||
float Frequency;
|
||||
float OneOverQ;
|
||||
|
||||
typedef struct XAUDIO2_FILTER_PARAMETERS {
|
||||
XAUDIO2_FILTER_TYPE Type;
|
||||
float Frequency;
|
||||
float OneOverQ;
|
||||
} XAUDIO2_FILTER_PARAMETERS;
|
||||
|
||||
typedef struct XAUDIO2_BUFFER
|
||||
{
|
||||
UINT32 Flags;
|
||||
UINT32 AudioBytes;
|
||||
const BYTE* pAudioData;
|
||||
UINT32 PlayBegin;
|
||||
UINT32 PlayLength;
|
||||
UINT32 LoopBegin;
|
||||
UINT32 LoopLength;
|
||||
UINT32 LoopCount;
|
||||
void* pContext;
|
||||
typedef struct XAUDIO2_BUFFER {
|
||||
UINT32 Flags;
|
||||
UINT32 AudioBytes;
|
||||
const BYTE* pAudioData;
|
||||
UINT32 PlayBegin;
|
||||
UINT32 PlayLength;
|
||||
UINT32 LoopBegin;
|
||||
UINT32 LoopLength;
|
||||
UINT32 LoopCount;
|
||||
void* pContext;
|
||||
} XAUDIO2_BUFFER;
|
||||
|
||||
typedef struct XAUDIO2_BUFFER_WMA
|
||||
{
|
||||
const UINT32* pDecodedPacketCumulativeBytes;
|
||||
UINT32 PacketCount;
|
||||
typedef struct XAUDIO2_BUFFER_WMA {
|
||||
const UINT32* pDecodedPacketCumulativeBytes;
|
||||
UINT32 PacketCount;
|
||||
} XAUDIO2_BUFFER_WMA;
|
||||
|
||||
typedef struct XAUDIO2_VOICE_STATE
|
||||
{
|
||||
void* pCurrentBufferContext;
|
||||
UINT32 BuffersQueued;
|
||||
UINT64 SamplesPlayed;
|
||||
typedef struct XAUDIO2_VOICE_STATE {
|
||||
void* pCurrentBufferContext;
|
||||
UINT32 BuffersQueued;
|
||||
UINT64 SamplesPlayed;
|
||||
} XAUDIO2_VOICE_STATE;
|
||||
|
||||
typedef struct XAUDIO2_PERFORMANCE_DATA
|
||||
{
|
||||
UINT64 AudioCyclesSinceLastQuery;
|
||||
UINT64 TotalCyclesSinceLastQuery;
|
||||
UINT32 MinimumCyclesPerQuantum;
|
||||
UINT32 MaximumCyclesPerQuantum;
|
||||
UINT32 MemoryUsageInBytes;
|
||||
UINT32 CurrentLatencyInSamples;
|
||||
UINT32 GlitchesSinceEngineStarted;
|
||||
UINT32 ActiveSourceVoiceCount;
|
||||
UINT32 TotalSourceVoiceCount;
|
||||
UINT32 ActiveSubmixVoiceCount;
|
||||
UINT32 TotalSubmixVoiceCount;
|
||||
UINT32 ActiveXmaSourceVoices;
|
||||
UINT32 ActiveXmaStreams;
|
||||
typedef struct XAUDIO2_PERFORMANCE_DATA {
|
||||
UINT64 AudioCyclesSinceLastQuery;
|
||||
UINT64 TotalCyclesSinceLastQuery;
|
||||
UINT32 MinimumCyclesPerQuantum;
|
||||
UINT32 MaximumCyclesPerQuantum;
|
||||
UINT32 MemoryUsageInBytes;
|
||||
UINT32 CurrentLatencyInSamples;
|
||||
UINT32 GlitchesSinceEngineStarted;
|
||||
UINT32 ActiveSourceVoiceCount;
|
||||
UINT32 TotalSourceVoiceCount;
|
||||
UINT32 ActiveSubmixVoiceCount;
|
||||
UINT32 TotalSubmixVoiceCount;
|
||||
UINT32 ActiveXmaSourceVoices;
|
||||
UINT32 ActiveXmaStreams;
|
||||
} XAUDIO2_PERFORMANCE_DATA;
|
||||
|
||||
typedef struct XAUDIO2_DEBUG_CONFIGURATION
|
||||
{
|
||||
UINT32 TraceMask;
|
||||
UINT32 BreakMask;
|
||||
BOOL LogThreadID;
|
||||
BOOL LogFileline;
|
||||
BOOL LogFunctionName;
|
||||
BOOL LogTiming;
|
||||
typedef struct XAUDIO2_DEBUG_CONFIGURATION {
|
||||
UINT32 TraceMask;
|
||||
UINT32 BreakMask;
|
||||
BOOL LogThreadID;
|
||||
BOOL LogFileline;
|
||||
BOOL LogFunctionName;
|
||||
BOOL LogTiming;
|
||||
} XAUDIO2_DEBUG_CONFIGURATION;
|
||||
|
||||
DECLARE_INTERFACE(IXAudio2EngineCallback)
|
||||
{
|
||||
STDMETHOD_(void, OnProcessingPassStart) (THIS) PURE;
|
||||
STDMETHOD_(void, OnProcessingPassEnd) (THIS) PURE;
|
||||
STDMETHOD_(void, OnCriticalError) (THIS_ HRESULT Error) PURE;
|
||||
DECLARE_INTERFACE(IXAudio2EngineCallback) {
|
||||
STDMETHOD_(void, OnProcessingPassStart) (THIS) PURE;
|
||||
STDMETHOD_(void, OnProcessingPassEnd) (THIS) PURE;
|
||||
STDMETHOD_(void, OnCriticalError) (THIS_ HRESULT Error) PURE;
|
||||
};
|
||||
|
||||
DECLARE_INTERFACE(IXAudio2VoiceCallback)
|
||||
{
|
||||
STDMETHOD_(void, OnVoiceProcessingPassStart) (THIS_ UINT32 BytesRequired) PURE;
|
||||
STDMETHOD_(void, OnVoiceProcessingPassEnd) (THIS) PURE;
|
||||
STDMETHOD_(void, OnStreamEnd) (THIS) PURE;
|
||||
STDMETHOD_(void, OnBufferStart) (THIS_ void* pBufferContext) PURE;
|
||||
STDMETHOD_(void, OnBufferEnd) (THIS_ void* pBufferContext) PURE;
|
||||
STDMETHOD_(void, OnLoopEnd) (THIS_ void* pBufferContext) PURE;
|
||||
STDMETHOD_(void, OnVoiceError) (THIS_ void* pBufferContext, HRESULT Error) PURE;
|
||||
DECLARE_INTERFACE(IXAudio2VoiceCallback) {
|
||||
STDMETHOD_(void, OnVoiceProcessingPassStart) (THIS_ UINT32 BytesRequired) PURE;
|
||||
STDMETHOD_(void, OnVoiceProcessingPassEnd) (THIS) PURE;
|
||||
STDMETHOD_(void, OnStreamEnd) (THIS) PURE;
|
||||
STDMETHOD_(void, OnBufferStart) (THIS_ void* pBufferContext) PURE;
|
||||
STDMETHOD_(void, OnBufferEnd) (THIS_ void* pBufferContext) PURE;
|
||||
STDMETHOD_(void, OnLoopEnd) (THIS_ void* pBufferContext) PURE;
|
||||
STDMETHOD_(void, OnVoiceError) (THIS_ void* pBufferContext, HRESULT Error) PURE;
|
||||
};
|
||||
|
||||
DECLARE_INTERFACE(IXAudio2Voice)
|
||||
{
|
||||
#define Declare_IXAudio2Voice_Methods() \
|
||||
STDMETHOD_(void, GetVoiceDetails) (THIS_ XAUDIO2_VOICE_DETAILS* pVoiceDetails) PURE; \
|
||||
STDMETHOD(SetOutputVoices) (THIS_ const XAUDIO2_VOICE_SENDS* pSendList) PURE; \
|
||||
STDMETHOD(SetEffectChain) (THIS_ const XAUDIO2_EFFECT_CHAIN* pEffectChain) PURE; \
|
||||
STDMETHOD(EnableEffect) (THIS_ UINT32 EffectIndex, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD(DisableEffect) (THIS_ UINT32 EffectIndex, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetEffectState) (THIS_ UINT32 EffectIndex, BOOL* pEnabled) PURE; \
|
||||
STDMETHOD(SetEffectParameters) (THIS_ UINT32 EffectIndex, \
|
||||
const void* pParameters, \
|
||||
UINT32 ParametersByteSize, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD(GetEffectParameters) (THIS_ UINT32 EffectIndex, void* pParameters, \
|
||||
UINT32 ParametersByteSize) PURE; \
|
||||
STDMETHOD(SetFilterParameters) (THIS_ const XAUDIO2_FILTER_PARAMETERS* pParameters, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetFilterParameters) (THIS_ XAUDIO2_FILTER_PARAMETERS* pParameters) PURE; \
|
||||
STDMETHOD(SetVolume) (THIS_ float Volume, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetVolume) (THIS_ float* pVolume) PURE; \
|
||||
STDMETHOD(SetChannelVolumes) (THIS_ UINT32 Channels, const float* pVolumes, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetChannelVolumes) (THIS_ UINT32 Channels, float* pVolumes) PURE; \
|
||||
STDMETHOD(SetOutputMatrix) (THIS_ IXAudio2Voice* pDestinationVoice, \
|
||||
UINT32 SourceChannels, UINT32 DestinationChannels, \
|
||||
const float* pLevelMatrix, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetOutputMatrix) (THIS_ IXAudio2Voice* pDestinationVoice, \
|
||||
UINT32 SourceChannels, UINT32 DestinationChannels, \
|
||||
float* pLevelMatrix) PURE; \
|
||||
STDMETHOD_(void, DestroyVoice) (THIS) PURE
|
||||
DECLARE_INTERFACE(IXAudio2Voice) {
|
||||
#define Declare_IXAudio2Voice_Methods() \
|
||||
STDMETHOD_(void, GetVoiceDetails) (THIS_ XAUDIO2_VOICE_DETAILS* pVoiceDetails) PURE; \
|
||||
STDMETHOD(SetOutputVoices) (THIS_ const XAUDIO2_VOICE_SENDS* pSendList) PURE; \
|
||||
STDMETHOD(SetEffectChain) (THIS_ const XAUDIO2_EFFECT_CHAIN* pEffectChain) PURE; \
|
||||
STDMETHOD(EnableEffect) (THIS_ UINT32 EffectIndex, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD(DisableEffect) (THIS_ UINT32 EffectIndex, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetEffectState) (THIS_ UINT32 EffectIndex, BOOL* pEnabled) PURE; \
|
||||
STDMETHOD(SetEffectParameters) (THIS_ UINT32 EffectIndex, \
|
||||
const void* pParameters, \
|
||||
UINT32 ParametersByteSize, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD(GetEffectParameters) (THIS_ UINT32 EffectIndex, void* pParameters, \
|
||||
UINT32 ParametersByteSize) PURE; \
|
||||
STDMETHOD(SetFilterParameters) (THIS_ const XAUDIO2_FILTER_PARAMETERS* pParameters, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetFilterParameters) (THIS_ XAUDIO2_FILTER_PARAMETERS* pParameters) PURE; \
|
||||
STDMETHOD(SetVolume) (THIS_ float Volume, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetVolume) (THIS_ float* pVolume) PURE; \
|
||||
STDMETHOD(SetChannelVolumes) (THIS_ UINT32 Channels, const float* pVolumes, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetChannelVolumes) (THIS_ UINT32 Channels, float* pVolumes) PURE; \
|
||||
STDMETHOD(SetOutputMatrix) (THIS_ IXAudio2Voice* pDestinationVoice, \
|
||||
UINT32 SourceChannels, UINT32 DestinationChannels, \
|
||||
const float* pLevelMatrix, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetOutputMatrix) (THIS_ IXAudio2Voice* pDestinationVoice, \
|
||||
UINT32 SourceChannels, UINT32 DestinationChannels, \
|
||||
float* pLevelMatrix) PURE; \
|
||||
STDMETHOD_(void, DestroyVoice) (THIS) PURE
|
||||
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
};
|
||||
|
||||
|
||||
DECLARE_INTERFACE_(IXAudio2MasteringVoice, IXAudio2Voice)
|
||||
{
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
DECLARE_INTERFACE_(IXAudio2MasteringVoice, IXAudio2Voice) {
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
};
|
||||
|
||||
DECLARE_INTERFACE_(IXAudio2SubmixVoice, IXAudio2Voice)
|
||||
{
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
DECLARE_INTERFACE_(IXAudio2SubmixVoice, IXAudio2Voice) {
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
};
|
||||
|
||||
DECLARE_INTERFACE_(IXAudio2SourceVoice, IXAudio2Voice)
|
||||
{
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
STDMETHOD(Start) (THIS_ UINT32 Flags, UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD(Stop) (THIS_ UINT32 Flags, UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD(SubmitSourceBuffer) (THIS_ const XAUDIO2_BUFFER* pBuffer, const XAUDIO2_BUFFER_WMA* pBufferWMA X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(FlushSourceBuffers) (THIS) PURE;
|
||||
STDMETHOD(Discontinuity) (THIS) PURE;
|
||||
STDMETHOD(ExitLoop) (THIS_ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD_(void, GetState) (THIS_ XAUDIO2_VOICE_STATE* pVoiceState) PURE;
|
||||
STDMETHOD(SetFrequencyRatio) (THIS_ float Ratio,
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD_(void, GetFrequencyRatio) (THIS_ float* pRatio) PURE;
|
||||
DECLARE_INTERFACE_(IXAudio2SourceVoice, IXAudio2Voice) {
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
STDMETHOD(Start) (THIS_ UINT32 Flags, UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD(Stop) (THIS_ UINT32 Flags, UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD(SubmitSourceBuffer) (THIS_ const XAUDIO2_BUFFER* pBuffer, const XAUDIO2_BUFFER_WMA* pBufferWMA X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(FlushSourceBuffers) (THIS) PURE;
|
||||
STDMETHOD(Discontinuity) (THIS) PURE;
|
||||
STDMETHOD(ExitLoop) (THIS_ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD_(void, GetState) (THIS_ XAUDIO2_VOICE_STATE* pVoiceState) PURE;
|
||||
STDMETHOD(SetFrequencyRatio) (THIS_ float Ratio,
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD_(void, GetFrequencyRatio) (THIS_ float* pRatio) PURE;
|
||||
};
|
||||
|
||||
DECLARE_INTERFACE_(IXAudio2, IUnknown)
|
||||
{
|
||||
STDMETHOD(QueryInterface) (THIS_ REFIID riid, void** ppvInterface) PURE;
|
||||
STDMETHOD_(ULONG, AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG, Release) (THIS) PURE;
|
||||
STDMETHOD(GetDeviceCount) (THIS_ UINT32* pCount) PURE;
|
||||
STDMETHOD(GetDeviceDetails) (THIS_ UINT32 Index, XAUDIO2_DEVICE_DETAILS* pDeviceDetails) PURE;
|
||||
STDMETHOD(Initialize) (THIS_ UINT32 Flags X2DEFAULT(0),
|
||||
XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)) PURE;
|
||||
STDMETHOD(RegisterForCallbacks) (IXAudio2EngineCallback* pCallback) PURE;
|
||||
STDMETHOD_(void, UnregisterForCallbacks) (IXAudio2EngineCallback* pCallback) PURE;
|
||||
STDMETHOD(CreateSourceVoice) (THIS_ IXAudio2SourceVoice** ppSourceVoice,
|
||||
const WAVEFORMATEX* pSourceFormat,
|
||||
UINT32 Flags X2DEFAULT(0),
|
||||
float MaxFrequencyRatio X2DEFAULT(XAUDIO2_DEFAULT_FREQ_RATIO),
|
||||
IXAudio2VoiceCallback* pCallback X2DEFAULT(NULL),
|
||||
const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL),
|
||||
const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(CreateSubmixVoice) (THIS_ IXAudio2SubmixVoice** ppSubmixVoice,
|
||||
UINT32 InputChannels, UINT32 InputSampleRate,
|
||||
UINT32 Flags X2DEFAULT(0), UINT32 ProcessingStage X2DEFAULT(0),
|
||||
const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL),
|
||||
const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(CreateMasteringVoice) (THIS_ IXAudio2MasteringVoice** ppMasteringVoice,
|
||||
UINT32 InputChannels X2DEFAULT(XAUDIO2_DEFAULT_CHANNELS),
|
||||
UINT32 InputSampleRate X2DEFAULT(XAUDIO2_DEFAULT_SAMPLERATE),
|
||||
UINT32 Flags X2DEFAULT(0), UINT32 DeviceIndex X2DEFAULT(0),
|
||||
const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(StartEngine) (THIS) PURE;
|
||||
STDMETHOD_(void, StopEngine) (THIS) PURE;
|
||||
STDMETHOD(CommitChanges) (THIS_ UINT32 OperationSet) PURE;
|
||||
STDMETHOD_(void, GetPerformanceData) (THIS_ XAUDIO2_PERFORMANCE_DATA* pPerfData) PURE;
|
||||
STDMETHOD_(void, SetDebugConfiguration) (THIS_ const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration,
|
||||
void* pReserved X2DEFAULT(NULL)) PURE;
|
||||
DECLARE_INTERFACE_(IXAudio2, IUnknown) {
|
||||
STDMETHOD(QueryInterface) (THIS_ REFIID riid, void** ppvInterface) PURE;
|
||||
STDMETHOD_(ULONG, AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG, Release) (THIS) PURE;
|
||||
STDMETHOD(GetDeviceCount) (THIS_ UINT32* pCount) PURE;
|
||||
STDMETHOD(GetDeviceDetails) (THIS_ UINT32 Index, XAUDIO2_DEVICE_DETAILS* pDeviceDetails) PURE;
|
||||
STDMETHOD(Initialize) (THIS_ UINT32 Flags X2DEFAULT(0),
|
||||
XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)) PURE;
|
||||
STDMETHOD(RegisterForCallbacks) (IXAudio2EngineCallback* pCallback) PURE;
|
||||
STDMETHOD_(void, UnregisterForCallbacks) (IXAudio2EngineCallback* pCallback) PURE;
|
||||
STDMETHOD(CreateSourceVoice) (THIS_ IXAudio2SourceVoice** ppSourceVoice,
|
||||
const WAVEFORMATEX* pSourceFormat,
|
||||
UINT32 Flags X2DEFAULT(0),
|
||||
float MaxFrequencyRatio X2DEFAULT(XAUDIO2_DEFAULT_FREQ_RATIO),
|
||||
IXAudio2VoiceCallback* pCallback X2DEFAULT(NULL),
|
||||
const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL),
|
||||
const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(CreateSubmixVoice) (THIS_ IXAudio2SubmixVoice** ppSubmixVoice,
|
||||
UINT32 InputChannels, UINT32 InputSampleRate,
|
||||
UINT32 Flags X2DEFAULT(0), UINT32 ProcessingStage X2DEFAULT(0),
|
||||
const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL),
|
||||
const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(CreateMasteringVoice) (THIS_ IXAudio2MasteringVoice** ppMasteringVoice,
|
||||
UINT32 InputChannels X2DEFAULT(XAUDIO2_DEFAULT_CHANNELS),
|
||||
UINT32 InputSampleRate X2DEFAULT(XAUDIO2_DEFAULT_SAMPLERATE),
|
||||
UINT32 Flags X2DEFAULT(0), UINT32 DeviceIndex X2DEFAULT(0),
|
||||
const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(StartEngine) (THIS) PURE;
|
||||
STDMETHOD_(void, StopEngine) (THIS) PURE;
|
||||
STDMETHOD(CommitChanges) (THIS_ UINT32 OperationSet) PURE;
|
||||
STDMETHOD_(void, GetPerformanceData) (THIS_ XAUDIO2_PERFORMANCE_DATA* pPerfData) PURE;
|
||||
STDMETHOD_(void, SetDebugConfiguration) (THIS_ const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration,
|
||||
void* pReserved X2DEFAULT(NULL)) PURE;
|
||||
};
|
||||
|
||||
__inline HRESULT XAudio2Create(IXAudio2** ppXAudio2, UINT32 Flags X2DEFAULT(0),
|
||||
XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR))
|
||||
{
|
||||
IXAudio2* pXAudio2;
|
||||
HRESULT hr = CoCreateInstance((Flags & XAUDIO2_DEBUG_ENGINE) ? CLSID_XAudio2_Debug : CLSID_XAudio2,
|
||||
NULL, CLSCTX_INPROC_SERVER, IID_IXAudio2, (void**)&pXAudio2);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pXAudio2->Initialize(Flags, XAudio2Processor);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
*ppXAudio2 = pXAudio2;
|
||||
}
|
||||
else
|
||||
{
|
||||
pXAudio2->Release();
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)) {
|
||||
IXAudio2* pXAudio2;
|
||||
HRESULT hr = CoCreateInstance((Flags & XAUDIO2_DEBUG_ENGINE) ? CLSID_XAudio2_Debug : CLSID_XAudio2,
|
||||
NULL, CLSCTX_INPROC_SERVER, IID_IXAudio2, (void**)&pXAudio2);
|
||||
if(SUCCEEDED(hr)) {
|
||||
hr = pXAudio2->Initialize(Flags, XAudio2Processor);
|
||||
if(SUCCEEDED(hr)) {
|
||||
*ppXAudio2 = pXAudio2;
|
||||
} else {
|
||||
pXAudio2->Release();
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user