bsnes/higan/processor/wdc65816/instruction.cpp

64 lines
2.1 KiB
C++

auto WDC65816::interrupt() -> void {
read(PC);
idle();
N push(db(PC));
push(hi(PC));
push(lo(PC));
push(EF ? P & ~0x10 : P);
IF = 1;
DF = 0;
lo(PC) = read(r.vector + 0);
hi(PC) = read(r.vector + 1);
db(PC) = 0x00;
}
//both the accumulator and index registers can independently be in either 8-bit or 16-bit mode.
//controlled via the M/X flags, this changes the execution details of various instructions.
//rather than implement four instruction tables for all possible combinations of these bits,
//instead use macro abuse to generate all four tables based off of a single template table.
auto WDC65816::instruction() -> void {
//a = instructions unaffected by M/X flags
//m = instructions affected by M flag (1 = 8-bit; 0 = 16-bit)
//x = instructions affected by X flag (1 = 8-bit; 0 = 16-bit)
#define opA(id, name, ...) case id: return instruction##name(__VA_ARGS__);
if(MF) {
#define opM(id, name, ...) case id: return instruction##name##8(__VA_ARGS__);
#define m(name) &WDC65816::algorithm##name##8
if(XF) {
#define opX(id, name, ...) case id: return instruction##name##8(__VA_ARGS__);
#define x(name) &WDC65816::algorithm##name##8
#include "instruction.hpp"
#undef opX
#undef x
} else {
#define opX(id, name, ...) case id: return instruction##name##16(__VA_ARGS__);
#define x(name) &WDC65816::algorithm##name##16
#include "instruction.hpp"
#undef opX
#undef x
}
#undef opM
#undef m
} else {
#define opM(id, name, ...) case id: return instruction##name##16(__VA_ARGS__);
#define m(name) &WDC65816::algorithm##name##16
if(XF) {
#define opX(id, name, ...) case id: return instruction##name##8(__VA_ARGS__);
#define x(name) &WDC65816::algorithm##name##8
#include "instruction.hpp"
#undef opX
#undef x
} else {
#define opX(id, name, ...) case id: return instruction##name##16(__VA_ARGS__);
#define x(name) &WDC65816::algorithm##name##16
#include "instruction.hpp"
#undef opX
#undef x
}
#undef opM
#undef m
}
#undef opA
}