From a19395ee3c2ffd2e742952e37f4624017036c19e Mon Sep 17 00:00:00 2001 From: Brandon Wright Date: Wed, 14 Sep 2011 12:54:51 -0500 Subject: [PATCH] Start converting some opcodes to cycle-based. --- apu/bapu/smp/core.cpp | 13 + apu/bapu/smp/core/opcycle_misc.cpp | 420 ++++++++--------------------- apu/bapu/smp/core/opcycle_rmw.cpp | 90 ++----- apu/bapu/smp/smp.hpp | 2 + 4 files changed, 147 insertions(+), 378 deletions(-) diff --git a/apu/bapu/smp/core.cpp b/apu/bapu/smp/core.cpp index 5664da36..7e9c4a95 100644 --- a/apu/bapu/smp/core.cpp +++ b/apu/bapu/smp/core.cpp @@ -13,12 +13,25 @@ void SMP::tick() { #endif } +void SMP::tick(unsigned clocks) { + timer0.tick(clocks); + timer1.tick(clocks); + timer2.tick(clocks); + + clock += clocks; + dsp.clock += clocks; +} + void SMP::op_io() { #if defined(CYCLE_ACCURATE) tick(); #endif } +void SMP::op_io(unsigned clocks) { + tick(clocks); +} + uint8 SMP::op_read(uint16 addr) { #if defined(CYCLE_ACCURATE) tick(); diff --git a/apu/bapu/smp/core/opcycle_misc.cpp b/apu/bapu/smp/core/opcycle_misc.cpp index 963f9fc2..5fe164f1 100644 --- a/apu/bapu/smp/core/opcycle_misc.cpp +++ b/apu/bapu/smp/core/opcycle_misc.cpp @@ -1,188 +1,109 @@ case 0x00: { - switch(opcode_cycle++) { - case 1: - op_io(); - opcode_cycle = 0; - break; - } + op_io(); + opcode_cycle = 0; break; } case 0xef: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - regs.pc--; - opcode_cycle = 0; - break; - } + op_io(2); + regs.pc--; + opcode_cycle = 0; break; } case 0xff: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - regs.pc--; - opcode_cycle = 0; - break; - } + op_io(2); + regs.pc--; + opcode_cycle = 0; break; } case 0x9f: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - break; - case 3: - op_io(); - break; - case 4: - op_io(); - regs.a = (regs.a >> 4) | (regs.a << 4); - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); - opcode_cycle = 0; - break; - } + op_io(4); + regs.a = (regs.a >> 4) | (regs.a << 4); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + opcode_cycle = 0; break; } case 0xdf: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - if(regs.p.c || (regs.a) > 0x99) { - regs.a += 0x60; - regs.p.c = 1; - } - if(regs.p.h || (regs.a & 15) > 0x09) { - regs.a += 0x06; - } - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); - opcode_cycle = 0; - break; + op_io(2); + if(regs.p.c || (regs.a) > 0x99) { + regs.a += 0x60; + regs.p.c = 1; } + if(regs.p.h || (regs.a & 15) > 0x09) { + regs.a += 0x06; + } + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + opcode_cycle = 0; break; } case 0xbe: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - if(!regs.p.c || (regs.a) > 0x99) { - regs.a -= 0x60; - regs.p.c = 0; - } - if(!regs.p.h || (regs.a & 15) > 0x09) { - regs.a -= 0x06; - } - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); - opcode_cycle = 0; - break; + op_io(2); + if(!regs.p.c || (regs.a) > 0x99) { + regs.a -= 0x60; + regs.p.c = 0; } + if(!regs.p.h || (regs.a & 15) > 0x09) { + regs.a -= 0x06; + } + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + opcode_cycle = 0; break; } case 0x60: { - switch(opcode_cycle++) { - case 1: - op_io(); - regs.p.c = 0; - opcode_cycle = 0; - break; - } + op_io(); + regs.p.c = 0; + opcode_cycle = 0; break; } case 0x20: { - switch(opcode_cycle++) { - case 1: - op_io(); - regs.p.p = 0; - opcode_cycle = 0; - break; - } + op_io(); + regs.p.p = 0; + opcode_cycle = 0; break; } case 0x80: { - switch(opcode_cycle++) { - case 1: - op_io(); - regs.p.c = 1; - opcode_cycle = 0; - break; - } + op_io(); + regs.p.c = 1; + opcode_cycle = 0; break; } case 0x40: { - switch(opcode_cycle++) { - case 1: - op_io(); - regs.p.p = 1; - opcode_cycle = 0; - break; - } + op_io(); + regs.p.p = 1; + opcode_cycle = 0; break; } case 0xe0: { - switch(opcode_cycle++) { - case 1: - op_io(); - regs.p.v = 0; - regs.p.h = 0; - opcode_cycle = 0; - break; - } + op_io(); + regs.p.v = 0; + regs.p.h = 0; + opcode_cycle = 0; break; } case 0xed: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - regs.p.c = !regs.p.c; - opcode_cycle = 0; - break; - } + op_io(2); + regs.p.c = !regs.p.c; + opcode_cycle = 0; break; } case 0xa0: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - regs.p.i = 1; - opcode_cycle = 0; - break; - } + op_io(2); + regs.p.i = 1; + opcode_cycle = 0; break; } @@ -473,224 +394,93 @@ case 0xf2: { } case 0x2d: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - break; - case 3: - op_writestack(regs.a); - opcode_cycle = 0; - break; - } + op_io(2); + op_writestack(regs.a); + opcode_cycle = 0; break; } case 0x4d: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - break; - case 3: - op_writestack(regs.x); - opcode_cycle = 0; - break; - } + op_io(2); + op_writestack(regs.x); + opcode_cycle = 0; break; } case 0x6d: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - break; - case 3: - op_writestack(regs.y); - opcode_cycle = 0; - break; - } + op_io(2); + op_writestack(regs.y); + opcode_cycle = 0; break; } case 0x0d: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - break; - case 3: - op_writestack(regs.p); - opcode_cycle = 0; - break; - } + op_io(2); + op_writestack(regs.p); + opcode_cycle = 0; break; } case 0xae: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - break; - case 3: - regs.a = op_readstack(); - opcode_cycle = 0; - break; - } + op_io(2); + regs.a = op_readstack(); + opcode_cycle = 0; break; } case 0xce: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - break; - case 3: - regs.x = op_readstack(); - opcode_cycle = 0; - break; - } + op_io(2); + regs.x = op_readstack(); + opcode_cycle = 0; break; } case 0xee: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - break; - case 3: - regs.y = op_readstack(); - opcode_cycle = 0; - break; - } + op_io(2); + regs.y = op_readstack(); + opcode_cycle = 0; break; } case 0x8e: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - break; - case 3: - regs.p = op_readstack(); - opcode_cycle = 0; - break; - } + op_io(2); + regs.p = op_readstack(); + opcode_cycle = 0; break; } case 0xcf: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - break; - case 3: - op_io(); - break; - case 4: - op_io(); - break; - case 5: - op_io(); - break; - case 6: - op_io(); - break; - case 7: - op_io(); - break; - case 8: - op_io(); - ya = regs.y * regs.a; - regs.a = ya; - regs.y = ya >> 8; - //result is set based on y (high-byte) only - regs.p.n = !!(regs.y & 0x80); - regs.p.z = (regs.y == 0); - opcode_cycle = 0; - break; - } + op_io(8); + ya = regs.y * regs.a; + regs.a = ya; + regs.y = ya >> 8; + //result is set based on y (high-byte) only + regs.p.n = !!(regs.y & 0x80); + regs.p.z = (regs.y == 0); + opcode_cycle = 0; break; } case 0x9e: { - switch(opcode_cycle++) { - case 1: - op_io(); - break; - case 2: - op_io(); - break; - case 3: - op_io(); - break; - case 4: - op_io(); - break; - case 5: - op_io(); - break; - case 6: - op_io(); - break; - case 7: - op_io(); - break; - case 8: - op_io(); - break; - case 9: - op_io(); - break; - case 10: - op_io(); - break; - case 11: - op_io(); - ya = regs.ya; - //overflow set if quotient >= 256 - regs.p.v = !!(regs.y >= regs.x); - regs.p.h = !!((regs.y & 15) >= (regs.x & 15)); - if(regs.y < (regs.x << 1)) { - //if quotient is <= 511 (will fit into 9-bit result) - regs.a = ya / regs.x; - regs.y = ya % regs.x; - } else { - //otherwise, the quotient won't fit into regs.p.v + regs.a - //this emulates the odd behavior of the S-SMP in this case - regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x); - regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); - } - //result is set based on a (quotient) only - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); - opcode_cycle = 0; - break; + op_io(11); + ya = regs.ya; + //overflow set if quotient >= 256 + regs.p.v = !!(regs.y >= regs.x); + regs.p.h = !!((regs.y & 15) >= (regs.x & 15)); + if(regs.y < (regs.x << 1)) { + //if quotient is <= 511 (will fit into 9-bit result) + regs.a = ya / regs.x; + regs.y = ya % regs.x; + } else { + //otherwise, the quotient won't fit into regs.p.v + regs.a + //this emulates the odd behavior of the S-SMP in this case + regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x); + regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); } + //result is set based on a (quotient) only + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + opcode_cycle = 0; break; } diff --git a/apu/bapu/smp/core/opcycle_rmw.cpp b/apu/bapu/smp/core/opcycle_rmw.cpp index eca62f02..4677628e 100644 --- a/apu/bapu/smp/core/opcycle_rmw.cpp +++ b/apu/bapu/smp/core/opcycle_rmw.cpp @@ -1,99 +1,63 @@ case 0xbc: { - switch(opcode_cycle++) { - case 1: - op_io(); - regs.a = op_inc(regs.a); - opcode_cycle = 0; - break; - } + op_io(); + regs.a = op_inc(regs.a); + opcode_cycle = 0; break; } case 0x3d: { - switch(opcode_cycle++) { - case 1: - op_io(); - regs.x = op_inc(regs.x); - opcode_cycle = 0; - break; - } + op_io(); + regs.x = op_inc(regs.x); + opcode_cycle = 0; break; } case 0xfc: { - switch(opcode_cycle++) { - case 1: - op_io(); - regs.y = op_inc(regs.y); - opcode_cycle = 0; - break; - } + op_io(); + regs.y = op_inc(regs.y); + opcode_cycle = 0; break; } case 0x9c: { - switch(opcode_cycle++) { - case 1: - op_io(); - regs.a = op_dec(regs.a); - opcode_cycle = 0; - break; - } + op_io(); + regs.a = op_dec(regs.a); + opcode_cycle = 0; break; } case 0x1d: { - switch(opcode_cycle++) { - case 1: - op_io(); - regs.x = op_dec(regs.x); - opcode_cycle = 0; - break; - } + op_io(); + regs.x = op_dec(regs.x); + opcode_cycle = 0; break; } case 0xdc: { - switch(opcode_cycle++) { - case 1: - op_io(); - regs.y = op_dec(regs.y); - opcode_cycle = 0; - break; - } + op_io(); + regs.y = op_dec(regs.y); + opcode_cycle = 0; break; } case 0x1c: { - switch(opcode_cycle++) { - case 1: - op_io(); - regs.a = op_asl(regs.a); - opcode_cycle = 0; - break; - } + op_io(); + regs.a = op_asl(regs.a); + opcode_cycle = 0; break; } case 0x5c: { - switch(opcode_cycle++) { - case 1: - op_io(); - regs.a = op_lsr(regs.a); - opcode_cycle = 0; - break; - } + op_io(); + regs.a = op_lsr(regs.a); + opcode_cycle = 0; break; } case 0x3c: { - switch(opcode_cycle++) { - case 1: - op_io(); - regs.a = op_rol(regs.a); - opcode_cycle = 0; - break; - } + op_io(); + regs.a = op_rol(regs.a); + opcode_cycle = 0; break; } diff --git a/apu/bapu/smp/smp.hpp b/apu/bapu/smp/smp.hpp index 9d7a9ea7..0a17cb8f 100644 --- a/apu/bapu/smp/smp.hpp +++ b/apu/bapu/smp/smp.hpp @@ -96,7 +96,9 @@ public: Timer< 16> timer2; inline void tick(); + inline void tick(unsigned clocks); alwaysinline void op_io(); + alwaysinline void op_io(unsigned clocks); debugvirtual alwaysinline uint8 op_read(uint16 addr); debugvirtual alwaysinline void op_write(uint16 addr, uint8 data); debugvirtual alwaysinline void op_step();