Update to v095r05 release.

byuu says:

Changelog:
- GBA: lots of emulation improvements
- PPU PRAM is 16-bits wide
- DMA masks &~1/Half, &~3/Word
- VRAM OBJ 8-bit writes are ignored
- OAM 8-bit writes are ignored
- BGnCNT unused bits are writable*
- BG(0,1)CNT can't set the d13
- BLDALPHA is readable (fixes Donkey Kong Country, etc)
- SNES: lots of code cleanups
- sfc/chip => sfc/coprocessor
- UI: save most recent controller selection

GBA test scores: 1552/1552, 37/38, 1020/1260

(* forgot to add the value to the read function, so endrift's I/O tests
for them will fail. Fixed locally.)

Note: SNES is the only system with multiple controller/expansion port
options, and as such is the only one with a "None" option. Because it's
shared by the controller and expansion port, it ends up sorted first in
the list. This means that on your first run, you'll need to go to Super
Famicom->Controller Port 1 and select "Gamepad", otherwise input won't
work.

Also note that changing the expansion port device requires loading a new
cart. Unlike controllers, you aren't meant to hotplug expansion port
devices.
This commit is contained in:
Tim Allen 2015-11-12 21:15:03 +11:00
parent d1ffd59c29
commit 6d9f43a37b
166 changed files with 913 additions and 1187 deletions

View File

