mirror of
https://github.com/libretro/bsnes-libretro.git
synced 2025-01-09 03:10:25 +00:00
e2ee6689a0
byuu says: Changelog: - emulation cores now refresh video from host thread instead of cothreads (fix AMD crash) - SFC: fixed another bug with leap year months in SharpRTC emulation - SFC: cleaned up camelCase on function names for armdsp,epsonrtc,hitachidsp,mcc,nss,sharprtc classes - GB: added MBC1M emulation (requires manually setting mapper=MBC1M in manifest.bml for now, sorry) - audio: implemented Emulator::Audio mixer and effects processor - audio: implemented Emulator::Stream interface - it is now possible to have more than two audio streams: eg SNES + SGB + MSU1 + Voicer-Kun (eventually) - audio: added reverb delay + reverb level settings; exposed balance configuration in UI - video: reworked palette generation to re-enable saturation, gamma, luminance adjustments - higan/emulator.cpp is gone since there was nothing left in it I know you guys are going to say the color adjust/balance/reverb stuff is pointless. And indeed it mostly is. But I like the idea of allowing some fun special effects and configurability that isn't system-wide. Note: there seems to be some kind of added audio lag in the SGB emulation now, and I don't really understand why. The code should be effectively identical to what I had before. The only main thing is that I'm sampling things to 48000hz instead of 32040hz before mixing. There's no point where I'm intentionally introducing added latency though. I'm kind of stumped, so if anyone wouldn't mind taking a look at it, it'd be much appreciated :/ I don't have an MSU1 test ROM, but the latency issue may affect MSU1 as well, and that would be very bad.
137 lines
3.4 KiB
C++
137 lines
3.4 KiB
C++
#include <sfc/sfc.hpp>
|
|
|
|
namespace SuperFamicom {
|
|
|
|
#include "serialization.cpp"
|
|
MCC mcc;
|
|
|
|
auto MCC::init() -> void {
|
|
}
|
|
|
|
auto MCC::load() -> void {
|
|
}
|
|
|
|
auto MCC::unload() -> void {
|
|
rom.reset();
|
|
ram.reset();
|
|
}
|
|
|
|
auto MCC::power() -> void {
|
|
}
|
|
|
|
auto MCC::reset() -> void {
|
|
for(auto n : range(16)) r[n] = 0x00;
|
|
r[0x07] = 0x80;
|
|
r[0x08] = 0x80;
|
|
commit();
|
|
}
|
|
|
|
auto MCC::memoryAccess(bool write, Memory& memory, uint24 addr, uint8 data) -> uint8 {
|
|
addr = bus.mirror(addr, memory.size());
|
|
if(!write) {
|
|
return memory.read(addr, data);
|
|
} else {
|
|
memory.write(addr, data);
|
|
}
|
|
}
|
|
|
|
//map address=00-3f,80-bf:8000-ffff mask=0x408000
|
|
//map address=40-7d,c0-ff:0000-ffff
|
|
auto MCC::mcuAccess(bool write, uint24 addr, uint8 data) -> uint8 {
|
|
if(addr < 0x400000) {
|
|
//note: manifest maps 00-3f,80-bf:8000-ffff mask=0x408000 => 00-3f:0000-ffff
|
|
//the intention is consistency in pre-decoding as much as possible
|
|
//however, the MCC code is intended to be rewritten; and is too convoluted
|
|
//so for right now, I'm simply transforming it back to its original state
|
|
//this is very wasteful; but will be addressed once things are rewritten
|
|
addr = ((addr & 0x200000) << 2) | ((addr & 0x1f8000) << 1) | 0x8000 | (addr & 0x7fff);
|
|
}
|
|
|
|
if((addr & 0xe08000) == 0x008000) { //$00-1f:8000-ffff
|
|
if(r07 == 1) {
|
|
addr = ((addr & 0x1f0000) >> 1) | (addr & 0x7fff);
|
|
return memoryAccess(write, rom, addr, data);
|
|
}
|
|
}
|
|
|
|
if((addr & 0xe08000) == 0x808000) { //$80-9f:8000-ffff
|
|
if(r08 == 1) {
|
|
addr = ((addr & 0x1f0000) >> 1) | (addr & 0x7fff);
|
|
return memoryAccess(write, rom, addr, data);
|
|
}
|
|
}
|
|
|
|
if((addr & 0xf00000) == 0x400000) { //$40-4f:0000-ffff
|
|
if(r05 == 0) return memoryAccess(write, ram, addr & 0x0fffff, data);
|
|
}
|
|
|
|
if((addr & 0xf00000) == 0x500000) { //$50-5f:0000-ffff
|
|
if(r06 == 0) return memoryAccess(write, ram, addr & 0x0fffff, data);
|
|
}
|
|
|
|
if((addr & 0xf00000) == 0x600000) { //$60-6f:0000-ffff
|
|
if(r03 == 1) return memoryAccess(write, ram, addr & 0x0fffff, data);
|
|
}
|
|
|
|
if((addr & 0xf80000) == 0x700000) { //$70-77:0000-ffff
|
|
return memoryAccess(write, ram, addr & 0x07ffff, data);
|
|
}
|
|
|
|
if(((addr & 0x408000) == 0x008000) //$00-3f,80-bf:8000-ffff
|
|
|| ((addr & 0x400000) == 0x400000) //$40-7f,c0-ff:0000-ffff
|
|
) {
|
|
if(r02 == 0) addr = ((addr & 0x7f0000) >> 1) | (addr & 0x7fff);
|
|
Memory& memory = (r01 == 0 ? (Memory&)bsmemory : (Memory&)ram);
|
|
return memoryAccess(write, memory, addr & 0x7fffff, data);
|
|
}
|
|
|
|
return 0x00;
|
|
}
|
|
|
|
auto MCC::mcuRead(uint24 addr, uint8 data) -> uint8 {
|
|
return mcuAccess(false, addr, data);
|
|
}
|
|
|
|
auto MCC::mcuWrite(uint24 addr, uint8 data) -> void {
|
|
mcuAccess(true, addr, data);
|
|
}
|
|
|
|
auto MCC::read(uint24 addr, uint8 data) -> uint8 {
|
|
if((addr & 0xf0ffff) == 0x005000) { //$00-0f:5000
|
|
uint8 n = (addr >> 16) & 15;
|
|
return r[n];
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
auto MCC::write(uint24 addr, uint8 data) -> void {
|
|
if((addr & 0xf0ffff) == 0x005000) { //$00-0f:5000
|
|
uint8 n = (addr >> 16) & 15;
|
|
r[n] = data;
|
|
if(n == 0x0e && data & 0x80) commit();
|
|
return;
|
|
}
|
|
}
|
|
|
|
auto MCC::commit() -> void {
|
|
r00 = r[0x00] & 0x80;
|
|
r01 = r[0x01] & 0x80;
|
|
r02 = r[0x02] & 0x80;
|
|
r03 = r[0x03] & 0x80;
|
|
r04 = r[0x04] & 0x80;
|
|
r05 = r[0x05] & 0x80;
|
|
r06 = r[0x06] & 0x80;
|
|
r07 = r[0x07] & 0x80;
|
|
r08 = r[0x08] & 0x80;
|
|
r09 = r[0x09] & 0x80;
|
|
r0a = r[0x0a] & 0x80;
|
|
r0b = r[0x0b] & 0x80;
|
|
r0c = r[0x0c] & 0x80;
|
|
r0d = r[0x0d] & 0x80;
|
|
r0e = r[0x0e] & 0x80;
|
|
r0f = r[0x0f] & 0x80;
|
|
}
|
|
|
|
}
|