bsnes/processor/r65816/opcode_pc.cpp
Tim Allen 83f684c66c Update to v094r29 release.
byuu says:

Note: for Windows users, please go to nall/intrinsics.hpp line 60 and
correct the typo from "DISPLAY_WINDOW" to "DISPLAY_WINDOWS" before
compiling, otherwise things won't work at all.

This will be a really major WIP for the core SNES emulation, so please
test as thoroughly as possible.

I rewrote the 65816 CPU core's dispatcher from a jump table to a switch
table. This was so that I could pass class variables as parameters to
opcodes without crazy theatrics.

With that, I killed the regs.r[N] stuff, the flag_t operator|=, &=, ^=
stuff, and all of the template versions of opcodes.

I also removed some stupid pointless flag tests in xcn and pflag that
would always be true.

I sure hope that AWJ is happy with this; because this change was so that
my flag assignments and branch tests won't need to build regs.P into
a full 8-bit variable anymore.

It does of course incur a slight performance hit when you pass in
variables by-value to functions, but it should help with binary size
(and thus cache) by reducing a lot of extra functions. (I know I could
have used template parameters for some things even with a switch table,
but chose not to for the aforementioned reasons.)

Overall, it's about a ~1% speedup from the previous build. The CPU core
instructions were never a bottleneck, but I did want to fix the P flag
building stuff because that really was a dumb mistake v_v'
2015-06-22 23:31:49 +10:00

177 lines
3.3 KiB
C++

auto R65816::op_branch(bool flag, bool value) {
if(flag != value) {
L rd.l = op_readpc();
} else {
rd.l = op_readpc();
aa.w = regs.pc.d + (int8)rd.l;
op_io_cond6(aa.w);
L op_io();
regs.pc.w = aa.w;
}
}
auto R65816::op_bra() {
rd.l = op_readpc();
aa.w = regs.pc.d + (int8)rd.l;
op_io_cond6(aa.w);
L op_io();
regs.pc.w = aa.w;
}
auto R65816::op_brl() {
rd.l = op_readpc();
rd.h = op_readpc();
L op_io();
regs.pc.w = regs.pc.d + (int16)rd.w;
}
auto R65816::op_jmp_addr() {
rd.l = op_readpc();
L rd.h = op_readpc();
regs.pc.w = rd.w;
}
auto R65816::op_jmp_long() {
rd.l = op_readpc();
rd.h = op_readpc();
L rd.b = op_readpc();
regs.pc.d = rd.d & 0xffffff;
}
auto R65816::op_jmp_iaddr() {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readaddr(aa.w + 0);
L rd.h = op_readaddr(aa.w + 1);
regs.pc.w = rd.w;
}
auto R65816::op_jmp_iaddrx() {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
rd.l = op_readpbr(aa.w + regs.x.w + 0);
L rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
}
auto R65816::op_jmp_iladdr() {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readaddr(aa.w + 0);
rd.h = op_readaddr(aa.w + 1);
L rd.b = op_readaddr(aa.w + 2);
regs.pc.d = rd.d & 0xffffff;
}
auto R65816::op_jsr_addr() {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
regs.pc.w--;
op_writestack(regs.pc.h);
L op_writestack(regs.pc.l);
regs.pc.w = aa.w;
}
auto R65816::op_jsr_long_e() {
aa.l = op_readpc();
aa.h = op_readpc();
op_writestackn(regs.pc.b);
op_io();
aa.b = op_readpc();
regs.pc.w--;
op_writestackn(regs.pc.h);
L op_writestackn(regs.pc.l);
regs.pc.d = aa.d & 0xffffff;
regs.s.h = 0x01;
}
auto R65816::op_jsr_long_n() {
aa.l = op_readpc();
aa.h = op_readpc();
op_writestackn(regs.pc.b);
op_io();
aa.b = op_readpc();
regs.pc.w--;
op_writestackn(regs.pc.h);
L op_writestackn(regs.pc.l);
regs.pc.d = aa.d & 0xffffff;
}
auto R65816::op_jsr_iaddrx_e() {
aa.l = op_readpc();
op_writestackn(regs.pc.h);
op_writestackn(regs.pc.l);
aa.h = op_readpc();
op_io();
rd.l = op_readpbr(aa.w + regs.x.w + 0);
L rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
regs.s.h = 0x01;
}
auto R65816::op_jsr_iaddrx_n() {
aa.l = op_readpc();
op_writestackn(regs.pc.h);
op_writestackn(regs.pc.l);
aa.h = op_readpc();
op_io();
rd.l = op_readpbr(aa.w + regs.x.w + 0);
L rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
}
auto R65816::op_rti_e() {
op_io();
op_io();
regs.p = op_readstack() | 0x30;
rd.l = op_readstack();
L rd.h = op_readstack();
regs.pc.w = rd.w;
}
auto R65816::op_rti_n() {
op_io();
op_io();
regs.p = op_readstack();
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
rd.l = op_readstack();
rd.h = op_readstack();
L rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
}
auto R65816::op_rts() {
op_io();
op_io();
rd.l = op_readstack();
rd.h = op_readstack();
L op_io();
regs.pc.w = ++rd.w;
}
auto R65816::op_rtl_e() {
op_io();
op_io();
rd.l = op_readstackn();
rd.h = op_readstackn();
L rd.b = op_readstackn();
regs.pc.b = rd.b;
regs.pc.w = ++rd.w;
regs.s.h = 0x01;
}
auto R65816::op_rtl_n() {
op_io();
op_io();
rd.l = op_readstackn();
rd.h = op_readstackn();
L rd.b = op_readstackn();
regs.pc.b = rd.b;
regs.pc.w = ++rd.w;
}