Simplications in source, removing no longer needed files and simplifying tests
This commit is contained in:
parent
4530713b01
commit
131aa5bb97
|
@ -22,20 +22,6 @@ int32_t *_initF_VideoPalette()
|
|||
// Initialize the video palette
|
||||
const int32_t *HQNState::NES_VIDEO_PALETTE = _initF_VideoPalette();
|
||||
|
||||
// simulate the write so we'll know how long the buffer needs to be
|
||||
class Sim_Writer : public Data_Writer
|
||||
{
|
||||
long size_;
|
||||
public:
|
||||
Sim_Writer() :size_(0) { }
|
||||
error_t write(const void *, long size)
|
||||
{
|
||||
size_ += size;
|
||||
return 0;
|
||||
}
|
||||
long size() const { return size_; }
|
||||
};
|
||||
|
||||
// Constructor
|
||||
HQNState::HQNState()
|
||||
{
|
||||
|
@ -71,34 +57,17 @@ error_t HQNState::setSampleRate(int rate)
|
|||
|
||||
error_t HQNState::saveState(void *dest, size_t size, size_t *size_out)
|
||||
{
|
||||
Mem_Writer w(dest, size, 0);
|
||||
Auto_File_Writer a(w);
|
||||
auto ret = m_emu->save_state(a);
|
||||
if (size_out)
|
||||
*size_out = w.size();
|
||||
if (!ret && w.size() != size)
|
||||
return "Buffer Underrun!";
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
error_t HQNState::saveStateSize(size_t *size) const
|
||||
{
|
||||
Sim_Writer w;
|
||||
Auto_File_Writer a(w);
|
||||
const char *ret = m_emu->save_state(a);
|
||||
if (size)
|
||||
*size = w.size();
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
error_t HQNState::loadState(const char *data, size_t size)
|
||||
{
|
||||
Mem_File_Reader r(data, size);
|
||||
Auto_File_Reader a(r);
|
||||
error_t result = m_emu->load_state(a);
|
||||
if (m_listener)
|
||||
m_listener->onLoadState(this);
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Advance the emulator
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Data_Reader.h"
|
||||
|
||||
#include "blargg_endian.h"
|
||||
#include <errno.h>
|
||||
|
||||
/* Copyright (C) 2005-2009 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
// Data_Reader
|
||||
|
||||
const char * Data_Reader::read( void* p, int n_ )
|
||||
{
|
||||
if ( n_ < 0 )
|
||||
return "Internal usage bug";
|
||||
|
||||
if ( n_ == 0 )
|
||||
return 0;
|
||||
|
||||
size_t n = n_;
|
||||
|
||||
if ( n > remain() )
|
||||
return "Truncated file";
|
||||
|
||||
const char * err = read_v( p, n );
|
||||
if ( !err )
|
||||
remain_ -= n;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
const char * Data_Reader::read_avail( void* p, int* n_ )
|
||||
{
|
||||
int n = min( (uint64_t)(*n_), remain() );
|
||||
*n_ = 0;
|
||||
|
||||
if ( n < 0 )
|
||||
return "Internal usage bug";
|
||||
|
||||
if ( n <= 0 )
|
||||
return 0;
|
||||
|
||||
const char * err = read_v( p, n );
|
||||
if ( !err )
|
||||
{
|
||||
remain_ -= n;
|
||||
*n_ = n;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
const char * Data_Reader::read_avail( void* p, long* n )
|
||||
{
|
||||
int i = STATIC_CAST(int, *n);
|
||||
const char * err = read_avail( p, &i );
|
||||
*n = i;
|
||||
return err;
|
||||
}
|
||||
|
||||
const char * Data_Reader::skip_v( int count )
|
||||
{
|
||||
char buf [512];
|
||||
while ( count )
|
||||
{
|
||||
int n = min( count, (int) sizeof buf );
|
||||
count -= n;
|
||||
RETURN_ERR( read_v( buf, n ) );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * Data_Reader::skip( int n_ )
|
||||
{
|
||||
if ( n_ < 0 )
|
||||
return "Internal usage bug";
|
||||
|
||||
if ( n_ == 0 ) return 0;
|
||||
|
||||
size_t n = n_;
|
||||
|
||||
if ( n > remain() )
|
||||
return "Truncated file";
|
||||
|
||||
const char * err = skip_v( n );
|
||||
if ( !err )
|
||||
remain_ -= n;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
// File_Reader
|
||||
|
||||
// Mem_File_Reader
|
||||
|
||||
Mem_File_Reader::Mem_File_Reader( const void* p, long s ) :
|
||||
begin( STATIC_CAST(const char*, p) )
|
||||
{
|
||||
set_size( s );
|
||||
}
|
||||
|
||||
const char * Mem_File_Reader::read_v( void* p, int s )
|
||||
{
|
||||
memcpy( p, begin + tell(), s );
|
||||
return 0;
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
// Lightweight interface for reading data from byte stream
|
||||
|
||||
// File_Extractor 1.0.0
|
||||
#ifndef DATA_READER_H
|
||||
#define DATA_READER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "blargg_common.h"
|
||||
|
||||
/* Some functions accept a long instead of int for convenience where caller has
|
||||
a long due to some other interface, and would otherwise have to get a warning,
|
||||
or cast it (and verify that it wasn't outside the range of an int).
|
||||
|
||||
To really support huge (>2GB) files, long isn't a solution, since there's no
|
||||
guarantee it's more than 32 bits. We'd need to use long long (if available), or
|
||||
something compiler-specific, and change all places file sizes or offsets are
|
||||
used. */
|
||||
|
||||
// Supports reading and finding out how many bytes are remaining
|
||||
class Data_Reader {
|
||||
public:
|
||||
|
||||
// Reads min(*n,remain()) bytes and sets *n to this number, thus trying to read more
|
||||
// tham remain() bytes doesn't result in error, just *n being set to remain().
|
||||
const char * read_avail( void* p, int* n );
|
||||
const char * read_avail( void* p, long* n );
|
||||
|
||||
// Reads exactly n bytes, or returns error if they couldn't ALL be read.
|
||||
// Reading past end of file results in blargg_err_file_eof.
|
||||
const char * read( void* p, int n );
|
||||
|
||||
// Number of bytes remaining until end of file
|
||||
uint64_t remain() const { return remain_; }
|
||||
|
||||
// Reads and discards n bytes. Skipping past end of file results in blargg_err_file_eof.
|
||||
const char * skip( int n );
|
||||
|
||||
virtual ~Data_Reader() { }
|
||||
|
||||
private:
|
||||
// noncopyable
|
||||
Data_Reader( const Data_Reader& );
|
||||
Data_Reader& operator = ( const Data_Reader& );
|
||||
|
||||
// Derived interface
|
||||
protected:
|
||||
Data_Reader() : remain_( 0 ) { }
|
||||
|
||||
// Sets remain
|
||||
void set_remain( uint64_t n ) { remain_ = n; }
|
||||
|
||||
// Do same as read(). Guaranteed that 0 < n <= remain(). Value of remain() is updated
|
||||
// AFTER this call succeeds, not before. set_remain() should NOT be called from this.
|
||||
virtual const char * read_v( void*, int n ) BLARGG_PURE( { (void)n; return 0; } )
|
||||
|
||||
// Do same as skip(). Guaranteed that 0 < n <= remain(). Default just reads data
|
||||
// and discards it. Value of remain() is updated AFTER this call succeeds, not
|
||||
// before. set_remain() should NOT be called from this.
|
||||
virtual const char * skip_v( int n );
|
||||
|
||||
private:
|
||||
uint64_t remain_;
|
||||
};
|
||||
|
||||
|
||||
// Supports seeking in addition to Data_Reader operations
|
||||
class File_Reader : public Data_Reader {
|
||||
public:
|
||||
|
||||
// Size of file
|
||||
uint64_t size() const { return size_; }
|
||||
|
||||
// Current position in file
|
||||
uint64_t tell() const { return size_ - remain(); }
|
||||
|
||||
// Derived interface
|
||||
protected:
|
||||
// Sets size and resets position
|
||||
void set_size( uint64_t n ) { size_ = n; Data_Reader::set_remain( n ); }
|
||||
void set_size( int n ) { set_size( STATIC_CAST(uint64_t, n) ); }
|
||||
void set_size( long n ) { set_size( STATIC_CAST(uint64_t, n) ); }
|
||||
|
||||
// Sets reported position
|
||||
void set_tell( uint64_t i ) { Data_Reader::set_remain( size_ - i ); }
|
||||
// Implementation
|
||||
protected:
|
||||
File_Reader() : size_( 0 ) { }
|
||||
|
||||
private:
|
||||
uint64_t size_;
|
||||
|
||||
void set_remain(); // avoid accidental use of set_remain
|
||||
};
|
||||
|
||||
|
||||
// Treats range of memory as a file
|
||||
class Mem_File_Reader : public File_Reader {
|
||||
public:
|
||||
|
||||
Mem_File_Reader( const void* begin, long size );
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
virtual const char * read_v( void*, int );
|
||||
|
||||
private:
|
||||
const char* const begin;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -91,13 +91,11 @@ const char *Effects_Buffer::set_sample_rate( long rate, int msec )
|
|||
if ( !echo_buf )
|
||||
{
|
||||
echo_buf = new blip_sample_t [echo_size];
|
||||
CHECK_ALLOC( echo_buf );
|
||||
}
|
||||
|
||||
if ( !reverb_buf )
|
||||
{
|
||||
reverb_buf = new blip_sample_t [reverb_size];
|
||||
CHECK_ALLOC( reverb_buf );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < buf_count; i++ )
|
||||
|
|
|
@ -18,9 +18,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|||
#ifndef NES_CART_H
|
||||
#define NES_CART_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
#include "blargg_common.h"
|
||||
#include "abstract_file.h"
|
||||
|
||||
|
||||
class Nes_Cart {
|
||||
|
|
|
@ -23,7 +23,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|||
#include "Nes_Cpu.h"
|
||||
#include "Nes_Ppu.h"
|
||||
#include "Nes_Mapper.h"
|
||||
#include "Nes_State.h"
|
||||
|
||||
/*
|
||||
New mapping distribution by Sergio Martin (eien86)
|
||||
|
@ -100,6 +99,34 @@ unsigned const low_ram_end = 0x2000;
|
|||
unsigned const sram_end = 0x8000;
|
||||
const int irq_inhibit_mask = 0x04;
|
||||
|
||||
struct nes_state_t
|
||||
{
|
||||
uint16_t timestamp; // CPU clocks * 15 (for NTSC)
|
||||
uint8_t pal;
|
||||
uint8_t unused [1];
|
||||
uint32_t frame_count; // number of frames emulated since power-up
|
||||
};
|
||||
|
||||
struct joypad_state_t
|
||||
{
|
||||
uint32_t joypad_latches [2]; // joypad 1 & 2 shift registers
|
||||
uint8_t w4016; // strobe
|
||||
uint8_t unused [3];
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (joypad_state_t) == 12 );
|
||||
|
||||
struct cpu_state_t
|
||||
{
|
||||
uint16_t pc;
|
||||
uint8_t s;
|
||||
uint8_t p;
|
||||
uint8_t a;
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
uint8_t unused [1];
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (cpu_state_t) == 8 );
|
||||
|
||||
class Nes_Core : private Nes_Cpu {
|
||||
typedef Nes_Cpu cpu;
|
||||
public:
|
||||
|
@ -124,7 +151,7 @@ public:
|
|||
{
|
||||
if ( !impl )
|
||||
{
|
||||
CHECK_ALLOC( impl = new impl_t );
|
||||
impl = new impl_t;
|
||||
impl->apu.dmc_reader( read_dmc, this );
|
||||
impl->apu.irq_notifier( apu_irq_changed, this );
|
||||
}
|
||||
|
@ -617,92 +644,7 @@ public:
|
|||
disable_rendering();
|
||||
}
|
||||
|
||||
void save_state( Nes_State* out ) const
|
||||
{
|
||||
save_state( reinterpret_cast<Nes_State_*>(out) );
|
||||
}
|
||||
|
||||
void save_state( Nes_State_* out ) const
|
||||
{
|
||||
out->clear();
|
||||
|
||||
out->nes = nes;
|
||||
out->nes_valid = true;
|
||||
|
||||
*out->cpu = cpu::r;
|
||||
out->cpu_valid = true;
|
||||
|
||||
*out->joypad = joypad;
|
||||
out->joypad_valid = true;
|
||||
|
||||
impl->apu.save_state( out->apu );
|
||||
out->apu_valid = true;
|
||||
|
||||
ppu.save_state( out );
|
||||
|
||||
memcpy( out->ram, cpu::low_mem, out->ram_size );
|
||||
out->ram_valid = true;
|
||||
|
||||
out->sram_size = 0;
|
||||
if ( sram_present )
|
||||
{
|
||||
out->sram_size = sizeof impl->sram;
|
||||
memcpy( out->sram, impl->sram, out->sram_size );
|
||||
}
|
||||
|
||||
out->mapper->size = 0;
|
||||
mapper->save_state( *out->mapper );
|
||||
out->mapper_valid = true;
|
||||
}
|
||||
|
||||
void load_state( Nes_State_ const& in )
|
||||
{
|
||||
// disable_rendering();
|
||||
// error_count = 0;
|
||||
|
||||
// if ( in.nes_valid )
|
||||
// nes = in.nes;
|
||||
|
||||
// // always use frame count
|
||||
// ppu.burst_phase = 0; // avoids shimmer when seeking to same time over and over
|
||||
// nes.frame_count = in.nes.frame_count;
|
||||
// if ( (frame_count_t) nes.frame_count == invalid_frame_count )
|
||||
// nes.frame_count = 0;
|
||||
|
||||
// if ( in.cpu_valid )
|
||||
// cpu::r = *in.cpu;
|
||||
|
||||
// if ( in.joypad_valid )
|
||||
// joypad = *in.joypad;
|
||||
|
||||
// if ( in.apu_valid )
|
||||
// {
|
||||
// impl->apu.load_state( *in.apu );
|
||||
// // prevent apu from running extra at beginning of frame
|
||||
// impl->apu.end_frame( -(int) nes.timestamp / ppu_overclock );
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// impl->apu.reset();
|
||||
// }
|
||||
|
||||
// ppu.load_state( in );
|
||||
|
||||
// if ( in.ram_valid )
|
||||
// memcpy( cpu::low_mem, in.ram, in.ram_size );
|
||||
|
||||
// sram_present = false;
|
||||
// if ( in.sram_size )
|
||||
// {
|
||||
// sram_present = true;
|
||||
// // memcpy( impl->sram, in.sram, min( (int) in.sram_size, (int) sizeof impl->sram ) );
|
||||
// enable_sram( true ); // mapper can override (read-only, unmapped, etc.)
|
||||
// }
|
||||
|
||||
// if ( in.mapper_valid ) // restore last since it might reconfigure things
|
||||
// mapper->load_state( *in.mapper );
|
||||
}
|
||||
|
||||
void irq_changed()
|
||||
{
|
||||
cpu_set_irq_time( earliest_irq( cpu_time() ) );
|
||||
|
@ -1032,12 +974,8 @@ private:
|
|||
unsigned char data_writer_mapped [page_count + 1];
|
||||
};
|
||||
|
||||
int mem_differs( void const* p, int cmp, unsigned long s );
|
||||
|
||||
inline int Nes_Core::cpu_read( nes_addr_t addr, nes_time_t time )
|
||||
{
|
||||
//LOG_FREQ( "cpu_read", 16, addr >> 12 );
|
||||
|
||||
{
|
||||
int result = cpu::low_mem [addr & 0x7FF];
|
||||
if ( !(addr & 0xE000) )
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include "Nes_State.h"
|
||||
#include "Nes_Mapper.h"
|
||||
|
||||
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
|
||||
|
@ -182,53 +181,6 @@ const char * Nes_Emu::load_ines( const uint8_t* buffer )
|
|||
return set_cart( &private_cart );
|
||||
}
|
||||
|
||||
const char * Nes_Emu::save_battery_ram( Auto_File_Writer out )
|
||||
{
|
||||
RETURN_ERR( out.open() );
|
||||
return out->write( emu.impl->sram, emu.impl->sram_size );
|
||||
}
|
||||
|
||||
const char * Nes_Emu::load_battery_ram( Auto_File_Reader in )
|
||||
{
|
||||
RETURN_ERR( in.open() );
|
||||
emu.sram_present = true;
|
||||
return in->read( emu.impl->sram, emu.impl->sram_size );
|
||||
}
|
||||
|
||||
void Nes_Emu::load_state( Nes_State_ const& in )
|
||||
{
|
||||
clear_sound_buf();
|
||||
emu.load_state( in );
|
||||
}
|
||||
|
||||
void Nes_Emu::load_state( Nes_State const& in )
|
||||
{
|
||||
loading_state( in );
|
||||
load_state( STATIC_CAST(Nes_State_ const&,in) );
|
||||
}
|
||||
|
||||
const char * Nes_Emu::load_state( Auto_File_Reader in )
|
||||
{
|
||||
Nes_State* state = new Nes_State;
|
||||
state->clear(); //initialize it
|
||||
CHECK_ALLOC( state );
|
||||
const char * err = state->read( in );
|
||||
if ( !err )
|
||||
load_state( *state );
|
||||
delete state;
|
||||
return err;
|
||||
}
|
||||
|
||||
const char * Nes_Emu::save_state( Auto_File_Writer out ) const
|
||||
{
|
||||
Nes_State* state = new Nes_State;
|
||||
CHECK_ALLOC( state );
|
||||
save_state( state );
|
||||
const char * err = state->write( out );
|
||||
delete state;
|
||||
return err;
|
||||
}
|
||||
|
||||
void Nes_Emu::write_chr( void const* p, long count, long offset )
|
||||
{
|
||||
long end = offset + count;
|
||||
|
@ -275,8 +227,7 @@ const char * Nes_Emu::set_sample_rate( long rate, Multi_Buffer* new_buf )
|
|||
|
||||
const char * Nes_Emu::set_sample_rate( long rate )
|
||||
{
|
||||
if ( !default_sound_buf )
|
||||
CHECK_ALLOC( default_sound_buf = new Mono_Buffer );
|
||||
if ( !default_sound_buf ) default_sound_buf = new Mono_Buffer;
|
||||
return set_sample_rate( rate, default_sound_buf );
|
||||
}
|
||||
|
||||
|
|
|
@ -139,24 +139,12 @@ public:
|
|||
// File save/load
|
||||
|
||||
// Save emulator state
|
||||
void save_state( Nes_State* s ) const { emu.save_state( s ); }
|
||||
const char * save_state( Auto_File_Writer ) const;
|
||||
size_t serializeState (uint8_t* buffer) const { return emu.serializeState(buffer); }
|
||||
size_t deserializeState (const uint8_t* buffer) { return emu.deserializeState(buffer); }
|
||||
|
||||
// Load state into emulator
|
||||
void load_state( Nes_State const& );
|
||||
const char * load_state( Auto_File_Reader );
|
||||
|
||||
// True if current cartridge claims it uses battery-backed memory
|
||||
bool has_battery_ram() const { return cart()->has_battery_ram(); }
|
||||
|
||||
// Save current battery RAM
|
||||
const char * save_battery_ram( Auto_File_Writer );
|
||||
|
||||
// Load battery RAM from file. Best called just after reset() or loading cartridge.
|
||||
const char * load_battery_ram( Auto_File_Reader );
|
||||
|
||||
// Graphics
|
||||
|
||||
// Number of frames generated per second
|
||||
|
@ -221,8 +209,6 @@ private:
|
|||
virtual const char * init_();
|
||||
|
||||
virtual void loading_state( Nes_State const& ) { }
|
||||
void load_state( Nes_State_ const& );
|
||||
void save_state( Nes_State_* s ) const { emu.save_state( s ); }
|
||||
long timestamp() const { return emu.nes.frame_count; }
|
||||
void set_timestamp( long t ) { emu.nes.frame_count = t; }
|
||||
|
||||
|
|
|
@ -1,213 +0,0 @@
|
|||
|
||||
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Nes_File.h"
|
||||
#include "blargg_endian.h"
|
||||
#include "blargg_source.h"
|
||||
|
||||
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
||||
more details. You should have received a copy of the GNU Lesser General
|
||||
Public License along with this module; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
// Nes_File_Writer
|
||||
|
||||
Nes_File_Writer::Nes_File_Writer()
|
||||
{
|
||||
write_remain = 0;
|
||||
depth_ = 0;
|
||||
}
|
||||
|
||||
Nes_File_Writer::~Nes_File_Writer()
|
||||
{
|
||||
}
|
||||
|
||||
const char * Nes_File_Writer::begin( Auto_File_Writer dw, nes_tag_t tag )
|
||||
{
|
||||
out = dw;
|
||||
RETURN_ERR( out.open_comp() );
|
||||
return begin_group( tag );
|
||||
}
|
||||
|
||||
const char * Nes_File_Writer::begin_group( nes_tag_t tag )
|
||||
{
|
||||
depth_++;
|
||||
return write_header( tag, group_begin_size );
|
||||
}
|
||||
|
||||
const char * Nes_File_Writer::write_header( nes_tag_t tag, long size )
|
||||
{
|
||||
nes_block_t h;
|
||||
h.tag = tag;
|
||||
h.size = size;
|
||||
h.swap();
|
||||
return out->write( &h, sizeof h );
|
||||
}
|
||||
|
||||
const char * Nes_File_Writer::write_block( nes_tag_t tag, void const* data, long size )
|
||||
{
|
||||
RETURN_ERR( write_block_header( tag, size ) );
|
||||
return write( data, size );
|
||||
}
|
||||
|
||||
const char * Nes_File_Writer::write_block_header( nes_tag_t tag, long size )
|
||||
{
|
||||
write_remain = size;
|
||||
return write_header( tag, size );
|
||||
}
|
||||
|
||||
const char *Nes_File_Writer::write( void const* p, long s )
|
||||
{
|
||||
write_remain -= s;
|
||||
return out->write( p, s );
|
||||
}
|
||||
|
||||
const char * Nes_File_Writer::end()
|
||||
{
|
||||
return end_group();
|
||||
}
|
||||
|
||||
const char * Nes_File_Writer::end_group()
|
||||
{
|
||||
depth_--;
|
||||
return write_header( group_end_tag, 0 );
|
||||
}
|
||||
|
||||
// Nes_File_Reader
|
||||
|
||||
Nes_File_Reader::Nes_File_Reader()
|
||||
{
|
||||
h.tag = 0;
|
||||
h.size = 0;
|
||||
block_type_ = invalid;
|
||||
depth_ = -1;
|
||||
}
|
||||
|
||||
Nes_File_Reader::~Nes_File_Reader()
|
||||
{
|
||||
}
|
||||
|
||||
const char * Nes_File_Reader::read_block_data( void* p, long s )
|
||||
{
|
||||
long extra = remain();
|
||||
if ( s > extra )
|
||||
s = extra;
|
||||
extra -= s;
|
||||
RETURN_ERR( read( p, s ) );
|
||||
if ( extra )
|
||||
RETURN_ERR( skip( extra ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * Nes_File_Reader::begin( Auto_File_Reader dr )
|
||||
{
|
||||
RETURN_ERR( dr.open() );
|
||||
in = dr;
|
||||
RETURN_ERR( read_header() );
|
||||
if ( block_type() != group_begin )
|
||||
return "File is wrong type";
|
||||
return enter_group();
|
||||
}
|
||||
|
||||
const char * Nes_File_Reader::read_header()
|
||||
{
|
||||
RETURN_ERR( in->read( &h, sizeof h ) );
|
||||
h.swap();
|
||||
block_type_ = data_block;
|
||||
if ( h.size == group_begin_size )
|
||||
{
|
||||
block_type_ = group_begin;
|
||||
h.size = 0;
|
||||
}
|
||||
if ( (long) h.tag == group_end_tag )
|
||||
{
|
||||
block_type_ = group_end;
|
||||
h.tag = 0;
|
||||
}
|
||||
set_remain( h.size );
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * Nes_File_Reader::next_block()
|
||||
{
|
||||
switch ( block_type() )
|
||||
{
|
||||
case group_end:
|
||||
return "Tried to go past end of blocks";
|
||||
|
||||
case group_begin: {
|
||||
int d = 1;
|
||||
do
|
||||
{
|
||||
RETURN_ERR( skip( h.size ) );
|
||||
RETURN_ERR( read_header() );
|
||||
if ( block_type() == group_begin )
|
||||
d++;
|
||||
if ( block_type() == group_end )
|
||||
d--;
|
||||
}
|
||||
while ( d > 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case data_block:
|
||||
RETURN_ERR( skip( h.size ) );
|
||||
break;
|
||||
|
||||
case invalid:
|
||||
break;
|
||||
}
|
||||
return read_header();
|
||||
}
|
||||
|
||||
const char * Nes_File_Reader::enter_group()
|
||||
{
|
||||
block_type_ = invalid; // cause next_block() not to skip group
|
||||
depth_++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * Nes_File_Reader::exit_group()
|
||||
{
|
||||
int d = 1;
|
||||
while ( true )
|
||||
{
|
||||
if ( block_type() == group_end )
|
||||
d--;
|
||||
if ( block_type() == group_begin )
|
||||
d++;
|
||||
if ( d == 0 )
|
||||
break;
|
||||
RETURN_ERR( skip( h.size ) );
|
||||
RETURN_ERR( read_header() );
|
||||
}
|
||||
|
||||
block_type_ = invalid; // cause next_block() to read past end block
|
||||
depth_--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * Nes_File_Reader::skip_v( int s )
|
||||
{
|
||||
if ( (unsigned long) s > h.size )
|
||||
return "Tried to skip past end of data";
|
||||
h.size -= s;
|
||||
set_remain( h.size );
|
||||
return in->skip( s );
|
||||
}
|
||||
|
||||
const char * Nes_File_Reader::read_v( void* p, int n )
|
||||
{
|
||||
if ( (unsigned long) n > h.size )
|
||||
n = h.size;
|
||||
h.size -= n;
|
||||
set_remain( h.size );
|
||||
return in->read( p, n );
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
|
||||
// NES block-oriented file access
|
||||
|
||||
// Nes_Emu 0.7.0
|
||||
|
||||
#ifndef NES_FILE_H
|
||||
#define NES_FILE_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
#include "abstract_file.h"
|
||||
#include "nes_data.h"
|
||||
|
||||
// Writes a structured file
|
||||
class Nes_File_Writer : public Data_Writer {
|
||||
public:
|
||||
Nes_File_Writer();
|
||||
~Nes_File_Writer();
|
||||
|
||||
// Begin writing file with specified signature tag
|
||||
const char * begin( Auto_File_Writer, nes_tag_t );
|
||||
|
||||
// Begin tagged group
|
||||
const char * begin_group( nes_tag_t );
|
||||
|
||||
// Write tagged block
|
||||
const char * write_block( nes_tag_t, void const*, long size );
|
||||
|
||||
// Write tagged block header. 'Size' bytes must be written before next block.
|
||||
const char * write_block_header( nes_tag_t, long size );
|
||||
|
||||
// Write data to current block
|
||||
const char *write( void const*, long );
|
||||
|
||||
// End tagged group
|
||||
const char * end_group();
|
||||
|
||||
// End file
|
||||
const char * end();
|
||||
|
||||
private:
|
||||
Auto_File_Writer out;
|
||||
long write_remain;
|
||||
int depth_;
|
||||
const char * write_header( nes_tag_t tag, long size );
|
||||
};
|
||||
|
||||
// Reads a structured file
|
||||
class Nes_File_Reader : public Data_Reader {
|
||||
public:
|
||||
Nes_File_Reader();
|
||||
~Nes_File_Reader();
|
||||
|
||||
// If true, verify checksums of any blocks that have them
|
||||
void enable_checksums( bool = true );
|
||||
|
||||
// Begin reading file. Until next_block() is called, block_tag() yields tag for file.
|
||||
const char * begin( Auto_File_Reader );
|
||||
|
||||
// Read header of next block in current group
|
||||
const char * next_block();
|
||||
|
||||
// Type of current block
|
||||
enum block_type_t {
|
||||
data_block,
|
||||
group_begin,
|
||||
group_end,
|
||||
invalid
|
||||
};
|
||||
block_type_t block_type() const { return block_type_; }
|
||||
|
||||
// Tag of current block
|
||||
nes_tag_t block_tag() const { return h.tag; }
|
||||
|
||||
// Read at most s bytes from block and skip any remaining bytes
|
||||
const char * read_block_data( void*, long s );
|
||||
|
||||
// Read at most 's' bytes from current block and return number of bytes actually read
|
||||
virtual const char * read_v( void*, int n );
|
||||
|
||||
// Skip 's' bytes in current block
|
||||
virtual const char * skip_v( int s );
|
||||
|
||||
// Read first sub-block of current group block
|
||||
const char * enter_group();
|
||||
|
||||
// Skip past current group
|
||||
const char * exit_group();
|
||||
|
||||
// Current depth, where 0 is top-level in file and higher is deeper
|
||||
int depth() const { return depth_; }
|
||||
|
||||
// True if all data has been read
|
||||
bool done() const { return depth() == 0 && block_type() == group_end; }
|
||||
private:
|
||||
Auto_File_Reader in;
|
||||
nes_block_t h;
|
||||
block_type_t block_type_;
|
||||
int depth_;
|
||||
const char * read_header();
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline const char * read_nes_state( Nes_File_Reader& in, T* out )
|
||||
{
|
||||
const char * err = in.read_block_data( out, sizeof *out );
|
||||
out->swap();
|
||||
return err;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline const char * write_nes_state( Nes_File_Writer& out, T& in )
|
||||
{
|
||||
in.swap();
|
||||
const char * err = out.write_block( in.tag, &in, sizeof in );
|
||||
in.swap();
|
||||
return err;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline const char * write_nes_state( Nes_File_Writer& out, const T& in )
|
||||
{
|
||||
T copy = in;
|
||||
copy.swap();
|
||||
return out.write_block( copy.tag, ©, sizeof copy );
|
||||
}
|
||||
|
||||
#endif
|
|
@ -8,11 +8,25 @@
|
|||
|
||||
#include "Nes_Cart.h"
|
||||
#include "Nes_Cpu.h"
|
||||
#include "nes_data.h"
|
||||
class Blip_Buffer;
|
||||
class blip_eq_t;
|
||||
class Nes_Core;
|
||||
|
||||
// Increase this (and let me know) if your mapper requires more state. This only
|
||||
// sets the size of the in-memory buffer; it doesn't affect the file format at all.
|
||||
static unsigned const max_mapper_state_size = 512; //was 256, needed more for VRC7 audio state
|
||||
struct mapper_state_t
|
||||
{
|
||||
int size;
|
||||
union {
|
||||
double align;
|
||||
uint8_t data [max_mapper_state_size];
|
||||
};
|
||||
|
||||
void write( const void* p, unsigned long s );
|
||||
int read( void* p, unsigned long s ) const;
|
||||
};
|
||||
|
||||
class Nes_Mapper {
|
||||
public:
|
||||
virtual ~Nes_Mapper();
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "Nes_Ppu.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "Nes_State.h"
|
||||
#include "Nes_Mapper.h"
|
||||
#include "Nes_Core.h"
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <cstdio>
|
||||
#include <string.h>
|
||||
#include "blargg_endian.h"
|
||||
#include "Nes_State.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
|
||||
|
@ -60,7 +59,6 @@ const char *Nes_Ppu_Impl::open_chr( uint8_t const* new_chr, long chr_data_size )
|
|||
if ( !impl )
|
||||
{
|
||||
impl = new impl_t;
|
||||
CHECK_ALLOC( impl );
|
||||
chr_ram = impl->chr_ram;
|
||||
}
|
||||
|
||||
|
@ -79,7 +77,6 @@ const char *Nes_Ppu_Impl::open_chr( uint8_t const* new_chr, long chr_data_size )
|
|||
// allocate aligned memory for cache
|
||||
long tile_count = chr_size / bytes_per_tile;
|
||||
tile_cache_mem = new uint8_t [tile_count * sizeof (cached_tile_t) * 2 + cache_line_size];
|
||||
CHECK_ALLOC( tile_cache_mem );
|
||||
tile_cache = (cached_tile_t*) (tile_cache_mem + cache_line_size -
|
||||
(uintptr_t) tile_cache_mem % cache_line_size);
|
||||
flipped_tiles = tile_cache + tile_count;
|
||||
|
@ -140,56 +137,6 @@ void Nes_Ppu_Impl::set_chr_bank_ex( int addr, int size, long data )
|
|||
}
|
||||
}
|
||||
|
||||
void Nes_Ppu_Impl::save_state( Nes_State_* out ) const
|
||||
{
|
||||
*out->ppu = *this;
|
||||
out->ppu_valid = true;
|
||||
|
||||
memcpy( out->spr_ram, spr_ram, out->spr_ram_size );
|
||||
out->spr_ram_valid = true;
|
||||
|
||||
out->nametable_size = 0x800;
|
||||
memcpy( out->nametable, impl->nt_ram, 0x800 );
|
||||
if ( nt_banks [3] >= &impl->nt_ram [0xC00] )
|
||||
{
|
||||
// save extra nametable data in chr
|
||||
out->nametable_size = 0x1000;
|
||||
memcpy( out->chr, &impl->nt_ram [0x800], 0x800 );
|
||||
}
|
||||
|
||||
out->chr_size = 0;
|
||||
if ( chr_is_writable )
|
||||
{
|
||||
out->chr_size = chr_size;
|
||||
memcpy( out->chr, impl->chr_ram, out->chr_size );
|
||||
}
|
||||
}
|
||||
|
||||
void Nes_Ppu_Impl::load_state( Nes_State_ const& in )
|
||||
{
|
||||
set_nt_banks( 0, 0, 0, 0 );
|
||||
set_chr_bank( 0, 0x2000, 0 );
|
||||
|
||||
if ( in.ppu_valid )
|
||||
STATIC_CAST(ppu_state_t&,*this) = *in.ppu;
|
||||
|
||||
if ( in.spr_ram_valid )
|
||||
memcpy( spr_ram, in.spr_ram, sizeof spr_ram );
|
||||
|
||||
if ( in.nametable_size >= 0x800 )
|
||||
{
|
||||
if ( in.nametable_size > 0x800 )
|
||||
memcpy( &impl->nt_ram [0x800], in.chr, 0x800 );
|
||||
memcpy( impl->nt_ram, in.nametable, 0x800 );
|
||||
}
|
||||
|
||||
if ( chr_is_writable && in.chr_size )
|
||||
{
|
||||
memcpy( impl->chr_ram, in.chr, in.chr_size );
|
||||
all_tiles_modified();
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t const initial_palette [0x20] =
|
||||
{
|
||||
0x0f,0x01,0x00,0x01,0x00,0x02,0x02,0x0D,0x08,0x10,0x08,0x24,0x00,0x00,0x04,0x2C,
|
||||
|
|
|
@ -6,9 +6,31 @@
|
|||
#ifndef NES_PPU_IMPL_H
|
||||
#define NES_PPU_IMPL_H
|
||||
|
||||
#include "nes_data.h"
|
||||
#include <blargg_common.h>
|
||||
#include <cstdint>
|
||||
|
||||
class Nes_State_;
|
||||
|
||||
struct ppu_state_t
|
||||
{
|
||||
uint8_t w2000; // control
|
||||
uint8_t w2001; // control
|
||||
uint8_t r2002; // status
|
||||
uint8_t w2003; // sprite ram addr
|
||||
uint8_t r2007; // vram read buffer
|
||||
uint8_t second_write; // next write to $2005/$2006 is second since last $2002 read
|
||||
uint16_t vram_addr; // loopy_v
|
||||
uint16_t vram_temp; // loopy_t
|
||||
uint8_t pixel_x; // fine-scroll (0-7)
|
||||
uint8_t unused;
|
||||
uint8_t palette [0x20]; // entries $10, $14, $18, $1c should be ignored
|
||||
uint16_t decay_low;
|
||||
uint16_t decay_high;
|
||||
uint8_t open_bus;
|
||||
uint8_t unused2[3];
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (ppu_state_t) == 20 + 0x20 );
|
||||
|
||||
class Nes_Ppu_Impl : public ppu_state_t {
|
||||
public:
|
||||
Nes_Ppu_Impl();
|
||||
|
|
|
@ -1,285 +0,0 @@
|
|||
|
||||
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Nes_State.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "blargg_endian.h"
|
||||
#include "Nes_Apu.h"
|
||||
#include "Nes_Emu.h"
|
||||
#include "Nes_Mapper.h"
|
||||
|
||||
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
||||
more details. You should have received a copy of the GNU Lesser General
|
||||
Public License along with this module; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
int mem_differs( void const* p, int cmp, unsigned long s )
|
||||
{
|
||||
unsigned char const* cp = (unsigned char*) p;
|
||||
while ( s-- )
|
||||
{
|
||||
if ( *cp++ != cmp )
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Nes_State::Nes_State()
|
||||
{
|
||||
Nes_State_::cpu = &this->cpu;
|
||||
Nes_State_::joypad = &this->joypad;
|
||||
Nes_State_::apu = &this->apu;
|
||||
Nes_State_::ppu = &this->ppu;
|
||||
Nes_State_::mapper = &this->mapper;
|
||||
Nes_State_::ram = this->ram;
|
||||
Nes_State_::sram = this->sram;
|
||||
Nes_State_::spr_ram = this->spr_ram;
|
||||
Nes_State_::nametable = this->nametable;
|
||||
Nes_State_::chr = this->chr;
|
||||
}
|
||||
|
||||
void Nes_State_::clear()
|
||||
{
|
||||
memset( &nes, 0, sizeof nes );
|
||||
nes.frame_count = static_cast<unsigned>(invalid_frame_count);
|
||||
|
||||
nes_valid = false;
|
||||
cpu_valid = false;
|
||||
joypad_valid = false;
|
||||
apu_valid = false;
|
||||
ppu_valid = false;
|
||||
mapper_valid = false;
|
||||
ram_valid = false;
|
||||
sram_size = 0;
|
||||
spr_ram_valid = false;
|
||||
nametable_size = 0;
|
||||
chr_size = 0;
|
||||
}
|
||||
|
||||
// write
|
||||
|
||||
const char * Nes_State_Writer::end( Nes_Emu const& emu )
|
||||
{
|
||||
Nes_State* state = new Nes_State;
|
||||
CHECK_ALLOC( state );
|
||||
emu.save_state( state );
|
||||
const char * err = end( *state );
|
||||
delete state;
|
||||
return err;
|
||||
}
|
||||
|
||||
const char * Nes_State_Writer::end( Nes_State const& ss )
|
||||
{
|
||||
RETURN_ERR( ss.write_blocks( *this ) );
|
||||
return Nes_File_Writer::end();
|
||||
}
|
||||
|
||||
const char * Nes_State::write( Auto_File_Writer out ) const
|
||||
{
|
||||
Nes_State_Writer writer;
|
||||
RETURN_ERR( writer.begin( out ) );
|
||||
return writer.end( *this );
|
||||
}
|
||||
|
||||
const char * Nes_State_::write_blocks( Nes_File_Writer& out ) const
|
||||
{
|
||||
if ( nes_valid )
|
||||
{
|
||||
nes_state_t s = nes;
|
||||
s.timestamp *= 5;
|
||||
RETURN_ERR( write_nes_state( out, s ) );
|
||||
}
|
||||
|
||||
if ( cpu_valid )
|
||||
{
|
||||
cpu_state_t s;
|
||||
memset( &s, 0, sizeof s );
|
||||
s.pc = cpu->pc;
|
||||
s.s = cpu->sp;
|
||||
s.a = cpu->a;
|
||||
s.x = cpu->x;
|
||||
s.y = cpu->y;
|
||||
s.p = cpu->status;
|
||||
RETURN_ERR( write_nes_state( out, s ) );
|
||||
}
|
||||
|
||||
if ( ppu_valid )
|
||||
{
|
||||
ppu_state_t s = *ppu;
|
||||
RETURN_ERR( write_nes_state( out, s ) );
|
||||
}
|
||||
|
||||
if ( apu_valid )
|
||||
{
|
||||
Nes_Apu::apu_state_t s = *apu;
|
||||
RETURN_ERR( write_nes_state( out, s ) );
|
||||
}
|
||||
|
||||
if ( joypad_valid )
|
||||
{
|
||||
joypad_state_t s = *joypad;
|
||||
RETURN_ERR( write_nes_state( out, s ) );
|
||||
}
|
||||
|
||||
if ( mapper_valid )
|
||||
RETURN_ERR( out.write_block( FOUR_CHAR('MAPR'), mapper->data, mapper->size ) );
|
||||
|
||||
if ( ram_valid )
|
||||
RETURN_ERR( out.write_block( FOUR_CHAR('LRAM'), ram, ram_size ) );
|
||||
|
||||
if ( spr_ram_valid )
|
||||
RETURN_ERR( out.write_block( FOUR_CHAR('SPRT'), spr_ram, spr_ram_size ) );
|
||||
|
||||
if ( nametable_size )
|
||||
{
|
||||
RETURN_ERR( out.write_block_header( FOUR_CHAR('NTAB'), nametable_size ) );
|
||||
RETURN_ERR( out.write( nametable, 0x800 ) );
|
||||
if ( nametable_size > 0x800 )
|
||||
RETURN_ERR( out.write( chr, 0x800 ) );
|
||||
}
|
||||
|
||||
if ( chr_size )
|
||||
RETURN_ERR( out.write_block( FOUR_CHAR('CHRR'), chr, chr_size ) );
|
||||
|
||||
if ( sram_size )
|
||||
RETURN_ERR( out.write_block( FOUR_CHAR('SRAM'), sram, sram_size ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read
|
||||
|
||||
Nes_State_Reader::Nes_State_Reader() { state_ = 0; owned = 0; }
|
||||
|
||||
Nes_State_Reader::~Nes_State_Reader() { delete owned; }
|
||||
|
||||
const char * Nes_State_Reader::begin( Auto_File_Reader dr, Nes_State* out )
|
||||
{
|
||||
state_ = out;
|
||||
if ( !out )
|
||||
CHECK_ALLOC( state_ = owned = new Nes_State );
|
||||
|
||||
RETURN_ERR( Nes_File_Reader::begin( dr ) );
|
||||
if ( block_tag() != state_file_tag )
|
||||
return "Not a state snapshot file";
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * Nes_State::read( Auto_File_Reader in )
|
||||
{
|
||||
Nes_State_Reader reader;
|
||||
RETURN_ERR( reader.begin( in, this ) );
|
||||
while ( !reader.done() )
|
||||
RETURN_ERR( reader.next_block() );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * Nes_State_Reader::next_block()
|
||||
{
|
||||
if ( depth() != 0 )
|
||||
return Nes_File_Reader::next_block();
|
||||
return state_->read_blocks( *this );
|
||||
}
|
||||
|
||||
void Nes_State_::set_nes_state( nes_state_t const& s )
|
||||
{
|
||||
nes = s;
|
||||
nes.timestamp /= 5;
|
||||
nes_valid = true;
|
||||
}
|
||||
|
||||
const char * Nes_State_::read_blocks( Nes_File_Reader& in )
|
||||
{
|
||||
while ( true )
|
||||
{
|
||||
RETURN_ERR( in.next_block() );
|
||||
switch ( in.block_tag() )
|
||||
{
|
||||
case nes_state_t::tag:
|
||||
memset( &nes, 0, sizeof nes );
|
||||
RETURN_ERR( read_nes_state( in, &nes ) );
|
||||
set_nes_state( nes );
|
||||
break;
|
||||
|
||||
case cpu_state_t::tag: {
|
||||
cpu_state_t s;
|
||||
memset( &s, 0, sizeof s );
|
||||
RETURN_ERR( read_nes_state( in, &s ) );
|
||||
cpu->pc = s.pc;
|
||||
cpu->sp = s.s;
|
||||
cpu->a = s.a;
|
||||
cpu->x = s.x;
|
||||
cpu->y = s.y;
|
||||
cpu->status = s.p;
|
||||
cpu_valid = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case ppu_state_t::tag:
|
||||
memset( ppu, 0, sizeof *ppu );
|
||||
RETURN_ERR( read_nes_state( in, ppu ) );
|
||||
ppu_valid = true;
|
||||
break;
|
||||
|
||||
case FOUR_CHAR('APUR'):
|
||||
memset( apu, 0, sizeof *apu );
|
||||
RETURN_ERR( read_nes_state( in, apu ) );
|
||||
apu_valid = true;
|
||||
break;
|
||||
|
||||
case joypad_state_t::tag:
|
||||
memset( joypad, 0, sizeof *joypad );
|
||||
RETURN_ERR( read_nes_state( in, joypad ) );
|
||||
joypad_valid = true;
|
||||
break;
|
||||
|
||||
case FOUR_CHAR('MAPR'):
|
||||
mapper->size = in.remain();
|
||||
RETURN_ERR( in.read_block_data( mapper->data, sizeof mapper->data ) );
|
||||
mapper_valid = true;
|
||||
break;
|
||||
|
||||
case FOUR_CHAR('SPRT'):
|
||||
spr_ram_valid = true;
|
||||
RETURN_ERR( in.read_block_data( spr_ram, spr_ram_size ) );
|
||||
break;
|
||||
|
||||
case FOUR_CHAR('NTAB'):
|
||||
nametable_size = in.remain();
|
||||
RETURN_ERR( in.read( nametable, 0x800 ) );
|
||||
if ( nametable_size > 0x800 )
|
||||
RETURN_ERR( in.read( chr, 0x800 ) );
|
||||
break;
|
||||
|
||||
case FOUR_CHAR('LRAM'):
|
||||
ram_valid = true;
|
||||
RETURN_ERR( in.read_block_data( ram, ram_size ) );
|
||||
break;
|
||||
|
||||
case FOUR_CHAR('CHRR'):
|
||||
chr_size = in.remain();
|
||||
RETURN_ERR( in.read_block_data( chr, chr_max ) );
|
||||
break;
|
||||
|
||||
case FOUR_CHAR('SRAM'):
|
||||
sram_size = in.remain();
|
||||
RETURN_ERR( in.read_block_data( sram, sram_max ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
|
||||
// NES state snapshot for saving and restoring emulator state
|
||||
|
||||
// Nes_Emu 0.7.0
|
||||
|
||||
#ifndef NES_STATE_H
|
||||
#define NES_STATE_H
|
||||
|
||||
#include "Nes_File.h"
|
||||
#include "Nes_Cpu.h"
|
||||
#include "Nes_Apu.h"
|
||||
class Nes_Emu;
|
||||
class Nes_State;
|
||||
|
||||
typedef long frame_count_t;
|
||||
|
||||
// Writes state to a file
|
||||
class Nes_State_Writer : public Nes_File_Writer {
|
||||
public:
|
||||
// Begin writing file
|
||||
const char * begin( Auto_File_Writer );
|
||||
|
||||
// Write emulator's current state to file and end
|
||||
const char * end( Nes_Emu const& );
|
||||
|
||||
// Write state to file and end
|
||||
const char * end( Nes_State const& );
|
||||
};
|
||||
|
||||
// Reads state from a file
|
||||
class Nes_State_Reader : public Nes_File_Reader {
|
||||
public:
|
||||
|
||||
// Begin reading state snapshot from file
|
||||
const char * begin( Auto_File_Reader, Nes_State* = 0 );
|
||||
|
||||
// Go to next unrecognized block in file
|
||||
const char * next_block();
|
||||
|
||||
// State as read from file. Only valid after all blocks have been read.
|
||||
Nes_State const& state() const;
|
||||
|
||||
public:
|
||||
Nes_State_Reader();
|
||||
~Nes_State_Reader();
|
||||
private:
|
||||
Nes_State* owned;
|
||||
Nes_State* state_;
|
||||
};
|
||||
|
||||
class Nes_State_ {
|
||||
public:
|
||||
|
||||
const char * write_blocks( Nes_File_Writer& ) const;
|
||||
void set_nes_state( nes_state_t const& );
|
||||
const char * read_blocks( Nes_File_Reader& );
|
||||
|
||||
enum { ram_size = 0x800 };
|
||||
enum { sram_max = 0x2000 };
|
||||
enum { spr_ram_size = 0x100 };
|
||||
enum { nametable_max = 0x800 };
|
||||
enum { chr_max = 0x2000 };
|
||||
uint8_t *ram, *sram, *spr_ram, *nametable, *chr;
|
||||
nes_state_t nes;
|
||||
Nes_Cpu::registers_t* cpu;
|
||||
joypad_state_t* joypad;
|
||||
Nes_Apu::apu_state_t* apu;
|
||||
ppu_state_t* ppu;
|
||||
mapper_state_t* mapper;
|
||||
|
||||
bool nes_valid, cpu_valid, joypad_valid, apu_valid, ppu_valid;
|
||||
bool mapper_valid, ram_valid, spr_ram_valid;
|
||||
short sram_size, nametable_size, chr_size;
|
||||
|
||||
// Invalidate all state
|
||||
void clear();
|
||||
|
||||
// Change timestamp
|
||||
void set_timestamp( frame_count_t );
|
||||
|
||||
// Timestamp snapshot was taken at
|
||||
frame_count_t timestamp() const;
|
||||
};
|
||||
|
||||
// Snapshot of emulator state
|
||||
class Nes_State : private Nes_State_ {
|
||||
public:
|
||||
|
||||
Nes_State();
|
||||
|
||||
// Write snapshot to file
|
||||
const char * write( Auto_File_Writer ) const;
|
||||
|
||||
// Read snapshot from file
|
||||
const char * read( Auto_File_Reader );
|
||||
|
||||
private:
|
||||
Nes_Cpu::registers_t cpu;
|
||||
joypad_state_t joypad;
|
||||
Nes_Apu::apu_state_t apu;
|
||||
ppu_state_t ppu;
|
||||
mapper_state_t mapper;
|
||||
uint8_t ram [ram_size];
|
||||
uint8_t sram [sram_max];
|
||||
uint8_t spr_ram [spr_ram_size];
|
||||
uint8_t nametable [nametable_max];
|
||||
uint8_t chr [chr_max];
|
||||
|
||||
friend class Nes_Emu;
|
||||
friend class Nes_State_Writer;
|
||||
friend class Nes_State_Reader;
|
||||
};
|
||||
|
||||
frame_count_t const invalid_frame_count = LONG_MAX / 2 + 1; // a large positive value
|
||||
|
||||
int mem_differs( void const* in, int compare, unsigned long count );
|
||||
|
||||
inline Nes_State const& Nes_State_Reader::state() const
|
||||
{
|
||||
return *state_;
|
||||
}
|
||||
|
||||
inline const char * Nes_State_Writer::begin( Auto_File_Writer dw )
|
||||
{
|
||||
return Nes_File_Writer::begin( dw, state_file_tag );
|
||||
}
|
||||
|
||||
inline void Nes_State_::set_timestamp( frame_count_t t ) { nes.frame_count = t; }
|
||||
|
||||
inline frame_count_t Nes_State_::timestamp() const { return nes.frame_count; }
|
||||
|
||||
#endif
|
|
@ -1,210 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
/* Copyright (C) 2005-2006 Shay Green. Permission is hereby granted, free of
|
||||
charge, to any person obtaining a copy of this software module and associated
|
||||
documentation files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell copies of the Software, and
|
||||
to permit persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions: The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions of the Software. THE
|
||||
SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
// Abstract file access interfaces
|
||||
|
||||
#include "Data_Reader.h"
|
||||
#include <cstring>
|
||||
|
||||
// Supports writing
|
||||
class Data_Writer {
|
||||
public:
|
||||
Data_Writer() { }
|
||||
virtual ~Data_Writer() { }
|
||||
|
||||
// Write 'n' bytes. NULL on success, otherwise error string.
|
||||
virtual const char *write( const void*, long ) { return 0; }
|
||||
|
||||
private:
|
||||
// noncopyable
|
||||
Data_Writer( const Data_Writer& );
|
||||
Data_Writer& operator = ( const Data_Writer& );
|
||||
};
|
||||
|
||||
// Write data to memory
|
||||
class Mem_Writer : public Data_Writer {
|
||||
char* data_;
|
||||
size_t size_;
|
||||
size_t allocated;
|
||||
enum { expanding, fixed, ignore_excess } mode;
|
||||
public:
|
||||
// Keep all written data in expanding block of memory
|
||||
Mem_Writer()
|
||||
{
|
||||
data_ = 0;
|
||||
size_ = 0;
|
||||
allocated = 0;
|
||||
mode = expanding;
|
||||
}
|
||||
|
||||
// Write to fixed-size block of memory. If ignore_excess is false, returns
|
||||
// error if more than 'size' data is written, otherwise ignores any excess.
|
||||
Mem_Writer( void* p, long s, int b )
|
||||
{
|
||||
data_ = (char*) p;
|
||||
size_ = 0;
|
||||
allocated = s;
|
||||
mode = b ? ignore_excess : fixed;
|
||||
}
|
||||
|
||||
const char * write( const void* p, long s )
|
||||
{
|
||||
long remain = allocated - size_;
|
||||
if ( s > remain )
|
||||
{
|
||||
if ( mode == fixed )
|
||||
return "Tried to write more data than expected";
|
||||
|
||||
if ( mode == ignore_excess )
|
||||
{
|
||||
s = remain;
|
||||
}
|
||||
else // expanding
|
||||
{
|
||||
long new_allocated = size_ + s;
|
||||
new_allocated += (new_allocated >> 1) + 2048;
|
||||
void* p = realloc( data_, new_allocated );
|
||||
if ( !p )
|
||||
return "Out of memory";
|
||||
data_ = (char*) p;
|
||||
allocated = new_allocated;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy( data_ + size_, p, s );
|
||||
size_ += s;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Pointer to beginning of written data
|
||||
char* data() { return data_; }
|
||||
|
||||
// Number of bytes written
|
||||
size_t size() const { return size_; }
|
||||
|
||||
~Mem_Writer()
|
||||
{
|
||||
if ( ( mode == expanding ) && data_ ) free( data_ );
|
||||
}
|
||||
};
|
||||
|
||||
// Dry writer to get the state size
|
||||
class Dry_Writer : public Data_Writer {
|
||||
long size_;
|
||||
|
||||
public:
|
||||
|
||||
Dry_Writer()
|
||||
{
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
~Dry_Writer()
|
||||
{
|
||||
}
|
||||
|
||||
const char *write( const void* p, long s )
|
||||
{
|
||||
size_ += s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Pointer to beginning of written data
|
||||
char* data() { return NULL; }
|
||||
|
||||
// Number of bytes written
|
||||
long size() const { return size_; }
|
||||
};
|
||||
|
||||
|
||||
// Auto_File to use in place of Data_Reader&/Data_Writer&, allowing a normal
|
||||
// file path to be used in addition to a Data_Reader/Data_Writer.
|
||||
|
||||
class Auto_File_Reader {
|
||||
public:
|
||||
Auto_File_Reader() : data( 0 ), path( 0 ) { }
|
||||
Auto_File_Reader( Data_Reader& r ) : data( &r ), path( 0 ) { }
|
||||
Auto_File_Reader( Auto_File_Reader const& );
|
||||
Auto_File_Reader& operator = ( Auto_File_Reader const& );
|
||||
|
||||
const char* open()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
~Auto_File_Reader()
|
||||
{
|
||||
if ( path )
|
||||
delete data;
|
||||
}
|
||||
|
||||
int operator ! () const { return !data; }
|
||||
Data_Reader* operator -> () const { return data; }
|
||||
Data_Reader& operator * () const { return *data; }
|
||||
private:
|
||||
/* mutable */ Data_Reader* data;
|
||||
const char* path;
|
||||
};
|
||||
|
||||
class Auto_File_Writer {
|
||||
public:
|
||||
Auto_File_Writer() : data( 0 ), path( 0 ) { }
|
||||
Auto_File_Writer( Data_Writer& r ) : data( &r ), path( 0 ) { }
|
||||
Auto_File_Writer( Auto_File_Writer const& );
|
||||
Auto_File_Writer& operator = ( Auto_File_Writer const& );
|
||||
|
||||
~Auto_File_Writer()
|
||||
{
|
||||
}
|
||||
|
||||
const char* open()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* open_comp( int level = -1 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int operator ! () const { return !data; }
|
||||
Data_Writer* operator -> () const { return data; }
|
||||
Data_Writer& operator * () const { return *data; }
|
||||
private:
|
||||
/* mutable */ Data_Writer* data;
|
||||
const char* path;
|
||||
};
|
||||
|
||||
inline Auto_File_Reader& Auto_File_Reader::operator = ( Auto_File_Reader const& r )
|
||||
{
|
||||
data = r.data;
|
||||
path = r.path;
|
||||
((Auto_File_Reader*) &r)->data = 0;
|
||||
return *this;
|
||||
}
|
||||
inline Auto_File_Reader::Auto_File_Reader( Auto_File_Reader const& r ) { *this = r; }
|
||||
|
||||
inline Auto_File_Writer& Auto_File_Writer::operator = ( Auto_File_Writer const& r )
|
||||
{
|
||||
data = r.data;
|
||||
path = r.path;
|
||||
((Auto_File_Writer*) &r)->data = 0;
|
||||
return *this;
|
||||
}
|
||||
inline Auto_File_Writer::Auto_File_Writer( Auto_File_Writer const& r ) { *this = r; }
|
|
@ -24,14 +24,6 @@ otherwise continues normally. */
|
|||
return blargg_return_err_;\
|
||||
} while ( 0 )
|
||||
|
||||
/* If ptr is NULL, returns out-of-memory error, otherwise continues normally. */
|
||||
#undef CHECK_ALLOC
|
||||
#define CHECK_ALLOC( ptr ) \
|
||||
do {\
|
||||
if ( !(ptr) )\
|
||||
return "Out of memory";\
|
||||
} while ( 0 )
|
||||
|
||||
template<typename T> T min( T x, T y ) { return x < y ? x : y; }
|
||||
template<typename T> T max( T x, T y ) { return x > y ? x : y; }
|
||||
|
||||
|
|
|
@ -21,6 +21,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|||
|
||||
// MMC1
|
||||
|
||||
struct mmc1_state_t
|
||||
{
|
||||
uint8_t regs [4]; // current registers (5 bits each)
|
||||
uint8_t bit; // number of bits in buffer (0 to 4)
|
||||
uint8_t buf; // currently buffered bits (new bits added to bottom)
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (mmc1_state_t) == 6 );
|
||||
|
||||
class Mapper001 : public Nes_Mapper, mmc1_state_t {
|
||||
public:
|
||||
Mapper001()
|
||||
|
|
|
@ -28,6 +28,19 @@ nes_time_t const last_scanline = first_scanline + 240 * Nes_Ppu::scanline_len;
|
|||
|
||||
// MMC3
|
||||
|
||||
struct mmc3_state_t
|
||||
{
|
||||
uint8_t banks [8]; // last writes to $8001 indexed by (mode & 7)
|
||||
uint8_t mode; // $8000
|
||||
uint8_t mirror; // $a000
|
||||
uint8_t sram_mode; // $a001
|
||||
uint8_t irq_ctr; // internal counter
|
||||
uint8_t irq_latch; // $c000
|
||||
uint8_t irq_enabled;// last write was to 0) $e000, 1) $e001
|
||||
uint8_t irq_flag;
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (mmc3_state_t) == 15 );
|
||||
|
||||
class Mapper004 : public Nes_Mapper, mmc3_state_t {
|
||||
public:
|
||||
Mapper004()
|
||||
|
|
|
@ -2,17 +2,14 @@
|
|||
|
||||
quickerNESSrc = [
|
||||
'Nes_Apu.cpp',
|
||||
'Nes_File.cpp',
|
||||
'Nes_Oscs.cpp',
|
||||
'Nes_Buffer.cpp',
|
||||
'Nes_Fme7_Apu.cpp',
|
||||
'Nes_Ppu.cpp',
|
||||
'Blip_Buffer.cpp',
|
||||
'Nes_Ppu_Impl.cpp',
|
||||
'Data_Reader.cpp',
|
||||
'Nes_Ppu_Rendering.cpp',
|
||||
'Effects_Buffer.cpp',
|
||||
'Nes_State.cpp',
|
||||
'emu2413.cpp',
|
||||
'emu2413_state.cpp',
|
||||
'Nes_Effects_Buffer.cpp',
|
||||
|
|
|
@ -1,182 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
// NES data file block formats
|
||||
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
||||
more details. You should have received a copy of the GNU Lesser General
|
||||
Public License along with this module; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
// Nes_Emu 0.7.0
|
||||
|
||||
#include "blargg_common.h"
|
||||
#include "blargg_endian.h"
|
||||
|
||||
typedef long nes_tag_t;
|
||||
|
||||
#if 'ABCD' == '\101\102\103\104'
|
||||
#define FOUR_CHAR( c ) (\
|
||||
((c) / '\1\0\0\0' % 0x100 * 0x01000000L) +\
|
||||
((c) / '\0\1\0\0' % 0x100 * 0x00010000L) +\
|
||||
((c) / '\0\0\1\0' % 0x100 * 0x00000100L) +\
|
||||
((c) / '\0\0\0\1' % 0x100 * 0x00000001L)\
|
||||
)
|
||||
#else
|
||||
#if 'ABCD' == 0x41424344
|
||||
#define FOUR_CHAR( c ) c
|
||||
#else
|
||||
#define FOUR_CHAR( c ) (\
|
||||
((c) / 0x01000000 % 0x100 * 0x00000001) +\
|
||||
((c) / 0x00010000 % 0x100 * 0x00000100) +\
|
||||
((c) / 0x00000100 % 0x100 * 0x00010000) +\
|
||||
((c) / 0x00000001 % 0x100 * 0x01000000)\
|
||||
)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Binary format of save state blocks. All multi-uint8_t values are stored in little-endian.
|
||||
|
||||
nes_tag_t const state_file_tag = FOUR_CHAR('NESS');
|
||||
|
||||
|
||||
// Name of cartridge file in 8-bit characters (UTF-8 preferred) with ".nes" etc *removed*,
|
||||
// no NUL termination. Yes: "Castlevania (U)". No: "Strider (U).nes".
|
||||
nes_tag_t const cart_name_tag = FOUR_CHAR('romn');
|
||||
|
||||
// CRC-32 of cartridge's PRG and CHR data combined
|
||||
nes_tag_t const cart_checksum_tag = FOUR_CHAR('csum');
|
||||
|
||||
struct nes_block_t
|
||||
{
|
||||
uint32_t tag; // ** stored in big-endian
|
||||
uint32_t size;
|
||||
|
||||
void swap()
|
||||
{
|
||||
SWAP_BE( tag );
|
||||
SWAP_LE( size );
|
||||
}
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (nes_block_t) == 8 );
|
||||
|
||||
unsigned long const group_begin_size = 0xffffffff; // group block has this size
|
||||
nes_tag_t const group_end_tag = FOUR_CHAR('gend'); // group end block has this tag
|
||||
|
||||
struct nes_state_t
|
||||
{
|
||||
uint16_t timestamp; // CPU clocks * 15 (for NTSC)
|
||||
uint8_t pal;
|
||||
uint8_t unused [1];
|
||||
uint32_t frame_count; // number of frames emulated since power-up
|
||||
|
||||
enum { tag = FOUR_CHAR('TIME') };
|
||||
void swap()
|
||||
{
|
||||
SWAP_LE( timestamp );
|
||||
SWAP_LE( frame_count );
|
||||
}
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (nes_state_t) == 8 );
|
||||
|
||||
struct joypad_state_t
|
||||
{
|
||||
uint32_t joypad_latches [2]; // joypad 1 & 2 shift registers
|
||||
uint8_t w4016; // strobe
|
||||
uint8_t unused [3];
|
||||
|
||||
enum { tag = FOUR_CHAR('CTRL') };
|
||||
void swap()
|
||||
{
|
||||
SWAP_LE( joypad_latches [0] );
|
||||
SWAP_LE( joypad_latches [1] );
|
||||
}
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (joypad_state_t) == 12 );
|
||||
|
||||
// Increase this (and let me know) if your mapper requires more state. This only
|
||||
// sets the size of the in-memory buffer; it doesn't affect the file format at all.
|
||||
unsigned const max_mapper_state_size = 512; //was 256, needed more for VRC7 audio state
|
||||
struct mapper_state_t
|
||||
{
|
||||
int size;
|
||||
union {
|
||||
double align;
|
||||
uint8_t data [max_mapper_state_size];
|
||||
};
|
||||
|
||||
void write( const void* p, unsigned long s );
|
||||
int read( void* p, unsigned long s ) const;
|
||||
};
|
||||
|
||||
struct cpu_state_t
|
||||
{
|
||||
uint16_t pc;
|
||||
uint8_t s;
|
||||
uint8_t p;
|
||||
uint8_t a;
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
uint8_t unused [1];
|
||||
|
||||
enum { tag = FOUR_CHAR('CPUR') };
|
||||
void swap()
|
||||
{
|
||||
SWAP_LE( pc );
|
||||
}
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (cpu_state_t) == 8 );
|
||||
|
||||
struct ppu_state_t
|
||||
{
|
||||
uint8_t w2000; // control
|
||||
uint8_t w2001; // control
|
||||
uint8_t r2002; // status
|
||||
uint8_t w2003; // sprite ram addr
|
||||
uint8_t r2007; // vram read buffer
|
||||
uint8_t second_write; // next write to $2005/$2006 is second since last $2002 read
|
||||
uint16_t vram_addr; // loopy_v
|
||||
uint16_t vram_temp; // loopy_t
|
||||
uint8_t pixel_x; // fine-scroll (0-7)
|
||||
uint8_t unused;
|
||||
uint8_t palette [0x20]; // entries $10, $14, $18, $1c should be ignored
|
||||
uint16_t decay_low;
|
||||
uint16_t decay_high;
|
||||
uint8_t open_bus;
|
||||
uint8_t unused2[3];
|
||||
|
||||
enum { tag = FOUR_CHAR('PPUR') };
|
||||
void swap()
|
||||
{
|
||||
SWAP_LE( vram_addr );
|
||||
SWAP_LE( vram_temp );
|
||||
SWAP_LE( decay_low );
|
||||
SWAP_LE( decay_high );
|
||||
}
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (ppu_state_t) == 20 + 0x20 );
|
||||
|
||||
struct mmc1_state_t
|
||||
{
|
||||
uint8_t regs [4]; // current registers (5 bits each)
|
||||
uint8_t bit; // number of bits in buffer (0 to 4)
|
||||
uint8_t buf; // currently buffered bits (new bits added to bottom)
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (mmc1_state_t) == 6 );
|
||||
|
||||
struct mmc3_state_t
|
||||
{
|
||||
uint8_t banks [8]; // last writes to $8001 indexed by (mode & 7)
|
||||
uint8_t mode; // $8000
|
||||
uint8_t mirror; // $a000
|
||||
uint8_t sram_mode; // $a001
|
||||
uint8_t irq_ctr; // internal counter
|
||||
uint8_t irq_latch; // $c000
|
||||
uint8_t irq_enabled;// last write was to 0) $e000, 1) $e001
|
||||
uint8_t irq_flag;
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (mmc3_state_t) == 15 );
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <Nes_Emu.h>
|
||||
#include <Nes_State.h>
|
||||
#include <emuInstance.hpp>
|
||||
|
||||
class QuickerNESInstance : public EmuInstance
|
||||
|
|
|
@ -22,10 +22,9 @@ int main(int argc, char *argv[])
|
|||
.help("Path to the test script file to run.")
|
||||
.required();
|
||||
|
||||
program.add_argument("--fullCycle")
|
||||
.help("Performs the full load / advance frame / save cycle, as opposed to just advance frame")
|
||||
.default_value(false)
|
||||
.implicit_value(true);
|
||||
program.add_argument("--cycleType")
|
||||
.help("Specifies the emulation actions to be performed per each input. Possible values: 'Simple': performs only advance state, 'Rerecord': performs load/advance/save, and 'Full': performs load/advance/save/advance.")
|
||||
.default_value(std::string("Simple"));
|
||||
|
||||
program.add_argument("--hashOutputFile")
|
||||
.help("Path to write the hash output to.")
|
||||
|
@ -42,7 +41,7 @@ int main(int argc, char *argv[])
|
|||
std::string hashOutputFile = program.get<std::string>("--hashOutputFile");
|
||||
|
||||
// Getting reproduce flag
|
||||
bool isFullCycle = program.get<bool>("--fullCycle");
|
||||
std::string cycleType = program.get<std::string>("--cycleType");
|
||||
|
||||
// Loading script file
|
||||
std::string scriptJsonRaw;
|
||||
|
@ -120,7 +119,7 @@ int main(int argc, char *argv[])
|
|||
// Printing test information
|
||||
printf("[] -----------------------------------------\n");
|
||||
printf("[] Running Script: '%s'\n", scriptFilePath.c_str());
|
||||
printf("[] Cycle Type: '%s'\n", isFullCycle ? "Advance / Load / Advance / Save" : "Advance Only");
|
||||
printf("[] Cycle Type: '%s'\n", cycleType.c_str());
|
||||
printf("[] Emulation Core: '%s'\n", emulationCoreName.c_str());
|
||||
printf("[] ROM File: '%s'\n", romFilePath.c_str());
|
||||
printf("[] ROM SHA1: '%s'\n", romSHA1.c_str());
|
||||
|
@ -137,14 +136,19 @@ int main(int argc, char *argv[])
|
|||
uint8_t* currentState = (uint8_t*) malloc (stateSize);
|
||||
e.serializeState(currentState);
|
||||
|
||||
// Check whether to perform each action
|
||||
bool doPreAdvance = cycleType == "Full";
|
||||
bool doDeserialize = cycleType == "Rerecord" || cycleType == "Full";
|
||||
bool doSerialize = cycleType == "Rerecord" || cycleType == "Full";
|
||||
|
||||
// Actually running the sequence
|
||||
auto t0 = std::chrono::high_resolution_clock::now();
|
||||
for (const std::string& input : sequence)
|
||||
{
|
||||
if (isFullCycle == true) e.advanceState(input);
|
||||
if (isFullCycle == true) e.deserializeState(currentState);
|
||||
if (doPreAdvance == true) e.advanceState(input);
|
||||
if (doDeserialize == true) e.deserializeState(currentState);
|
||||
e.advanceState(input);
|
||||
if (isFullCycle == true) e.serializeState(currentState);
|
||||
if (doSerialize == true) e.serializeState(currentState);
|
||||
}
|
||||
auto tf = std::chrono::high_resolution_clock::now();
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
game = 'arkanoid'
|
||||
|
||||
bash = find_program('bash')
|
||||
|
||||
goal = 'warpless'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
||||
|
||||
goal = 'warps'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
|
@ -0,0 +1,7 @@
|
|||
game = 'castlevania1'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
||||
|
||||
goal = 'pacifist'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
|
@ -0,0 +1,4 @@
|
|||
game = 'galaga'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
|
@ -1,9 +0,0 @@
|
|||
game = 'arkanoid'
|
||||
|
||||
bash = find_program('bash')
|
||||
|
||||
goal = 'warpless'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
||||
|
||||
goal = 'warps'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -1,593 +0,0 @@
|
|||
~/quickerNES/tests/games/arkanoid ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'warps.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Arkanoid (U) [!].nes'
|
||||
[] ROM SHA1: 'B2B30C4F30DD853C215C17B0C67CFE63D61A3062'
|
||||
[] Verification State File: 'warps.final.state'
|
||||
[] Sequence File: 'warps.sol'
|
||||
[] Sequence Length: 15806
|
||||
[] Initial State Hash: 0xB1413A628D2B1D1B79B4F07B3E70AE83
|
||||
[] State Size: 12793 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.371s
|
||||
[] Performance: 42649.438 steps / s
|
||||
[] Final State Hash: 0x1FA0AE49927B0C7485B8A8931F14A57A
|
||||
[] Verification Hash: 0x1FA0AE49927B0C7485B8A8931F14A57A (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'warps.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Arkanoid (U) [!].nes'
|
||||
[] ROM SHA1: 'B2B30C4F30DD853C215C17B0C67CFE63D61A3062'
|
||||
[] Verification State File: 'warps.final.state'
|
||||
[] Sequence File: 'warps.sol'
|
||||
[] Sequence Length: 15806
|
||||
[] Initial State Hash: 0xB1413A628D2B1D1B79B4F07B3E70AE83
|
||||
[] State Size: 12793 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.466s
|
||||
[] Performance: 33946.979 steps / s
|
||||
[] Final State Hash: 0x1FA0AE49927B0C7485B8A8931F14A57A
|
||||
[] Verification Hash: 0x1FA0AE49927B0C7485B8A8931F14A57A (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/arkanoid ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'warpless.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Arkanoid (U) [!].nes'
|
||||
[] ROM SHA1: 'B2B30C4F30DD853C215C17B0C67CFE63D61A3062'
|
||||
[] Verification State File: 'warpless.final.state'
|
||||
[] Sequence File: 'warpless.sol'
|
||||
[] Sequence Length: 39431
|
||||
[] Initial State Hash: 0xB1413A628D2B1D1B79B4F07B3E70AE83
|
||||
[] State Size: 12793 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.041s
|
||||
[] Performance: 37887.081 steps / s
|
||||
[] Final State Hash: 0xCDD173D996245BF7133375B2217A01C
|
||||
[] Verification Hash: 0xCDD173D996245BF7133375B2217A01C (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'warpless.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Arkanoid (U) [!].nes'
|
||||
[] ROM SHA1: 'B2B30C4F30DD853C215C17B0C67CFE63D61A3062'
|
||||
[] Verification State File: 'warpless.final.state'
|
||||
[] Sequence File: 'warpless.sol'
|
||||
[] Sequence Length: 39431
|
||||
[] Initial State Hash: 0xB1413A628D2B1D1B79B4F07B3E70AE83
|
||||
[] State Size: 12793 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.284s
|
||||
[] Performance: 30711.413 steps / s
|
||||
[] Final State Hash: 0xCDD173D996245BF7133375B2217A01C
|
||||
[] Verification Hash: 0xCDD173D996245BF7133375B2217A01C (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/ninjaGaiden2 ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'pacifist.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Ninja Gaiden II - The Dark Sword of Chaos (U) [!].nes'
|
||||
[] ROM SHA1: 'B1796660E4A4CEFC72181D4BF4F97999BC048A77'
|
||||
[] Verification State File: 'pacifist.final.state'
|
||||
[] Sequence File: 'pacifist.sol'
|
||||
[] Sequence Length: 36619
|
||||
[] Initial State Hash: 0x3CA9F26CF6511A0694C15C1FF876FCC
|
||||
[] State Size: 12807 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.322s
|
||||
[] Performance: 27709.000 steps / s
|
||||
[] Final State Hash: 0xB6A66050EB4D7445D6A84A76D7B2BB65
|
||||
[] Verification Hash: 0xB6A66050EB4D7445D6A84A76D7B2BB65 (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'pacifist.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Ninja Gaiden II - The Dark Sword of Chaos (U) [!].nes'
|
||||
[] ROM SHA1: 'B1796660E4A4CEFC72181D4BF4F97999BC048A77'
|
||||
[] Verification State File: 'pacifist.final.state'
|
||||
[] Sequence File: 'pacifist.sol'
|
||||
[] Sequence Length: 36619
|
||||
[] Initial State Hash: 0x3CA9F26CF6511A0694C15C1FF876FCC
|
||||
[] State Size: 12807 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.444s
|
||||
[] Performance: 25359.141 steps / s
|
||||
[] Final State Hash: 0xB6A66050EB4D7445D6A84A76D7B2BB65
|
||||
[] Verification Hash: 0xB6A66050EB4D7445D6A84A76D7B2BB65 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/ninjaGaiden2 ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Ninja Gaiden II - The Dark Sword of Chaos (U) [!].nes'
|
||||
[] ROM SHA1: 'B1796660E4A4CEFC72181D4BF4F97999BC048A77'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 34660
|
||||
[] Initial State Hash: 0x3CA9F26CF6511A0694C15C1FF876FCC
|
||||
[] State Size: 12807 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.229s
|
||||
[] Performance: 28201.243 steps / s
|
||||
[] Final State Hash: 0xDF97F201F54959948D4C4B89C4D220FC
|
||||
[] Verification Hash: 0xDF97F201F54959948D4C4B89C4D220FC (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Ninja Gaiden II - The Dark Sword of Chaos (U) [!].nes'
|
||||
[] ROM SHA1: 'B1796660E4A4CEFC72181D4BF4F97999BC048A77'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 34660
|
||||
[] Initial State Hash: 0x3CA9F26CF6511A0694C15C1FF876FCC
|
||||
[] State Size: 12807 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.349s
|
||||
[] Performance: 25693.351 steps / s
|
||||
[] Final State Hash: 0xDF97F201F54959948D4C4B89C4D220FC
|
||||
[] Verification Hash: 0xDF97F201F54959948D4C4B89C4D220FC (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/superOffroad ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Ivan 'Ironman' Stewart's Super Off Road (USA).nes'
|
||||
[] ROM SHA1: '57919B685B55EE3ED3AD98FB1D25626B98BE7D39'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 182180
|
||||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 6.923s
|
||||
[] Performance: 26314.176 steps / s
|
||||
[] Final State Hash: 0xF0F317E40A902D175E6902B49500DF4B
|
||||
[] Verification Hash: 0xF0F317E40A902D175E6902B49500DF4B (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Ivan 'Ironman' Stewart's Super Off Road (USA).nes'
|
||||
[] ROM SHA1: '57919B685B55EE3ED3AD98FB1D25626B98BE7D39'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 182180
|
||||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 8.073s
|
||||
[] Performance: 22567.975 steps / s
|
||||
[] Final State Hash: 0xF0F317E40A902D175E6902B49500DF4B
|
||||
[] Verification Hash: 0xF0F317E40A902D175E6902B49500DF4B (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/nigelMansell ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Nigel Mansell's World Championship Challenge (U) [!].nes'
|
||||
[] ROM SHA1: 'BBE5CF2DFA0B5422776A530D6F1B617238A8569F'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 296590
|
||||
[] Initial State Hash: 0xB6C7EB1C577108C7C0E045D00EC73DDC
|
||||
[] State Size: 12798 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 10.213s
|
||||
[] Performance: 29040.916 steps / s
|
||||
[] Final State Hash: 0x407AA16502BE4D678916D218B1310132
|
||||
[] Verification Hash: 0x407AA16502BE4D678916D218B1310132 (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Nigel Mansell's World Championship Challenge (U) [!].nes'
|
||||
[] ROM SHA1: 'BBE5CF2DFA0B5422776A530D6F1B617238A8569F'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 296590
|
||||
[] Initial State Hash: 0xB6C7EB1C577108C7C0E045D00EC73DDC
|
||||
[] State Size: 12798 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 11.460s
|
||||
[] Performance: 25880.599 steps / s
|
||||
[] Final State Hash: 0x407AA16502BE4D678916D218B1310132
|
||||
[] Verification Hash: 0x407AA16502BE4D678916D218B1310132 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/castlevania1 ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'pacifist.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Castlevania (U) (PRG0) [!].nes'
|
||||
[] ROM SHA1: 'A31B8BD5B370A9103343C866F3C2B2998E889341'
|
||||
[] Verification State File: 'pacifist.final.state'
|
||||
[] Sequence File: 'pacifist.sol'
|
||||
[] Sequence Length: 39555
|
||||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.197s
|
||||
[] Performance: 33054.929 steps / s
|
||||
[] Final State Hash: 0x65214803DC4559ABBED8C449F04D4C91
|
||||
[] Verification Hash: 0x65214803DC4559ABBED8C449F04D4C91 (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'pacifist.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Castlevania (U) (PRG0) [!].nes'
|
||||
[] ROM SHA1: 'A31B8BD5B370A9103343C866F3C2B2998E889341'
|
||||
[] Verification State File: 'pacifist.final.state'
|
||||
[] Sequence File: 'pacifist.sol'
|
||||
[] Sequence Length: 39555
|
||||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.456s
|
||||
[] Performance: 27170.490 steps / s
|
||||
[] Final State Hash: 0x65214803DC4559ABBED8C449F04D4C91
|
||||
[] Verification Hash: 0x65214803DC4559ABBED8C449F04D4C91 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/castlevania1 ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Castlevania (U) (PRG0) [!].nes'
|
||||
[] ROM SHA1: 'A31B8BD5B370A9103343C866F3C2B2998E889341'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 37338
|
||||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.205s
|
||||
[] Performance: 30997.240 steps / s
|
||||
[] Final State Hash: 0x9042C9EFA138F36E505AA33BF50436
|
||||
[] Verification Hash: 0x9042C9EFA138F36E505AA33BF50436 (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Castlevania (U) (PRG0) [!].nes'
|
||||
[] ROM SHA1: 'A31B8BD5B370A9103343C866F3C2B2998E889341'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 37338
|
||||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.379s
|
||||
[] Performance: 27072.935 steps / s
|
||||
[] Final State Hash: 0x9042C9EFA138F36E505AA33BF50436
|
||||
[] Verification Hash: 0x9042C9EFA138F36E505AA33BF50436 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/saintSeiyaKanketsuHen ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Saint Seiya - Ougon Densetsu Kanketsu Hen (J) [!].nes'
|
||||
[] ROM SHA1: 'F871D9B3DAFDDCDAD5F2ACD71044292E5169064E'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 86170
|
||||
[] Initial State Hash: 0x7BE2D5D63A0545DF3D44A5881CA69E9D
|
||||
[] State Size: 12798 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 2.279s
|
||||
[] Performance: 37805.440 steps / s
|
||||
[] Final State Hash: 0xFFB8ABEE93CDEA838DB6B69470AC819A
|
||||
[] Verification Hash: 0xFFB8ABEE93CDEA838DB6B69470AC819A (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Saint Seiya - Ougon Densetsu Kanketsu Hen (J) [!].nes'
|
||||
[] ROM SHA1: 'F871D9B3DAFDDCDAD5F2ACD71044292E5169064E'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 86170
|
||||
[] Initial State Hash: 0x7BE2D5D63A0545DF3D44A5881CA69E9D
|
||||
[] State Size: 12798 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 2.578s
|
||||
[] Performance: 33421.778 steps / s
|
||||
[] Final State Hash: 0xFFB8ABEE93CDEA838DB6B69470AC819A
|
||||
[] Verification Hash: 0xFFB8ABEE93CDEA838DB6B69470AC819A (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/tennis ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Tennis (JU) [!].nes'
|
||||
[] ROM SHA1: '80D99C035E6A5AB9718E413EC25CBE094F085962'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 40627
|
||||
[] Initial State Hash: 0x43443FDD057BBE517B4CDA12736CAD67
|
||||
[] State Size: 12792 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.987s
|
||||
[] Performance: 41154.805 steps / s
|
||||
[] Final State Hash: 0x926C1D6B031E5BD739B13B5734C3D500
|
||||
[] Verification Hash: 0x926C1D6B031E5BD739B13B5734C3D500 (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Tennis (JU) [!].nes'
|
||||
[] ROM SHA1: '80D99C035E6A5AB9718E413EC25CBE094F085962'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 40627
|
||||
[] Initial State Hash: 0x43443FDD057BBE517B4CDA12736CAD67
|
||||
[] State Size: 12792 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.139s
|
||||
[] Performance: 35662.187 steps / s
|
||||
[] Final State Hash: 0x926C1D6B031E5BD739B13B5734C3D500
|
||||
[] Verification Hash: 0x926C1D6B031E5BD739B13B5734C3D500 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/superMarioBros ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'warps.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Super Mario Bros. (W) [!].nes'
|
||||
[] ROM SHA1: 'EA343F4E445A9050D4B4FBAC2C77D0693B1D0922'
|
||||
[] Verification State File: 'warps.final.state'
|
||||
[] Sequence File: 'warps.sol'
|
||||
[] Sequence Length: 17866
|
||||
[] Initial State Hash: 0x1F405ED3A13732A3DBEDC4C54A50AC79
|
||||
[] State Size: 12792 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.711s
|
||||
[] Performance: 25110.880 steps / s
|
||||
[] Final State Hash: 0xFBB1BE4D99BB17041747DF056C079D57
|
||||
[] Verification Hash: 0xFBB1BE4D99BB17041747DF056C079D57 (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'warps.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Super Mario Bros. (W) [!].nes'
|
||||
[] ROM SHA1: 'EA343F4E445A9050D4B4FBAC2C77D0693B1D0922'
|
||||
[] Verification State File: 'warps.final.state'
|
||||
[] Sequence File: 'warps.sol'
|
||||
[] Sequence Length: 17866
|
||||
[] Initial State Hash: 0x1F405ED3A13732A3DBEDC4C54A50AC79
|
||||
[] State Size: 12792 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.796s
|
||||
[] Performance: 22454.426 steps / s
|
||||
[] Final State Hash: 0xFBB1BE4D99BB17041747DF056C079D57
|
||||
[] Verification Hash: 0xFBB1BE4D99BB17041747DF056C079D57 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/superMarioBros ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'warpless.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Super Mario Bros. (W) [!].nes'
|
||||
[] ROM SHA1: 'EA343F4E445A9050D4B4FBAC2C77D0693B1D0922'
|
||||
[] Verification State File: 'warpless.final.state'
|
||||
[] Sequence File: 'warpless.sol'
|
||||
[] Sequence Length: 67115
|
||||
[] Initial State Hash: 0x1F405ED3A13732A3DBEDC4C54A50AC79
|
||||
[] State Size: 12792 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 2.669s
|
||||
[] Performance: 25144.154 steps / s
|
||||
[] Final State Hash: 0xDC3A45216E64D193849B0B248D18E0C3
|
||||
[] Verification Hash: 0xDC3A45216E64D193849B0B248D18E0C3 (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'warpless.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Super Mario Bros. (W) [!].nes'
|
||||
[] ROM SHA1: 'EA343F4E445A9050D4B4FBAC2C77D0693B1D0922'
|
||||
[] Verification State File: 'warpless.final.state'
|
||||
[] Sequence File: 'warpless.sol'
|
||||
[] Sequence Length: 67115
|
||||
[] Initial State Hash: 0x1F405ED3A13732A3DBEDC4C54A50AC79
|
||||
[] State Size: 12792 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 3.027s
|
||||
[] Performance: 22172.893 steps / s
|
||||
[] Final State Hash: 0xDC3A45216E64D193849B0B248D18E0C3
|
||||
[] Verification Hash: 0xDC3A45216E64D193849B0B248D18E0C3 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/ninjaGaiden ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'pacifist.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Ninja Gaiden (U) [!].nes'
|
||||
[] ROM SHA1: 'CA513F841D75EFEB33BB8099FB02BEEB39F6BB9C'
|
||||
[] Verification State File: 'pacifist.final.state'
|
||||
[] Sequence File: 'pacifist.sol'
|
||||
[] Sequence Length: 40680
|
||||
[] Initial State Hash: 0x7CC865ED649238B850937BAE9DCADC5
|
||||
[] State Size: 12798 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.354s
|
||||
[] Performance: 30050.484 steps / s
|
||||
[] Final State Hash: 0x358165AE6BC7A3EAE0E08D24F9A19BC6
|
||||
[] Verification Hash: 0x358165AE6BC7A3EAE0E08D24F9A19BC6 (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'pacifist.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Ninja Gaiden (U) [!].nes'
|
||||
[] ROM SHA1: 'CA513F841D75EFEB33BB8099FB02BEEB39F6BB9C'
|
||||
[] Verification State File: 'pacifist.final.state'
|
||||
[] Sequence File: 'pacifist.sol'
|
||||
[] Sequence Length: 40680
|
||||
[] Initial State Hash: 0x7CC865ED649238B850937BAE9DCADC5
|
||||
[] State Size: 12798 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.495s
|
||||
[] Performance: 27202.786 steps / s
|
||||
[] Final State Hash: 0x358165AE6BC7A3EAE0E08D24F9A19BC6
|
||||
[] Verification Hash: 0x358165AE6BC7A3EAE0E08D24F9A19BC6 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/ninjaGaiden ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Ninja Gaiden (U) [!].nes'
|
||||
[] ROM SHA1: 'CA513F841D75EFEB33BB8099FB02BEEB39F6BB9C'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 39111
|
||||
[] Initial State Hash: 0x7CC865ED649238B850937BAE9DCADC5
|
||||
[] State Size: 12798 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.283s
|
||||
[] Performance: 30473.552 steps / s
|
||||
[] Final State Hash: 0x5527602EE5679B55EC45BA654B704477
|
||||
[] Verification Hash: 0x5527602EE5679B55EC45BA654B704477 (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Ninja Gaiden (U) [!].nes'
|
||||
[] ROM SHA1: 'CA513F841D75EFEB33BB8099FB02BEEB39F6BB9C'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 39111
|
||||
[] Initial State Hash: 0x7CC865ED649238B850937BAE9DCADC5
|
||||
[] State Size: 12798 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.410s
|
||||
[] Performance: 27739.742 steps / s
|
||||
[] Final State Hash: 0x5527602EE5679B55EC45BA654B704477
|
||||
[] Verification Hash: 0x5527602EE5679B55EC45BA654B704477 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/ironSword ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Ironsword - Wizards & Warriors II (U) [!].nes'
|
||||
[] ROM SHA1: '97B79E432F62403FB9F877090850C41112A9A168'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 25785
|
||||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.850s
|
||||
[] Performance: 30334.074 steps / s
|
||||
[] Final State Hash: 0xCCB65DF6BED258071A720C5FA2FE4FB9
|
||||
[] Verification Hash: 0xCCB65DF6BED258071A720C5FA2FE4FB9 (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Ironsword - Wizards & Warriors II (U) [!].nes'
|
||||
[] ROM SHA1: '97B79E432F62403FB9F877090850C41112A9A168'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 25785
|
||||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.972s
|
||||
[] Performance: 26518.493 steps / s
|
||||
[] Final State Hash: 0xCCB65DF6BED258071A720C5FA2FE4FB9
|
||||
[] Verification Hash: 0xCCB65DF6BED258071A720C5FA2FE4FB9 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/saintSeiyaOugonDensetsu ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Saint Seiya - Ougon Densetsu (J) [!].nes'
|
||||
[] ROM SHA1: '3F3B499CF50386084E053BCA096AE8E52330CFAE'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 76723
|
||||
[] Initial State Hash: 0xA1482537F260939E3E0059719CD723AD
|
||||
[] State Size: 12793 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 2.249s
|
||||
[] Performance: 34119.293 steps / s
|
||||
[] Final State Hash: 0xC988A4BDCB3B44DA54AD97D2F2E0F4AF
|
||||
[] Verification Hash: 0xC988A4BDCB3B44DA54AD97D2F2E0F4AF (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/princeOfPersia ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'lvl7.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Prince of Persia (U) [!].nes'
|
||||
[] ROM SHA1: '6B58F149F34FA829135619C58700CAAA95B9CDE3'
|
||||
[] Verification State File: 'lvl7.final.state'
|
||||
[] Sequence File: 'lvl7.sol'
|
||||
[] Sequence Length: 26003
|
||||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.679s
|
||||
[] Performance: 38318.621 steps / s
|
||||
[] Final State Hash: 0x3D0ACE9B9D592AE6922354DDC3682BAB
|
||||
[] Verification Hash: 0x3D0ACE9B9D592AE6922354DDC3682BAB (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'lvl7.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Prince of Persia (U) [!].nes'
|
||||
[] ROM SHA1: '6B58F149F34FA829135619C58700CAAA95B9CDE3'
|
||||
[] Verification State File: 'lvl7.final.state'
|
||||
[] Sequence File: 'lvl7.sol'
|
||||
[] Sequence Length: 26003
|
||||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.796s
|
||||
[] Performance: 32683.333 steps / s
|
||||
[] Final State Hash: 0x3D0ACE9B9D592AE6922354DDC3682BAB
|
||||
[] Verification Hash: 0x3D0ACE9B9D592AE6922354DDC3682BAB (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/solarJetman ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Solar Jetman - Hunt for the Golden Warpship (U) [!].nes'
|
||||
[] ROM SHA1: '872B91A2F7A2F635061EF43F79E7F7E9F59F5C50'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 45983
|
||||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.699s
|
||||
[] Performance: 27068.620 steps / s
|
||||
[] Final State Hash: 0x1E08CEBDE3EC56B659D54328D3D9E344
|
||||
[] Verification Hash: 0x1E08CEBDE3EC56B659D54328D3D9E344 (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Solar Jetman - Hunt for the Golden Warpship (U) [!].nes'
|
||||
[] ROM SHA1: '872B91A2F7A2F635061EF43F79E7F7E9F59F5C50'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 45983
|
||||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.946s
|
||||
[] Performance: 23625.746 steps / s
|
||||
[] Final State Hash: 0x1E08CEBDE3EC56B659D54328D3D9E344
|
||||
[] Verification Hash: 0x1E08CEBDE3EC56B659D54328D3D9E344 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
~/quickerNES/tests/games/galaga ~/quickerNES/tests/games
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickerNES'
|
||||
[] ROM File: 'Galaga - Demons of Death (U) [!].nes'
|
||||
[] ROM SHA1: 'DA54C223D79FA59EB95437854B677CF69B5CAC8A'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 29916
|
||||
[] Initial State Hash: 0x4BB3E8B61F496038D8A01894B8B824F
|
||||
[] State Size: 12792 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.870s
|
||||
[] Performance: 34371.423 steps / s
|
||||
[] Final State Hash: 0x4E40A40820C188009A061C5C7FC7DB29
|
||||
[] Verification Hash: 0x4E40A40820C188009A061C5C7FC7DB29 (Passed)
|
||||
[] -----------------------------------------
|
||||
[] Running Script: 'anyPercent.test'
|
||||
[] Emulation Core: 'QuickNES'
|
||||
[] ROM File: 'Galaga - Demons of Death (U) [!].nes'
|
||||
[] ROM SHA1: 'DA54C223D79FA59EB95437854B677CF69B5CAC8A'
|
||||
[] Verification State File: 'anyPercent.final.state'
|
||||
[] Sequence File: 'anyPercent.sol'
|
||||
[] Sequence Length: 29916
|
||||
[] Initial State Hash: 0x4BB3E8B61F496038D8A01894B8B824F
|
||||
[] State Size: 12792 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.002s
|
||||
[] Performance: 29855.358 steps / s
|
||||
[] Final State Hash: 0x4E40A40820C188009A061C5C7FC7DB29
|
||||
[] Verification Hash: 0x4E40A40820C188009A061C5C7FC7DB29 (Passed)
|
||||
~/quickerNES/tests/games
|
|
@ -1,7 +0,0 @@
|
|||
game = 'castlevania1'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
||||
|
||||
goal = 'pacifist'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(),timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -1,4 +0,0 @@
|
|||
game = 'galaga'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -1,4 +0,0 @@
|
|||
game = 'ironSword'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -1,22 +0,0 @@
|
|||
nomalloc = environment({'MALLOC_PERTURB_': '0'})
|
||||
|
||||
bash = find_program('bash')
|
||||
testCommands = ['../run_test.sh', quickerNESTester.path(), quickNESTester.path() ]
|
||||
testTimeout = 120
|
||||
|
||||
subdir('arkanoid')
|
||||
subdir('castlevania1')
|
||||
subdir('superOffroad')
|
||||
subdir('princeOfPersia')
|
||||
subdir('ninjaGaiden')
|
||||
subdir('ninjaGaiden2')
|
||||
subdir('ironSword')
|
||||
subdir('solarJetman')
|
||||
subdir('tennis')
|
||||
subdir('nigelMansell')
|
||||
subdir('galaga')
|
||||
subdir('saintSeiyaOugonDensetsu')
|
||||
subdir('saintSeiyaKanketsuHen')
|
||||
subdir('superMarioBros')
|
||||
subdir('superMarioBros3')
|
||||
subdir('saiyuukiWorld')
|
|
@ -1,4 +0,0 @@
|
|||
game = 'nigelMansell'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -1,7 +0,0 @@
|
|||
game = 'ninjaGaiden'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
||||
|
||||
goal = 'pacifist'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -1,7 +0,0 @@
|
|||
game = 'ninjaGaiden2'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
||||
|
||||
goal = 'pacifist'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -1,4 +0,0 @@
|
|||
game = 'princeOfPersia'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -1,4 +0,0 @@
|
|||
game = 'saintSeiyaKanketsuHen'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -1,4 +0,0 @@
|
|||
game = 'saintSeiyaOugonDensetsu'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -1,4 +0,0 @@
|
|||
game = 'solarJetman'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -1,7 +0,0 @@
|
|||
game = 'superMarioBros'
|
||||
|
||||
goal = 'warps'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
||||
|
||||
goal = 'warpless'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -1,4 +0,0 @@
|
|||
game = 'superMarioBros3'
|
||||
|
||||
goal = 'warps'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -1,4 +0,0 @@
|
|||
game = 'superOffroad'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -1,4 +0,0 @@
|
|||
game = 'tennis'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
|
@ -0,0 +1,4 @@
|
|||
game = 'ironSword'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
|
@ -1,3 +1,22 @@
|
|||
nomalloc = environment({'MALLOC_PERTURB_': '0'})
|
||||
|
||||
subdir('games')
|
||||
bash = find_program('bash')
|
||||
testCommands = ['../run_test.sh', quickerNESTester.path(), quickNESTester.path() ]
|
||||
testTimeout = 120
|
||||
|
||||
subdir('arkanoid')
|
||||
subdir('castlevania1')
|
||||
subdir('superOffroad')
|
||||
subdir('princeOfPersia')
|
||||
subdir('ninjaGaiden')
|
||||
subdir('ninjaGaiden2')
|
||||
subdir('ironSword')
|
||||
subdir('solarJetman')
|
||||
subdir('tennis')
|
||||
subdir('nigelMansell')
|
||||
subdir('galaga')
|
||||
subdir('saintSeiyaOugonDensetsu')
|
||||
subdir('saintSeiyaKanketsuHen')
|
||||
subdir('superMarioBros')
|
||||
subdir('superMarioBros3')
|
||||
subdir('saiyuukiWorld')
|
|
@ -0,0 +1,4 @@
|
|||
game = 'nigelMansell'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
|
@ -0,0 +1,7 @@
|
|||
game = 'ninjaGaiden'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
||||
|
||||
goal = 'pacifist'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
|
@ -0,0 +1,7 @@
|
|||
game = 'ninjaGaiden2'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
||||
|
||||
goal = 'pacifist'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
|
@ -0,0 +1,4 @@
|
|||
game = 'princeOfPersia'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
|
@ -16,10 +16,10 @@ for script in ${testScriptList}; do
|
|||
pushd ${folder}
|
||||
|
||||
# Running script on quickerNES
|
||||
quickerNESTester ${fileName}
|
||||
quickerNESTester ${fileName} --cycleType Rerecord
|
||||
|
||||
# Running script on quickerNES
|
||||
quickNESTester ${fileName}
|
||||
quickNESTester ${fileName} --cycleType Rerecord
|
||||
|
||||
# Coming back
|
||||
popd
|
|
@ -17,9 +17,15 @@ testerArgs=${@:4}
|
|||
mode="normal"
|
||||
if [ "${4}" = "--fullCycle" ]; then mode="fullCycle"; fi
|
||||
|
||||
# Getting current folder (game name)
|
||||
folder=`basename $PWD`
|
||||
|
||||
# Getting pid (for uniqueness)
|
||||
pid=$$
|
||||
|
||||
# Hash files
|
||||
quickerNESHashFile="quickerNES.${script}.${mode}.hash"
|
||||
quickNESHashFile="quickNES.${script}.${mode}.hash"
|
||||
quickerNESHashFile="/tmp/quickerNES.${folder}.${script}.${mode}.${pid}.hash"
|
||||
quickNESHashFile="/tmp/quickNES.${folder}.${script}.${mode}.${pid}.hash"
|
||||
|
||||
# Removing them if already present
|
||||
rm -f ${quickerNESHashFile}
|
|
@ -0,0 +1,4 @@
|
|||
game = 'saintSeiyaKanketsuHen'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
|
@ -0,0 +1,4 @@
|
|||
game = 'saintSeiyaOugonDensetsu'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
|
@ -3,7 +3,7 @@ game = 'saiyuukiWorld'
|
|||
bash = find_program('bash')
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
||||
|
||||
goal = 'lastHalf'
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--fullCycle'], suite: [ game, goal ] )
|
||||
test(goal + '-FullCycle', bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
|
@ -0,0 +1,4 @@
|
|||
game = 'solarJetman'
|
||||
|
||||
goal = 'anyPercent'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), timeout: testTimeout, args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
|
@ -0,0 +1,7 @@
|
|||
game = 'superMarioBros'
|
||||
|
||||
goal = 'warps'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
||||
|
||||
goal = 'warpless'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
|
@ -0,0 +1,4 @@
|
|||
game = 'superMarioBros3'
|
||||
|
||||
goal = 'warps'
|
||||
test(goal, bash, workdir : meson.current_source_dir(), args : [ testCommands, goal + '.test', '--cycleType', 'Full'], suite: [ game, goal ] )
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue