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 }