Update to 20100809 release.

byuu says:

This adds some sync.sh improvements to make it handle errors more
gracefully.
It also updates asnes a good bit. All of the four base processors now
have all publicly accessible functions right at the top of the main
headers, and everything else is private. This is to allow these headers
to essentially take the place of the previous base classes in the old
bsnes-merged format. So if there's something public there, you need to
implement that exact function to make your own module.
I removed the frame counter from the PPU, as it has nothing to do with
emulation. That now resides inside the Qt -> SNES interface code. Quite
amazing, I was actually saving the frame counter into the save state
files before, yuck.
Removed some baggage in the System class: it was friending a bunch of
long-dead functions and classes.
Forgot to re-add the CHEAT_SYSTEM define to info.hpp, so that's been put
back.
This commit is contained in:
Tim Allen 2010-08-09 23:33:44 +10:00
parent 94675634c1
commit 973ef89d4a
41 changed files with 205 additions and 283 deletions

View File

@ -9,11 +9,11 @@ Configuration::Configuration() {
region = System::Region::Autodetect;
cpu.version = 2;
cpu.ntsc_frequency = 21477272;
cpu.ntsc_frequency = 21477272; //315 / 88 * 6000000
cpu.pal_frequency = 21281370;
cpu.wram_init_value = 0x55;
smp.ntsc_frequency = 24607104; //32040.5 * 768
smp.ntsc_frequency = 24607104; //32040.5 * 768
smp.pal_frequency = 24607104;
ppu1.version = 1;

View File

@ -106,7 +106,7 @@ void CPU::power() {
void CPU::reset() {
create(Enter, system.cpu_frequency());
coprocessors.reset();
PPUCounter::reset();
PPUcounter::reset();
//note: some registers are not fully reset by SNES
regs.pc = 0x000000;
@ -132,7 +132,7 @@ void CPU::reset() {
}
CPU::CPU() {
PPUCounter::scanline = { &CPU::scanline, this };
PPUcounter::scanline = { &CPU::scanline, this };
}
CPU::~CPU() {

View File

@ -1,25 +1,32 @@
class CPU : public Processor, public PPUCounter, public MMIO, public CPUcore {
class CPU : public Processor, public CPUcore, public PPUcounter, public MMIO {
public:
//synchronization
array<Processor*> coprocessors;
alwaysinline void step(unsigned clocks);
alwaysinline void synchronize_smp();
void synchronize_ppu();
void synchronize_coprocessor();
static void Enter();
void enter();
debugvirtual void op_step();
void op_irq();
bool interrupt_pending() { return status.interrupt_pending; }
uint8 pio();
bool joylatch();
alwaysinline bool interrupt_pending() { return status.interrupt_pending; }
alwaysinline uint8 port_read(uint8 port) { return apu_port[port & 3]; }
alwaysinline void port_write(uint8 port, uint8 data) { apu_port[port & 3] = data; }
uint8 cpu_version;
void power();
void reset();
void serialize(serializer&);
CPU();
~CPU();
private:
#include "dma/dma.hpp"
#include "memory/memory.hpp"
#include "mmio/mmio.hpp"
#include "timing/timing.hpp"
uint8 cpu_version;
struct Status {
bool interrupt_pending;
uint16 interrupt_vector;
@ -27,10 +34,7 @@ public:
unsigned clock_count;
unsigned line_clocks;
//======
//timing
//======
bool irq_lock;
unsigned dram_refresh_position;
@ -56,10 +60,7 @@ public:
bool reset_pending;
//===
//DMA
//===
bool dma_active;
unsigned dma_counter;
unsigned dma_clocks;
@ -67,10 +68,7 @@ public:
bool hdma_pending;
bool hdma_mode; //0 = init, 1 = run
//====
//MMIO
//====
//$2181-$2183
uint32 wram_addr;
@ -118,12 +116,10 @@ public:
unsigned shift;
} alu;
void power();
void reset();
void serialize(serializer&);
CPU();
~CPU();
static void Enter();
void enter();
void op_irq();
debugvirtual void op_step();
friend class CPUDebugger;
};

View File

@ -1,14 +1,4 @@
//============================
//CPU<>APU communication ports
//============================
uint8 apu_port[4];
uint8 port_read(uint8 port) { return apu_port[port & 3]; }
void port_write(uint8 port, uint8 data) { apu_port[port & 3] = data; }
//======================
//core CPU bus functions
//======================
void op_io();
debugvirtual uint8 op_read(uint32 addr);

View File

@ -3,9 +3,6 @@ void mmio_reset();
uint8 mmio_read(unsigned addr);
void mmio_write(unsigned addr, uint8 data);
uint8 pio();
bool joylatch();
uint8 mmio_r2180();
uint8 mmio_r4016();
uint8 mmio_r4017();

View File

@ -1,9 +1,9 @@
#ifdef CPU_CPP
void CPU::serialize(serializer &s) {
CPUcore::core_serialize(s);
Processor::serialize(s);
PPUCounter::serialize(s);
CPUcore::core_serialize(s);
PPUcounter::serialize(s);
s.integer(cpu_version);
s.integer(status.interrupt_pending);

View File

@ -1,13 +1,8 @@
class DSP : public Processor {
public:
//synchronization
alwaysinline void step(unsigned clocks);
alwaysinline void synchronize_smp();
static void Enter();
void enter();
void tick();
uint8 read(uint8 addr);
void write(uint8 addr, uint8 data);
@ -18,7 +13,7 @@ public:
DSP();
~DSP();
protected:
private:
//global registers
enum global_reg_t {
r_mvoll = 0x0c, r_mvolr = 0x1c,
@ -168,6 +163,11 @@ protected:
void echo_29();
void echo_30();
//dsp
static void Enter();
void enter();
void tick();
friend class DSPDebugger;
};

View File

@ -1,9 +1,10 @@
namespace SNES {
namespace Info {
static const char Name[] = "asnes";
static const char Version[] = "000.01";
static const char Version[] = "000.02";
static const unsigned SerializerVersion = 12;
}
}
//#define DEBUGGER
#define CHEAT_SYSTEM

View File

@ -1,6 +1,6 @@
//this should only be called by CPU::PPUcounter::tick();
//keeps track of previous counter positions in history table
void PPUCounter::tick() {
void PPUcounter::tick() {
status.hcounter += 2; //increment by smallest unit of time
if(status.hcounter >= 1360 && status.hcounter == lineclocks()) {
status.hcounter = 0;
@ -15,7 +15,7 @@ void PPUCounter::tick() {
//this should only be called by PPU::PPUcounter::tick(n);
//allows stepping by more than the smallest unit of time
void PPUCounter::tick(unsigned clocks) {
void PPUcounter::tick(unsigned clocks) {
status.hcounter += clocks;
if(status.hcounter >= lineclocks()) {
status.hcounter -= lineclocks();
@ -24,7 +24,7 @@ void PPUCounter::tick(unsigned clocks) {
}
//internal
void PPUCounter::vcounter_tick() {
void PPUcounter::vcounter_tick() {
if(++status.vcounter == 128) status.interlace = ppu.interlace();
if((system.region() == System::Region::NTSC && status.interlace == false && status.vcounter == 262)
@ -40,13 +40,13 @@ void PPUCounter::vcounter_tick() {
if(scanline) scanline();
}
bool PPUCounter::field () const { return status.field; }
uint16 PPUCounter::vcounter() const { return status.vcounter; }
uint16 PPUCounter::hcounter() const { return status.hcounter; }
bool PPUcounter::field () const { return status.field; }
uint16 PPUcounter::vcounter() const { return status.vcounter; }
uint16 PPUcounter::hcounter() const { return status.hcounter; }
bool PPUCounter::field (unsigned offset) const { return history.field [(history.index - (offset >> 1)) & 2047]; }
uint16 PPUCounter::vcounter(unsigned offset) const { return history.vcounter[(history.index - (offset >> 1)) & 2047]; }
uint16 PPUCounter::hcounter(unsigned offset) const { return history.hcounter[(history.index - (offset >> 1)) & 2047]; }
bool PPUcounter::field (unsigned offset) const { return history.field [(history.index - (offset >> 1)) & 2047]; }
uint16 PPUcounter::vcounter(unsigned offset) const { return history.vcounter[(history.index - (offset >> 1)) & 2047]; }
uint16 PPUcounter::hcounter(unsigned offset) const { return history.hcounter[(history.index - (offset >> 1)) & 2047]; }
//one PPU dot = 4 CPU clocks
//
@ -57,7 +57,7 @@ uint16 PPUCounter::hcounter(unsigned offset) const { return history.hcounter[(hi
//dot 323 range = { 1292, 1294, 1296 }
//dot 327 range = { 1310, 1312, 1314 }
uint16 PPUCounter::hdot() const {
uint16 PPUcounter::hdot() const {
if(system.region() == System::Region::NTSC && status.interlace == false && vcounter() == 240 && field() == 1) {
return (hcounter() >> 2);
} else {
@ -65,12 +65,12 @@ uint16 PPUCounter::hdot() const {
}
}
uint16 PPUCounter::lineclocks() const {
uint16 PPUcounter::lineclocks() const {
if(system.region() == System::Region::NTSC && status.interlace == false && vcounter() == 240 && field() == 1) return 1360;
return 1364;
}
void PPUCounter::reset() {
void PPUcounter::reset() {
status.interlace = false;
status.field = 0;
status.vcounter = 0;

View File

@ -1,4 +1,4 @@
//PPUCounter emulates the H/V latch counters of the S-PPU2.
//PPUcounter emulates the H/V latch counters of the S-PPU2.
//
//real hardware has the S-CPU maintain its own copy of these counters that are
//updated based on the state of the S-PPU Vblank and Hblank pins. emulating this
@ -10,7 +10,7 @@
//point before this in the frame, which is handled internally by this class at
//V=128.
class PPUCounter {
class PPUcounter {
public:
alwaysinline void tick();
alwaysinline void tick(unsigned clocks);

View File

@ -82,7 +82,6 @@ struct {
uint16 vcounter;
} regs;
void latch_counters();
uint16 get_vram_address();
uint8 vram_read(unsigned addr);
@ -94,10 +93,6 @@ void oam_write(unsigned addr, uint8 data);
uint8 cgram_read(unsigned addr);
void cgram_write(unsigned addr, uint8 data);
bool interlace() const;
bool overscan() const;
bool hires() const;
void mmio_update_video_mode();
void mmio_w2100(uint8); //INIDISP

View File

@ -86,7 +86,7 @@ void PPU::power() {
void PPU::reset() {
create(Enter, system.cpu_frequency());
PPUCounter::reset();
PPUcounter::reset();
memset(surface, 0, 512 * 512 * sizeof(uint16));
mmio_reset();
@ -118,19 +118,6 @@ void PPU::frame() {
display.interlace = regs.interlace;
display.overscan = regs.overscan;
//frame counter
static signed framecount = 0;
static time_t prev, curr;
framecount++;
time(&curr);
if(curr != prev) {
status.frames_updated = true;
status.frames_executed = framecount;
framecount = 0;
prev = curr;
}
}
PPU::PPU() :
@ -143,9 +130,6 @@ window(*this),
screen(*this) {
surface = new uint16[512 * 512];
output = surface + 16 * 512;
status.frames_updated = false;
status.frames_executed = 0;
}
PPU::~PPU() {

View File

@ -1,7 +1,23 @@
#include "counter/counter.hpp"
class PPU : public Processor, public PPUCounter, public MMIO {
class PPU : public Processor, public PPUcounter, public MMIO {
public:
alwaysinline void step(unsigned clocks);
alwaysinline void synchronize_cpu();
void latch_counters();
bool interlace() const;
bool overscan() const;
bool hires() const;
void power();
void reset();
void serialize(serializer&);
PPU();
~PPU();
private:
#include "background/background.hpp"
#include "mmio/mmio.hpp"
#include "screen/screen.hpp"
@ -19,11 +35,6 @@ public:
uint16 *surface;
uint16 *output;
struct {
bool frames_updated;
unsigned frames_executed;
} status;
uint8 ppu1_version;
uint8 ppu2_version;
@ -32,23 +43,18 @@ public:
bool overscan;
} display;
//synchronization
alwaysinline void step(unsigned clocks);
alwaysinline void synchronize_cpu();
static void Enter();
void enter();
void add_clocks(unsigned);
void power();
void reset();
void scanline();
void frame();
void serialize(serializer&);
PPU();
~PPU();
friend class PPU::Background;
friend class PPU::Sprite;
friend class PPU::Window;
friend class PPU::Screen;
friend class Video;
};
#if defined(DEBUGGER)

View File

@ -1,6 +1,6 @@
#ifdef PPU_CPP
void PPUCounter::serialize(serializer &s) {
void PPUcounter::serialize(serializer &s) {
s.integer(status.interlace);
s.integer(status.field);
s.integer(status.vcounter);
@ -14,10 +14,7 @@ void PPUCounter::serialize(serializer &s) {
void PPU::serialize(serializer &s) {
Processor::serialize(s);
PPUCounter::serialize(s);
s.integer(status.frames_updated);
s.integer(status.frames_executed);
PPUcounter::serialize(s);
s.integer(ppu1_version);
s.integer(ppu2_version);

View File

@ -1,9 +1,6 @@
uint8 ram_read(uint16 addr);
void ram_write(uint16 addr, uint8 data);
uint8 port_read(uint8 port);
void port_write(uint8 port, uint8 data);
uint8 op_busread(uint16 addr);
void op_buswrite(uint16 addr, uint8 data);

View File

@ -4,8 +4,6 @@ void SMP::serialize(serializer &s) {
Processor::serialize(s);
SMPcore::core_serialize(s);
s.integer(status.opcode);
s.integer(status.clock_counter);
s.integer(status.dsp_counter);
s.integer(status.timer_step);

View File

@ -1,22 +1,26 @@
class SMP : public Processor, public SMPcore {
public:
static const uint8 iplrom[64];
//synchronization
alwaysinline void step(unsigned clocks);
alwaysinline void synchronize_cpu();
alwaysinline void synchronize_dsp();
static void Enter();
void enter();
debugvirtual void op_step();
uint8 port_read(uint8 port);
void port_write(uint8 port, uint8 data);
void power();
void reset();
void serialize(serializer&);
SMP();
~SMP();
private:
#include "memory/memory.hpp"
#include "timing/timing.hpp"
struct {
uint8 opcode;
static const uint8 iplrom[64];
struct {
//timing
unsigned clock_counter;
unsigned dsp_counter;
@ -40,14 +44,11 @@ public:
uint8 smp_f8, smp_f9;
} status;
//ssmp.cpp
void power();
void reset();
void serialize(serializer&);
SMP();
~SMP();
static void Enter();
void enter();
debugvirtual void op_step();
friend class SMPcore;
friend class SMPDebugger;
};

View File

@ -28,7 +28,6 @@ public:
bool unserialize(serializer&);
System();
virtual ~System() {}
private:
Interface *interface;
@ -42,8 +41,6 @@ private:
friend class Video;
friend class Audio;
friend class Input;
friend class StateManager;
friend void threadentry_cop();
};
#include <video/video.hpp>

View File

@ -1,4 +1,5 @@
class Video {
private:
bool frame_hires;
bool frame_interlace;
unsigned line_width[240];

View File

@ -9,11 +9,11 @@ Configuration::Configuration() {
region = System::Region::Autodetect;
cpu.version = 2;
cpu.ntsc_frequency = 21477272;
cpu.ntsc_frequency = 21477272; //315 / 88 * 6000000
cpu.pal_frequency = 21281370;
cpu.wram_init_value = 0x55;
smp.ntsc_frequency = 24607104; //32040.5 * 768
smp.ntsc_frequency = 24607104; //32040.5 * 768
smp.pal_frequency = 24607104;
ppu1.version = 1;

View File

@ -106,7 +106,7 @@ void CPU::power() {
void CPU::reset() {
create(Enter, system.cpu_frequency());
coprocessors.reset();
PPUCounter::reset();
PPUcounter::reset();
//note: some registers are not fully reset by SNES
regs.pc = 0x000000;
@ -132,7 +132,7 @@ void CPU::reset() {
}
CPU::CPU() {
PPUCounter::scanline = { &CPU::scanline, this };
PPUcounter::scanline = { &CPU::scanline, this };
}
CPU::~CPU() {

View File

@ -1,25 +1,32 @@
class CPU : public Processor, public PPUCounter, public MMIO, public CPUcore {
class CPU : public Processor, public CPUcore, public PPUcounter, public MMIO {
public:
//synchronization
array<Processor*> coprocessors;
alwaysinline void step(unsigned clocks);
alwaysinline void synchronize_smp();
void synchronize_ppu();
void synchronize_coprocessor();
static void Enter();
void enter();
debugvirtual void op_step();
void op_irq();
bool interrupt_pending() { return status.interrupt_pending; }
uint8 pio();
bool joylatch();
alwaysinline bool interrupt_pending() { return status.interrupt_pending; }
alwaysinline uint8 port_read(uint8 port) { return apu_port[port & 3]; }
alwaysinline void port_write(uint8 port, uint8 data) { apu_port[port & 3] = data; }
uint8 cpu_version;
void power();
void reset();
void serialize(serializer&);
CPU();
~CPU();
private:
#include "dma/dma.hpp"
#include "memory/memory.hpp"
#include "mmio/mmio.hpp"
#include "timing/timing.hpp"
uint8 cpu_version;
struct Status {
bool interrupt_pending;
uint16 interrupt_vector;
@ -27,10 +34,7 @@ public:
unsigned clock_count;
unsigned line_clocks;
//======
//timing
//======
bool irq_lock;
unsigned dram_refresh_position;
@ -56,10 +60,7 @@ public:
bool reset_pending;
//===
//DMA
//===
bool dma_active;
unsigned dma_counter;
unsigned dma_clocks;
@ -67,10 +68,7 @@ public:
bool hdma_pending;
bool hdma_mode; //0 = init, 1 = run
//====
//MMIO
//====
//$2181-$2183
uint32 wram_addr;
@ -118,12 +116,10 @@ public:
unsigned shift;
} alu;
void power();
void reset();
void serialize(serializer&);
CPU();
~CPU();
static void Enter();
void enter();
void op_irq();
debugvirtual void op_step();
friend class CPUDebugger;
};

View File

@ -1,14 +1,4 @@
//============================
//CPU<>APU communication ports
//============================
uint8 apu_port[4];
uint8 port_read(uint8 port) { return apu_port[port & 3]; }
void port_write(uint8 port, uint8 data) { apu_port[port & 3] = data; }
//======================
//core CPU bus functions
//======================
void op_io();
debugvirtual uint8 op_read(uint32 addr);

View File

@ -3,9 +3,6 @@ void mmio_reset();
uint8 mmio_read(unsigned addr);
void mmio_write(unsigned addr, uint8 data);
uint8 pio();
bool joylatch();
uint8 mmio_r2180();
uint8 mmio_r4016();
uint8 mmio_r4017();

View File

@ -1,9 +1,9 @@
#ifdef CPU_CPP
void CPU::serialize(serializer &s) {
CPUcore::core_serialize(s);
Processor::serialize(s);
PPUCounter::serialize(s);
CPUcore::core_serialize(s);
PPUcounter::serialize(s);
s.integer(cpu_version);
s.integer(status.interrupt_pending);

View File

@ -1,10 +1,11 @@
namespace SNES {
namespace Info {
static const char Name[] = "bsnes";
static const char Version[] = "067.07";
static const char Version[] = "067.08";
static const unsigned SerializerVersion = 12;
}
}
#define DSP_STATE_MACHINE
//#define DEBUGGER
#define DSP_STATE_MACHINE
#define CHEAT_SYSTEM

View File

@ -1,6 +1,6 @@
//this should only be called by CPU::PPUcounter::tick();
//keeps track of previous counter positions in history table
void PPUCounter::tick() {
void PPUcounter::tick() {
status.hcounter += 2; //increment by smallest unit of time
if(status.hcounter >= 1360 && status.hcounter == lineclocks()) {
status.hcounter = 0;
@ -15,7 +15,7 @@ void PPUCounter::tick() {
//this should only be called by PPU::PPUcounter::tick(n);
//allows stepping by more than the smallest unit of time
void PPUCounter::tick(unsigned clocks) {
void PPUcounter::tick(unsigned clocks) {
status.hcounter += clocks;
if(status.hcounter >= lineclocks()) {
status.hcounter -= lineclocks();
@ -24,7 +24,7 @@ void PPUCounter::tick(unsigned clocks) {
}
//internal
void PPUCounter::vcounter_tick() {
void PPUcounter::vcounter_tick() {
if(++status.vcounter == 128) status.interlace = ppu.interlace();
if((system.region() == System::Region::NTSC && status.interlace == false && status.vcounter == 262)
@ -40,13 +40,13 @@ void PPUCounter::vcounter_tick() {
if(scanline) scanline();
}
bool PPUCounter::field () const { return status.field; }
uint16 PPUCounter::vcounter() const { return status.vcounter; }
uint16 PPUCounter::hcounter() const { return status.hcounter; }
bool PPUcounter::field () const { return status.field; }
uint16 PPUcounter::vcounter() const { return status.vcounter; }
uint16 PPUcounter::hcounter() const { return status.hcounter; }
bool PPUCounter::field (unsigned offset) const { return history.field [(history.index - (offset >> 1)) & 2047]; }
uint16 PPUCounter::vcounter(unsigned offset) const { return history.vcounter[(history.index - (offset >> 1)) & 2047]; }
uint16 PPUCounter::hcounter(unsigned offset) const { return history.hcounter[(history.index - (offset >> 1)) & 2047]; }
bool PPUcounter::field (unsigned offset) const { return history.field [(history.index - (offset >> 1)) & 2047]; }
uint16 PPUcounter::vcounter(unsigned offset) const { return history.vcounter[(history.index - (offset >> 1)) & 2047]; }
uint16 PPUcounter::hcounter(unsigned offset) const { return history.hcounter[(history.index - (offset >> 1)) & 2047]; }
//one PPU dot = 4 CPU clocks
//
@ -57,7 +57,7 @@ uint16 PPUCounter::hcounter(unsigned offset) const { return history.hcounter[(hi
//dot 323 range = { 1292, 1294, 1296 }
//dot 327 range = { 1310, 1312, 1314 }
uint16 PPUCounter::hdot() const {
uint16 PPUcounter::hdot() const {
if(system.region() == System::Region::NTSC && status.interlace == false && vcounter() == 240 && field() == 1) {
return (hcounter() >> 2);
} else {
@ -65,12 +65,12 @@ uint16 PPUCounter::hdot() const {
}
}
uint16 PPUCounter::lineclocks() const {
uint16 PPUcounter::lineclocks() const {
if(system.region() == System::Region::NTSC && status.interlace == false && vcounter() == 240 && field() == 1) return 1360;
return 1364;
}
void PPUCounter::reset() {
void PPUcounter::reset() {
status.interlace = false;
status.field = 0;
status.vcounter = 0;

View File

@ -1,4 +1,4 @@
//PPUCounter emulates the H/V latch counters of the S-PPU2.
//PPUcounter emulates the H/V latch counters of the S-PPU2.
//
//real hardware has the S-CPU maintain its own copy of these counters that are
//updated based on the state of the S-PPU Vblank and Hblank pins. emulating this
@ -10,7 +10,7 @@
//point before this in the frame, which is handled internally by this class at
//V=128.
class PPUCounter {
class PPUcounter {
public:
alwaysinline void tick();
alwaysinline void tick(unsigned clocks);

View File

@ -112,19 +112,6 @@ void PPU::frame() {
display.interlace = regs.interlace;
regs.scanlines = (regs.overscan == false) ? 224 : 239;
}
//frame counter
static signed framecount = 0;
static time_t prev, curr;
framecount++;
time(&curr);
if(curr != prev) {
status.frames_updated = true;
status.frames_executed = framecount;
framecount = 0;
prev = curr;
}
}
void PPU::power() {
@ -347,7 +334,7 @@ void PPU::power() {
void PPU::reset() {
create(Enter, system.cpu_frequency());
PPUCounter::reset();
PPUcounter::reset();
memset(surface, 0, 512 * 512 * sizeof(uint16));
frame();
@ -377,9 +364,6 @@ PPU::PPU() {
surface = new uint16[512 * 512];
output = surface + 16 * 512;
status.frames_updated = false;
status.frames_executed = 0;
alloc_tiledata_cache();
for(unsigned l = 0; l < 16; l++) {

View File

@ -1,6 +1,6 @@
#include "counter/counter.hpp"
class PPU : public Processor, public PPUCounter, public MMIO {
class PPU : public Processor, public PPUcounter, public MMIO {
public:
#include "memory/memory.hpp"
#include "mmio/mmio.hpp"
@ -9,11 +9,6 @@ public:
uint16 *surface;
uint16 *output;
struct {
bool frames_updated;
unsigned frames_executed;
} status;
uint8 ppu1_version;
uint8 ppu2_version;

View File

@ -1,6 +1,6 @@
#ifdef PPU_CPP
void PPUCounter::serialize(serializer &s) {
void PPUcounter::serialize(serializer &s) {
s.integer(status.interlace);
s.integer(status.field);
s.integer(status.vcounter);
@ -14,10 +14,7 @@ void PPUCounter::serialize(serializer &s) {
void PPU::serialize(serializer &s) {
Processor::serialize(s);
PPUCounter::serialize(s);
s.integer(status.frames_updated);
s.integer(status.frames_executed);
PPUcounter::serialize(s);
s.integer(ppu1_version);
s.integer(ppu2_version);

View File

@ -1,9 +1,6 @@
uint8 ram_read(uint16 addr);
void ram_write(uint16 addr, uint8 data);
uint8 port_read(uint8 port);
void port_write(uint8 port, uint8 data);
uint8 op_busread(uint16 addr);
void op_buswrite(uint16 addr, uint8 data);

View File

@ -4,8 +4,6 @@ void SMP::serialize(serializer &s) {
Processor::serialize(s);
SMPcore::core_serialize(s);
s.integer(status.opcode);
s.integer(status.clock_counter);
s.integer(status.dsp_counter);
s.integer(status.timer_step);

View File

@ -1,22 +1,26 @@
class SMP : public Processor, public SMPcore {
public:
static const uint8 iplrom[64];
//synchronization
alwaysinline void step(unsigned clocks);
alwaysinline void synchronize_cpu();
alwaysinline void synchronize_dsp();
static void Enter();
void enter();
debugvirtual void op_step();
uint8 port_read(uint8 port);
void port_write(uint8 port, uint8 data);
void power();
void reset();
void serialize(serializer&);
SMP();
~SMP();
private:
#include "memory/memory.hpp"
#include "timing/timing.hpp"
struct {
uint8 opcode;
static const uint8 iplrom[64];
struct {
//timing
unsigned clock_counter;
unsigned dsp_counter;
@ -40,14 +44,11 @@ public:
uint8 smp_f8, smp_f9;
} status;
//ssmp.cpp
void power();
void reset();
void serialize(serializer&);
SMP();
~SMP();
static void Enter();
void enter();
debugvirtual void op_step();
friend class SMPcore;
friend class SMPDebugger;
};

View File

@ -1,35 +1,25 @@
rm -r audio
rm -r cartridge
rm -r cheat
rm -r chip
rm -r config
rm -r cpu
rm -r debugger
rm -r input
rm -r interface
rm -r libsnes
rm -r memory
rm -r scheduler
rm -r smp
rm -r system
rm -r video
rm -r snes.hpp
rm -r Makefile
synchronize() {
if [ -d ../asnes/"$1" ]; then
test -d "$1" && rm -r "$1"
cp -r ../asnes/"$1" ./"$1"
fi
}
cp -r ../asnes/audio ./audio
cp -r ../asnes/cartridge ./cartridge
cp -r ../asnes/cheat ./cheat
cp -r ../asnes/chip ./chip
cp -r ../asnes/config ./config
cp -r ../asnes/cpu ./cpu
cp -r ../asnes/debugger ./debugger
cp -r ../asnes/input ./input
cp -r ../asnes/interface ./interface
cp -r ../asnes/libsnes ./libsnes
cp -r ../asnes/memory ./memory
cp -r ../asnes/scheduler ./scheduler
cp -r ../asnes/smp ./smp
cp -r ../asnes/system ./system
cp -r ../asnes/video ./video
cp -r ../asnes/snes.hpp ./snes.hpp
cp -r ../asnes/Makefile ./Makefile
synchronize "audio"
synchronize "cartridge"
synchronize "cheat"
synchronize "chip"
synchronize "config"
synchronize "cpu"
synchronize "debugger"
synchronize "input"
synchronize "interface"
synchronize "libsnes"
synchronize "memory"
synchronize "ppu/counter"
synchronize "scheduler"
synchronize "smp"
synchronize "system"
synchronize "video"
synchronize "snes.hpp"
synchronize "Makefile"

View File

@ -28,7 +28,6 @@ public:
bool unserialize(serializer&);
System();
virtual ~System() {}
private:
Interface *interface;
@ -42,8 +41,6 @@ private:
friend class Video;
friend class Audio;
friend class Input;
friend class StateManager;
friend void threadentry_cop();
};
#include <video/video.hpp>

View File

@ -1,4 +1,5 @@
class Video {
private:
bool frame_hires;
bool frame_interlace;
unsigned line_width[240];

View File

@ -43,6 +43,19 @@ void Interface::video_refresh(const uint16_t *data, unsigned width, unsigned hei
#if defined(DEBUGGER)
debugger->frameTick();
#endif
//frame counter
static signed frameCount = 0;
static time_t prev, curr;
frameCount++;
time(&curr);
if(curr != prev) {
framesUpdated = true;
framesExecuted = frameCount;
frameCount = 0;
prev = curr;
}
}
void Interface::audio_sample(uint16_t left, uint16_t right) {

View File

@ -8,6 +8,8 @@ public:
Interface();
void captureScreenshot(uint32_t*, unsigned, unsigned, unsigned);
bool saveScreenshot;
bool framesUpdated;
unsigned framesExecuted;
};
extern Interface interface;

View File

@ -30,9 +30,9 @@ void Utility::updateSystemState() {
text = "Power off";
} else if(application.pause == true || application.autopause == true) {
text = "Paused";
} else if(SNES::ppu.status.frames_updated == true) {
SNES::ppu.status.frames_updated = false;
text << SNES::ppu.status.frames_executed;
} else if(interface.framesUpdated == true) {
interface.framesUpdated = false;
text << interface.framesExecuted;
text << " fps";
} else {
//nothing to update

19
sync.sh
View File

@ -1,10 +1,13 @@
rm -r libco
rm -r nall
rm -r ruby
synchronize() {
if [ -d ../"$1" ]; then
test -d "$1" && rm -r "$1"
cp -r ../"$1" ./"$1"
fi
}
cp -r ../libco ./libco
cp -r ../nall ./nall
cp -r ../ruby ./ruby
synchronize "libco"
synchronize "nall"
synchronize "ruby"
rm -r libco/doc
rm -r libco/test
test -d libco/doc && rm -r libco/doc
test -d libco/test && rm -r libco/test