From 4c9266d18f1e64463e78e69b45ea795fc0b49bd0 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Sat, 27 Jun 2015 12:38:47 +1000 Subject: [PATCH] Update to v094r33 release. byuu says: Small WIP, just fixes the timings for GSU multiply. However, the actual product may still be wrong when CLSR and MS0 are both set. Since I wasn't 'corrupting' the value in said case before, then this behavior can only be better than before. Turned the (cache,memory)_access_timing into functions that compute the values; and pulled "clockspeed" into GSU. Also, I'm thinking it might be kind of pointless to have clockspeed at all. Supposedly even the Mario Chip can run at 21.48MHz anyway. Enforcing 10.74MHz mode seems kind of silly. If we change it to just be a "default value for CLSR", then we can just inline the memory access tests without the need for the access_timing functions (literally just clsr?2:1 then) Slight compilation bug: go to processor/gsu/registers.hpp:33 and add reg16_t() = default; I missed it due to a partial recompile. Too lazy to upload another WIP just for that. Probably not worth doing much SuperFX testing just yet, as it looks like they're doing some other tests at the moment on NESdev. --- emulator/emulator.hpp | 2 +- processor/gsu/gsu.cpp | 47 ++-- processor/gsu/gsu.hpp | 205 ++++++++--------- processor/gsu/instructions.cpp | 208 +++++++++++------- processor/gsu/registers.hpp | 58 ++--- processor/gsu/serialization.cpp | 4 +- processor/gsu/table.cpp | 2 +- sfc/chip/superfx/bus/bus.cpp | 12 +- sfc/chip/superfx/bus/bus.hpp | 12 +- sfc/chip/superfx/core/core.cpp | 16 +- sfc/chip/superfx/core/core.hpp | 10 +- .../superfx/disassembler/disassembler.cpp | 10 +- .../superfx/disassembler/disassembler.hpp | 10 +- sfc/chip/superfx/memory/memory.cpp | 26 +-- sfc/chip/superfx/memory/memory.hpp | 19 +- sfc/chip/superfx/mmio/mmio.cpp | 6 +- sfc/chip/superfx/mmio/mmio.hpp | 4 +- sfc/chip/superfx/serialization.cpp | 7 +- sfc/chip/superfx/superfx.cpp | 16 +- sfc/chip/superfx/superfx.hpp | 23 +- sfc/chip/superfx/timing/timing.cpp | 47 +--- sfc/chip/superfx/timing/timing.hpp | 25 +-- 22 files changed, 403 insertions(+), 366 deletions(-) diff --git a/emulator/emulator.hpp b/emulator/emulator.hpp index efd5d2b9..8e27c495 100644 --- a/emulator/emulator.hpp +++ b/emulator/emulator.hpp @@ -8,7 +8,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "094.32"; + static const string Version = "094.33"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/processor/gsu/gsu.cpp b/processor/gsu/gsu.cpp index 01f36e62..ae9eb601 100644 --- a/processor/gsu/gsu.cpp +++ b/processor/gsu/gsu.cpp @@ -7,26 +7,41 @@ namespace Processor { #include "table.cpp" #include "serialization.cpp" -void GSU::power() { +//note: multiplication results *may* sometimes be invalid when both CLSR and MS0 are set +//the product of multiplication in this mode (21mhz + fast-multiply) has not been analyzed; +//however, the timing of this mode has been confirmed to work as specified below +auto GSU::cache_access_speed() -> unsigned { + if(clockmode == 1) return 2; + if(clockmode == 2) return 1; + return regs.clsr ? 1 : 2; } -void GSU::reset() { +auto GSU::memory_access_speed() -> unsigned { + if(clockmode == 1) return 6; + if(clockmode == 2) return 5; + return regs.clsr ? 5 : 6; +} + +auto GSU::power() -> void { +} + +auto GSU::reset() -> void { for(auto& r : regs.r) r = 0x0000; - regs.sfr = 0x0000; - regs.pbr = 0x00; - regs.rombr = 0x00; - regs.rambr = 0; - regs.cbr = 0x0000; - regs.scbr = 0x00; - regs.scmr = 0x00; - regs.colr = 0x00; - regs.por = 0x00; - regs.bramr = 0; - regs.vcr = 0x04; - regs.cfgr = 0x00; - regs.clsr = 0; + regs.sfr = 0x0000; + regs.pbr = 0x00; + regs.rombr = 0x00; + regs.rambr = 0; + regs.cbr = 0x0000; + regs.scbr = 0x00; + regs.scmr = 0x00; + regs.colr = 0x00; + regs.por = 0x00; + regs.bramr = 0; + regs.vcr = 0x04; + regs.cfgr = 0x00; + regs.clsr = 0; regs.pipeline = 0x01; //nop - regs.ramaddr = 0x0000; + regs.ramaddr = 0x0000; regs.reset(); } diff --git a/processor/gsu/gsu.hpp b/processor/gsu/gsu.hpp index f847f125..54b29770 100644 --- a/processor/gsu/gsu.hpp +++ b/processor/gsu/gsu.hpp @@ -4,113 +4,120 @@ namespace Processor { struct GSU { + unsigned clockmode; //0 = selectable; 1 = force 10.74mhz; 2 = force 21.48mhz #include "registers.hpp" - virtual void step(unsigned clocks) = 0; + virtual auto step(unsigned clocks) -> void = 0; - virtual void stop() = 0; - virtual uint8 color(uint8 source) = 0; - virtual void plot(uint8 x, uint8 y) = 0; - virtual uint8 rpix(uint8 x, uint8 y) = 0; + virtual auto stop() -> void = 0; + virtual auto color(uint8 source) -> uint8 = 0; + virtual auto plot(uint8 x, uint8 y) -> void = 0; + virtual auto rpix(uint8 x, uint8 y) -> uint8 = 0; - virtual uint8 pipe() = 0; - virtual void rombuffer_sync() = 0; - virtual uint8 rombuffer_read() = 0; - virtual void rambuffer_sync() = 0; - virtual uint8 rambuffer_read(uint16 addr) = 0; - virtual void rambuffer_write(uint16 addr, uint8 data) = 0; - virtual void cache_flush() = 0; + virtual auto pipe() -> uint8 = 0; + virtual auto rombuffer_sync() -> void = 0; + virtual auto rombuffer_read() -> uint8 = 0; + virtual auto rambuffer_sync() -> void = 0; + virtual auto rambuffer_read(uint16 addr) -> uint8 = 0; + virtual auto rambuffer_write(uint16 addr, uint8 data) -> void = 0; + virtual auto cache_flush() -> void = 0; - void power(); - void reset(); - void serialize(serializer&); + //gsu.cpp + auto cache_access_speed() -> unsigned; + auto memory_access_speed() -> unsigned; - //table.cpp - void (GSU::*opcode_table[1024])(); - void initialize_opcode_table(); + auto power() -> void; + auto reset() -> void; //instructions.cpp - template void op_adc_i(); - template void op_adc_r(); - template void op_add_i(); - template void op_add_r(); - void op_alt1(); - void op_alt2(); - void op_alt3(); - template void op_and_i(); - template void op_and_r(); - void op_asr(); - void op_bge(); - void op_bcc(); - void op_bcs(); - void op_beq(); - template void op_bic_i(); - template void op_bic_r(); - void op_blt(); - void op_bmi(); - void op_bne(); - void op_bpl(); - void op_bra(); - void op_bvc(); - void op_bvs(); - void op_cache(); - void op_cmode(); - template void op_cmp_r(); - void op_color(); - template void op_dec_r(); - void op_div2(); - void op_fmult(); - template void op_from_r(); - void op_getb(); - void op_getbl(); - void op_getbh(); - void op_getbs(); - void op_getc(); - void op_hib(); - template void op_ibt_r(); - template void op_inc_r(); - template void op_iwt_r(); - template void op_jmp_r(); - template void op_ldb_ir(); - template void op_ldw_ir(); - template void op_link(); - template void op_ljmp_r(); - template void op_lm_r(); - template void op_lms_r(); - void op_lmult(); - void op_lob(); - void op_loop(); - void op_lsr(); - void op_merge(); - template void op_mult_i(); - template void op_mult_r(); - void op_nop(); - void op_not(); - template void op_or_i(); - template void op_or_r(); - void op_plot(); - void op_ramb(); - void op_rol(); - void op_romb(); - void op_ror(); - void op_rpix(); - template void op_sbc_r(); - void op_sbk(); - void op_sex(); - template void op_sm_r(); - template void op_sms_r(); - template void op_stb_ir(); - void op_stop(); - template void op_stw_ir(); - template void op_sub_i(); - template void op_sub_r(); - void op_swap(); - template void op_to_r(); - template void op_umult_i(); - template void op_umult_r(); - template void op_with_r(); - template void op_xor_i(); - template void op_xor_r(); + template auto op_adc_i(); + template auto op_adc_r(); + template auto op_add_i(); + template auto op_add_r(); + auto op_alt1(); + auto op_alt2(); + auto op_alt3(); + template auto op_and_i(); + template auto op_and_r(); + auto op_asr(); + auto op_bge(); + auto op_bcc(); + auto op_bcs(); + auto op_beq(); + template auto op_bic_i(); + template auto op_bic_r(); + auto op_blt(); + auto op_bmi(); + auto op_bne(); + auto op_bpl(); + auto op_bra(); + auto op_bvc(); + auto op_bvs(); + auto op_cache(); + auto op_cmode(); + template auto op_cmp_r(); + auto op_color(); + template auto op_dec_r(); + auto op_div2(); + auto op_fmult(); + template auto op_from_r(); + auto op_getb(); + auto op_getbl(); + auto op_getbh(); + auto op_getbs(); + auto op_getc(); + auto op_hib(); + template auto op_ibt_r(); + template auto op_inc_r(); + template auto op_iwt_r(); + template auto op_jmp_r(); + template auto op_ldb_ir(); + template auto op_ldw_ir(); + template auto op_link(); + template auto op_ljmp_r(); + template auto op_lm_r(); + template auto op_lms_r(); + auto op_lmult(); + auto op_lob(); + auto op_loop(); + auto op_lsr(); + auto op_merge(); + template auto op_mult_i(); + template auto op_mult_r(); + auto op_nop(); + auto op_not(); + template auto op_or_i(); + template auto op_or_r(); + auto op_plot(); + auto op_ramb(); + auto op_rol(); + auto op_romb(); + auto op_ror(); + auto op_rpix(); + template auto op_sbc_r(); + auto op_sbk(); + auto op_sex(); + template auto op_sm_r(); + template auto op_sms_r(); + template auto op_stb_ir(); + auto op_stop(); + template auto op_stw_ir(); + template auto op_sub_i(); + template auto op_sub_r(); + auto op_swap(); + template auto op_to_r(); + template auto op_umult_i(); + template auto op_umult_r(); + template auto op_with_r(); + template auto op_xor_i(); + template auto op_xor_r(); + + //table.cpp + auto (GSU::*opcode_table[1024])() -> void; + auto initialize_opcode_table() -> void; + + //serialization.cpp + auto serialize(serializer&) -> void; }; } diff --git a/processor/gsu/instructions.cpp b/processor/gsu/instructions.cpp index d6b20631..aafe78de 100644 --- a/processor/gsu/instructions.cpp +++ b/processor/gsu/instructions.cpp @@ -1,5 +1,5 @@ //$00 stop -void GSU::op_stop() { +auto GSU::op_stop() { if(regs.cfgr.irq == 0) { regs.sfr.irq = 1; stop(); @@ -11,12 +11,12 @@ void GSU::op_stop() { } //$01 nop -void GSU::op_nop() { +auto GSU::op_nop() { regs.reset(); } //$02 cache -void GSU::op_cache() { +auto GSU::op_cache() { if(regs.cbr != (regs.r[15] & 0xfff0)) { regs.cbr = regs.r[15] & 0xfff0; cache_flush(); @@ -25,7 +25,7 @@ void GSU::op_cache() { } //$03 lsr -void GSU::op_lsr() { +auto GSU::op_lsr() { regs.sfr.cy = (regs.sr() & 1); regs.dr() = regs.sr() >> 1; regs.sfr.s = (regs.dr() & 0x8000); @@ -34,7 +34,7 @@ void GSU::op_lsr() { } //$04 rol -void GSU::op_rol() { +auto GSU::op_rol() { bool carry = (regs.sr() & 0x8000); regs.dr() = (regs.sr() << 1) | regs.sfr.cy; regs.sfr.s = (regs.dr() & 0x8000); @@ -44,73 +44,74 @@ void GSU::op_rol() { } //$05 bra e -void GSU::op_bra() { +auto GSU::op_bra() { regs.r[15] += (int8)pipe(); } //$06 blt e -void GSU::op_blt() { +auto GSU::op_blt() { int e = (int8)pipe(); if((regs.sfr.s ^ regs.sfr.ov) == 0) regs.r[15] += e; } //$07 bge e -void GSU::op_bge() { +auto GSU::op_bge() { int e = (int8)pipe(); if((regs.sfr.s ^ regs.sfr.ov) == 1) regs.r[15] += e; } //$08 bne e -void GSU::op_bne() { +auto GSU::op_bne() { int e = (int8)pipe(); if(regs.sfr.z == 0) regs.r[15] += e; } //$09 beq e -void GSU::op_beq() { +auto GSU::op_beq() { int e = (int8)pipe(); if(regs.sfr.z == 1) regs.r[15] += e; } //$0a bpl e -void GSU::op_bpl() { +auto GSU::op_bpl() { int e = (int8)pipe(); if(regs.sfr.s == 0) regs.r[15] += e; } //$0b bmi e -void GSU::op_bmi() { +auto GSU::op_bmi() { int e = (int8)pipe(); if(regs.sfr.s == 1) regs.r[15] += e; } //$0c bcc e -void GSU::op_bcc() { +auto GSU::op_bcc() { int e = (int8)pipe(); if(regs.sfr.cy == 0) regs.r[15] += e; } //$0d bcs e -void GSU::op_bcs() { +auto GSU::op_bcs() { int e = (int8)pipe(); if(regs.sfr.cy == 1) regs.r[15] += e; } //$0e bvc e -void GSU::op_bvc() { +auto GSU::op_bvc() { int e = (int8)pipe(); if(regs.sfr.ov == 0) regs.r[15] += e; } //$0f bvs e -void GSU::op_bvs() { +auto GSU::op_bvs() { int e = (int8)pipe(); if(regs.sfr.ov == 1) regs.r[15] += e; } //$10-1f(b0): to rN //$10-1f(b1): move rN -template void GSU::op_to_r() { +template +auto GSU::op_to_r() { if(regs.sfr.b == 0) { regs.dreg = n; } else { @@ -120,14 +121,16 @@ template void GSU::op_to_r() { } //$20-2f: with rN -template void GSU::op_with_r() { +template +auto GSU::op_with_r() { regs.sreg = n; regs.dreg = n; regs.sfr.b = 1; } //$30-3b(alt0): stw (rN) -template void GSU::op_stw_ir() { +template +auto GSU::op_stw_ir() { regs.ramaddr = regs.r[n]; rambuffer_write(regs.ramaddr ^ 0, regs.sr() >> 0); rambuffer_write(regs.ramaddr ^ 1, regs.sr() >> 8); @@ -135,14 +138,15 @@ template void GSU::op_stw_ir() { } //$30-3b(alt1): stb (rN) -template void GSU::op_stb_ir() { +template +auto GSU::op_stb_ir() { regs.ramaddr = regs.r[n]; rambuffer_write(regs.ramaddr, regs.sr()); regs.reset(); } //$3c loop -void GSU::op_loop() { +auto GSU::op_loop() { regs.r[12]--; regs.sfr.s = (regs.r[12] & 0x8000); regs.sfr.z = (regs.r[12] == 0); @@ -151,26 +155,27 @@ void GSU::op_loop() { } //$3d alt1 -void GSU::op_alt1() { +auto GSU::op_alt1() { regs.sfr.b = 0; regs.sfr.alt1 = 1; } //$3e alt2 -void GSU::op_alt2() { +auto GSU::op_alt2() { regs.sfr.b = 0; regs.sfr.alt2 = 1; } //$3f alt3 -void GSU::op_alt3() { +auto GSU::op_alt3() { regs.sfr.b = 0; regs.sfr.alt1 = 1; regs.sfr.alt2 = 1; } //$40-4b(alt0): ldw (rN) -template void GSU::op_ldw_ir() { +template +auto GSU::op_ldw_ir() { regs.ramaddr = regs.r[n]; uint16_t data; data = rambuffer_read(regs.ramaddr ^ 0) << 0; @@ -180,21 +185,22 @@ template void GSU::op_ldw_ir() { } //$40-4b(alt1): ldb (rN) -template void GSU::op_ldb_ir() { +template +auto GSU::op_ldb_ir() { regs.ramaddr = regs.r[n]; regs.dr() = rambuffer_read(regs.ramaddr); regs.reset(); } //$4c(alt0): plot -void GSU::op_plot() { +auto GSU::op_plot() { plot(regs.r[1], regs.r[2]); regs.r[1]++; regs.reset(); } //$4c(alt1): rpix -void GSU::op_rpix() { +auto GSU::op_rpix() { regs.dr() = rpix(regs.r[1], regs.r[2]); regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); @@ -202,7 +208,7 @@ void GSU::op_rpix() { } //$4d: swap -void GSU::op_swap() { +auto GSU::op_swap() { regs.dr() = (regs.sr() >> 8) | (regs.sr() << 8); regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); @@ -210,19 +216,19 @@ void GSU::op_swap() { } //$4e(alt0): color -void GSU::op_color() { +auto GSU::op_color() { regs.colr = color(regs.sr()); regs.reset(); } //$4e(alt1): cmode -void GSU::op_cmode() { +auto GSU::op_cmode() { regs.por = regs.sr(); regs.reset(); } //$4f: not -void GSU::op_not() { +auto GSU::op_not() { regs.dr() = ~regs.sr(); regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); @@ -230,7 +236,8 @@ void GSU::op_not() { } //$50-5f(alt0): add rN -template void GSU::op_add_r() { +template +auto GSU::op_add_r() { int r = regs.sr() + regs.r[n]; regs.sfr.ov = ~(regs.sr() ^ regs.r[n]) & (regs.r[n] ^ r) & 0x8000; regs.sfr.s = (r & 0x8000); @@ -241,7 +248,8 @@ template void GSU::op_add_r() { } //$50-5f(alt1): adc rN -template void GSU::op_adc_r() { +template +auto GSU::op_adc_r() { int r = regs.sr() + regs.r[n] + regs.sfr.cy; regs.sfr.ov = ~(regs.sr() ^ regs.r[n]) & (regs.r[n] ^ r) & 0x8000; regs.sfr.s = (r & 0x8000); @@ -252,7 +260,8 @@ template void GSU::op_adc_r() { } //$50-5f(alt2): add #N -template void GSU::op_add_i() { +template +auto GSU::op_add_i() { int r = regs.sr() + n; regs.sfr.ov = ~(regs.sr() ^ n) & (n ^ r) & 0x8000; regs.sfr.s = (r & 0x8000); @@ -263,7 +272,8 @@ template void GSU::op_add_i() { } //$50-5f(alt3): adc #N -template void GSU::op_adc_i() { +template +auto GSU::op_adc_i() { int r = regs.sr() + n + regs.sfr.cy; regs.sfr.ov = ~(regs.sr() ^ n) & (n ^ r) & 0x8000; regs.sfr.s = (r & 0x8000); @@ -274,7 +284,8 @@ template void GSU::op_adc_i() { } //$60-6f(alt0): sub rN -template void GSU::op_sub_r() { +template +auto GSU::op_sub_r() { int r = regs.sr() - regs.r[n]; regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000; regs.sfr.s = (r & 0x8000); @@ -285,7 +296,8 @@ template void GSU::op_sub_r() { } //$60-6f(alt1): sbc rN -template void GSU::op_sbc_r() { +template +auto GSU::op_sbc_r() { int r = regs.sr() - regs.r[n] - !regs.sfr.cy; regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000; regs.sfr.s = (r & 0x8000); @@ -296,7 +308,8 @@ template void GSU::op_sbc_r() { } //$60-6f(alt2): sub #N -template void GSU::op_sub_i() { +template +auto GSU::op_sub_i() { int r = regs.sr() - n; regs.sfr.ov = (regs.sr() ^ n) & (regs.sr() ^ r) & 0x8000; regs.sfr.s = (r & 0x8000); @@ -307,7 +320,8 @@ template void GSU::op_sub_i() { } //$60-6f(alt3): cmp rN -template void GSU::op_cmp_r() { +template +auto GSU::op_cmp_r() { int r = regs.sr() - regs.r[n]; regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000; regs.sfr.s = (r & 0x8000); @@ -317,7 +331,7 @@ template void GSU::op_cmp_r() { } //$70: merge -void GSU::op_merge() { +auto GSU::op_merge() { regs.dr() = (regs.r[7] & 0xff00) | (regs.r[8] >> 8); regs.sfr.ov = (regs.dr() & 0xc0c0); regs.sfr.s = (regs.dr() & 0x8080); @@ -327,7 +341,8 @@ void GSU::op_merge() { } //$71-7f(alt0): and rN -template void GSU::op_and_r() { +template +auto GSU::op_and_r() { regs.dr() = regs.sr() & regs.r[n]; regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); @@ -335,7 +350,8 @@ template void GSU::op_and_r() { } //$71-7f(alt1): bic rN -template void GSU::op_bic_r() { +template +auto GSU::op_bic_r() { regs.dr() = regs.sr() & ~regs.r[n]; regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); @@ -343,7 +359,8 @@ template void GSU::op_bic_r() { } //$71-7f(alt2): and #N -template void GSU::op_and_i() { +template +auto GSU::op_and_i() { regs.dr() = regs.sr() & n; regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); @@ -351,7 +368,8 @@ template void GSU::op_and_i() { } //$71-7f(alt3): bic #N -template void GSU::op_bic_i() { +template +auto GSU::op_bic_i() { regs.dr() = regs.sr() & ~n; regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); @@ -359,56 +377,61 @@ template void GSU::op_bic_i() { } //$80-8f(alt0): mult rN -template void GSU::op_mult_r() { +template +auto GSU::op_mult_r() { regs.dr() = (int8)regs.sr() * (int8)regs.r[n]; regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); regs.reset(); - if(!regs.cfgr.ms0) step(2); + if(!regs.cfgr.ms0) step(cache_access_speed()); } //$80-8f(alt1): umult rN -template void GSU::op_umult_r() { +template +auto GSU::op_umult_r() { regs.dr() = (uint8)regs.sr() * (uint8)regs.r[n]; regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); regs.reset(); - if(!regs.cfgr.ms0) step(2); + if(!regs.cfgr.ms0) step(cache_access_speed()); } //$80-8f(alt2): mult #N -template void GSU::op_mult_i() { +template +auto GSU::op_mult_i() { regs.dr() = (int8)regs.sr() * (int8)n; regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); regs.reset(); - if(!regs.cfgr.ms0) step(2); + if(!regs.cfgr.ms0) step(cache_access_speed()); } //$80-8f(alt3): umult #N -template void GSU::op_umult_i() { +template +auto GSU::op_umult_i() { regs.dr() = (uint8)regs.sr() * (uint8)n; regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); regs.reset(); - if(!regs.cfgr.ms0) step(2); + if(!regs.cfgr.ms0) step(cache_access_speed()); } //$90: sbk -void GSU::op_sbk() { +auto GSU::op_sbk() { rambuffer_write(regs.ramaddr ^ 0, regs.sr() >> 0); rambuffer_write(regs.ramaddr ^ 1, regs.sr() >> 8); regs.reset(); } //$91-94: link #N -template void GSU::op_link() { +template +auto GSU::op_link() { regs.r[11] = regs.r[15] + n; regs.reset(); } //$95: sex -void GSU::op_sex() { +auto GSU::op_sex() { regs.dr() = (int8)regs.sr(); regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); @@ -416,7 +439,7 @@ void GSU::op_sex() { } //$96(alt0): asr -void GSU::op_asr() { +auto GSU::op_asr() { regs.sfr.cy = (regs.sr() & 1); regs.dr() = (int16_t)regs.sr() >> 1; regs.sfr.s = (regs.dr() & 0x8000); @@ -425,7 +448,7 @@ void GSU::op_asr() { } //$96(alt1): div2 -void GSU::op_div2() { +auto GSU::op_div2() { regs.sfr.cy = (regs.sr() & 1); regs.dr() = ((int16_t)regs.sr() >> 1) + ((regs.sr() + 1) >> 16); regs.sfr.s = (regs.dr() & 0x8000); @@ -434,7 +457,7 @@ void GSU::op_div2() { } //$97: ror -void GSU::op_ror() { +auto GSU::op_ror() { bool carry = (regs.sr() & 1); regs.dr() = (regs.sfr.cy << 15) | (regs.sr() >> 1); regs.sfr.s = (regs.dr() & 0x8000); @@ -444,13 +467,15 @@ void GSU::op_ror() { } //$98-9d(alt0): jmp rN -template void GSU::op_jmp_r() { +template +auto GSU::op_jmp_r() { regs.r[15] = regs.r[n]; regs.reset(); } //$98-9d(alt1): ljmp rN -template void GSU::op_ljmp_r() { +template +auto GSU::op_ljmp_r() { regs.pbr = regs.r[n] & 0x7f; regs.r[15] = regs.sr(); regs.cbr = regs.r[15] & 0xfff0; @@ -459,7 +484,7 @@ template void GSU::op_ljmp_r() { } //$9e: lob -void GSU::op_lob() { +auto GSU::op_lob() { regs.dr() = regs.sr() & 0xff; regs.sfr.s = (regs.dr() & 0x80); regs.sfr.z = (regs.dr() == 0); @@ -467,7 +492,7 @@ void GSU::op_lob() { } //$9f(alt0): fmult -void GSU::op_fmult() { +auto GSU::op_fmult() { uint32_t result = (int16_t)regs.sr() * (int16_t)regs.r[6]; regs.dr() = result >> 16; regs.sfr.s = (regs.dr() & 0x8000); @@ -478,7 +503,7 @@ void GSU::op_fmult() { } //$9f(alt1): lmult -void GSU::op_lmult() { +auto GSU::op_lmult() { uint32_t result = (int16_t)regs.sr() * (int16_t)regs.r[6]; regs.r[4] = result; regs.dr() = result >> 16; @@ -490,13 +515,15 @@ void GSU::op_lmult() { } //$a0-af(alt0): ibt rN,#pp -template void GSU::op_ibt_r() { +template +auto GSU::op_ibt_r() { regs.r[n] = (int8)pipe(); regs.reset(); } //$a0-af(alt1): lms rN,(yy) -template void GSU::op_lms_r() { +template +auto GSU::op_lms_r() { regs.ramaddr = pipe() << 1; uint16_t data; data = rambuffer_read(regs.ramaddr ^ 0) << 0; @@ -506,7 +533,8 @@ template void GSU::op_lms_r() { } //$a0-af(alt2): sms (yy),rN -template void GSU::op_sms_r() { +template +auto GSU::op_sms_r() { regs.ramaddr = pipe() << 1; rambuffer_write(regs.ramaddr ^ 0, regs.r[n] >> 0); rambuffer_write(regs.ramaddr ^ 1, regs.r[n] >> 8); @@ -515,7 +543,8 @@ template void GSU::op_sms_r() { //$b0-bf(b0): from rN //$b0-bf(b1): moves rN -template void GSU::op_from_r() { +template +auto GSU::op_from_r() { if(regs.sfr.b == 0) { regs.sreg = n; } else { @@ -528,7 +557,7 @@ template void GSU::op_from_r() { } //$c0: hib -void GSU::op_hib() { +auto GSU::op_hib() { regs.dr() = regs.sr() >> 8; regs.sfr.s = (regs.dr() & 0x80); regs.sfr.z = (regs.dr() == 0); @@ -536,7 +565,8 @@ void GSU::op_hib() { } //$c1-cf(alt0): or rN -template void GSU::op_or_r() { +template +auto GSU::op_or_r() { regs.dr() = regs.sr() | regs.r[n]; regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); @@ -544,7 +574,8 @@ template void GSU::op_or_r() { } //$c1-cf(alt1): xor rN -template void GSU::op_xor_r() { +template +auto GSU::op_xor_r() { regs.dr() = regs.sr() ^ regs.r[n]; regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); @@ -552,7 +583,8 @@ template void GSU::op_xor_r() { } //$c1-cf(alt2): or #N -template void GSU::op_or_i() { +template +auto GSU::op_or_i() { regs.dr() = regs.sr() | n; regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); @@ -560,7 +592,8 @@ template void GSU::op_or_i() { } //$c1-cf(alt3): xor #N -template void GSU::op_xor_i() { +template +auto GSU::op_xor_i() { regs.dr() = regs.sr() ^ n; regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); @@ -568,7 +601,8 @@ template void GSU::op_xor_i() { } //$d0-de: inc rN -template void GSU::op_inc_r() { +template +auto GSU::op_inc_r() { regs.r[n]++; regs.sfr.s = (regs.r[n] & 0x8000); regs.sfr.z = (regs.r[n] == 0); @@ -576,27 +610,28 @@ template void GSU::op_inc_r() { } //$df(alt0): getc -void GSU::op_getc() { +auto GSU::op_getc() { regs.colr = color(rombuffer_read()); regs.reset(); } //$df(alt2): ramb -void GSU::op_ramb() { +auto GSU::op_ramb() { rambuffer_sync(); regs.rambr = regs.sr(); regs.reset(); } //$df(alt3): romb -void GSU::op_romb() { +auto GSU::op_romb() { rombuffer_sync(); regs.rombr = regs.sr() & 0x7f; regs.reset(); } //$e0-ee: dec rN -template void GSU::op_dec_r() { +template +auto GSU::op_dec_r() { regs.r[n]--; regs.sfr.s = (regs.r[n] & 0x8000); regs.sfr.z = (regs.r[n] == 0); @@ -604,31 +639,32 @@ template void GSU::op_dec_r() { } //$ef(alt0): getb -void GSU::op_getb() { +auto GSU::op_getb() { regs.dr() = rombuffer_read(); regs.reset(); } //$ef(alt1): getbh -void GSU::op_getbh() { +auto GSU::op_getbh() { regs.dr() = (rombuffer_read() << 8) | (regs.sr() & 0x00ff); regs.reset(); } //$ef(alt2): getbl -void GSU::op_getbl() { +auto GSU::op_getbl() { regs.dr() = (regs.sr() & 0xff00) | (rombuffer_read() << 0); regs.reset(); } //$ef(alt3): getbs -void GSU::op_getbs() { +auto GSU::op_getbs() { regs.dr() = (int8)rombuffer_read(); regs.reset(); } //$f0-ff(alt0): iwt rN,#xx -template void GSU::op_iwt_r() { +template +auto GSU::op_iwt_r() { uint16_t data; data = pipe() << 0; data |= pipe() << 8; @@ -637,7 +673,8 @@ template void GSU::op_iwt_r() { } //$f0-ff(alt1): lm rN,(xx) -template void GSU::op_lm_r() { +template +auto GSU::op_lm_r() { regs.ramaddr = pipe() << 0; regs.ramaddr |= pipe() << 8; uint16_t data; @@ -648,7 +685,8 @@ template void GSU::op_lm_r() { } //$f0-ff(alt2): sm (xx),rN -template void GSU::op_sm_r() { +template +auto GSU::op_sm_r() { regs.ramaddr = pipe() << 0; regs.ramaddr |= pipe() << 8; rambuffer_write(regs.ramaddr ^ 0, regs.r[n] >> 0); diff --git a/processor/gsu/registers.hpp b/processor/gsu/registers.hpp index 070bf729..fcff3d6f 100644 --- a/processor/gsu/registers.hpp +++ b/processor/gsu/registers.hpp @@ -1,34 +1,36 @@ //accepts a callback binding so r14 writes can trigger ROM buffering transparently struct reg16_t { - uint16 data; - function modify; + uint16 data = 0; + function void> modify; - inline operator unsigned() const { return data; } - inline uint16 assign(uint16 i) { + inline operator unsigned() const { + return data; + } + + inline auto assign(uint16 i) -> uint16 { if(modify) modify(i); else data = i; return data; } - inline unsigned operator++() { return assign(data + 1); } - inline unsigned operator--() { return assign(data - 1); } - inline unsigned operator++(int) { unsigned r = data; assign(data + 1); return r; } - inline unsigned operator--(int) { unsigned r = data; assign(data - 1); return r; } - inline unsigned operator = (unsigned i) { return assign(i); } - inline unsigned operator |= (unsigned i) { return assign(data | i); } - inline unsigned operator ^= (unsigned i) { return assign(data ^ i); } - inline unsigned operator &= (unsigned i) { return assign(data & i); } - inline unsigned operator <<= (unsigned i) { return assign(data << i); } - inline unsigned operator >>= (unsigned i) { return assign(data >> i); } - inline unsigned operator += (unsigned i) { return assign(data + i); } - inline unsigned operator -= (unsigned i) { return assign(data - i); } - inline unsigned operator *= (unsigned i) { return assign(data * i); } - inline unsigned operator /= (unsigned i) { return assign(data / i); } - inline unsigned operator %= (unsigned i) { return assign(data % i); } + inline auto operator++() { return assign(data + 1); } + inline auto operator--() { return assign(data - 1); } + inline auto operator++(int) { unsigned r = data; assign(data + 1); return r; } + inline auto operator--(int) { unsigned r = data; assign(data - 1); return r; } + inline auto operator = (unsigned i) { return assign(i); } + inline auto operator |= (unsigned i) { return assign(data | i); } + inline auto operator ^= (unsigned i) { return assign(data ^ i); } + inline auto operator &= (unsigned i) { return assign(data & i); } + inline auto operator <<= (unsigned i) { return assign(data << i); } + inline auto operator >>= (unsigned i) { return assign(data >> i); } + inline auto operator += (unsigned i) { return assign(data + i); } + inline auto operator -= (unsigned i) { return assign(data - i); } + inline auto operator *= (unsigned i) { return assign(data * i); } + inline auto operator /= (unsigned i) { return assign(data / i); } + inline auto operator %= (unsigned i) { return assign(data % i); } - inline unsigned operator = (const reg16_t& i) { return assign(i); } + inline auto operator = (const reg16_t& i) { return assign(i); } - reg16_t() : data(0) {} reg16_t(const reg16_t&) = delete; }; @@ -51,7 +53,7 @@ struct sfr_t { | (r << 6) | (g << 5) | (ov << 4) | (s << 3) | (cy << 2) | (z << 1); } - sfr_t& operator=(uint16_t data) { + auto& operator=(uint16_t data) { irq = data & 0x8000; b = data & 0x1000; ih = data & 0x0800; @@ -78,7 +80,7 @@ struct scmr_t { return ((ht >> 1) << 5) | (ron << 4) | (ran << 3) | ((ht & 1) << 2) | (md); } - scmr_t& operator=(uint8 data) { + auto& operator=(uint8 data) { ht = (bool)(data & 0x20) << 1; ht |= (bool)(data & 0x04) << 0; ron = data & 0x10; @@ -99,7 +101,7 @@ struct por_t { return (obj << 4) | (freezehigh << 3) | (highnibble << 2) | (dither << 1) | (transparent); } - por_t& operator=(uint8 data) { + auto& operator=(uint8 data) { obj = data & 0x10; freezehigh = data & 0x08; highnibble = data & 0x04; @@ -117,7 +119,7 @@ struct cfgr_t { return (irq << 7) | (ms0 << 5); } - cfgr_t& operator=(uint8 data) { + auto& operator=(uint8 data) { irq = data & 0x80; ms0 = data & 0x20; return *this; @@ -151,10 +153,10 @@ struct regs_t { uint8 ramdr; //RAM buffer data register unsigned sreg, dreg; - reg16_t& sr() { return r[sreg]; } //source register (from) - reg16_t& dr() { return r[dreg]; } //destination register (to) + auto& sr() { return r[sreg]; } //source register (from) + auto& dr() { return r[dreg]; } //destination register (to) - void reset() { + auto reset() -> void { sfr.b = 0; sfr.alt1 = 0; sfr.alt2 = 0; diff --git a/processor/gsu/serialization.cpp b/processor/gsu/serialization.cpp index 28ec16b6..169602cd 100644 --- a/processor/gsu/serialization.cpp +++ b/processor/gsu/serialization.cpp @@ -1,4 +1,6 @@ -void GSU::serialize(serializer& s) { +auto GSU::serialize(serializer& s) -> void { + s.integer(clockmode); + s.integer(regs.pipeline); s.integer(regs.ramaddr); diff --git a/processor/gsu/table.cpp b/processor/gsu/table.cpp index 7d3c96b9..2bc51f05 100644 --- a/processor/gsu/table.cpp +++ b/processor/gsu/table.cpp @@ -1,4 +1,4 @@ -void GSU::initialize_opcode_table() { +auto GSU::initialize_opcode_table() -> void { #define op4(id, name) \ op(id+ 0, name< 1>) op(id+ 1, name< 2>) op(id+ 2, name< 3>) op(id+ 3, name< 4>) diff --git a/sfc/chip/superfx/bus/bus.cpp b/sfc/chip/superfx/bus/bus.cpp index 7e3a34b5..d969a423 100644 --- a/sfc/chip/superfx/bus/bus.cpp +++ b/sfc/chip/superfx/bus/bus.cpp @@ -2,11 +2,11 @@ //ROM / RAM access from the S-CPU -unsigned SuperFX::CPUROM::size() const { +auto SuperFX::CPUROM::size() const -> unsigned { return superfx.rom.size(); } -uint8 SuperFX::CPUROM::read(unsigned addr) { +auto SuperFX::CPUROM::read(unsigned addr) -> uint8 { if(superfx.regs.sfr.g && superfx.regs.scmr.ron) { static const uint8_t data[16] = { 0x00, 0x01, 0x00, 0x01, 0x04, 0x01, 0x00, 0x01, @@ -17,20 +17,20 @@ uint8 SuperFX::CPUROM::read(unsigned addr) { return superfx.rom.read(addr); } -void SuperFX::CPUROM::write(unsigned addr, uint8 data) { +auto SuperFX::CPUROM::write(unsigned addr, uint8 data) -> void { superfx.rom.write(addr, data); } -unsigned SuperFX::CPURAM::size() const { +auto SuperFX::CPURAM::size() const -> unsigned { return superfx.ram.size(); } -uint8 SuperFX::CPURAM::read(unsigned addr) { +auto SuperFX::CPURAM::read(unsigned addr) -> uint8 { if(superfx.regs.sfr.g && superfx.regs.scmr.ran) return cpu.regs.mdr; return superfx.ram.read(addr); } -void SuperFX::CPURAM::write(unsigned addr, uint8 data) { +auto SuperFX::CPURAM::write(unsigned addr, uint8 data) -> void { superfx.ram.write(addr, data); } diff --git a/sfc/chip/superfx/bus/bus.hpp b/sfc/chip/superfx/bus/bus.hpp index ebf38aff..1c6f14da 100644 --- a/sfc/chip/superfx/bus/bus.hpp +++ b/sfc/chip/superfx/bus/bus.hpp @@ -1,11 +1,11 @@ struct CPUROM : Memory { - unsigned size() const; - uint8 read(unsigned); - void write(unsigned, uint8); + auto size() const -> unsigned; + auto read(unsigned) -> uint8; + auto write(unsigned, uint8) -> void; } cpurom; struct CPURAM : Memory { - unsigned size() const; - uint8 read(unsigned); - void write(unsigned, uint8); + auto size() const -> unsigned; + auto read(unsigned) -> uint8; + auto write(unsigned, uint8) -> void; } cpuram; diff --git a/sfc/chip/superfx/core/core.cpp b/sfc/chip/superfx/core/core.cpp index 61d74c66..66b136e9 100644 --- a/sfc/chip/superfx/core/core.cpp +++ b/sfc/chip/superfx/core/core.cpp @@ -1,16 +1,16 @@ #ifdef SUPERFX_CPP -void SuperFX::stop() { +auto SuperFX::stop() -> void { cpu.regs.irq = 1; } -uint8 SuperFX::color(uint8 source) { +auto SuperFX::color(uint8 source) -> uint8 { if(regs.por.highnibble) return (regs.colr & 0xf0) | (source >> 4); if(regs.por.freezehigh) return (regs.colr & 0xf0) | (source & 0x0f); return source; } -void SuperFX::plot(uint8 x, uint8 y) { +auto SuperFX::plot(uint8 x, uint8 y) -> void { uint8 color = regs.colr; if(regs.por.dither && regs.scmr.md != 3) { @@ -48,7 +48,7 @@ void SuperFX::plot(uint8 x, uint8 y) { } } -uint8 SuperFX::rpix(uint8 x, uint8 y) { +auto SuperFX::rpix(uint8 x, uint8 y) -> uint8 { pixelcache_flush(pixelcache[1]); pixelcache_flush(pixelcache[0]); @@ -66,14 +66,14 @@ uint8 SuperFX::rpix(uint8 x, uint8 y) { for(unsigned n = 0; n < bpp; n++) { unsigned byte = ((n >> 1) << 4) + (n & 1); // = [n]{ 0, 1, 16, 17, 32, 33, 48, 49 }; - step(memory_access_speed); + step(memory_access_speed()); data |= ((bus_read(addr + byte) >> x) & 1) << n; } return data; } -void SuperFX::pixelcache_flush(pixelcache_t& cache) { +auto SuperFX::pixelcache_flush(pixelcache_t& cache) -> void { if(cache.bitpend == 0x00) return; uint8 x = cache.offset << 3; @@ -94,11 +94,11 @@ void SuperFX::pixelcache_flush(pixelcache_t& cache) { uint8 data = 0x00; for(unsigned x = 0; x < 8; x++) data |= ((cache.data[x] >> n) & 1) << x; if(cache.bitpend != 0xff) { - step(memory_access_speed); + step(memory_access_speed()); data &= cache.bitpend; data |= bus_read(addr + byte) & ~cache.bitpend; } - step(memory_access_speed); + step(memory_access_speed()); bus_write(addr + byte, data); } diff --git a/sfc/chip/superfx/core/core.hpp b/sfc/chip/superfx/core/core.hpp index 26f69ecc..7254b437 100644 --- a/sfc/chip/superfx/core/core.hpp +++ b/sfc/chip/superfx/core/core.hpp @@ -1,5 +1,5 @@ -void stop(); -uint8 color(uint8 source); -void plot(uint8 x, uint8 y); -uint8 rpix(uint8 x, uint8 y); -void pixelcache_flush(pixelcache_t& cache); +auto stop() -> void; +auto color(uint8 source) -> uint8; +auto plot(uint8 x, uint8 y) -> void; +auto rpix(uint8 x, uint8 y) -> uint8; +auto pixelcache_flush(pixelcache_t& cache) -> void; diff --git a/sfc/chip/superfx/disassembler/disassembler.cpp b/sfc/chip/superfx/disassembler/disassembler.cpp index de173288..49308fc2 100644 --- a/sfc/chip/superfx/disassembler/disassembler.cpp +++ b/sfc/chip/superfx/disassembler/disassembler.cpp @@ -2,7 +2,7 @@ //TODO: this belongs in processor/gsu -void SuperFX::disassemble_opcode(char* output) { +auto SuperFX::disassemble_opcode(char* output) -> void { *output = 0; if(!regs.sfr.alt2) { @@ -41,7 +41,7 @@ void SuperFX::disassemble_opcode(char* output) { #define op1 bus_read((regs.pbr << 16) + regs.r[15] + 0) #define op2 bus_read((regs.pbr << 16) + regs.r[15] + 1) -void SuperFX::disassemble_alt0(char* output) { +auto SuperFX::disassemble_alt0(char* output) -> void { char t[256] = ""; switch(op0) { case (0x00): sprintf(t, "stop"); break; @@ -98,7 +98,7 @@ void SuperFX::disassemble_alt0(char* output) { strcat(output, t); } -void SuperFX::disassemble_alt1(char* output) { +auto SuperFX::disassemble_alt1(char* output) -> void { char t[256] = ""; switch(op0) { case (0x00): sprintf(t, "stop"); break; @@ -155,7 +155,7 @@ void SuperFX::disassemble_alt1(char* output) { strcat(output, t); } -void SuperFX::disassemble_alt2(char* output) { +auto SuperFX::disassemble_alt2(char* output) -> void { char t[256] = ""; switch(op0) { case (0x00): sprintf(t, "stop"); break; @@ -212,7 +212,7 @@ void SuperFX::disassemble_alt2(char* output) { strcat(output, t); } -void SuperFX::disassemble_alt3(char* output) { +auto SuperFX::disassemble_alt3(char* output) -> void { char t[256] = ""; switch(op0) { case (0x00): sprintf(t, "stop"); break; diff --git a/sfc/chip/superfx/disassembler/disassembler.hpp b/sfc/chip/superfx/disassembler/disassembler.hpp index d87fa6b8..23b025e8 100644 --- a/sfc/chip/superfx/disassembler/disassembler.hpp +++ b/sfc/chip/superfx/disassembler/disassembler.hpp @@ -1,5 +1,5 @@ -void disassemble_opcode(char* output); -void disassemble_alt0(char* output); -void disassemble_alt1(char* output); -void disassemble_alt2(char* output); -void disassemble_alt3(char* output); +auto disassemble_opcode(char* output) -> void; +auto disassemble_alt0(char* output) -> void; +auto disassemble_alt1(char* output) -> void; +auto disassemble_alt2(char* output) -> void; +auto disassemble_alt3(char* output) -> void; diff --git a/sfc/chip/superfx/memory/memory.cpp b/sfc/chip/superfx/memory/memory.cpp index a65e02f7..3a993872 100644 --- a/sfc/chip/superfx/memory/memory.cpp +++ b/sfc/chip/superfx/memory/memory.cpp @@ -1,6 +1,6 @@ #ifdef SUPERFX_CPP -uint8 SuperFX::bus_read(unsigned addr) { +auto SuperFX::bus_read(unsigned addr) -> uint8 { if((addr & 0xc00000) == 0x000000) { //$00-3f:0000-7fff, $00-3f:8000-ffff while(!regs.scmr.ron && scheduler.sync != Scheduler::SynchronizeMode::All) { step(6); @@ -26,7 +26,7 @@ uint8 SuperFX::bus_read(unsigned addr) { } } -void SuperFX::bus_write(unsigned addr, uint8 data) { +auto SuperFX::bus_write(unsigned addr, uint8 data) -> void { if((addr & 0xe00000) == 0x600000) { //$60-7f:0000-ffff while(!regs.scmr.ran && scheduler.sync != Scheduler::SynchronizeMode::All) { step(6); @@ -36,19 +36,19 @@ void SuperFX::bus_write(unsigned addr, uint8 data) { } } -uint8 SuperFX::op_read(uint16 addr) { +auto SuperFX::op_read(uint16 addr) -> uint8 { uint16 offset = addr - regs.cbr; if(offset < 512) { if(cache.valid[offset >> 4] == false) { unsigned dp = offset & 0xfff0; unsigned sp = (regs.pbr << 16) + ((regs.cbr + dp) & 0xfff0); for(unsigned n = 0; n < 16; n++) { - step(memory_access_speed); + step(memory_access_speed()); cache.buffer[dp++] = bus_read(sp++); } cache.valid[offset >> 4] = true; } else { - step(cache_access_speed); + step(cache_access_speed()); } return cache.buffer[offset]; } @@ -56,46 +56,46 @@ uint8 SuperFX::op_read(uint16 addr) { if(regs.pbr <= 0x5f) { //$[00-5f]:[0000-ffff] ROM rombuffer_sync(); - step(memory_access_speed); + step(memory_access_speed()); return bus_read((regs.pbr << 16) + addr); } else { //$[60-7f]:[0000-ffff] RAM rambuffer_sync(); - step(memory_access_speed); + step(memory_access_speed()); return bus_read((regs.pbr << 16) + addr); } } -uint8 SuperFX::peekpipe() { +auto SuperFX::peekpipe() -> uint8 { uint8 result = regs.pipeline; regs.pipeline = op_read(regs.r[15]); r15_modified = false; return result; } -uint8 SuperFX::pipe() { +auto SuperFX::pipe() -> uint8 { uint8 result = regs.pipeline; regs.pipeline = op_read(++regs.r[15]); r15_modified = false; return result; } -void SuperFX::cache_flush() { +auto SuperFX::cache_flush() -> void { for(unsigned n = 0; n < 32; n++) cache.valid[n] = false; } -uint8 SuperFX::cache_mmio_read(uint16 addr) { +auto SuperFX::cache_mmio_read(uint16 addr) -> uint8 { addr = (addr + regs.cbr) & 511; return cache.buffer[addr]; } -void SuperFX::cache_mmio_write(uint16 addr, uint8 data) { +auto SuperFX::cache_mmio_write(uint16 addr, uint8 data) -> void { addr = (addr + regs.cbr) & 511; cache.buffer[addr] = data; if((addr & 15) == 15) cache.valid[addr >> 4] = true; } -void SuperFX::memory_reset() { +auto SuperFX::memory_reset() -> void { rom_mask = rom.size() - 1; ram_mask = ram.size() - 1; diff --git a/sfc/chip/superfx/memory/memory.hpp b/sfc/chip/superfx/memory/memory.hpp index 2ff62857..2c4046f3 100644 --- a/sfc/chip/superfx/memory/memory.hpp +++ b/sfc/chip/superfx/memory/memory.hpp @@ -1,14 +1,15 @@ unsigned rom_mask; //rom_size - 1 unsigned ram_mask; //ram_size - 1 -uint8 bus_read(unsigned addr); -void bus_write(unsigned addr, uint8 data); -uint8 op_read(uint16 addr); -alwaysinline uint8 peekpipe(); -alwaysinline uint8 pipe(); +auto bus_read(unsigned addr) -> uint8; +auto bus_write(unsigned addr, uint8 data) -> void; -void cache_flush(); -uint8 cache_mmio_read(uint16 addr); -void cache_mmio_write(uint16 addr, uint8 data); +auto op_read(uint16 addr) -> uint8; +alwaysinline auto peekpipe() -> uint8; +alwaysinline auto pipe() -> uint8; -void memory_reset(); +auto cache_flush() -> void; +auto cache_mmio_read(uint16 addr) -> uint8; +auto cache_mmio_write(uint16 addr, uint8 data) -> void; + +auto memory_reset() -> void; diff --git a/sfc/chip/superfx/mmio/mmio.cpp b/sfc/chip/superfx/mmio/mmio.cpp index 71477f8c..a5d7c008 100644 --- a/sfc/chip/superfx/mmio/mmio.cpp +++ b/sfc/chip/superfx/mmio/mmio.cpp @@ -1,6 +1,6 @@ #ifdef SUPERFX_CPP -uint8 SuperFX::mmio_read(unsigned addr) { +auto SuperFX::mmio_read(unsigned addr) -> uint8 { cpu.synchronize_coprocessors(); addr &= 0xffff; @@ -52,7 +52,7 @@ uint8 SuperFX::mmio_read(unsigned addr) { return 0x00; } -void SuperFX::mmio_write(unsigned addr, uint8 data) { +auto SuperFX::mmio_write(unsigned addr, uint8 data) -> void { cpu.synchronize_coprocessors(); addr &= 0xffff; @@ -97,7 +97,6 @@ void SuperFX::mmio_write(unsigned addr, uint8 data) { case 0x3037: { regs.cfgr = data; - update_speed(); } break; case 0x3038: { @@ -106,7 +105,6 @@ void SuperFX::mmio_write(unsigned addr, uint8 data) { case 0x3039: { regs.clsr = data; - update_speed(); } break; case 0x303a: { diff --git a/sfc/chip/superfx/mmio/mmio.hpp b/sfc/chip/superfx/mmio/mmio.hpp index 08cc85a9..6d129b6b 100644 --- a/sfc/chip/superfx/mmio/mmio.hpp +++ b/sfc/chip/superfx/mmio/mmio.hpp @@ -1,2 +1,2 @@ -uint8 mmio_read(unsigned addr); -void mmio_write(unsigned addr, uint8 data); +auto mmio_read(unsigned addr) -> uint8; +auto mmio_write(unsigned addr, uint8 data) -> void; diff --git a/sfc/chip/superfx/serialization.cpp b/sfc/chip/superfx/serialization.cpp index 7d291a9f..edffca98 100644 --- a/sfc/chip/superfx/serialization.cpp +++ b/sfc/chip/superfx/serialization.cpp @@ -1,16 +1,11 @@ #ifdef SUPERFX_CPP -void SuperFX::serialize(serializer& s) { +auto SuperFX::serialize(serializer& s) -> void { GSU::serialize(s); Thread::serialize(s); s.array(ram.data(), ram.size()); - - s.integer(clockmode); s.integer(instruction_counter); - - s.integer(cache_access_speed); - s.integer(memory_access_speed); s.integer(r15_modified); } diff --git a/sfc/chip/superfx/superfx.cpp b/sfc/chip/superfx/superfx.cpp index 608beabb..fd2aa4a6 100644 --- a/sfc/chip/superfx/superfx.cpp +++ b/sfc/chip/superfx/superfx.cpp @@ -13,9 +13,11 @@ namespace SuperFamicom { SuperFX superfx; -void SuperFX::Enter() { superfx.enter(); } +auto SuperFX::Enter() -> void { + superfx.enter(); +} -void SuperFX::enter() { +auto SuperFX::enter() -> void { while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::All) { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); @@ -37,25 +39,25 @@ void SuperFX::enter() { } } -void SuperFX::init() { +auto SuperFX::init() -> void { initialize_opcode_table(); regs.r[14].modify = {&SuperFX::r14_modify, this}; regs.r[15].modify = {&SuperFX::r15_modify, this}; } -void SuperFX::load() { +auto SuperFX::load() -> void { } -void SuperFX::unload() { +auto SuperFX::unload() -> void { rom.reset(); ram.reset(); } -void SuperFX::power() { +auto SuperFX::power() -> void { GSU::power(); } -void SuperFX::reset() { +auto SuperFX::reset() -> void { GSU::reset(); create(SuperFX::Enter, system.cpu_frequency()); instruction_counter = 0; diff --git a/sfc/chip/superfx/superfx.hpp b/sfc/chip/superfx/superfx.hpp index 7a9c00a8..96529a06 100644 --- a/sfc/chip/superfx/superfx.hpp +++ b/sfc/chip/superfx/superfx.hpp @@ -9,18 +9,21 @@ struct SuperFX : Processor::GSU, Coprocessor { #include "timing/timing.hpp" #include "disassembler/disassembler.hpp" - static void Enter(); - void enter(); - void init(); - void load(); - void unload(); - void power(); - void reset(); - void serialize(serializer&); + //superfx.cpp + static auto Enter() -> void; + + auto enter() -> void; + auto init() -> void; + auto load() -> void; + auto unload() -> void; + auto power() -> void; + auto reset() -> void; + + //serialization.cpp + auto serialize(serializer&) -> void; privileged: - unsigned clockmode = 0; //0 = selectable, 1 = force 10.74mhz, 2 = force 21.48mhz - unsigned instruction_counter; + unsigned instruction_counter = 0; }; extern SuperFX superfx; diff --git a/sfc/chip/superfx/timing/timing.cpp b/sfc/chip/superfx/timing/timing.cpp index d34ba4cd..ab68e79b 100644 --- a/sfc/chip/superfx/timing/timing.cpp +++ b/sfc/chip/superfx/timing/timing.cpp @@ -1,6 +1,6 @@ #ifdef SUPERFX_CPP -void SuperFX::step(unsigned clocks) { +auto SuperFX::step(unsigned clocks) -> void { if(regs.romcl) { regs.romcl -= min(clocks, regs.romcl); if(regs.romcl == 0) { @@ -20,70 +20,47 @@ void SuperFX::step(unsigned clocks) { synchronize_cpu(); } -void SuperFX::rombuffer_sync() { +auto SuperFX::rombuffer_sync() -> void { if(regs.romcl) step(regs.romcl); } -void SuperFX::rombuffer_update() { +auto SuperFX::rombuffer_update() -> void { regs.sfr.r = 1; - regs.romcl = memory_access_speed; + regs.romcl = memory_access_speed(); } -uint8 SuperFX::rombuffer_read() { +auto SuperFX::rombuffer_read() -> uint8 { rombuffer_sync(); return regs.romdr; } -void SuperFX::rambuffer_sync() { +auto SuperFX::rambuffer_sync() -> void { if(regs.ramcl) step(regs.ramcl); } -uint8 SuperFX::rambuffer_read(uint16 addr) { +auto SuperFX::rambuffer_read(uint16 addr) -> uint8 { rambuffer_sync(); return bus_read(0x700000 + (regs.rambr << 16) + addr); } -void SuperFX::rambuffer_write(uint16 addr, uint8 data) { +auto SuperFX::rambuffer_write(uint16 addr, uint8 data) -> void { rambuffer_sync(); - regs.ramcl = memory_access_speed; + regs.ramcl = memory_access_speed(); regs.ramar = addr; regs.ramdr = data; } -void SuperFX::r14_modify(uint16 data) { +auto SuperFX::r14_modify(uint16 data) -> void { regs.r[14].data = data; rombuffer_update(); } -void SuperFX::r15_modify(uint16 data) { +auto SuperFX::r15_modify(uint16 data) -> void { regs.r[15].data = data; r15_modified = true; } -void SuperFX::update_speed() { - //force SuperFX1 mode? - if(clockmode == 1) { - cache_access_speed = 2; - memory_access_speed = 6; - return; - } - - //force SuperFX2 mode? - if(clockmode == 2) { - cache_access_speed = 1; - memory_access_speed = 5; - regs.cfgr.ms0 = 0; //cannot use high-speed multiplication in 21MHz mode - return; - } - - //default: allow S-CPU to select mode - cache_access_speed = (regs.clsr ? 1 : 2); - memory_access_speed = (regs.clsr ? 5 : 6); - if(regs.clsr) regs.cfgr.ms0 = 0; //cannot use high-speed multiplication in 21MHz mode -} - -void SuperFX::timing_reset() { - update_speed(); +auto SuperFX::timing_reset() -> void { r15_modified = false; regs.romcl = 0; diff --git a/sfc/chip/superfx/timing/timing.hpp b/sfc/chip/superfx/timing/timing.hpp index 6d88fcd9..25cc195c 100644 --- a/sfc/chip/superfx/timing/timing.hpp +++ b/sfc/chip/superfx/timing/timing.hpp @@ -1,19 +1,16 @@ -unsigned cache_access_speed; -unsigned memory_access_speed; -bool r15_modified; +bool r15_modified = false; -void step(unsigned clocks); +auto step(unsigned clocks) -> void; -void rombuffer_sync(); -void rombuffer_update(); -uint8 rombuffer_read(); +auto rombuffer_sync() -> void; +auto rombuffer_update() -> void; +auto rombuffer_read() -> uint8; -void rambuffer_sync(); -uint8 rambuffer_read(uint16 addr); -void rambuffer_write(uint16 addr, uint8 data); +auto rambuffer_sync() -> void; +auto rambuffer_read(uint16 addr) -> uint8; +auto rambuffer_write(uint16 addr, uint8 data) -> void; -void r14_modify(uint16); -void r15_modify(uint16); +auto r14_modify(uint16) -> void; +auto r15_modify(uint16) -> void; -void update_speed(); -void timing_reset(); +auto timing_reset() -> void;