@ -7,7 +7,7 @@ using namespace nall;
namespace Emulator {
static const string Name = "higan";
static const string Version = "095.04";
static const string Version = "095.05";
static const string Author = "byuu";
static const string License = "GPLv3";
static const string Website = "http://byuu.org/";

View File

@ -36,13 +36,19 @@ auto CPU::dma_exec(Registers::DMA& dma) -> void {
if(dma.run.source < 0x0200'0000) {
idle(); //cannot access BIOS
} else {
dma.data = bus_read(mode, dma.run.source);
uint32 addr = dma.run.source;
if(mode & Word) addr &= ~3;
if(mode & Half) addr &= ~1;
dma.data = bus_read(mode, addr);
}
if(dma.run.target < 0x0200'0000) {
idle(); //cannot access BIOS
} else {
bus_write(mode, dma.run.target, dma.data);
uint32 addr = dma.run.target;
if(mode & Word) addr &= ~3;
if(mode & Half) addr &= ~1;
bus_write(mode, addr, dma.data);
}
switch(dma.control.sourcemode) {

View File

@ -9,9 +9,9 @@ auto PPU::vram_read(unsigned mode, uint32 addr) -> uint32 {
return vram[addr + 0] << 0 | vram[addr + 1] << 8;
} else if(mode & Byte) {
return vram[addr];
} else {
throw;
}
return 0; //should never occur
}
auto PPU::vram_write(unsigned mode, uint32 addr, uint32 word) -> void {
@ -28,9 +28,13 @@ auto PPU::vram_write(unsigned mode, uint32 addr, uint32 word) -> void {
vram[addr + 0] = word >> 0;
vram[addr + 1] = word >> 8;
} else if(mode & Byte) {
//8-bit writes to OBJ section of VRAM are ignored
if(regs.control.bgmode <= 2 && addr >= 0x10000) return;
if(regs.control.bgmode <= 5 && addr >= 0x14000) return;
addr &= ~1;
vram[addr + 0] = word;
vram[addr + 1] = word;
vram[addr + 0] = (uint8)word;
vram[addr + 1] = (uint8)word;
}
}
@ -48,10 +52,11 @@ auto PPU::pram_write(unsigned mode, uint32 addr, uint32 word) -> void {
}
if(mode & Byte) {
word = (uint8)word;
return pram_write(Half, addr, word << 8 | word << 0);
}
pram[addr >> 1 & 511] = word & 0x7fff;
pram[addr >> 1 & 511] = (uint16)word;
}
auto PPU::oam_read(unsigned mode, uint32 addr) -> uint32 {
@ -105,9 +110,7 @@ auto PPU::oam_write(unsigned mode, uint32 addr, uint32 word) -> void {
return;
}
if(mode & Byte) {
return oam_write(Half, addr, word << 8 | word << 0);
}
if(mode & Byte) return; //8-bit writes to OAM are ignored
auto& obj = object[addr >> 3 & 127];
auto& par = objectparam[addr >> 5 & 31];
@ -147,14 +150,14 @@ auto PPU::oam_write(unsigned mode, uint32 addr, uint32 word) -> void {
}
static unsigned widths[] = {
static uint widths[] = {
8, 16, 32, 64,
16, 32, 32, 64,
8, 8, 16, 32,
8, 8, 8, 8, //invalid modes
};
static unsigned heights[] = {
static uint heights[] = {
8, 16, 32, 64,
8, 8, 16, 32,
16, 32, 32, 64,

View File

@ -37,6 +37,10 @@ uint8 PPU::read(uint32 addr) {
case 0x04000050: return regs.blend.control >> 0;
case 0x04000051: return regs.blend.control >> 8;
//BLDALPHA
case 0x04000052: return regs.blend.eva;
case 0x04000053: return regs.blend.evb;
}
return 0u;
@ -70,6 +74,7 @@ void PPU::write(uint32 addr, uint8 byte) {
case 0x0400000e: case 0x0400000f: {
auto& bg = regs.bg[(addr >> 1) & 3];
unsigned shift = (addr & 1) * 8;
if(addr == 0x04000009 || addr == 0x0400000b) byte &= 0xdf; //clear affine wrap for BG0,1
bg.control = (bg.control & ~(255 << shift)) | (byte << shift);
return;
}

View File

@ -73,6 +73,7 @@ PPU::Registers::BackgroundControl::operator uint16() const {
uint16 PPU::Registers::BackgroundControl::operator=(uint16 source) {
priority = source >> 0;
characterbaseblock = source >> 2;
unused = source >> 4;
mosaic = source >> 6;
colormode = source >> 7;
screenbaseblock = source >> 8;

View File

@ -38,6 +38,7 @@ struct Registers {
struct BackgroundControl {
uint2 priority;
uint2 characterbaseblock;
uint2 unused;
uint1 mosaic;
uint1 colormode;
uint5 screenbaseblock;

View File

@ -28,6 +28,7 @@ void PPU::serialize(serializer& s) {
for(auto& bg : regs.bg) {
s.integer(bg.control.priority);
s.integer(bg.control.characterbaseblock);
s.integer(bg.control.unused);
s.integer(bg.control.mosaic);
s.integer(bg.control.colormode);
s.integer(bg.control.screenbaseblock);

View File

@ -1,20 +1,20 @@
struct Pixel {
bool enable;
unsigned priority;
unsigned color;
bool enable;
uint2 priority;
uint15 color;
//objects only
bool translucent;
bool mosaic;
alwaysinline void write(bool e) { enable = e; }
alwaysinline void write(bool e, unsigned p, unsigned c) { enable = e; priority = p; color = c; }
alwaysinline void write(bool e, unsigned p, unsigned c, bool t, bool m) { enable = e; priority = p; color = c; translucent = t; mosaic = m; }
alwaysinline auto write(bool e) { enable = e; }
alwaysinline auto write(bool e, uint p, uint c) { enable = e; priority = p; color = c; }
alwaysinline auto write(bool e, uint p, uint c, bool t, bool m) { enable = e; priority = p; color = c; translucent = t; mosaic = m; }
} layer[6][240];
bool windowmask[3][240];
unsigned vmosaic[5];
unsigned hmosaic[5];
uint vmosaic[5];
uint hmosaic[5];
struct Object {
uint8 y;
@ -36,8 +36,8 @@ struct Object {
uint4 palette;
//ancillary data
unsigned width;
unsigned height;
uint width;
uint height;
} object[128];
struct ObjectParam {

View File

@ -56,6 +56,18 @@ struct Node {
children.append(node);
}
auto find(const string& path) -> maybe<Node&> {
auto p = path.split("/");
auto name = p.takeFirst();
for(auto& child : children) {
if(child.name == name) {
if(p.size() == 0) return child;
return child.find(p.merge("/"));
}
}
return nothing;
}
auto load(Markup::Node path) -> void {
for(auto& child : children) {
if(auto leaf = path[child.name]) {

View File

@ -1,32 +1,31 @@
#ifndef NALL_EMULATION_SUPER_FAMICOM_USART_HPP
#define NALL_EMULATION_SUPER_FAMICOM_USART_HPP
#include <nall/platform.hpp>
#include <nall/function.hpp>
#include <nall/nall.hpp>
#include <nall/serial.hpp>
#include <nall/stdint.hpp>
using namespace nall;
#include <signal.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/time.h>
#define usartproc dllexport
static nall::function<bool ()> usart_quit;
static nall::function<void (unsigned milliseconds)> usart_usleep;
static nall::function<bool ()> usart_readable;
static nall::function<uint8_t ()> usart_read;
static nall::function<bool ()> usart_writable;
static nall::function<void (uint8_t data)> usart_write;
static function<bool ()> usart_quit;
static function<void (uint milliseconds)> usart_usleep;
static function<bool ()> usart_readable;
static function<uint8 ()> usart_read;
static function<bool ()> usart_writable;
static function<void (uint8 data)> usart_write;
extern "C" usartproc void usart_init(
nall::function<bool ()> quit,
nall::function<void (unsigned milliseconds)> usleep,
nall::function<bool ()> readable,
nall::function<uint8_t ()> read,
nall::function<bool ()> writable,
nall::function<void (uint8_t data)> write
) {
extern "C" usartproc auto usart_init(
function<bool ()> quit,
function<void (uint milliseconds)> usleep,
function<bool ()> readable,
function<uint8 ()> read,
function<bool ()> writable,
function<void (uint8 data)> write
) -> void {
usart_quit = quit;
usart_usleep = usleep;
usart_readable = readable;
@ -35,69 +34,67 @@ extern "C" usartproc void usart_init(
usart_write = write;
}
extern "C" usartproc void usart_main(int, char**);
extern "C" usartproc auto usart_main(nall::lstring) -> void;
//
static nall::serial usart;
static serial usart;
static bool usart_is_virtual = true;
static bool usart_sigint = false;
static bool usart_virtual() {
static auto usart_virtual() -> bool {
return usart_is_virtual;
}
//
static bool usarthw_quit() {
static auto usarthw_quit() -> bool {
return usart_sigint;
}
static void usarthw_usleep(unsigned milliseconds) {
static auto usarthw_usleep(uint milliseconds) -> void {
usleep(milliseconds);
}
static bool usarthw_readable() {
static auto usarthw_readable() -> bool {
return usart.readable();
}
static uint8_t usarthw_read() {
static auto usarthw_read() -> uint8 {
while(true) {
uint8_t buffer[1];
signed length = usart.read((uint8_t*)&buffer, 1);
uint8 buffer[1];
int length = usart.read((uint8_t*)&buffer, 1);
if(length > 0) return buffer[0];
}
}
static bool usarthw_writable() {
static auto usarthw_writable() -> bool {
return usart.writable();
}
static void usarthw_write(uint8_t data) {
uint8_t buffer[1] = { data };
usart.write((uint8_t*)&buffer, 1);
static auto usarthw_write(uint8 data) -> void {
uint8 buffer[1] = {data};
usart.write((uint8*)&buffer, 1);
}
static void sigint(int) {
static auto sigint(int) -> void {
signal(SIGINT, SIG_DFL);
usart_sigint = true;
}
int main(int argc, char** argv) {
#include <nall/main.hpp>
auto nall::main(lstring args) -> void {
setpriority(PRIO_PROCESS, 0, -20); //requires superuser privileges; otherwise priority = +0
signal(SIGINT, sigint);
if(usart.open("/dev/ttyACM0", 57600, true) == false) {
printf("error: unable to open USART hardware device\n");
return 0;
if(!usart.open("/dev/ttyACM0", 57600, true)) {
return print("error: unable to open USART hardware device\n");
}
usart_is_virtual = false;
usart_init(usarthw_quit, usarthw_usleep, usarthw_readable, usarthw_read, usarthw_writable, usarthw_write);
usart_main(argc, argv);
usart_main(args);
usart.close();
return 0;
}
#endif

View File

@ -47,26 +47,26 @@ obj/sfc-ppu.o: $(sfcppu)/ppu.cpp $(call rwildcard,$(sfcppu)/)
obj/sfc-eboot.o: $(sfc)/expansion/eboot/eboot.cpp $(call rwildcard,$(sfc)/expansion/eboot/)
obj/sfc-satellaviewbase.o: $(sfc)/expansion/satellaview/satellaview.cpp $(call rwildcard,$(sfc)/expansion/satellaview/)
obj/sfc-icd2.o: $(sfc)/chip/icd2/icd2.cpp $(call rwildcard,$(sfc)/chip/icd2/)
obj/sfc-mcc.o: $(sfc)/chip/mcc/mcc.cpp $(call rwildcard,$(sfc)/chip/mcc/)
obj/sfc-nss.o: $(sfc)/chip/nss/nss.cpp $(call rwildcard,$(sfc)/chip/nss/)
obj/sfc-event.o: $(sfc)/chip/event/event.cpp $(call rwildcard,$(sfc)/chip/event/)
obj/sfc-icd2.o: $(sfc)/coprocessor/icd2/icd2.cpp $(call rwildcard,$(sfc)/coprocessor/icd2/)
obj/sfc-mcc.o: $(sfc)/coprocessor/mcc/mcc.cpp $(call rwildcard,$(sfc)/coprocessor/mcc/)
obj/sfc-nss.o: $(sfc)/coprocessor/nss/nss.cpp $(call rwildcard,$(sfc)/coprocessor/nss/)
obj/sfc-event.o: $(sfc)/coprocessor/event/event.cpp $(call rwildcard,$(sfc)/coprocessor/event/)
obj/sfc-sa1.o: $(sfc)/chip/sa1/sa1.cpp $(call rwildcard,$(sfc)/chip/sa1/)
obj/sfc-superfx.o: $(sfc)/chip/superfx/superfx.cpp $(call rwildcard,$(sfc)/chip/superfx/)
obj/sfc-sa1.o: $(sfc)/coprocessor/sa1/sa1.cpp $(call rwildcard,$(sfc)/coprocessor/sa1/)
obj/sfc-superfx.o: $(sfc)/coprocessor/superfx/superfx.cpp $(call rwildcard,$(sfc)/coprocessor/superfx/)
obj/sfc-armdsp.o: $(sfc)/chip/armdsp/armdsp.cpp $(call rwildcard,$(sfc)/chip/armdsp/)
obj/sfc-hitachidsp.o: $(sfc)/chip/hitachidsp/hitachidsp.cpp $(call rwildcard,$(sfc)/chip/hitachidsp/)
obj/sfc-necdsp.o: $(sfc)/chip/necdsp/necdsp.cpp $(call rwildcard,$(sfc)/chip/necdsp/)
obj/sfc-armdsp.o: $(sfc)/coprocessor/armdsp/armdsp.cpp $(call rwildcard,$(sfc)/coprocessor/armdsp/)
obj/sfc-hitachidsp.o: $(sfc)/coprocessor/hitachidsp/hitachidsp.cpp $(call rwildcard,$(sfc)/coprocessor/hitachidsp/)
obj/sfc-necdsp.o: $(sfc)/coprocessor/necdsp/necdsp.cpp $(call rwildcard,$(sfc)/coprocessor/necdsp/)
obj/sfc-epsonrtc.o: $(sfc)/chip/epsonrtc/epsonrtc.cpp $(call rwildcard,$(sfc)/chip/epsonrtc/)
obj/sfc-sharprtc.o: $(sfc)/chip/sharprtc/sharprtc.cpp $(call rwildcard,$(sfc)/chip/sharprtc/)
obj/sfc-epsonrtc.o: $(sfc)/coprocessor/epsonrtc/epsonrtc.cpp $(call rwildcard,$(sfc)/coprocessor/epsonrtc/)
obj/sfc-sharprtc.o: $(sfc)/coprocessor/sharprtc/sharprtc.cpp $(call rwildcard,$(sfc)/coprocessor/sharprtc/)
obj/sfc-spc7110.o: $(sfc)/chip/spc7110/spc7110.cpp $(call rwildcard,$(sfc)/chip/spc7110/)
obj/sfc-sdd1.o: $(sfc)/chip/sdd1/sdd1.cpp $(call rwildcard,$(sfc)/chip/sdd1/)
obj/sfc-obc1.o: $(sfc)/chip/obc1/obc1.cpp $(call rwildcard,$(sfc)/chip/obc1/)
obj/sfc-spc7110.o: $(sfc)/coprocessor/spc7110/spc7110.cpp $(call rwildcard,$(sfc)/coprocessor/spc7110/)
obj/sfc-sdd1.o: $(sfc)/coprocessor/sdd1/sdd1.cpp $(call rwildcard,$(sfc)/coprocessor/sdd1/)
obj/sfc-obc1.o: $(sfc)/coprocessor/obc1/obc1.cpp $(call rwildcard,$(sfc)/coprocessor/obc1/)
obj/sfc-msu1.o: $(sfc)/chip/msu1/msu1.cpp $(call rwildcard,$(sfc)/chip/msu1/)
obj/sfc-msu1.o: $(sfc)/coprocessor/msu1/msu1.cpp $(call rwildcard,$(sfc)/coprocessor/msu1/)
obj/sfc-satellaviewcart.o: $(sfc)/slot/satellaview/satellaview.cpp $(call rwildcard,$(sfc)/slot/satellaview/)
obj/sfc-sufamiturbo.o: $(sfc)/slot/sufamiturbo/sufamiturbo.cpp $(call rwildcard,$(sfc)/slot/sufamiturbo/)

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define CARTRIDGE_CPP
namespace SuperFamicom {
#include "markup.cpp"

View File

@ -1,5 +1,3 @@
#ifdef CARTRIDGE_CPP
Cartridge::Mapping::Mapping(SuperFamicom::Memory& memory) {
this->reader = {&SuperFamicom::Memory::read, &memory};
this->writer = {&SuperFamicom::Memory::write, &memory};
@ -548,5 +546,3 @@ auto Cartridge::parseMarkupMSU1(Markup::Node root) -> void {
}
}
}
#endif

View File

@ -1,7 +1,3 @@
#ifdef CARTRIDGE_CPP
auto Cartridge::serialize(serializer& s) -> void {
s.array(ram.data(), ram.size());
}
#endif

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define CHEAT_CPP
namespace SuperFamicom {
Cheat cheat;

View File

@ -1,33 +0,0 @@
struct Coprocessor : Thread {
alwaysinline auto step(unsigned clocks) -> void;
alwaysinline auto synchronize_cpu() -> void;
};
#include <sfc/chip/icd2/icd2.hpp>
#include <sfc/chip/mcc/mcc.hpp>
#include <sfc/chip/nss/nss.hpp>
#include <sfc/chip/event/event.hpp>
#include <sfc/chip/sa1/sa1.hpp>
#include <sfc/chip/superfx/superfx.hpp>
#include <sfc/chip/armdsp/armdsp.hpp>
#include <sfc/chip/hitachidsp/hitachidsp.hpp>
#include <sfc/chip/necdsp/necdsp.hpp>
#include <sfc/chip/epsonrtc/epsonrtc.hpp>
#include <sfc/chip/sharprtc/sharprtc.hpp>
#include <sfc/chip/spc7110/spc7110.hpp>
#include <sfc/chip/sdd1/sdd1.hpp>
#include <sfc/chip/obc1/obc1.hpp>
#include <sfc/chip/msu1/msu1.hpp>
auto Coprocessor::step(unsigned clocks) -> void {
clock += clocks * (uint64)cpu.frequency;
}
auto Coprocessor::synchronize_cpu() -> void {
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread);
}

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define CONTROLLER_CPP
namespace SuperFamicom {
#include "gamepad/gamepad.cpp"

View File

@ -1,5 +1,3 @@
#ifdef CONTROLLER_CPP
Gamepad::Gamepad(bool port) : Controller(port) {
latched = 0;
counter = 0;
@ -53,5 +51,3 @@ auto Gamepad::latch(bool data) -> void {
r = interface->inputPoll(port, id, R);
}
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef CONTROLLER_CPP
Justifier::Justifier(bool port, bool chained):
Controller(port),
chained(chained),
@ -128,5 +126,3 @@ auto Justifier::latch(bool data) -> void {
counter = 0;
if(latched == 0) active = !active; //toggle between both controllers, even when unchained
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef CONTROLLER_CPP
Mouse::Mouse(bool port) : Controller(port) {
latched = 0;
counter = 0;
@ -86,5 +84,3 @@ auto Mouse::latch(bool data) -> void {
x = min(127, x);
y = min(127, y);
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef CONTROLLER_CPP
Multitap::Multitap(bool port) : Controller(port) {
latched = 0;
counter1 = 0;
@ -37,5 +35,3 @@ auto Multitap::latch(bool data) -> void {
counter1 = 0;
counter2 = 0;
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef CONTROLLER_CPP
//The Super Scope is a light-gun: it detects the CRT beam cannon position,
//and latches the counters by toggling iobit. This only works on controller
//port 2, as iobit there is connected to the PPU H/V counter latch.
@ -119,5 +117,3 @@ auto SuperScope::latch(bool data) -> void {
latched = data;
counter = 0;
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef CONTROLLER_CPP
//Synchronous serial communications cable emulation
//Hardware:
@ -133,5 +131,3 @@ auto USART::latch(bool data) -> void {
latched = data;
counter = 0;
}
#endif

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define ARMDSP_CPP
namespace SuperFamicom {
#include "memory.cpp"
@ -49,7 +48,7 @@ void ArmDSP::step(unsigned clocks) {
//a0 ignored
uint8 ArmDSP::mmio_read(unsigned addr) {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
uint8 data = 0x00;
addr &= 0xff06;
@ -73,7 +72,7 @@ uint8 ArmDSP::mmio_read(unsigned addr) {
}
void ArmDSP::mmio_write(unsigned addr, uint8 data) {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
addr &= 0xff06;

View File

@ -1,5 +1,3 @@
#ifdef ARMDSP_CPP
//note: timings are completely unverified
//due to the ST018 chip design (on-die ROM), testing is nearly impossible
@ -98,5 +96,3 @@ void ArmDSP::bus_write(unsigned mode, uint32 addr, uint32 word) {
return;
}
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef ARMDSP_CPP
nall::vector<uint8> ArmDSP::firmware() {
nall::vector<uint8> buffer;
if(!cartridge.hasARMDSP()) return buffer;
@ -25,5 +23,3 @@ void ArmDSP::serialize(serializer& s) {
s.integer(bridge.ready);
s.integer(bridge.signal);
}
#endif

View File

@ -0,0 +1,33 @@
struct Coprocessor : Thread {
alwaysinline auto step(uint clocks) -> void;
alwaysinline auto synchronize_cpu() -> void;
};
#include <sfc/coprocessor/icd2/icd2.hpp>
#include <sfc/coprocessor/mcc/mcc.hpp>
#include <sfc/coprocessor/nss/nss.hpp>
#include <sfc/coprocessor/event/event.hpp>
#include <sfc/coprocessor/sa1/sa1.hpp>
#include <sfc/coprocessor/superfx/superfx.hpp>
#include <sfc/coprocessor/armdsp/armdsp.hpp>
#include <sfc/coprocessor/hitachidsp/hitachidsp.hpp>
#include <sfc/coprocessor/necdsp/necdsp.hpp>
#include <sfc/coprocessor/epsonrtc/epsonrtc.hpp>
#include <sfc/coprocessor/sharprtc/sharprtc.hpp>
#include <sfc/coprocessor/spc7110/spc7110.hpp>
#include <sfc/coprocessor/sdd1/sdd1.hpp>
#include <sfc/coprocessor/obc1/obc1.hpp>
#include <sfc/coprocessor/msu1/msu1.hpp>
auto Coprocessor::step(uint clocks) -> void {
clock += clocks * (uint64)cpu.frequency;
}
auto Coprocessor::synchronize_cpu() -> void {
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread);
}

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define EPSONRTC_CPP
namespace SuperFamicom {
#include "memory.cpp"
@ -145,7 +144,7 @@ void EpsonRTC::sync() {
}
uint8 EpsonRTC::read(unsigned addr) {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
addr &= 3;
if(addr == 0) {
@ -168,7 +167,7 @@ uint8 EpsonRTC::read(unsigned addr) {
}
void EpsonRTC::write(unsigned addr, uint8 data) {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
addr &= 3, data &= 15;
if(addr == 0) {

View File

@ -1,5 +1,3 @@
#ifdef EPSONRTC_CPP
void EpsonRTC::rtc_reset() {
state = State::Mode;
offset = 0;
@ -180,5 +178,3 @@ void EpsonRTC::save(uint8* data) {
timestamp >>= 8;
}
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef EPSONRTC_CPP
void EpsonRTC::serialize(serializer& s) {
Thread::serialize(s);
@ -53,5 +51,3 @@ void EpsonRTC::serialize(serializer& s) {
s.integer(atime);
s.integer(test);
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef EPSONRTC_CPP
void EpsonRTC::irq(uint2 period) {
if(stop || pause) return;
@ -182,5 +180,3 @@ void EpsonRTC::tick_year() {
}
}
}
#endif

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define EVENT_CPP
namespace SuperFamicom {
Event event;
@ -59,40 +58,6 @@ void Event::submitScore() {
data.append("mk:", mk[0], ",", mk[1], "\n");
data.append("ba:", ba[0], ",", ba[1], "\n");
}
/*lstring side = interface->server().split("@", 1L);
string username = side(0).split(":", 1L)(0);
string password = side(0).split(":", 1L)(1);
side(1).ltrim("http://", 1L);
string hostname = side(1).split("/", 1L)(0);
string hostpath = side(1).split("/", 1L)(1);
side = hostname.split(":", 1L);
hostname = side(0);
string hostport = side(1);
if(hostport.empty()) hostport = "80";
http server;
if(server.connect(hostname, decimal(hostport))) {
string content = {
"username:", username, "\n",
"password:", password, "\n",
"emulator:bsnes\n",
"sha256:", interface->sha256(), "\n",
"\n",
data
};
string packet = {
"POST /", hostpath, " HTTP/1.0\r\n",
"Host: ", hostname, "\r\n",
"Connection: close\r\n",
"Content-Type: application/octet-stream\r\n",
"Content-Length: ", content.length(), "\r\n",
"\r\n",
content
};
server.send(packet);
server.disconnect();
}*/
}
void Event::init() {

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define HITACHIDSP_CPP
namespace SuperFamicom {
#include "memory.cpp"

View File

@ -1,5 +1,3 @@
#ifdef HITACHIDSP_CPP
uint8 HitachiDSP::bus_read(uint24 addr) {
if((addr & 0x408000) == 0x008000) return bus.read(addr); //$00-3f,80-bf:6000-7fff
if((addr & 0xf88000) == 0x700000) return bus.read(addr); //$70-77:0000-7fff
@ -139,5 +137,3 @@ void HitachiDSP::dsp_write(unsigned addr, uint8 data) {
}
}
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef HITACHIDSP_CPP
vector<uint8> HitachiDSP::firmware() {
vector<uint8> buffer;
if(!cartridge.hasHitachiDSP()) return buffer;
@ -30,5 +28,3 @@ void HitachiDSP::serialize(serializer& s) {
s.integer(mmio.r1f52);
s.array(mmio.vector);
}
#endif

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define ICD2_CPP
namespace SuperFamicom {
#include "interface/interface.cpp"

View File

@ -1,5 +1,3 @@
#ifdef ICD2_CPP
void ICD2::lcdScanline() {
if(GameBoy::ppu.status.ly > 143) return; //Vblank
if((GameBoy::ppu.status.ly & 7) == 0) {
@ -122,5 +120,3 @@ int16_t ICD2::inputPoll(unsigned port, unsigned device, unsigned id) {
return 0;
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef ICD2_CPP
uint8 ICD2::read(unsigned addr) {
addr &= 0xffff;
@ -73,5 +71,3 @@ void ICD2::write(unsigned addr, uint8 data) {
if(addr == 0x6006) { r6006 = data; return; } //joypad 3
if(addr == 0x6007) { r6007 = data; return; } //joypad 4
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef ICD2_CPP
void ICD2::serialize(serializer& s) {
Thread::serialize(s);
GameBoy::system.serialize_all(s);
@ -32,5 +30,3 @@ void ICD2::serialize(serializer& s) {
s.integer(write_bank);
s.integer(write_addr);
}
#endif

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define MCC_CPP
namespace SuperFamicom {
#include "serialization.cpp"

View File

@ -1,8 +1,4 @@
#ifdef MCC_CPP
auto MCC::serialize(serializer& s) -> void {
s.array(ram.data(), ram.size());
s.array(psram.data(), psram.size());
}
#endif

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define MSU1_CPP
namespace SuperFamicom {
MSU1 msu1;
@ -125,7 +124,7 @@ auto MSU1::audioOpen() -> void {
}
auto MSU1::mmioRead(unsigned addr) -> uint8 {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
addr = 0x2000 | (addr & 7);
switch(addr) {
@ -151,7 +150,7 @@ auto MSU1::mmioRead(unsigned addr) -> uint8 {
}
auto MSU1::mmioWrite(unsigned addr, uint8 data) -> void {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
addr = 0x2000 | (addr & 7);
switch(addr) {

View File

@ -1,5 +1,3 @@
#ifdef MSU1_CPP
auto MSU1::serialize(serializer& s) -> void {
Thread::serialize(s);
@ -24,5 +22,3 @@ auto MSU1::serialize(serializer& s) -> void {
dataOpen();
audioOpen();
}
#endif

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define NECDSP_CPP
namespace SuperFamicom {
#include "serialization.cpp"
@ -21,7 +20,7 @@ void NECDSP::enter() {
}
uint8 NECDSP::read(unsigned addr) {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
if(addr & Select) {
return uPD96050::sr_read();
} else {
@ -30,7 +29,7 @@ uint8 NECDSP::read(unsigned addr) {
}
void NECDSP::write(unsigned addr, uint8 data) {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
if(addr & Select) {
return uPD96050::sr_write(data);
} else {
@ -39,12 +38,12 @@ void NECDSP::write(unsigned addr, uint8 data) {
}
uint8 NECDSP::ram_read(unsigned addr) {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
return uPD96050::dp_read(addr);
}
void NECDSP::ram_write(unsigned addr, uint8 data) {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
return uPD96050::dp_write(addr, data);
}

View File

@ -1,5 +1,3 @@
#ifdef NECDSP_CPP
vector<uint8> NECDSP::firmware() {
vector<uint8> buffer;
if(!cartridge.hasNECDSP()) return buffer;
@ -25,5 +23,3 @@ void NECDSP::serialize(serializer& s) {
uPD96050::serialize(s);
Thread::serialize(s);
}
#endif

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define NSS_CPP
namespace SuperFamicom {
NSS nss;

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define OBC1_CPP
namespace SuperFamicom {
#include "serialization.cpp"

View File

@ -1,5 +1,3 @@
#ifdef OBC1_CPP
void OBC1::serialize(serializer& s) {
s.array(ram.data(), ram.size());
@ -7,5 +5,3 @@ void OBC1::serialize(serializer& s) {
s.integer(status.baseptr);
s.integer(status.shift);
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef SA1_CPP
//ROM / RAM access from the S-CPU
unsigned SA1::CPUIRAM::size() const {
@ -7,12 +5,12 @@ unsigned SA1::CPUIRAM::size() const {
}
uint8 SA1::CPUIRAM::read(unsigned addr) {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
return sa1.iram.read(addr & 0x07ff);
}
void SA1::CPUIRAM::write(unsigned addr, uint8 data) {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
sa1.iram.write(addr & 0x07ff, data);
}
@ -21,14 +19,12 @@ unsigned SA1::CPUBWRAM::size() const {
}
uint8 SA1::CPUBWRAM::read(unsigned addr) {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
if(dma) return sa1.dma_cc1_read(addr);
return sa1.bwram.read(addr);
}
void SA1::CPUBWRAM::write(unsigned addr, uint8 data) {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
sa1.bwram.write(addr, data);
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef SA1_CPP
//====================
//direct data transfer
//====================
@ -135,5 +133,3 @@ void SA1::dma_cc2() {
dma.line = (dma.line + 1) & 15;
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef SA1_CPP
uint8 SA1::bus_read(unsigned addr) {
if((addr & 0x40fe00) == 0x002200) { //$00-3f|80-bf:2200-23ff
return mmio_read(addr);
@ -182,7 +180,7 @@ void SA1::mmcrom_write(unsigned addr, uint8 data) {
uint8 SA1::mmcbwram_read(unsigned addr) {
if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size());
return cpubwram.read(addr);
}
@ -196,7 +194,7 @@ uint8 SA1::mmcbwram_read(unsigned addr) {
void SA1::mmcbwram_write(unsigned addr, uint8 data) {
if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size());
return cpubwram.write(addr, data);
}
@ -277,5 +275,3 @@ void SA1::bitmap_write(unsigned addr, uint8 data) {
bwram.write(addr, data);
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef SA1_CPP
//(CCNT) SA-1 control
void SA1::mmio_w2200(uint8 data) {
if(mmio.sa1_resb && !(data & 0x80)) {
@ -444,7 +442,7 @@ uint8 SA1::mmio_r230e() {
}
uint8 SA1::mmio_read(unsigned addr) {
(co_active() == cpu.thread ? cpu.synchronize_coprocessors() : synchronize_cpu());
(co_active() == cpu.thread ? cpu.synchronizeCoprocessors() : synchronize_cpu());
addr &= 0xffff;
switch(addr) {
@ -469,7 +467,7 @@ uint8 SA1::mmio_read(unsigned addr) {
}
void SA1::mmio_write(unsigned addr, uint8 data) {
(co_active() == cpu.thread ? cpu.synchronize_coprocessors() : synchronize_cpu());
(co_active() == cpu.thread ? cpu.synchronizeCoprocessors() : synchronize_cpu());
addr &= 0xffff;
switch(addr) {
@ -550,5 +548,3 @@ void SA1::mmio_write(unsigned addr, uint8 data) {
case 0x225b: return mmio_w225b(data);
}
}
#endif

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define SA1_CPP
namespace SuperFamicom {
SA1 sa1;

View File

@ -1,5 +1,3 @@
#ifdef SA1_CPP
void SA1::serialize(serializer& s) {
R65816::serialize(s);
Thread::serialize(s);
@ -147,5 +145,3 @@ void SA1::serialize(serializer& s) {
s.integer(mmio.overflow);
}
#endif

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define SDD1_CPP
namespace SuperFamicom {
SDD1 sdd1;

View File

@ -1,5 +1,3 @@
#ifdef SDD1_CPP
void SDD1::serialize(serializer& s) {
s.array(ram.data(), ram.size());
@ -13,5 +11,3 @@ void SDD1::serialize(serializer& s) {
s.integer(dma[n].size);
}
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef SHARPRTC_CPP
void SharpRTC::serialize(serializer& s) {
Thread::serialize(s);
@ -14,5 +12,3 @@ void SharpRTC::serialize(serializer& s) {
s.integer(year);
s.integer(weekday);
}
#endif

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define SHARPRTC_CPP
namespace SuperFamicom {
#include "memory.cpp"

View File

@ -1,5 +1,3 @@
#ifdef SPC7110_CPP
void SPC7110::alu_multiply() {
add_clocks(30);
@ -83,5 +81,3 @@ void SPC7110::alu_divide() {
r482f &= 0x7f;
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef SPC7110_CPP
uint8 SPC7110::datarom_read(unsigned addr) {
unsigned size = 1 << (r4834 & 3); //size in MB
unsigned mask = 0x100000 * size - 1;
@ -58,5 +56,3 @@ void SPC7110::data_port_increment_481a() {
set_data_offset(offset + adjust);
data_port_read();
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef SPC7110_CPP
void SPC7110::serialize(serializer& s) {
s.array(ram.data(), ram.size());
@ -59,5 +57,3 @@ void SPC7110::serialize(serializer& s) {
s.integer(r4833);
s.integer(r4834);
}
#endif

View File

@ -1,6 +1,5 @@
#include <sfc/sfc.hpp>
#define SPC7110_CPP
namespace SuperFamicom {
#include "dcu.cpp"
@ -111,7 +110,7 @@ void SPC7110::reset() {
}
uint8 SPC7110::read(unsigned addr) {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
if((addr & 0xff0000) == 0x500000) addr = 0x4800;
addr = 0x4800 | (addr & 0x3f);
@ -200,7 +199,7 @@ uint8 SPC7110::read(unsigned addr) {
}
void SPC7110::write(unsigned addr, uint8 data) {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
addr = 0x4800 | (addr & 0x3f);
switch(addr) {

View File

@ -1,5 +1,3 @@
#ifdef SUPERFX_CPP
//ROM / RAM access from the S-CPU
auto SuperFX::CPUROM::size() const -> unsigned {
@ -33,5 +31,3 @@ auto SuperFX::CPURAM::read(unsigned addr) -> uint8 {
auto SuperFX::CPURAM::write(unsigned addr, uint8 data) -> void {
superfx.ram.write(addr, data);
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef SUPERFX_CPP
auto SuperFX::stop() -> void {
cpu.regs.irq = 1;
}
@ -104,5 +102,3 @@ auto SuperFX::pixelcache_flush(pixelcache_t& cache) -> void {
cache.bitpend = 0x00;
}
#endif

View File

@ -1,5 +1,3 @@
#ifdef SUPERFX_CPP
//TODO: this belongs in processor/gsu
auto SuperFX::disassemble_opcode(char* output) -> void {
@ -277,5 +275,3 @@ auto SuperFX::disassemble_alt3(char* output) -> void {
#undef op0
#undef op1
#undef op2
#endif

View File

@ -1,5 +1,3 @@
#ifdef SUPERFX_CPP
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) {
@ -106,5 +104,3 @@ auto SuperFX::memory_reset() -> void {
pixelcache[n].bitpend = 0x00;
}
}
#endif

View File

@ -1,7 +1,5 @@
#ifdef SUPERFX_CPP
auto SuperFX::mmio_read(unsigned addr) -> uint8 {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
addr &= 0xffff;
if(addr >= 0x3100 && addr <= 0x32ff) {
@ -53,7 +51,7 @@ auto SuperFX::mmio_read(unsigned addr) -> uint8 {
}
auto SuperFX::mmio_write(unsigned addr, uint8 data) -> void {
cpu.synchronize_coprocessors();
cpu.synchronizeCoprocessors();
addr &= 0xffff;
if(addr >= 0x3100 && addr <= 0x32ff) {
@ -112,5 +110,3 @@ auto SuperFX::mmio_write(unsigned addr, uint8 data) -> void {
} break;
}
}
#endif

Some files were not shown because too many files have changed in this diff Show More