bsnes/higan/sfc/memory/memory.cpp
Tim Allen 82293c95ae Update to v099r14 release.
byuu says:

Changelog:
- (u)int(max,ptr) abbreviations removed; use _t suffix now [didn't feel
  like they were contributing enough to be worth it]
- cleaned up nall::integer,natural,real functionality
  - toInteger, toNatural, toReal for parsing strings to numbers
  - fromInteger, fromNatural, fromReal for creating strings from numbers
  - (string,Markup::Node,SQL-based-classes)::(integer,natural,real)
    left unchanged
  - template<typename T> numeral(T value, long padding, char padchar)
    -> string for print() formatting
    - deduces integer,natural,real based on T ... cast the value if you
      want to override
    - there still exists binary,octal,hex,pointer for explicit print()
      formatting
- lstring -> string_vector [but using lstring = string_vector; is
  declared]
  - would be nice to remove the using lstring eventually ... but that'd
    probably require 10,000 lines of changes >_>
- format -> string_format [no using here; format was too ambiguous]
- using integer = Integer<sizeof(int)*8>; and using natural =
  Natural<sizeof(uint)*8>; declared
  - for consistency with boolean. These three are meant for creating
    zero-initialized values implicitly (various uses)
- R65816::io() -> idle() and SPC700::io() -> idle() [more clear; frees
  up struct IO {} io; naming]
- SFC CPU, PPU, SMP use struct IO {} io; over struct (Status,Registers) {}
  (status,registers); now
  - still some CPU::Status status values ... they didn't really fit into
    IO functionality ... will have to think about this more
- SFC CPU, PPU, SMP now use step() exclusively instead of addClocks()
  calling into step()
- SFC CPU joypad1_bits, joypad2_bits were unused; killed them
- SFC PPU CGRAM moved into PPU::Screen; since nothing else uses it
- SFC PPU OAM moved into PPU::Object; since nothing else uses it
  - the raw uint8[544] array is gone. OAM::read() constructs values from
    the OAM::Object[512] table now
  - this avoids having to determine how we want to sub-divide the two
    OAM memory sections
  - this also eliminates the OAM::synchronize() functionality
- probably more I'm forgetting

The FPS fluctuations are driving me insane. This WIP went from 128fps to
137fps. Settled on 133.5fps for the final build. But nothing I changed
should have affected performance at all. This level of fluctuation makes
it damn near impossible to know whether I'm speeding things up or slowing
things down with changes.
2016-07-01 21:50:32 +10:00

103 lines
2.7 KiB
C++

#include <sfc/sfc.hpp>
namespace SuperFamicom {
Bus bus;
Bus::~Bus() {
if(lookup) delete[] lookup;
if(target) delete[] target;
}
auto Bus::reset() -> void {
for(auto id : range(256)) {
reader[id].reset();
writer[id].reset();
counter[id] = 0;
}
if(lookup) delete[] lookup;
if(target) delete[] target;
lookup = new uint8 [16 * 1024 * 1024]();
target = new uint32[16 * 1024 * 1024]();
reader[0] = [](uint24, uint8 data) -> uint8 { return data; };
writer[0] = [](uint24, uint8) -> void {};
}
auto Bus::map(
const function<uint8 (uint24, uint8)>& read,
const function<void (uint24, uint8)>& write,
const string& addr, uint size, uint base, uint mask
) -> void {
uint id = 1;
while(counter[id]) {
if(++id >= 256) return print("SFC error: bus map exhausted\n");
}
reader[id] = read;
writer[id] = write;
auto p = addr.split(":", 1L);
auto banks = p(0).split(",");
auto addrs = p(1).split(",");
for(auto& bank : banks) {
for(auto& addr : addrs) {
auto bankRange = bank.split("-", 1L);
auto addrRange = addr.split("-", 1L);
uint bankLo = bankRange(0).hex();
uint bankHi = bankRange(1, bankRange(0)).hex();
uint addrLo = addrRange(0).hex();
uint addrHi = addrRange(1, addrRange(0)).hex();
for(uint bank = bankLo; bank <= bankHi; bank++) {
for(uint addr = addrLo; addr <= addrHi; addr++) {
uint pid = lookup[bank << 16 | addr];
if(pid && --counter[pid] == 0) {
reader[pid].reset();
writer[pid].reset();
}
uint offset = reduce(bank << 16 | addr, mask);
if(size) offset = base + mirror(offset, size - base);
lookup[bank << 16 | addr] = id;
target[bank << 16 | addr] = offset;
counter[id]++;
}
}
}
}
}
auto Bus::unmap(const string& addr) -> void {
auto p = addr.split(":", 1L);
auto banks = p(0).split(",");
auto addrs = p(1).split(",");
for(auto& bank : banks) {
for(auto& addr : addrs) {
auto bankRange = bank.split("-", 1L);
auto addrRange = addr.split("-", 1L);
uint bankLo = bankRange(0).hex();
uint bankHi = bankRange(1, bankRange(0)).hex();
uint addrLo = addrRange(0).hex();
uint addrHi = addrRange(1, addrRange(1)).hex();
for(uint bank = bankLo; bank <= bankHi; bank++) {
for(uint addr = addrLo; addr <= addrHi; addr++) {
uint pid = lookup[bank << 16 | addr];
if(pid && --counter[pid] == 0) {
reader[pid].reset();
writer[pid].reset();
}
lookup[bank << 16 | addr] = 0;
target[bank << 16 | addr] = 0;
}
}
}
}
}
}