mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-02-24 07:02:27 +01:00
byuu says: Changelog: - processor/arm: corrected MUL instruction timings [Jonas Quinn] - processor/wdc65816: finished phase two of the rewrite I'm really pleased with the visual results of the wdc65816 core rewrite. I was able to eliminate all of the weird `{Boolean,Natural}BitRange` templates, as well as the need to use unions/structs. Registers are now just simple `uint24` or `uint16` types (technically they're `Natural<T>` types, but then all of higan uses those), flags are now just bool types. I also eliminated all of the implicit object state inside of the core (aa, rd, dp, sp) and instead do all computations on the stack frame with local variables. Through using macros to reference the registers and individual parts of them, I was able to reduce the visual tensity of all of the instructions. And by using normal types without implicit states, I was able to eliminate about 15% of the instructions necessary, instead reusing existing ones. The final third phase of the rewrite will be to recode the disassembler. That code is probably the oldest code in all of higan right now, still using sprintf to generate the output. So it is very long overdue for a cleanup. And now for the bad news ... as with any large code cleanup, regression errors have seeped in. Currently, no games are running at all. I've left the old disassembler in for this reason: we can compare trace logs of v102r23 against trace logs of v102r25. The second there's any difference, we've spotted a buggy instruction and can correct it. With any luck, this will be the last time I ever rewrite the wdc65816 core. My style has changed wildly over the ~10 years since I wrote this core, but it's really solidifed in recent years.
64 lines
2.1 KiB
C++
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
|
|
}
|