From 6694a1c986ae0ff219d6e6f043acf7c20a95c0f7 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Thu, 5 May 2011 21:40:22 +1000 Subject: [PATCH] Update to v078r04 release. byuu says: Changelog: - file and slot load dialogs should now have perfectly square buttons that are based on the platform's default button height. - cleaned up bsnes/Accuracy SMP source code (removed old !! stuff, stage 3 timer is now uint4, memory access switch/case cleaned up, sSMPTimer->Timer, etc.) - cleaned up bsnes/Accuracy memory access functions (read/writestack -> read/writesp, read/writeaddr -> read/write) - minor optimization to bsnes/Performance SMP core in cycle-mode --- bsnes/snes/alt/smp/core.cpp | 13 +- bsnes/snes/alt/smp/core.hpp | 25 --- bsnes/snes/alt/smp/core/generate | Bin 48511 -> 0 bytes bsnes/snes/alt/smp/smp.cpp | 2 +- bsnes/snes/alt/smp/smp.hpp | 30 ++- bsnes/snes/alt/smp/timing.cpp | 19 +- bsnes/snes/smp/core/memory.hpp | 12 +- bsnes/snes/smp/core/opcode_misc.cpp | 20 +- bsnes/snes/smp/core/opcode_mov.cpp | 30 +-- bsnes/snes/smp/core/opcode_pc.cpp | 40 ++-- bsnes/snes/smp/core/opcode_read.cpp | 18 +- bsnes/snes/smp/core/opcode_rmw.cpp | 10 +- bsnes/snes/smp/memory/memory.cpp | 279 +++++++++++++--------------- bsnes/snes/smp/timing/timing.cpp | 12 +- bsnes/snes/smp/timing/timing.hpp | 12 +- bsnes/snes/snes.hpp | 2 +- bsnes/ui/general/file-browser.cpp | 6 +- bsnes/ui/general/slot-loader.cpp | 14 +- 18 files changed, 269 insertions(+), 275 deletions(-) delete mode 100755 bsnes/snes/alt/smp/core.hpp delete mode 100755 bsnes/snes/alt/smp/core/generate diff --git a/bsnes/snes/alt/smp/core.cpp b/bsnes/snes/alt/smp/core.cpp index 5fd3ea86..6e0a29b2 100755 --- a/bsnes/snes/alt/smp/core.cpp +++ b/bsnes/snes/alt/smp/core.cpp @@ -1,7 +1,7 @@ void SMP::tick() { - timer0.tick(1); - timer1.tick(1); - timer2.tick(1); + timer0.tick(); + timer1.tick(); + timer2.tick(); clock += cycle_step_cpu; dsp.clock -= 24; @@ -19,7 +19,7 @@ uint8 SMP::op_read(uint16 addr) { tick(); #endif if((addr & 0xfff0) == 0x00f0) return mmio_read(addr); - if((addr & 0xffc0) == 0xffc0 && status.iplrom_enable) return iplrom[addr & 0x3f]; + if(addr >= 0xffc0 && status.iplrom_enable) return iplrom[addr & 0x3f]; return apuram[addr]; } @@ -31,9 +31,6 @@ void SMP::op_write(uint16 addr, uint8 data) { apuram[addr] = data; //all writes go to RAM, even MMIO writes } -//TODO: -//* non-cycle accurate untaken conditional branches should subtract from opcode's cycle overhead - void SMP::op_step() { #define op_readpc() op_read(regs.pc++) #define op_readdp(addr) op_read((regs.p.p << 8) + addr) @@ -68,6 +65,8 @@ void SMP::op_step() { #include "core/op_rmw.cpp" } + //TODO: untaken branches should consume less cycles + timer0.tick(cycle_count_table[opcode]); timer1.tick(cycle_count_table[opcode]); timer2.tick(cycle_count_table[opcode]); diff --git a/bsnes/snes/alt/smp/core.hpp b/bsnes/snes/alt/smp/core.hpp deleted file mode 100755 index 65f52a59..00000000 --- a/bsnes/snes/alt/smp/core.hpp +++ /dev/null @@ -1,25 +0,0 @@ -void tick(); -alwaysinline void op_io(); -debugvirtual alwaysinline uint8 op_read(uint16 addr); -debugvirtual alwaysinline void op_write(uint16 addr, uint8 data); -debugvirtual alwaysinline void op_step(); -static const unsigned cycle_count_table[256]; -uint64 cycle_table_cpu[256]; -unsigned cycle_table_dsp[256]; -uint64 cycle_step_cpu; - -uint8 op_adc (uint8 x, uint8 y); -uint16 op_addw(uint16 x, uint16 y); -uint8 op_and (uint8 x, uint8 y); -uint8 op_cmp (uint8 x, uint8 y); -uint16 op_cmpw(uint16 x, uint16 y); -uint8 op_eor (uint8 x, uint8 y); -uint8 op_inc (uint8 x); -uint8 op_dec (uint8 x); -uint8 op_or (uint8 x, uint8 y); -uint8 op_sbc (uint8 x, uint8 y); -uint16 op_subw(uint16 x, uint16 y); -uint8 op_asl (uint8 x); -uint8 op_lsr (uint8 x); -uint8 op_rol (uint8 x); -uint8 op_ror (uint8 x); diff --git a/bsnes/snes/alt/smp/core/generate b/bsnes/snes/alt/smp/core/generate deleted file mode 100755 index ab6b9a6748d79e1a661e452b5ca4a709ef52d716..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48511 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 diff --git a/bsnes/snes/alt/smp/smp.cpp b/bsnes/snes/alt/smp/smp.cpp index 08a67ef0..a309db05 100755 --- a/bsnes/snes/alt/smp/smp.cpp +++ b/bsnes/snes/alt/smp/smp.cpp @@ -1,4 +1,4 @@ -#define CYCLE_ACCURATE +//#define CYCLE_ACCURATE #include diff --git a/bsnes/snes/alt/smp/smp.hpp b/bsnes/snes/alt/smp/smp.hpp index e9e6b28b..a7c14741 100755 --- a/bsnes/snes/alt/smp/smp.hpp +++ b/bsnes/snes/alt/smp/smp.hpp @@ -21,8 +21,7 @@ public: SMP(); ~SMP(); - #include "core.hpp" - +//private: struct Flags { bool n, v, p, b, h, i, z, c; @@ -75,12 +74,39 @@ public: uint8 stage2_ticks; uint8 stage3_ticks; + void tick(); void tick(unsigned clocks); }; Timer<128> timer0; Timer<128> timer1; Timer< 16> timer2; + + void tick(); + alwaysinline void op_io(); + debugvirtual alwaysinline uint8 op_read(uint16 addr); + debugvirtual alwaysinline void op_write(uint16 addr, uint8 data); + debugvirtual alwaysinline void op_step(); + static const unsigned cycle_count_table[256]; + uint64 cycle_table_cpu[256]; + unsigned cycle_table_dsp[256]; + uint64 cycle_step_cpu; + + uint8 op_adc (uint8 x, uint8 y); + uint16 op_addw(uint16 x, uint16 y); + uint8 op_and (uint8 x, uint8 y); + uint8 op_cmp (uint8 x, uint8 y); + uint16 op_cmpw(uint16 x, uint16 y); + uint8 op_eor (uint8 x, uint8 y); + uint8 op_inc (uint8 x); + uint8 op_dec (uint8 x); + uint8 op_or (uint8 x, uint8 y); + uint8 op_sbc (uint8 x, uint8 y); + uint16 op_subw(uint16 x, uint16 y); + uint8 op_asl (uint8 x); + uint8 op_lsr (uint8 x); + uint8 op_rol (uint8 x); + uint8 op_ror (uint8 x); }; #if defined(DEBUGGER) diff --git a/bsnes/snes/alt/smp/timing.cpp b/bsnes/snes/alt/smp/timing.cpp index f01adb3f..d278f6f4 100755 --- a/bsnes/snes/alt/smp/timing.cpp +++ b/bsnes/snes/alt/smp/timing.cpp @@ -1,3 +1,16 @@ +template +void SMP::Timer::tick() { + if(++stage1_ticks < cycle_frequency) return; + + stage1_ticks = 0; + if(enable == false) return; + + if(++stage2_ticks != target) return; + + stage2_ticks = 0; + stage3_ticks = (stage3_ticks + 1) & 15; +} + template void SMP::Timer::tick(unsigned clocks) { stage1_ticks += clocks; @@ -6,10 +19,8 @@ void SMP::Timer::tick(unsigned clocks) { stage1_ticks -= cycle_frequency; if(enable == false) return; - stage2_ticks++; - if(stage2_ticks != target) return; + if(++stage2_ticks != target) return; stage2_ticks = 0; - stage3_ticks++; - stage3_ticks &= 15; + stage3_ticks = (stage3_ticks + 1) & 15; } diff --git a/bsnes/snes/smp/core/memory.hpp b/bsnes/snes/smp/core/memory.hpp index 9af32956..4b7afba0 100755 --- a/bsnes/snes/smp/core/memory.hpp +++ b/bsnes/snes/smp/core/memory.hpp @@ -2,22 +2,14 @@ alwaysinline uint8_t op_readpc() { return op_read(regs.pc++); } -alwaysinline uint8_t op_readstack() { +alwaysinline uint8_t op_readsp() { return op_read(0x0100 | ++regs.sp); } -alwaysinline void op_writestack(uint8_t data) { +alwaysinline void op_writesp(uint8_t data) { op_write(0x0100 | regs.sp--, data); } -alwaysinline uint8_t op_readaddr(uint16_t addr) { - return op_read(addr); -} - -alwaysinline void op_writeaddr(uint16_t addr, uint8_t data) { - op_write(addr, data); -} - alwaysinline uint8_t op_readdp(uint8_t addr) { return op_read(((unsigned)regs.p.p << 8) + addr); } diff --git a/bsnes/snes/smp/core/opcode_misc.cpp b/bsnes/snes/smp/core/opcode_misc.cpp index 0f4d4ce3..533c8f96 100755 --- a/bsnes/snes/smp/core/opcode_misc.cpp +++ b/bsnes/snes/smp/core/opcode_misc.cpp @@ -31,7 +31,7 @@ void SMPcore::op_daa() { if(regs.p.h || (regs.a & 15) > 0x09) { regs.a += 0x06; } - regs.p.n = !!(regs.a & 0x80); + regs.p.n = (regs.a & 0x80); regs.p.z = (regs.a == 0); } @@ -45,7 +45,7 @@ void SMPcore::op_das() { if(!regs.p.h || (regs.a & 15) > 0x09) { regs.a -= 0x06; } - regs.p.n = !!(regs.a & 0x80); + regs.p.n = (regs.a & 0x80); regs.p.z = (regs.a == 0); } @@ -76,25 +76,25 @@ template void SMPcore::op_setbit_dp() { template void SMPcore::op_push_reg() { op_io(); op_io(); - op_writestack(regs.r[n]); + op_writesp(regs.r[n]); } void SMPcore::op_push_p() { op_io(); op_io(); - op_writestack(regs.p); + op_writesp(regs.p); } template void SMPcore::op_pop_reg() { op_io(); op_io(); - regs.r[n] = op_readstack(); + regs.r[n] = op_readsp(); } void SMPcore::op_pop_p() { op_io(); op_io(); - regs.p = op_readstack(); + regs.p = op_readsp(); } void SMPcore::op_mul_ya() { @@ -110,7 +110,7 @@ void SMPcore::op_mul_ya() { regs.a = ya; regs.y = ya >> 8; //result is set based on y (high-byte) only - regs.p.n = !!(regs.y & 0x80); + regs.p.n = (regs.y & 0x80); regs.p.z = (regs.y == 0); } @@ -128,8 +128,8 @@ void SMPcore::op_div_ya_x() { 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)); + 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; @@ -141,7 +141,7 @@ void SMPcore::op_div_ya_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.n = (regs.a & 0x80); regs.p.z = (regs.a == 0); } diff --git a/bsnes/snes/smp/core/opcode_mov.cpp b/bsnes/snes/smp/core/opcode_mov.cpp index e21593c8..f1767855 100755 --- a/bsnes/snes/smp/core/opcode_mov.cpp +++ b/bsnes/snes/smp/core/opcode_mov.cpp @@ -51,7 +51,7 @@ template void SMPcore::op_mov_reg_dpr() { template void SMPcore::op_mov_reg_addr() { sp = op_readpc() << 0; sp |= op_readpc() << 8; - regs.r[n] = op_readaddr(sp); + regs.r[n] = op_read(sp); regs.p.n = (regs.r[n] & 0x80); regs.p.z = (regs.r[n] == 0); } @@ -60,7 +60,7 @@ template void SMPcore::op_mov_a_addrr() { sp = op_readpc() << 0; sp |= op_readpc() << 8; op_io(); - regs.a = op_readaddr(sp + regs.r[i]); + regs.a = op_read(sp + regs.r[i]); regs.p.n = (regs.a & 0x80); regs.p.z = (regs.a == 0); } @@ -70,7 +70,7 @@ void SMPcore::op_mov_a_idpx() { op_io(); sp = op_readdp(dp + 0) << 0; sp |= op_readdp(dp + 1) << 8; - regs.a = op_readaddr(sp); + regs.a = op_read(sp); regs.p.n = (regs.a & 0x80); regs.p.z = (regs.a == 0); } @@ -80,7 +80,7 @@ void SMPcore::op_mov_a_idpy() { op_io(); sp = op_readdp(dp + 0) << 0; sp |= op_readdp(dp + 1) << 8; - regs.a = op_readaddr(sp + regs.y); + regs.a = op_read(sp + regs.y); regs.p.n = (regs.a & 0x80); regs.p.z = (regs.a == 0); } @@ -128,8 +128,8 @@ template void SMPcore::op_mov_dpr_reg() { template void SMPcore::op_mov_addr_reg() { dp = op_readpc() << 0; dp |= op_readpc() << 8; - op_readaddr(dp); - op_writeaddr(dp, regs.r[n]); + op_read(dp); + op_write(dp, regs.r[n]); } template void SMPcore::op_mov_addrr_a() { @@ -137,8 +137,8 @@ template void SMPcore::op_mov_addrr_a() { dp |= op_readpc() << 8; op_io(); dp += regs.r[i]; - op_readaddr(dp); - op_writeaddr(dp, regs.a); + op_read(dp); + op_write(dp, regs.a); } void SMPcore::op_mov_idpx_a() { @@ -147,8 +147,8 @@ void SMPcore::op_mov_idpx_a() { sp += regs.x; dp = op_readdp(sp + 0) << 0; dp |= op_readdp(sp + 1) << 8; - op_readaddr(dp); - op_writeaddr(dp, regs.a); + op_read(dp); + op_write(dp, regs.a); } void SMPcore::op_mov_idpy_a() { @@ -157,8 +157,8 @@ void SMPcore::op_mov_idpy_a() { dp |= op_readdp(sp + 1) << 8; op_io(); dp += regs.y; - op_readaddr(dp); - op_writeaddr(dp, regs.a); + op_read(dp); + op_write(dp, regs.a); } void SMPcore::op_movw_ya_dp() { @@ -182,7 +182,7 @@ void SMPcore::op_mov1_c_bit() { sp |= op_readpc() << 8; bit = sp >> 13; sp &= 0x1fff; - rd = op_readaddr(sp); + rd = op_read(sp); regs.p.c = (rd & (1 << bit)); } @@ -191,10 +191,10 @@ void SMPcore::op_mov1_bit_c() { dp |= op_readpc() << 8; bit = dp >> 13; dp &= 0x1fff; - rd = op_readaddr(dp); + rd = op_read(dp); (regs.p.c) ? rd |= (1 << bit) : rd &= ~(1 << bit); op_io(); - op_writeaddr(dp, rd); + op_write(dp, rd); } #endif diff --git a/bsnes/snes/smp/core/opcode_pc.cpp b/bsnes/snes/smp/core/opcode_pc.cpp index b69d8416..727522c8 100755 --- a/bsnes/snes/smp/core/opcode_pc.cpp +++ b/bsnes/snes/smp/core/opcode_pc.cpp @@ -82,8 +82,8 @@ void SMPcore::op_jmp_iaddrx() { dp |= op_readpc() << 8; op_io(); dp += regs.x; - rd = op_readaddr(dp + 0) << 0; - rd |= op_readaddr(dp + 1) << 8; + rd = op_read(dp + 0) << 0; + rd |= op_read(dp + 1) << 8; regs.pc = rd; } @@ -93,8 +93,8 @@ void SMPcore::op_call() { op_io(); op_io(); op_io(); - op_writestack(regs.pc >> 8); - op_writestack(regs.pc >> 0); + op_writesp(regs.pc >> 8); + op_writesp(regs.pc >> 0); regs.pc = rd; } @@ -102,48 +102,48 @@ void SMPcore::op_pcall() { rd = op_readpc(); op_io(); op_io(); - op_writestack(regs.pc >> 8); - op_writestack(regs.pc >> 0); + op_writesp(regs.pc >> 8); + op_writesp(regs.pc >> 0); regs.pc = 0xff00 | rd; } template void SMPcore::op_tcall() { dp = 0xffde - (n << 1); - rd = op_readaddr(dp + 0) << 0; - rd |= op_readaddr(dp + 1) << 8; + rd = op_read(dp + 0) << 0; + rd |= op_read(dp + 1) << 8; op_io(); op_io(); op_io(); - op_writestack(regs.pc >> 8); - op_writestack(regs.pc >> 0); + op_writesp(regs.pc >> 8); + op_writesp(regs.pc >> 0); regs.pc = rd; } void SMPcore::op_brk() { - rd = op_readaddr(0xffde) << 0; - rd |= op_readaddr(0xffdf) << 8; + rd = op_read(0xffde) << 0; + rd |= op_read(0xffdf) << 8; op_io(); op_io(); - op_writestack(regs.pc >> 8); - op_writestack(regs.pc >> 0); - op_writestack(regs.p); + op_writesp(regs.pc >> 8); + op_writesp(regs.pc >> 0); + op_writesp(regs.p); regs.pc = rd; regs.p.b = 1; regs.p.i = 0; } void SMPcore::op_ret() { - rd = op_readstack() << 0; - rd |= op_readstack() << 8; + rd = op_readsp() << 0; + rd |= op_readsp() << 8; op_io(); op_io(); regs.pc = rd; } void SMPcore::op_reti() { - regs.p = op_readstack(); - rd = op_readstack() << 0; - rd |= op_readstack() << 8; + regs.p = op_readsp(); + rd = op_readsp() << 0; + rd |= op_readsp() << 8; op_io(); op_io(); regs.pc = rd; diff --git a/bsnes/snes/smp/core/opcode_read.cpp b/bsnes/snes/smp/core/opcode_read.cpp index 2058cff2..25a5bc06 100755 --- a/bsnes/snes/smp/core/opcode_read.cpp +++ b/bsnes/snes/smp/core/opcode_read.cpp @@ -32,7 +32,7 @@ template void SMPcore::op_read_reg_addr() { dp = op_readpc() << 0; dp |= op_readpc() << 8; - rd = op_readaddr(dp); + rd = op_read(dp); regs.r[n] = (this->*op)(regs.r[n], rd); } @@ -41,7 +41,7 @@ void SMPcore::op_read_a_addrr() { dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - rd = op_readaddr(dp + regs.r[i]); + rd = op_read(dp + regs.r[i]); regs.a = (this->*op)(regs.a, rd); } @@ -51,7 +51,7 @@ void SMPcore::op_read_a_idpx() { op_io(); sp = op_readdp(dp + 0) << 0; sp |= op_readdp(dp + 1) << 8; - rd = op_readaddr(sp); + rd = op_read(sp); regs.a = (this->*op)(regs.a, rd); } @@ -61,7 +61,7 @@ void SMPcore::op_read_a_idpy() { op_io(); sp = op_readdp(dp + 0) << 0; sp |= op_readdp(dp + 1) << 8; - rd = op_readaddr(sp + regs.y); + rd = op_read(sp + regs.y); regs.a = (this->*op)(regs.a, rd); } @@ -117,7 +117,7 @@ template void SMPcore::op_and1_bit() { dp |= op_readpc() << 8; bit = dp >> 13; dp &= 0x1fff; - rd = op_readaddr(dp); + rd = op_read(dp); regs.p.c = regs.p.c & ((bool)(rd & (1 << bit)) ^ op); } @@ -126,7 +126,7 @@ void SMPcore::op_eor1_bit() { dp |= op_readpc() << 8; bit = dp >> 13; dp &= 0x1fff; - rd = op_readaddr(dp); + rd = op_read(dp); op_io(); regs.p.c = regs.p.c ^ (bool)(rd & (1 << bit)); } @@ -136,9 +136,9 @@ void SMPcore::op_not1_bit() { dp |= op_readpc() << 8; bit = dp >> 13; dp &= 0x1fff; - rd = op_readaddr(dp); + rd = op_read(dp); rd ^= 1 << bit; - op_writeaddr(dp, rd); + op_write(dp, rd); } template void SMPcore::op_or1_bit() { @@ -146,7 +146,7 @@ template void SMPcore::op_or1_bit() { dp |= op_readpc() << 8; bit = dp >> 13; dp &= 0x1fff; - rd = op_readaddr(dp); + rd = op_read(dp); op_io(); regs.p.c = regs.p.c | ((bool)(rd & (1 << bit)) ^ op); } diff --git a/bsnes/snes/smp/core/opcode_rmw.cpp b/bsnes/snes/smp/core/opcode_rmw.cpp index 103bd2db..df59f490 100755 --- a/bsnes/snes/smp/core/opcode_rmw.cpp +++ b/bsnes/snes/smp/core/opcode_rmw.cpp @@ -27,20 +27,20 @@ template void SMPcore::op_adjust_addr() { dp = op_readpc() << 0; dp |= op_readpc() << 8; - rd = op_readaddr(dp); + rd = op_read(dp); rd = (this->*op)(rd); - op_writeaddr(dp, rd); + op_write(dp, rd); } template void SMPcore::op_adjust_addr_a() { dp = op_readpc() << 0; dp |= op_readpc() << 8; - rd = op_readaddr(dp); + rd = op_read(dp); regs.p.n = ((regs.a - rd) & 0x80); regs.p.z = ((regs.a - rd) == 0); - op_readaddr(dp); - op_writeaddr(dp, (op ? rd | regs.a : rd & ~regs.a)); + op_read(dp); + op_write(dp, (op ? rd | regs.a : rd & ~regs.a)); } template diff --git a/bsnes/snes/smp/memory/memory.cpp b/bsnes/snes/smp/memory/memory.cpp index 7cd880fb..d4bab14a 100755 --- a/bsnes/snes/smp/memory/memory.cpp +++ b/bsnes/snes/smp/memory/memory.cpp @@ -20,175 +20,162 @@ void SMP::port_write(uint2 port, uint8 data) { } alwaysinline uint8 SMP::op_busread(uint16 addr) { - uint8 r; - if((addr & 0xfff0) == 0x00f0) { //00f0-00ff - switch(addr) { - case 0xf0: { //TEST -- write-only register - r = 0x00; - } break; + if((addr & 0xfff0) != 0x00f0) return ram_read(addr); - case 0xf1: { //CONTROL -- write-only register - r = 0x00; - } break; + unsigned result; - case 0xf2: { //DSPADDR - r = status.dsp_addr; - } break; + switch(addr) { + case 0xf0: //TEST -- write-only register + return 0x00; - case 0xf3: { //DSPDATA - //0x80-0xff are read-only mirrors of 0x00-0x7f - r = dsp.read(status.dsp_addr & 0x7f); - } break; + case 0xf1: //CONTROL -- write-only register + return 0x00; - case 0xf4: //CPUIO0 - case 0xf5: //CPUIO1 - case 0xf6: //CPUIO2 - case 0xf7: { //CPUIO3 - synchronize_cpu(); - r = cpu.port_read(addr); - } break; + case 0xf2: //DSPADDR + return status.dsp_addr; - case 0xf8: { //RAM0 - r = status.ram00f8; - } break; + case 0xf3: //DSPDATA + //0x80-0xff are read-only mirrors of 0x00-0x7f + return dsp.read(status.dsp_addr & 0x7f); - case 0xf9: { //RAM1 - r = status.ram00f9; - } break; + case 0xf4: //CPUIO0 + case 0xf5: //CPUIO1 + case 0xf6: //CPUIO2 + case 0xf7: //CPUIO3 + synchronize_cpu(); + return cpu.port_read(addr); - case 0xfa: //T0TARGET - case 0xfb: //T1TARGET - case 0xfc: { //T2TARGET -- write-only registers - r = 0x00; - } break; + case 0xf8: //RAM0 + return status.ram00f8; - case 0xfd: { //T0OUT -- 4-bit counter value - r = timer0.stage3_ticks & 15; - timer0.stage3_ticks = 0; - } break; + case 0xf9: //RAM1 + return status.ram00f9; - case 0xfe: { //T1OUT -- 4-bit counter value - r = timer1.stage3_ticks & 15; - timer1.stage3_ticks = 0; - } break; + case 0xfa: //T0TARGET + case 0xfb: //T1TARGET + case 0xfc: //T2TARGET -- write-only registers + return 0x00; - case 0xff: { //T2OUT -- 4-bit counter value - r = timer2.stage3_ticks & 15; - timer2.stage3_ticks = 0; - } break; - } - } else { - r = ram_read(addr); + case 0xfd: //T0OUT -- 4-bit counter value + result = timer0.stage3_ticks & 15; + timer0.stage3_ticks = 0; + return result; + + case 0xfe: //T1OUT -- 4-bit counter value + result = timer1.stage3_ticks & 15; + timer1.stage3_ticks = 0; + return result; + + case 0xff: //T2OUT -- 4-bit counter value + result = timer2.stage3_ticks & 15; + timer2.stage3_ticks = 0; + return result; } - return r; + return 0x00; //never used, avoids compiler warning } alwaysinline void SMP::op_buswrite(uint16 addr, uint8 data) { - if((addr & 0xfff0) == 0x00f0) { //$00f0-00ff - switch(addr) { - case 0xf0: { //TEST - if(regs.p.p) break; //writes only valid when P flag is clear + ram_write(addr, data); //all writes, even to MMIO registers, appear on bus + if((addr & 0xfff0) != 0x00f0) return; - status.clock_speed = (data >> 6) & 3; - status.timer_speed = (data >> 4) & 3; - status.timers_enable = data & 0x08; - status.ram_disable = data & 0x04; - status.ram_writable = data & 0x02; - status.timers_disable = data & 0x01; + switch(addr) { + case 0xf0: //TEST + if(regs.p.p) break; //writes only valid when P flag is clear - status.timer_step = (1 << status.clock_speed) + (2 << status.timer_speed); + status.clock_speed = (data >> 6) & 3; + status.timer_speed = (data >> 4) & 3; + status.timers_enable = data & 0x08; + status.ram_disable = data & 0x04; + status.ram_writable = data & 0x02; + status.timers_disable = data & 0x01; - timer0.sync_stage1(); - timer1.sync_stage1(); - timer2.sync_stage1(); - } break; + status.timer_step = (1 << status.clock_speed) + (2 << status.timer_speed); - case 0xf1: { //CONTROL - status.iplrom_enable = data & 0x80; + timer0.synchronize_stage1(); + timer1.synchronize_stage1(); + timer2.synchronize_stage1(); + break; - if(data & 0x30) { - //one-time clearing of APU port read registers, - //emulated by simulating CPU writes of 0x00 - synchronize_cpu(); - if(data & 0x20) { - cpu.port_write(2, 0x00); - cpu.port_write(3, 0x00); - } - if(data & 0x10) { - cpu.port_write(0, 0x00); - cpu.port_write(1, 0x00); - } - } + case 0xf1: //CONTROL + status.iplrom_enable = data & 0x80; - //0->1 transistion resets timers - if(timer2.enable == false && (data & 0x04)) { - timer2.stage2_ticks = 0; - timer2.stage3_ticks = 0; - } - timer2.enable = data & 0x04; - - if(timer1.enable == false && (data & 0x02)) { - timer1.stage2_ticks = 0; - timer1.stage3_ticks = 0; - } - timer1.enable = data & 0x02; - - if(timer0.enable == false && (data & 0x01)) { - timer0.stage2_ticks = 0; - timer0.stage3_ticks = 0; - } - timer0.enable = data & 0x01; - } break; - - case 0xf2: { //DSPADDR - status.dsp_addr = data; - } break; - - case 0xf3: { //DSPDATA - //0x80-0xff are read-only mirrors of 0x00-0x7f - if(!(status.dsp_addr & 0x80)) { - dsp.write(status.dsp_addr & 0x7f, data); - } - } break; - - case 0xf4: //CPUIO0 - case 0xf5: //CPUIO1 - case 0xf6: //CPUIO2 - case 0xf7: { //CPUIO3 - synchronize_cpu(); - port_write(addr, data); - } break; - - case 0xf8: { //RAM0 - status.ram00f8 = data; - } break; - - case 0xf9: { //RAM1 - status.ram00f9 = data; - } break; - - case 0xfa: { //T0TARGET - timer0.target = data; - } break; - - case 0xfb: { //T1TARGET - timer1.target = data; - } break; - - case 0xfc: { //T2TARGET - timer2.target = data; - } break; - - case 0xfd: //T0OUT - case 0xfe: //T1OUT - case 0xff: { //T2OUT -- read-only registers - } break; + if(data & 0x30) { + //one-time clearing of APU port read registers, + //emulated by simulating CPU writes of 0x00 + synchronize_cpu(); + if(data & 0x20) { + cpu.port_write(2, 0x00); + cpu.port_write(3, 0x00); + } + if(data & 0x10) { + cpu.port_write(0, 0x00); + cpu.port_write(1, 0x00); + } } - } - //all writes, even to MMIO registers, appear on bus - ram_write(addr, data); + //0->1 transistion resets timers + if(timer2.enable == false && (data & 0x04)) { + timer2.stage2_ticks = 0; + timer2.stage3_ticks = 0; + } + timer2.enable = data & 0x04; + + if(timer1.enable == false && (data & 0x02)) { + timer1.stage2_ticks = 0; + timer1.stage3_ticks = 0; + } + timer1.enable = data & 0x02; + + if(timer0.enable == false && (data & 0x01)) { + timer0.stage2_ticks = 0; + timer0.stage3_ticks = 0; + } + timer0.enable = data & 0x01; + break; + + case 0xf2: //DSPADDR + status.dsp_addr = data; + break; + + case 0xf3: //DSPDATA + if(status.dsp_addr & 0x80) break; //0x80-0xff are read-only mirrors of 0x00-0x7f + dsp.write(status.dsp_addr & 0x7f, data); + break; + + case 0xf4: //CPUIO0 + case 0xf5: //CPUIO1 + case 0xf6: //CPUIO2 + case 0xf7: //CPUIO3 + synchronize_cpu(); + port_write(addr, data); + break; + + case 0xf8: //RAM0 + status.ram00f8 = data; + break; + + case 0xf9: //RAM1 + status.ram00f9 = data; + break; + + case 0xfa: //T0TARGET + timer0.target = data; + break; + + case 0xfb: //T1TARGET + timer1.target = data; + break; + + case 0xfc: //T2TARGET + timer2.target = data; + break; + + case 0xfd: //T0OUT + case 0xfe: //T1OUT + case 0xff: //T2OUT -- read-only registers + break; + } } void SMP::op_io() { diff --git a/bsnes/snes/smp/timing/timing.cpp b/bsnes/snes/smp/timing/timing.cpp index a69a7f3f..40374d1c 100755 --- a/bsnes/snes/smp/timing/timing.cpp +++ b/bsnes/snes/smp/timing/timing.cpp @@ -25,7 +25,7 @@ void SMP::cycle_edge() { } template -void SMP::sSMPTimer::tick() { +void SMP::Timer::tick() { //stage 0 increment stage0_ticks += smp.status.timer_step; if(stage0_ticks < timer_frequency) return; @@ -33,11 +33,11 @@ void SMP::sSMPTimer::tick() { //stage 1 increment stage1_ticks ^= 1; - sync_stage1(); + synchronize_stage1(); } -template -void SMP::sSMPTimer::sync_stage1() { +template +void SMP::Timer::synchronize_stage1() { bool new_line = stage1_ticks; if(smp.status.timers_enable == false) new_line = false; if(smp.status.timers_disable == true) new_line = false; @@ -48,13 +48,11 @@ void SMP::sSMPTimer::sync_stage1() { //stage 2 increment if(enable == false) return; - stage2_ticks++; - if(stage2_ticks != target) return; + if(++stage2_ticks != target) return; //stage 3 increment stage2_ticks = 0; stage3_ticks++; - stage3_ticks &= 15; } #endif diff --git a/bsnes/snes/smp/timing/timing.hpp b/bsnes/snes/smp/timing/timing.hpp index c87d5095..2c282455 100755 --- a/bsnes/snes/smp/timing/timing.hpp +++ b/bsnes/snes/smp/timing/timing.hpp @@ -1,21 +1,21 @@ template -class sSMPTimer { +class Timer { public: uint8 stage0_ticks; uint8 stage1_ticks; uint8 stage2_ticks; - uint8 stage3_ticks; + uint4 stage3_ticks; bool current_line; bool enable; uint8 target; void tick(); - void sync_stage1(); + void synchronize_stage1(); }; -sSMPTimer<192> timer0; -sSMPTimer<192> timer1; -sSMPTimer< 24> timer2; +Timer<192> timer0; +Timer<192> timer1; +Timer< 24> timer2; alwaysinline void add_clocks(unsigned clocks); alwaysinline void cycle_edge(); diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp index c5e0f41d..0cafa6c0 100755 --- a/bsnes/snes/snes.hpp +++ b/bsnes/snes/snes.hpp @@ -1,7 +1,7 @@ namespace SNES { namespace Info { static const char Name[] = "bsnes"; - static const char Version[] = "078.03"; + static const char Version[] = "078.04"; static const unsigned SerializerVersion = 20; } } diff --git a/bsnes/ui/general/file-browser.cpp b/bsnes/ui/general/file-browser.cpp index 6482cf1f..045e1dd1 100755 --- a/bsnes/ui/general/file-browser.cpp +++ b/bsnes/ui/general/file-browser.cpp @@ -6,10 +6,12 @@ void FileBrowser::create() { browseButton.setText("..."); upButton.setText(".."); + const unsigned sq = browseButton.minimumGeometry().height; + layout.setMargin(5); pathLayout.append(pathBox, ~0, 0, 5); - pathLayout.append(browseButton, 25, 25, 5); - pathLayout.append(upButton, 25, 25 ); + pathLayout.append(browseButton, sq, sq, 5); + pathLayout.append(upButton, sq, sq ); layout.append(pathLayout, 5); layout.append(contentsBox, ~0, ~0 ); append(layout); diff --git a/bsnes/ui/general/slot-loader.cpp b/bsnes/ui/general/slot-loader.cpp index db8174c5..93efc3f0 100755 --- a/bsnes/ui/general/slot-loader.cpp +++ b/bsnes/ui/general/slot-loader.cpp @@ -10,14 +10,16 @@ void SingleSlotLoader::create() { slotBrowse.setText("..."); okButton.setText("Ok"); + const unsigned sq = baseBrowse.minimumGeometry().height; + layout.setMargin(5); baseLayout.append(baseLabel, 40, 0, 5); baseLayout.append(basePath, ~0, 0, 5); - baseLayout.append(baseBrowse, 25, 25 ); + baseLayout.append(baseBrowse, sq, sq ); layout.append(baseLayout, 5); slotLayout.append(slotLabel, 40, 0, 5); slotLayout.append(slotPath, ~0, 0, 5); - slotLayout.append(slotBrowse, 25, 25 ); + slotLayout.append(slotBrowse, sq, sq ); layout.append(slotLayout, 5); controlLayout.append(spacer, ~0, 0 ); controlLayout.append(okButton, 80, 0 ); @@ -103,18 +105,20 @@ void DoubleSlotLoader::create() { slotBBrowse.setText("..."); okButton.setText("Ok"); + const unsigned sq = baseBrowse.minimumGeometry().height; + layout.setMargin(5); baseLayout.append(baseLabel, 40, 0, 5); baseLayout.append(basePath, ~0, 0, 5); - baseLayout.append(baseBrowse, 25, 25 ); + baseLayout.append(baseBrowse, sq, sq ); layout.append(baseLayout, 5); slotALayout.append(slotALabel, 40, 0, 5); slotALayout.append(slotAPath, ~0, 0, 5); - slotALayout.append(slotABrowse, 25, 25 ); + slotALayout.append(slotABrowse, sq, sq ); layout.append(slotALayout, 5); slotBLayout.append(slotBLabel, 40, 0, 5); slotBLayout.append(slotBPath, ~0, 0, 5); - slotBLayout.append(slotBBrowse, 25, 25 ); + slotBLayout.append(slotBBrowse, sq, sq ); layout.append(slotBLayout, 5); controlLayout.append(spacer, ~0, 0 ); controlLayout.append(okButton, 80, 0 );