Reverting changes back to 0c8318e26e
since some of those commits did something that affected performance
This commit is contained in:
parent
95a95df8e1
commit
66e6632eea
|
@ -26,6 +26,7 @@ quickerNESCoreSrc = [
|
|||
'source/core/Nes_Cpu.cpp',
|
||||
'source/core/Nes_State.cpp',
|
||||
'source/core/emu2413.cpp',
|
||||
'source/core/nes_data.cpp',
|
||||
'source/core/nes_util.cpp',
|
||||
'source/core/emu2413_state.cpp',
|
||||
'source/core/Nes_Effects_Buffer.cpp',
|
||||
|
@ -40,7 +41,7 @@ quickerNESCoreSrc = [
|
|||
# quickerNES Core Configuration
|
||||
|
||||
quickerNESCoreDependency = declare_dependency(
|
||||
compile_args : [ '-Wfatal-errors', '-Wall', '-Werror', '-Wno-multichar', '-DBLARGG_NONPORTABLE'],
|
||||
compile_args : [ '-Wfatal-errors', '-Wall', '-Wno-multichar' ],
|
||||
include_directories : include_directories(['source', 'source/core', 'extern']),
|
||||
sources : [ quickerNESCoreSrc, 'extern/metrohash128/metrohash128.cpp' ]
|
||||
)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
||||
|
||||
#include <algorithm>
|
||||
#include "Data_Reader.h"
|
||||
|
||||
#include "blargg_endian.h"
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -20,7 +20,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|||
|
||||
// Data_Reader
|
||||
|
||||
const char * Data_Reader::read( void* p, size_t n )
|
||||
const char * Data_Reader::read( void* p, int n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return "Internal usage bug";
|
||||
|
@ -38,20 +38,52 @@ const char * Data_Reader::read( void* p, size_t 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 = std::min( count, (int) sizeof buf );
|
||||
int n = min( count, (int) sizeof buf );
|
||||
count -= n;
|
||||
RETURN_ERR( read_v( buf, n ) );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * Data_Reader::skip( size_t n )
|
||||
const char * Data_Reader::skip( int n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return "Internal usage bug";
|
||||
|
||||
if ( n <= 0 )
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -4,10 +4,8 @@
|
|||
#ifndef DATA_READER_H
|
||||
#define DATA_READER_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <stdint.h>
|
||||
#include "blargg_common.h"
|
||||
#include "blargg_source.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,
|
||||
|
@ -24,33 +22,18 @@ 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, size_t* count )
|
||||
{
|
||||
int n = std::min(*count, remain());
|
||||
*count = 0;
|
||||
|
||||
if ( n <= 0 )
|
||||
return 0;
|
||||
|
||||
const char * err = read_v( p, n );
|
||||
if ( !err )
|
||||
{
|
||||
remain_ -= n;
|
||||
*count = n;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
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, size_t n );
|
||||
const char * read( void* p, int n );
|
||||
|
||||
// Number of bytes remaining until end of file
|
||||
size_t remain() const { return remain_; }
|
||||
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( size_t n );
|
||||
const char * skip( int n );
|
||||
|
||||
virtual ~Data_Reader() { }
|
||||
|
||||
|
@ -64,7 +47,7 @@ protected:
|
|||
Data_Reader() : remain_( 0 ) { }
|
||||
|
||||
// Sets remain
|
||||
void set_remain( size_t n ) { remain_ = n; }
|
||||
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.
|
||||
|
|
|
@ -163,7 +163,7 @@ Nes_Nonlinearizer::Nes_Nonlinearizer()
|
|||
float const gain = 0x7fff * 1.3f;
|
||||
// don't use entire range, so any overflow will stay within table
|
||||
int const range = (int) (table_size * Nes_Apu::nonlinear_tnd_gain());
|
||||
for (uint32_t i = 0; i < table_size; i++ )
|
||||
for ( int i = 0; i < table_size; i++ )
|
||||
{
|
||||
int const offset = table_size - range;
|
||||
int j = i - offset;
|
||||
|
|
|
@ -11,8 +11,8 @@ class Nes_Apu;
|
|||
|
||||
class Nes_Nonlinearizer {
|
||||
private:
|
||||
static const uint8_t table_bits = 11;
|
||||
static const uint32_t table_size = 1 << table_bits;
|
||||
enum { table_bits = 11 };
|
||||
enum { table_size = 1 << table_bits };
|
||||
int16_t table [table_size];
|
||||
Nes_Apu* apu;
|
||||
long accum;
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
|
||||
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Nes_Core.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "Nes_Mapper.h"
|
||||
#include "Nes_State.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
|
||||
|
@ -9,76 +17,9 @@ 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. http://www.slack.net/~ant/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include "Nes_Core.h"
|
||||
#include "Nes_Mapper.h"
|
||||
#include "Nes_State.h"
|
||||
#include "blargg_source.h"
|
||||
|
||||
/*
|
||||
New mapping distribution by Sergio Martin (eien86)
|
||||
https://github.com/SergioMartin86/jaffarPlus
|
||||
*/
|
||||
#include "mappers/mapper000.hpp"
|
||||
#include "mappers/mapper001.hpp"
|
||||
#include "mappers/mapper002.hpp"
|
||||
#include "mappers/mapper003.hpp"
|
||||
#include "mappers/mapper004.hpp"
|
||||
#include "mappers/mapper005.hpp"
|
||||
#include "mappers/mapper007.hpp"
|
||||
#include "mappers/mapper009.hpp"
|
||||
#include "mappers/mapper010.hpp"
|
||||
#include "mappers/mapper011.hpp"
|
||||
#include "mappers/mapper015.hpp"
|
||||
#include "mappers/mapper019.hpp"
|
||||
#include "mappers/mapper021.hpp"
|
||||
#include "mappers/mapper022.hpp"
|
||||
#include "mappers/mapper023.hpp"
|
||||
#include "mappers/mapper024.hpp"
|
||||
#include "mappers/mapper025.hpp"
|
||||
#include "mappers/mapper026.hpp"
|
||||
#include "mappers/mapper030.hpp"
|
||||
#include "mappers/mapper032.hpp"
|
||||
#include "mappers/mapper033.hpp"
|
||||
#include "mappers/mapper034.hpp"
|
||||
#include "mappers/mapper060.hpp"
|
||||
#include "mappers/mapper066.hpp"
|
||||
#include "mappers/mapper069.hpp"
|
||||
#include "mappers/mapper070.hpp"
|
||||
#include "mappers/mapper071.hpp"
|
||||
#include "mappers/mapper073.hpp"
|
||||
#include "mappers/mapper075.hpp"
|
||||
#include "mappers/mapper078.hpp"
|
||||
#include "mappers/mapper079.hpp"
|
||||
#include "mappers/mapper085.hpp"
|
||||
#include "mappers/mapper086.hpp"
|
||||
#include "mappers/mapper087.hpp"
|
||||
#include "mappers/mapper088.hpp"
|
||||
#include "mappers/mapper089.hpp"
|
||||
#include "mappers/mapper093.hpp"
|
||||
#include "mappers/mapper094.hpp"
|
||||
#include "mappers/mapper097.hpp"
|
||||
#include "mappers/mapper113.hpp"
|
||||
#include "mappers/mapper140.hpp"
|
||||
#include "mappers/mapper152.hpp"
|
||||
#include "mappers/mapper154.hpp"
|
||||
#include "mappers/mapper156.hpp"
|
||||
#include "mappers/mapper180.hpp"
|
||||
#include "mappers/mapper184.hpp"
|
||||
#include "mappers/mapper190.hpp"
|
||||
#include "mappers/mapper193.hpp"
|
||||
#include "mappers/mapper206.hpp"
|
||||
#include "mappers/mapper207.hpp"
|
||||
#include "mappers/mapper232.hpp"
|
||||
#include "mappers/mapper240.hpp"
|
||||
#include "mappers/mapper241.hpp"
|
||||
#include "mappers/mapper244.hpp"
|
||||
#include "mappers/mapper246.hpp"
|
||||
|
||||
|
||||
extern const char unsupported_mapper [] = "Unsupported mapper";
|
||||
|
||||
bool const wait_states_enabled = true;
|
||||
|
@ -129,79 +70,9 @@ const char * Nes_Core::open( Nes_Cart const* new_cart )
|
|||
|
||||
RETURN_ERR( init() );
|
||||
|
||||
// Getting cartdrige mapper code
|
||||
auto mapperCode = new_cart->mapper_code();
|
||||
|
||||
// Storage for the mapper, NULL by default
|
||||
mapper = NULL;
|
||||
|
||||
// Now checking if the detected mapper code is supported
|
||||
if (mapperCode == 0) mapper = new Mapper000();
|
||||
if (mapperCode == 1) mapper = new Mapper001();
|
||||
if (mapperCode == 2) mapper = new Mapper002();
|
||||
if (mapperCode == 3) mapper = new Mapper003();
|
||||
if (mapperCode == 4) mapper = new Mapper004();
|
||||
if (mapperCode == 5) mapper = new Mapper005();
|
||||
if (mapperCode == 7) mapper = new Mapper007();
|
||||
if (mapperCode == 9) mapper = new Mapper009();
|
||||
if (mapperCode == 10) mapper = new Mapper010();
|
||||
if (mapperCode == 11) mapper = new Mapper011();
|
||||
if (mapperCode == 15) mapper = new Mapper015();
|
||||
if (mapperCode == 19) mapper = new Mapper019();
|
||||
if (mapperCode == 21) mapper = new Mapper021();
|
||||
if (mapperCode == 22) mapper = new Mapper022();
|
||||
if (mapperCode == 23) mapper = new Mapper023();
|
||||
if (mapperCode == 24) mapper = new Mapper024();
|
||||
if (mapperCode == 25) mapper = new Mapper025();
|
||||
if (mapperCode == 26) mapper = new Mapper026();
|
||||
if (mapperCode == 30) mapper = new Mapper030();
|
||||
if (mapperCode == 32) mapper = new Mapper032();
|
||||
if (mapperCode == 33) mapper = new Mapper033();
|
||||
if (mapperCode == 34) mapper = new Mapper034();
|
||||
if (mapperCode == 60) mapper = new Mapper060();
|
||||
if (mapperCode == 66) mapper = new Mapper066();
|
||||
if (mapperCode == 69) mapper = new Mapper069();
|
||||
if (mapperCode == 70) mapper = new Mapper070();
|
||||
if (mapperCode == 71) mapper = new Mapper071();
|
||||
if (mapperCode == 73) mapper = new Mapper073();
|
||||
if (mapperCode == 75) mapper = new Mapper075();
|
||||
if (mapperCode == 78) mapper = new Mapper078();
|
||||
if (mapperCode == 79) mapper = new Mapper079();
|
||||
if (mapperCode == 85) mapper = new Mapper085();
|
||||
if (mapperCode == 86) mapper = new Mapper086();
|
||||
if (mapperCode == 87) mapper = new Mapper087();
|
||||
if (mapperCode == 88) mapper = new Mapper088();
|
||||
if (mapperCode == 89) mapper = new Mapper089();
|
||||
if (mapperCode == 93) mapper = new Mapper093();
|
||||
if (mapperCode == 94) mapper = new Mapper094();
|
||||
if (mapperCode == 97) mapper = new Mapper097();
|
||||
if (mapperCode == 113) mapper = new Mapper113();
|
||||
if (mapperCode == 140) mapper = new Mapper140();
|
||||
if (mapperCode == 152) mapper = new Mapper152();
|
||||
if (mapperCode == 154) mapper = new Mapper154();
|
||||
if (mapperCode == 156) mapper = new Mapper156();
|
||||
if (mapperCode == 180) mapper = new Mapper180();
|
||||
if (mapperCode == 184) mapper = new Mapper184();
|
||||
if (mapperCode == 190) mapper = new Mapper190();
|
||||
if (mapperCode == 193) mapper = new Mapper193();
|
||||
if (mapperCode == 206) mapper = new Mapper206();
|
||||
if (mapperCode == 207) mapper = new Mapper207();
|
||||
if (mapperCode == 232) mapper = new Mapper232();
|
||||
if (mapperCode == 240) mapper = new Mapper240();
|
||||
if (mapperCode == 241) mapper = new Mapper241();
|
||||
if (mapperCode == 244) mapper = new Mapper244();
|
||||
if (mapperCode == 246) mapper = new Mapper246();
|
||||
|
||||
// If no mapper was found, return null (error) now
|
||||
if (mapper == NULL)
|
||||
{
|
||||
fprintf(stderr, "Could not find mapper for code: %u\n", mapperCode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Assigning backwards pointers to cartdrige and emulator now
|
||||
mapper->setCartridge(new_cart);
|
||||
mapper->setCore(this);
|
||||
mapper = Nes_Mapper::create( new_cart, this );
|
||||
if ( !mapper )
|
||||
return unsupported_mapper;
|
||||
|
||||
RETURN_ERR( ppu.open_chr( new_cart->chr(), new_cart->chr_size() ) );
|
||||
|
||||
|
@ -296,7 +167,7 @@ void Nes_Core::load_state( Nes_State_ const& in )
|
|||
if ( in.sram_size )
|
||||
{
|
||||
sram_present = true;
|
||||
memcpy( impl->sram, in.sram, std::min( (int) in.sram_size, (int) sizeof impl->sram ) );
|
||||
memcpy( impl->sram, in.sram, min( (int) in.sram_size, (int) sizeof impl->sram ) );
|
||||
enable_sram( true ); // mapper can override (read-only, unmapped, etc.)
|
||||
}
|
||||
|
||||
|
@ -334,6 +205,16 @@ void Nes_Core::enable_sram( bool b, bool read_only )
|
|||
}
|
||||
}
|
||||
|
||||
// Unmapped memory
|
||||
|
||||
#ifndef NDEBUG
|
||||
static nes_addr_t last_unmapped_addr;
|
||||
#endif
|
||||
|
||||
void Nes_Core::log_unmapped( nes_addr_t addr, int data )
|
||||
{
|
||||
}
|
||||
|
||||
inline void Nes_Core::cpu_adjust_time( int n )
|
||||
{
|
||||
ppu_2002_time -= n;
|
||||
|
@ -395,6 +276,10 @@ void Nes_Core::write_io( nes_addr_t addr, int data )
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
log_unmapped( addr, data );
|
||||
#endif
|
||||
}
|
||||
|
||||
int Nes_Core::read_io( nes_addr_t addr )
|
||||
|
@ -413,6 +298,10 @@ int Nes_Core::read_io( nes_addr_t addr )
|
|||
if ( addr == Nes_Apu::status_addr )
|
||||
return impl->apu.read_status( clock() );
|
||||
|
||||
#ifndef NDEBUG
|
||||
log_unmapped( addr );
|
||||
#endif
|
||||
|
||||
return addr >> 8; // simulate open bus
|
||||
}
|
||||
|
||||
|
@ -484,7 +373,7 @@ void Nes_Core::vector_interrupt( nes_addr_t vector )
|
|||
|
||||
inline nes_time_t Nes_Core::earliest_irq( nes_time_t present )
|
||||
{
|
||||
return std::min( impl->apu.earliest_irq( present ), mapper->next_irq( present ) );
|
||||
return min( impl->apu.earliest_irq( present ), mapper->next_irq( present ) );
|
||||
}
|
||||
|
||||
void Nes_Core::irq_changed()
|
||||
|
@ -509,13 +398,13 @@ inline nes_time_t Nes_Core::earliest_event( nes_time_t present )
|
|||
|
||||
// DMC
|
||||
if ( wait_states_enabled )
|
||||
t = std::min( t, impl->apu.next_dmc_read_time() + 1 );
|
||||
t = min( t, impl->apu.next_dmc_read_time() + 1 );
|
||||
|
||||
// NMI
|
||||
t = std::min( t, ppu.nmi_time() );
|
||||
t = min( t, ppu.nmi_time() );
|
||||
|
||||
if ( single_instruction_mode )
|
||||
t = std::min( t, present + 1 );
|
||||
t = min( t, present + 1 );
|
||||
|
||||
return t;
|
||||
}
|
||||
|
|
|
@ -104,7 +104,6 @@ public: private: friend class Nes_Mapper;
|
|||
void add_mapper_intercept( nes_addr_t start, unsigned size, bool read, bool write );
|
||||
|
||||
public: private: friend class Nes_Cpu;
|
||||
|
||||
int cpu_read_ppu( nes_addr_t, nes_time_t );
|
||||
int cpu_read( nes_addr_t, nes_time_t );
|
||||
void cpu_write( nes_addr_t, int data, nes_time_t );
|
||||
|
|
|
@ -1,4 +1,15 @@
|
|||
|
||||
// Nes_Emu 0.7.0. http://www.slack.net/~ant/nes-emu/
|
||||
|
||||
// TODO: remove
|
||||
#if !defined (NDEBUG) && 0
|
||||
#pragma peephole on
|
||||
#pragma global_optimizer on
|
||||
#pragma optimization_level 4
|
||||
#pragma scheduling 604
|
||||
#undef BLARGG_ENABLE_OPTIMIZER
|
||||
#endif
|
||||
|
||||
#include "Nes_Cpu.h"
|
||||
|
||||
#include <string.h>
|
||||
|
@ -8,17 +19,59 @@
|
|||
|
||||
#include "nes_cpu_io.h"
|
||||
|
||||
/* Copyright (C) 2003-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 */
|
||||
|
||||
#define NES_CPU_READ_PPU( cpu, addr, time ) STATIC_CAST(Nes_Core&,*cpu).cpu_read_ppu( addr, time )
|
||||
#define NES_CPU_READ( cpu, addr, time ) STATIC_CAST(Nes_Core&,*cpu).cpu_read( addr, time )
|
||||
#define NES_CPU_WRITEX( cpu, addr, data, time ) {STATIC_CAST(Nes_Core&,*cpu).cpu_write( addr, data, time );}
|
||||
#define NES_CPU_WRITE( cpu, addr, data, time ) \
|
||||
{\
|
||||
if ( addr < 0x800 ) cpu->low_mem [addr] = data;\
|
||||
else if ( addr == 0x2007 ) STATIC_CAST(Nes_Core&,*cpu).cpu_write_2007( data );\
|
||||
else STATIC_CAST(Nes_Core&,*cpu).cpu_write( addr, data, time );\
|
||||
#include "blargg_source.h"
|
||||
|
||||
#ifdef BLARGG_ENABLE_OPTIMIZER
|
||||
#include BLARGG_ENABLE_OPTIMIZER
|
||||
#endif
|
||||
|
||||
inline void Nes_Cpu::set_code_page( int i, uint8_t const* p )
|
||||
{
|
||||
code_map [i] = p - (unsigned) i * page_size;
|
||||
}
|
||||
|
||||
void Nes_Cpu::reset( void const* unmapped_page )
|
||||
{
|
||||
r.status = 0;
|
||||
r.sp = 0;
|
||||
r.pc = 0;
|
||||
r.a = 0;
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
|
||||
error_count_ = 0;
|
||||
clock_count = 0;
|
||||
clock_limit = 0;
|
||||
irq_time_ = LONG_MAX / 2 + 1;
|
||||
end_time_ = LONG_MAX / 2 + 1;
|
||||
|
||||
set_code_page( 0, low_mem );
|
||||
set_code_page( 1, low_mem );
|
||||
set_code_page( 2, low_mem );
|
||||
set_code_page( 3, low_mem );
|
||||
for ( int i = 4; i < page_count + 1; i++ )
|
||||
set_code_page( i, (uint8_t*) unmapped_page );
|
||||
|
||||
isCorrectExecution = true;
|
||||
}
|
||||
|
||||
void Nes_Cpu::map_code( nes_addr_t start, unsigned size, const void* data )
|
||||
{
|
||||
unsigned first_page = start / page_size;
|
||||
for ( unsigned i = size / page_size; i--; )
|
||||
set_code_page( first_page + i, (uint8_t*) data + i * page_size );
|
||||
}
|
||||
|
||||
// Note: 'addr' is evaulated more than once in the following macros, so it
|
||||
// must not contain side-effects.
|
||||
|
@ -39,6 +92,10 @@
|
|||
#define GET_SP() ((sp - 1) & 0xFF)
|
||||
#define PUSH( v ) ((sp = (sp - 1) | 0x100), WRITE_LOW( sp, v ))
|
||||
|
||||
#ifdef BLARGG_ENABLE_OPTIMIZER
|
||||
#include BLARGG_ENABLE_OPTIMIZER
|
||||
#endif
|
||||
|
||||
int Nes_Cpu::read( nes_addr_t addr )
|
||||
{
|
||||
return READ( addr );
|
||||
|
|
|
@ -1,19 +1,6 @@
|
|||
|
||||
// NES 6502 CPU emulator
|
||||
|
||||
// Nes_Emu 0.7.0. http://www.slack.net/~ant/nes-emu/
|
||||
|
||||
/* Copyright (C) 2003-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
|
||||
|
||||
#ifndef NES_CPU_H
|
||||
|
@ -27,50 +14,15 @@ typedef unsigned nes_addr_t; // 16-bit address
|
|||
|
||||
class Nes_Cpu {
|
||||
public:
|
||||
|
||||
inline void set_code_page( int i, uint8_t const* p )
|
||||
{
|
||||
code_map [i] = p - (unsigned) i * page_size;
|
||||
}
|
||||
|
||||
// Clear registers, unmap memory, and map code pages to unmapped_page.
|
||||
void reset( void const* unmapped_page = 0 )
|
||||
{
|
||||
r.status = 0;
|
||||
r.sp = 0;
|
||||
r.pc = 0;
|
||||
r.a = 0;
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
|
||||
error_count_ = 0;
|
||||
clock_count = 0;
|
||||
clock_limit = 0;
|
||||
irq_time_ = LONG_MAX / 2 + 1;
|
||||
end_time_ = LONG_MAX / 2 + 1;
|
||||
|
||||
set_code_page( 0, low_mem );
|
||||
set_code_page( 1, low_mem );
|
||||
set_code_page( 2, low_mem );
|
||||
set_code_page( 3, low_mem );
|
||||
for ( int i = 4; i < page_count + 1; i++ )
|
||||
set_code_page( i, (uint8_t*) unmapped_page );
|
||||
|
||||
isCorrectExecution = true;
|
||||
}
|
||||
void reset( void const* unmapped_page = 0 );
|
||||
|
||||
// Map code memory (memory accessed via the program counter). Start and size
|
||||
// must be multiple of page_size.
|
||||
static const uint8_t page_bits = 11;
|
||||
static const uint16_t page_count = 0x10000 >> page_bits;
|
||||
static const uint16_t page_size = 1L << page_bits;
|
||||
|
||||
void map_code( nes_addr_t start, unsigned size, void const* code )
|
||||
{
|
||||
unsigned first_page = start / page_size;
|
||||
for ( unsigned i = size / page_size; i--; )
|
||||
set_code_page( first_page + i, (uint8_t*) code + i * page_size );
|
||||
}
|
||||
enum { page_bits = 11 };
|
||||
enum { page_count = 0x10000 >> page_bits };
|
||||
enum { page_size = 1L << page_bits };
|
||||
void map_code( nes_addr_t start, unsigned size, void const* code );
|
||||
|
||||
// Access memory as the emulated CPU does.
|
||||
int read( nes_addr_t );
|
||||
|
@ -108,10 +60,10 @@ public:
|
|||
unsigned long error_count() const { return error_count_; }
|
||||
|
||||
// If PC exceeds 0xFFFF and encounters page_wrap_opcode, it will be silently wrapped.
|
||||
static const uint8_t page_wrap_opcode = 0xF2;
|
||||
enum { page_wrap_opcode = 0xF2 };
|
||||
|
||||
// One of the many opcodes that are undefined and stop CPU emulation.
|
||||
static const uint8_t bad_opcode = 0xD2;
|
||||
enum { bad_opcode = 0xD2 };
|
||||
|
||||
uint8_t const* code_map [page_count + 1];
|
||||
nes_time_t clock_limit;
|
||||
|
@ -120,7 +72,8 @@ public:
|
|||
nes_time_t end_time_;
|
||||
unsigned long error_count_;
|
||||
|
||||
static const uint8_t irq_inhibit = 0x04;
|
||||
enum { irq_inhibit = 0x04 };
|
||||
void set_code_page( int, uint8_t const* );
|
||||
void update_clock_limit();
|
||||
|
||||
registers_t r;
|
||||
|
|
|
@ -162,10 +162,10 @@ public:
|
|||
// Graphics
|
||||
|
||||
// Number of frames generated per second
|
||||
static const uint16_t frame_rate = 60;
|
||||
enum { frame_rate = 60 };
|
||||
|
||||
// Size of fixed NES color table (including the 8 color emphasis modes)
|
||||
static const uint16_t color_table_size = 8 * 64;
|
||||
enum { color_table_size = 8 * 64 };
|
||||
|
||||
// NES color lookup table based on standard NTSC TV decoder. Use nes_ntsc.h to
|
||||
// generate a palette with custom parameters.
|
||||
|
@ -183,7 +183,7 @@ public:
|
|||
// Set range of host palette entries to use in graphics buffer; default uses
|
||||
// all of them. Begin will be rounded up to next multiple of palette_alignment.
|
||||
// Use frame().palette_begin to find the adjusted beginning entry used.
|
||||
static const uint8_t palette_alignment = 64;
|
||||
enum { palette_alignment = 64 };
|
||||
void set_palette_range( int begin, int end = 256 );
|
||||
|
||||
// Access to emulated memory, for viewer/cheater/debugger
|
||||
|
@ -198,11 +198,11 @@ public:
|
|||
long nametable_size() const { return 0x1000; }
|
||||
|
||||
// Built-in 2K memory
|
||||
static const uint16_t low_mem_size = 0x800;
|
||||
enum { low_mem_size = 0x800 };
|
||||
uint8_t* low_mem() { return emu.low_mem; }
|
||||
|
||||
// Optional 8K memory
|
||||
static const uint16_t high_mem_size = 0x2000;
|
||||
enum { high_mem_size = 0x2000 };
|
||||
uint8_t* high_mem() { return emu.impl->sram; }
|
||||
|
||||
// End of public interface
|
||||
|
|
|
@ -60,7 +60,7 @@ private:
|
|||
} oscs [osc_count];
|
||||
blip_time_t last_time;
|
||||
|
||||
static const uint8_t amp_range = 192; // can be any value; this gives best error/quality tradeoff
|
||||
enum { amp_range = 192 }; // can be any value; this gives best error/quality tradeoff
|
||||
Blip_Synth<blip_good_quality,1> synth;
|
||||
|
||||
void run_until( blip_time_t );
|
||||
|
|
|
@ -6,8 +6,297 @@
|
|||
#include <cstdio>
|
||||
#include <string.h>
|
||||
#include "Nes_Core.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"
|
||||
|
||||
/*
|
||||
New mapping distribution by Sergio Martin (eien86)
|
||||
https://github.com/SergioMartin86/jaffarPlus
|
||||
*/
|
||||
#include "mappers/mapper000.hpp"
|
||||
#include "mappers/mapper001.hpp"
|
||||
#include "mappers/mapper002.hpp"
|
||||
#include "mappers/mapper003.hpp"
|
||||
#include "mappers/mapper004.hpp"
|
||||
#include "mappers/mapper005.hpp"
|
||||
#include "mappers/mapper007.hpp"
|
||||
#include "mappers/mapper009.hpp"
|
||||
#include "mappers/mapper010.hpp"
|
||||
#include "mappers/mapper011.hpp"
|
||||
#include "mappers/mapper015.hpp"
|
||||
#include "mappers/mapper019.hpp"
|
||||
#include "mappers/mapper021.hpp"
|
||||
#include "mappers/mapper022.hpp"
|
||||
#include "mappers/mapper023.hpp"
|
||||
#include "mappers/mapper024.hpp"
|
||||
#include "mappers/mapper025.hpp"
|
||||
#include "mappers/mapper026.hpp"
|
||||
#include "mappers/mapper030.hpp"
|
||||
#include "mappers/mapper032.hpp"
|
||||
#include "mappers/mapper033.hpp"
|
||||
#include "mappers/mapper034.hpp"
|
||||
#include "mappers/mapper060.hpp"
|
||||
#include "mappers/mapper066.hpp"
|
||||
#include "mappers/mapper069.hpp"
|
||||
#include "mappers/mapper070.hpp"
|
||||
#include "mappers/mapper071.hpp"
|
||||
#include "mappers/mapper073.hpp"
|
||||
#include "mappers/mapper075.hpp"
|
||||
#include "mappers/mapper078.hpp"
|
||||
#include "mappers/mapper079.hpp"
|
||||
#include "mappers/mapper085.hpp"
|
||||
#include "mappers/mapper086.hpp"
|
||||
#include "mappers/mapper087.hpp"
|
||||
#include "mappers/mapper088.hpp"
|
||||
#include "mappers/mapper089.hpp"
|
||||
#include "mappers/mapper093.hpp"
|
||||
#include "mappers/mapper094.hpp"
|
||||
#include "mappers/mapper097.hpp"
|
||||
#include "mappers/mapper113.hpp"
|
||||
#include "mappers/mapper140.hpp"
|
||||
#include "mappers/mapper152.hpp"
|
||||
#include "mappers/mapper154.hpp"
|
||||
#include "mappers/mapper156.hpp"
|
||||
#include "mappers/mapper180.hpp"
|
||||
#include "mappers/mapper184.hpp"
|
||||
#include "mappers/mapper190.hpp"
|
||||
#include "mappers/mapper193.hpp"
|
||||
#include "mappers/mapper206.hpp"
|
||||
#include "mappers/mapper207.hpp"
|
||||
#include "mappers/mapper232.hpp"
|
||||
#include "mappers/mapper240.hpp"
|
||||
#include "mappers/mapper241.hpp"
|
||||
#include "mappers/mapper244.hpp"
|
||||
#include "mappers/mapper246.hpp"
|
||||
|
||||
Nes_Mapper::Nes_Mapper()
|
||||
{
|
||||
emu_ = NULL;
|
||||
static char c;
|
||||
state = &c; // TODO: state must not be null?
|
||||
state_size = 0;
|
||||
}
|
||||
|
||||
Nes_Mapper::~Nes_Mapper()
|
||||
{
|
||||
}
|
||||
|
||||
// Sets mirroring, maps first 8K CHR in, first and last 16K of PRG,
|
||||
// intercepts writes to upper half of memory, and clears registered state.
|
||||
void Nes_Mapper::default_reset_state()
|
||||
{
|
||||
int mirroring = cart_->mirroring();
|
||||
if ( mirroring & 8 )
|
||||
mirror_full();
|
||||
else if ( mirroring & 1 )
|
||||
mirror_vert();
|
||||
else
|
||||
mirror_horiz();
|
||||
|
||||
set_chr_bank( 0, bank_8k, 0 );
|
||||
|
||||
set_prg_bank( 0x8000, bank_16k, 0 );
|
||||
set_prg_bank( 0xC000, bank_16k, last_bank );
|
||||
|
||||
intercept_writes( 0x8000, 0x8000 );
|
||||
|
||||
memset( state, 0, state_size );
|
||||
}
|
||||
|
||||
void Nes_Mapper::reset()
|
||||
{
|
||||
default_reset_state();
|
||||
reset_state();
|
||||
apply_mapping();
|
||||
}
|
||||
|
||||
void mapper_state_t::write( const void* p, unsigned long s )
|
||||
{
|
||||
size = s;
|
||||
memcpy( data, p, s );
|
||||
}
|
||||
|
||||
int mapper_state_t::read( void* p, unsigned long s ) const
|
||||
{
|
||||
if ( (long) s > size )
|
||||
s = size;
|
||||
memcpy( p, data, s );
|
||||
return s;
|
||||
}
|
||||
|
||||
void Nes_Mapper::save_state( mapper_state_t& out )
|
||||
{
|
||||
out.write( state, state_size );
|
||||
}
|
||||
|
||||
void Nes_Mapper::load_state( mapper_state_t const& in )
|
||||
{
|
||||
default_reset_state();
|
||||
read_state( in );
|
||||
apply_mapping();
|
||||
}
|
||||
|
||||
void Nes_Mapper::read_state( mapper_state_t const& in )
|
||||
{
|
||||
memset( state, 0, state_size );
|
||||
in.read( state, state_size );
|
||||
apply_mapping();
|
||||
}
|
||||
|
||||
// Timing
|
||||
|
||||
void Nes_Mapper::irq_changed() { emu_->irq_changed(); }
|
||||
|
||||
nes_time_t Nes_Mapper::next_irq( nes_time_t ) { return no_irq; }
|
||||
|
||||
void Nes_Mapper::a12_clocked() { }
|
||||
|
||||
void Nes_Mapper::run_until( nes_time_t ) { }
|
||||
|
||||
void Nes_Mapper::end_frame( nes_time_t ) { }
|
||||
|
||||
bool Nes_Mapper::ppu_enabled() const { return emu().ppu.w2001 & 0x08; }
|
||||
|
||||
// Sound
|
||||
|
||||
int Nes_Mapper::channel_count() const { return 0; }
|
||||
|
||||
void Nes_Mapper::set_channel_buf( int, Blip_Buffer* ) { }
|
||||
|
||||
void Nes_Mapper::set_treble( blip_eq_t const& ) { }
|
||||
|
||||
// Memory mapping
|
||||
|
||||
void Nes_Mapper::set_prg_bank( nes_addr_t addr, bank_size_t bs, int bank )
|
||||
{
|
||||
int bank_size = 1 << bs;
|
||||
|
||||
int bank_count = cart_->prg_size() >> bs;
|
||||
if ( bank < 0 )
|
||||
bank += bank_count;
|
||||
|
||||
if ( bank >= bank_count )
|
||||
bank %= bank_count;
|
||||
|
||||
emu().map_code( addr, bank_size, cart_->prg() + (bank << bs) );
|
||||
|
||||
if ( unsigned (addr - 0x6000) < 0x2000 )
|
||||
emu().enable_prg_6000();
|
||||
}
|
||||
|
||||
void Nes_Mapper::set_chr_bank( nes_addr_t addr, bank_size_t bs, int bank )
|
||||
{
|
||||
emu().ppu.render_until( emu().clock() );
|
||||
emu().ppu.set_chr_bank( addr, 1 << bs, bank << bs );
|
||||
}
|
||||
|
||||
void Nes_Mapper::set_chr_bank_ex( nes_addr_t addr, bank_size_t bs, int bank )
|
||||
{
|
||||
emu().ppu.render_until( emu().clock() );
|
||||
emu().ppu.set_chr_bank_ex( addr, 1 << bs, bank << bs );
|
||||
}
|
||||
|
||||
void Nes_Mapper::mirror_manual( int page0, int page1, int page2, int page3 )
|
||||
{
|
||||
emu().ppu.render_bg_until( emu().clock() );
|
||||
emu().ppu.set_nt_banks( page0, page1, page2, page3 );
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
int Nes_Mapper::handle_bus_conflict( nes_addr_t addr, int data )
|
||||
{
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Nes_Mapper* Nes_Mapper::create( Nes_Cart const* cart, Nes_Core* emu )
|
||||
{
|
||||
// Getting cartdrige mapper code
|
||||
auto mapperCode = cart->mapper_code();
|
||||
|
||||
// Storage for the mapper, NULL by default
|
||||
Nes_Mapper* mapper = NULL;
|
||||
|
||||
// Now checking if the detected mapper code is supported
|
||||
if (mapperCode == 0) mapper = new Mapper000();
|
||||
if (mapperCode == 1) mapper = new Mapper001();
|
||||
if (mapperCode == 2) mapper = new Mapper002();
|
||||
if (mapperCode == 3) mapper = new Mapper003();
|
||||
if (mapperCode == 4) mapper = new Mapper004();
|
||||
if (mapperCode == 5) mapper = new Mapper005();
|
||||
if (mapperCode == 7) mapper = new Mapper007();
|
||||
if (mapperCode == 9) mapper = new Mapper009();
|
||||
if (mapperCode == 10) mapper = new Mapper010();
|
||||
if (mapperCode == 11) mapper = new Mapper011();
|
||||
if (mapperCode == 15) mapper = new Mapper015();
|
||||
if (mapperCode == 19) mapper = new Mapper019();
|
||||
if (mapperCode == 21) mapper = new Mapper021();
|
||||
if (mapperCode == 22) mapper = new Mapper022();
|
||||
if (mapperCode == 23) mapper = new Mapper023();
|
||||
if (mapperCode == 24) mapper = new Mapper024();
|
||||
if (mapperCode == 25) mapper = new Mapper025();
|
||||
if (mapperCode == 26) mapper = new Mapper026();
|
||||
if (mapperCode == 30) mapper = new Mapper030();
|
||||
if (mapperCode == 32) mapper = new Mapper032();
|
||||
if (mapperCode == 33) mapper = new Mapper033();
|
||||
if (mapperCode == 34) mapper = new Mapper034();
|
||||
if (mapperCode == 60) mapper = new Mapper060();
|
||||
if (mapperCode == 66) mapper = new Mapper066();
|
||||
if (mapperCode == 69) mapper = new Mapper069();
|
||||
if (mapperCode == 70) mapper = new Mapper070();
|
||||
if (mapperCode == 71) mapper = new Mapper071();
|
||||
if (mapperCode == 73) mapper = new Mapper073();
|
||||
if (mapperCode == 75) mapper = new Mapper075();
|
||||
if (mapperCode == 78) mapper = new Mapper078();
|
||||
if (mapperCode == 79) mapper = new Mapper079();
|
||||
if (mapperCode == 85) mapper = new Mapper085();
|
||||
if (mapperCode == 86) mapper = new Mapper086();
|
||||
if (mapperCode == 87) mapper = new Mapper087();
|
||||
if (mapperCode == 88) mapper = new Mapper088();
|
||||
if (mapperCode == 89) mapper = new Mapper089();
|
||||
if (mapperCode == 93) mapper = new Mapper093();
|
||||
if (mapperCode == 94) mapper = new Mapper094();
|
||||
if (mapperCode == 97) mapper = new Mapper097();
|
||||
if (mapperCode == 113) mapper = new Mapper113();
|
||||
if (mapperCode == 140) mapper = new Mapper140();
|
||||
if (mapperCode == 152) mapper = new Mapper152();
|
||||
if (mapperCode == 154) mapper = new Mapper154();
|
||||
if (mapperCode == 156) mapper = new Mapper156();
|
||||
if (mapperCode == 180) mapper = new Mapper180();
|
||||
if (mapperCode == 184) mapper = new Mapper184();
|
||||
if (mapperCode == 190) mapper = new Mapper190();
|
||||
if (mapperCode == 193) mapper = new Mapper193();
|
||||
if (mapperCode == 206) mapper = new Mapper206();
|
||||
if (mapperCode == 207) mapper = new Mapper207();
|
||||
if (mapperCode == 232) mapper = new Mapper232();
|
||||
if (mapperCode == 240) mapper = new Mapper240();
|
||||
if (mapperCode == 241) mapper = new Mapper241();
|
||||
if (mapperCode == 244) mapper = new Mapper244();
|
||||
if (mapperCode == 246) mapper = new Mapper246();
|
||||
|
||||
// If no mapper was found, return null (error) now
|
||||
if (mapper == NULL)
|
||||
{
|
||||
fprintf(stderr, "Could not find mapper for code: %u\n", mapperCode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Assigning backwards pointers to cartdrige and emulator now
|
||||
mapper->cart_ = cart;
|
||||
mapper->emu_ = emu;
|
||||
|
||||
// Returning successfully created mapper
|
||||
return mapper;
|
||||
}
|
||||
|
|
|
@ -1,27 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
// NES mapper interface
|
||||
/* 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
|
||||
|
||||
#ifndef NES_MAPPER
|
||||
#define NES_MAPPER
|
||||
|
||||
#include "Nes_Cart.h"
|
||||
#include "Nes_Cpu.h"
|
||||
#include "nes_data.h"
|
||||
#include "Nes_Core.h"
|
||||
#include <cstdio>
|
||||
#include <string.h>
|
||||
#include "blargg_source.h"
|
||||
|
||||
class Blip_Buffer;
|
||||
class blip_eq_t;
|
||||
class Nes_Core;
|
||||
|
@ -35,43 +23,30 @@ public:
|
|||
// Register optional mappers included with Nes_Emu
|
||||
void register_optional_mappers();
|
||||
|
||||
virtual ~Nes_Mapper() = default;
|
||||
// Create mapper appropriate for cartridge. Returns NULL if it uses unsupported mapper.
|
||||
static Nes_Mapper* create( Nes_Cart const*, Nes_Core* );
|
||||
|
||||
virtual ~Nes_Mapper();
|
||||
|
||||
// Reset mapper to power-up state.
|
||||
virtual inline void reset()
|
||||
{
|
||||
default_reset_state();
|
||||
reset_state();
|
||||
apply_mapping();
|
||||
}
|
||||
virtual void reset();
|
||||
|
||||
// Save snapshot of mapper state. Default saves registered state.
|
||||
virtual inline void save_state( mapper_state_t& out )
|
||||
{
|
||||
out.write( state, state_size );
|
||||
}
|
||||
virtual void save_state( mapper_state_t& );
|
||||
|
||||
// Resets mapper, loads state, then applies it
|
||||
virtual inline void load_state( mapper_state_t const& in )
|
||||
{
|
||||
default_reset_state();
|
||||
read_state( in );
|
||||
apply_mapping();
|
||||
}
|
||||
|
||||
void setCartridge(const Nes_Cart* cart) { cart_ = cart; }
|
||||
void setCore(Nes_Core* core) { emu_ = core; }
|
||||
virtual void load_state( mapper_state_t const& );
|
||||
|
||||
// I/O
|
||||
|
||||
// Read from memory
|
||||
virtual inline int read( nes_time_t, nes_addr_t ) { return -1; } ;
|
||||
virtual int read( nes_time_t, nes_addr_t );
|
||||
|
||||
// Write to memory
|
||||
virtual void write( nes_time_t, nes_addr_t, int data ) = 0;
|
||||
|
||||
// Write to memory below 0x8000 (returns false if mapper didn't handle write)
|
||||
virtual inline bool write_intercepted( nes_time_t, nes_addr_t, int data ) { return false; }
|
||||
virtual bool write_intercepted( nes_time_t, nes_addr_t, int data );
|
||||
|
||||
// Timing
|
||||
|
||||
|
@ -79,66 +54,53 @@ public:
|
|||
enum { no_irq = LONG_MAX / 2 };
|
||||
|
||||
// Time next IRQ will occur at
|
||||
virtual inline nes_time_t next_irq( nes_time_t present ) { return no_irq; };
|
||||
virtual nes_time_t next_irq( nes_time_t present );
|
||||
|
||||
// Run mapper until given time
|
||||
virtual inline void run_until( nes_time_t ) { };
|
||||
virtual void run_until( nes_time_t );
|
||||
|
||||
// End video frame of given length
|
||||
virtual inline void end_frame( nes_time_t length ) { };
|
||||
virtual void end_frame( nes_time_t length );
|
||||
|
||||
// Sound
|
||||
|
||||
// Number of sound channels
|
||||
virtual inline int channel_count() const { return 0; };
|
||||
virtual int channel_count() const;
|
||||
|
||||
// Set sound buffer for channel to output to, or NULL to silence channel.
|
||||
virtual inline void set_channel_buf( int index, Blip_Buffer* ) { };
|
||||
virtual void set_channel_buf( int index, Blip_Buffer* );
|
||||
|
||||
// Set treble equalization
|
||||
virtual inline void set_treble( blip_eq_t const& ) { };
|
||||
virtual void set_treble( blip_eq_t const& );
|
||||
|
||||
// Misc
|
||||
|
||||
// Called when bit 12 of PPU's VRAM address changes from 0 to 1 due to
|
||||
// $2006 and $2007 accesses (but not due to PPU scanline rendering).
|
||||
virtual inline void a12_clocked() {};
|
||||
virtual void a12_clocked();
|
||||
|
||||
protected:
|
||||
// Services provided for derived mapper classes
|
||||
Nes_Mapper()
|
||||
{
|
||||
emu_ = NULL;
|
||||
static char c;
|
||||
state = &c; // TODO: state must not be null?
|
||||
state_size = 0;
|
||||
}
|
||||
Nes_Mapper();
|
||||
|
||||
// Register state data to automatically save and load. Be sure the binary
|
||||
// layout is suitable for use in a file, including any byte-order issues.
|
||||
// Automatically cleared to zero by default reset().
|
||||
inline void register_state(void* p, unsigned s)
|
||||
{
|
||||
state = p;
|
||||
state_size = s;
|
||||
}
|
||||
void register_state( void*, unsigned );
|
||||
|
||||
// Enable 8K of RAM at 0x6000-0x7FFF, optionally read-only.
|
||||
inline void enable_sram( bool enabled = true, bool read_only = false ) { emu_->enable_sram( enabled, read_only ); }
|
||||
void enable_sram( bool enabled = true, bool read_only = false );
|
||||
|
||||
// Cause CPU writes within given address range to call mapper's write() function.
|
||||
// Might map a larger address range, which the mapper can ignore and pass to
|
||||
// Nes_Mapper::write(). The range 0x8000-0xffff is always intercepted by the mapper.
|
||||
inline void intercept_writes( nes_addr_t addr, unsigned size ) { emu().add_mapper_intercept( addr, size, false, true ); }
|
||||
void intercept_writes( nes_addr_t addr, unsigned size );
|
||||
|
||||
// Cause CPU reads within given address range to call mapper's read() function.
|
||||
// Might map a larger address range, which the mapper can ignore and pass to
|
||||
// Nes_Mapper::read(). CPU opcode/operand reads and low-memory reads always
|
||||
// go directly to memory and cannot be intercepted.
|
||||
inline void intercept_reads( nes_addr_t addr, unsigned size )
|
||||
{
|
||||
emu().add_mapper_intercept( addr, size, true, false );
|
||||
}
|
||||
void intercept_reads( nes_addr_t addr, unsigned size );
|
||||
|
||||
// Bank sizes for mapping
|
||||
enum bank_size_t { // 1 << bank_Xk = X * 1024
|
||||
|
@ -155,51 +117,22 @@ protected:
|
|||
enum { last_bank = -1 };
|
||||
|
||||
// Map 'size' bytes from 'PRG + bank * size' to CPU address space starting at 'addr'
|
||||
void set_prg_bank( nes_addr_t addr, bank_size_t bs, int bank )
|
||||
{
|
||||
int bank_size = 1 << bs;
|
||||
|
||||
int bank_count = cart_->prg_size() >> bs;
|
||||
if ( bank < 0 )
|
||||
bank += bank_count;
|
||||
|
||||
if ( bank >= bank_count )
|
||||
bank %= bank_count;
|
||||
|
||||
emu().map_code( addr, bank_size, cart_->prg() + (bank << bs) );
|
||||
|
||||
if ( unsigned (addr - 0x6000) < 0x2000 )
|
||||
emu().enable_prg_6000();
|
||||
}
|
||||
void set_prg_bank( nes_addr_t addr, bank_size_t size, int bank );
|
||||
|
||||
// Map 'size' bytes from 'CHR + bank * size' to PPU address space starting at 'addr'
|
||||
inline void set_chr_bank( nes_addr_t addr, bank_size_t bs, int bank )
|
||||
{
|
||||
emu().ppu.render_until( emu().clock() );
|
||||
emu().ppu.set_chr_bank( addr, 1 << bs, bank << bs );
|
||||
}
|
||||
|
||||
inline void set_chr_bank_ex( nes_addr_t addr, bank_size_t bs, int bank )
|
||||
{
|
||||
emu().ppu.render_until( emu().clock() );
|
||||
emu().ppu.set_chr_bank_ex( addr, 1 << bs, bank << bs );
|
||||
}
|
||||
void set_chr_bank( nes_addr_t addr, bank_size_t size, int bank );
|
||||
void set_chr_bank_ex( nes_addr_t addr, bank_size_t size, int bank );
|
||||
|
||||
// Set PPU mirroring. All mappings implemented using mirror_manual().
|
||||
inline void mirror_manual( int page0, int page1, int page2, int page3 )
|
||||
{
|
||||
emu().ppu.render_bg_until( emu().clock() );
|
||||
emu().ppu.set_nt_banks( page0, page1, page2, page3 );
|
||||
}
|
||||
|
||||
inline void mirror_horiz( int p = 0) { mirror_manual( p, p, p ^ 1, p ^ 1 ); }
|
||||
inline void mirror_vert( int p = 0 ) { mirror_manual( p, p ^ 1, p, p ^ 1 ); }
|
||||
inline void mirror_single( int p ) { mirror_manual( p, p, p, p ); }
|
||||
inline void mirror_full() { mirror_manual( 0, 1, 2, 3 ); }
|
||||
void mirror_manual( int page0, int page1, int page2, int page3 );
|
||||
void mirror_single( int page );
|
||||
void mirror_horiz( int page = 0 );
|
||||
void mirror_vert( int page = 0 );
|
||||
void mirror_full();
|
||||
|
||||
// True if PPU rendering is enabled. Some mappers watch PPU memory accesses to determine
|
||||
// when scanlines occur, and can only do this when rendering is enabled.
|
||||
inline bool ppu_enabled() const { return emu().ppu.w2001 & 0x08; }
|
||||
bool ppu_enabled() const;
|
||||
|
||||
// Cartridge being emulated
|
||||
Nes_Cart const& cart() const { return *cart_; }
|
||||
|
@ -207,13 +140,13 @@ protected:
|
|||
// Must be called when next_irq()'s return value is earlier than previous,
|
||||
// current CPU run can be stopped earlier. Best to call whenever time may
|
||||
// have changed (no performance impact if called even when time didn't change).
|
||||
inline void irq_changed() { emu_->irq_changed(); }
|
||||
void irq_changed();
|
||||
|
||||
// Handle data written to mapper that doesn't handle bus conflict arising due to
|
||||
// PRG also reading data. Returns data that mapper should act as if were
|
||||
// written. Currently always returns 'data' and just checks that data written is
|
||||
// the same as byte in PRG at same address and writes debug message if it doesn't.
|
||||
int handle_bus_conflict( nes_addr_t addr, int data ) { return data; }
|
||||
int handle_bus_conflict( nes_addr_t addr, int data );
|
||||
|
||||
// Reference to emulator that uses this mapper.
|
||||
Nes_Core& emu() const { return *emu_; }
|
||||
|
@ -223,12 +156,7 @@ protected:
|
|||
|
||||
// Read state from snapshot. Default reads data into registered state, then calls
|
||||
// apply_mapping().
|
||||
inline void read_state( mapper_state_t const& in )
|
||||
{
|
||||
memset( state, 0, state_size );
|
||||
in.read( state, state_size );
|
||||
apply_mapping();
|
||||
}
|
||||
virtual void read_state( mapper_state_t const& );
|
||||
|
||||
// Apply current mapping state to hardware. Called after reading mapper state
|
||||
// from a snapshot.
|
||||
|
@ -244,26 +172,42 @@ private:
|
|||
unsigned state_size;
|
||||
Nes_Cart const* cart_;
|
||||
|
||||
// Sets mirroring, maps first 8K CHR in, first and last 16K of PRG,
|
||||
// intercepts writes to upper half of memory, and clears registered state.
|
||||
inline void default_reset_state()
|
||||
{
|
||||
int mirroring = cart_->mirroring();
|
||||
if ( mirroring & 8 )
|
||||
mirror_full();
|
||||
else if ( mirroring & 1 )
|
||||
mirror_vert();
|
||||
else
|
||||
mirror_horiz();
|
||||
|
||||
set_chr_bank( 0, bank_8k, 0 );
|
||||
|
||||
set_prg_bank( 0x8000, bank_16k, 0 );
|
||||
set_prg_bank( 0xC000, bank_16k, last_bank );
|
||||
|
||||
intercept_writes( 0x8000, 0x8000 );
|
||||
|
||||
memset( state, 0, state_size );
|
||||
}
|
||||
void default_reset_state();
|
||||
};
|
||||
|
||||
|
||||
#ifdef NDEBUG
|
||||
inline int Nes_Mapper::handle_bus_conflict( nes_addr_t addr, int data ) { return data; }
|
||||
#endif
|
||||
|
||||
inline void Nes_Mapper::mirror_horiz( int p ) { mirror_manual( p, p, p ^ 1, p ^ 1 ); }
|
||||
inline void Nes_Mapper::mirror_vert( int p ) { mirror_manual( p, p ^ 1, p, p ^ 1 ); }
|
||||
inline void Nes_Mapper::mirror_single( int p ) { mirror_manual( p, p, p, p ); }
|
||||
inline void Nes_Mapper::mirror_full() { mirror_manual( 0, 1, 2, 3 ); }
|
||||
|
||||
inline void Nes_Mapper::register_state( void* p, unsigned s )
|
||||
{
|
||||
state = p;
|
||||
state_size = s;
|
||||
}
|
||||
|
||||
inline bool Nes_Mapper::write_intercepted( nes_time_t, nes_addr_t, int ) { return false; }
|
||||
|
||||
inline int Nes_Mapper::read( nes_time_t, nes_addr_t ) { return -1; } // signal to caller
|
||||
|
||||
inline void Nes_Mapper::intercept_reads( nes_addr_t addr, unsigned size )
|
||||
{
|
||||
emu().add_mapper_intercept( addr, size, true, false );
|
||||
}
|
||||
|
||||
inline void Nes_Mapper::intercept_writes( nes_addr_t addr, unsigned size )
|
||||
{
|
||||
emu().add_mapper_intercept( addr, size, false, true );
|
||||
}
|
||||
|
||||
inline void Nes_Mapper::enable_sram( bool enabled, bool read_only )
|
||||
{
|
||||
emu_->enable_sram( enabled, read_only );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
void volume( double );
|
||||
void treble_eq( const blip_eq_t& );
|
||||
void output( Blip_Buffer* );
|
||||
static const uint8_t osc_count = 8;
|
||||
enum { osc_count = 8 };
|
||||
void osc_output( int index, Blip_Buffer* );
|
||||
void reset();
|
||||
void end_frame( nes_time_t );
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include "Nes_Ppu.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "Nes_State.h"
|
||||
#include "Nes_Mapper.h"
|
||||
#include "Nes_Core.h"
|
||||
|
@ -272,7 +272,7 @@ void Nes_Ppu::update_sprite_hit( nes_time_t cpu_time )
|
|||
if ( count_needed > 240 )
|
||||
count_needed = 240;
|
||||
while ( scanline_count < count_needed )
|
||||
render_bg_until( std::max( cpu_time, next_bg_time + 1 ) );
|
||||
render_bg_until( max( cpu_time, next_bg_time + 1 ) );
|
||||
|
||||
if ( sprite_hit_found < 0 )
|
||||
return; // sprite won't hit
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
while ( true )
|
||||
{
|
||||
while ( count-- )
|
||||
{
|
||||
int attrib = attr_table [addr >> 2 & 0x07];
|
||||
attrib >>= (addr >> 4 & 4) | (addr & 2);
|
||||
unsigned long offset = (attrib & 3) * attrib_factor + this->palette_offset;
|
||||
|
||||
// draw one tile
|
||||
cache_t const* lines = this->get_bg_tile( nametable [addr] + bg_bank );
|
||||
uint8_t* p = pixels;
|
||||
addr++;
|
||||
pixels += 8; // next tile
|
||||
|
||||
if ( !clipped )
|
||||
{
|
||||
// optimal case: no clipping
|
||||
for ( int n = 4; n--; )
|
||||
{
|
||||
unsigned long line = *lines++;
|
||||
((unaligned_uint32_t*) p) [0].val = (line >> 4 & mask) + offset;
|
||||
((unaligned_uint32_t*) p) [1].val = (line & mask) + offset;
|
||||
p += row_bytes;
|
||||
((unaligned_uint32_t*) p) [0].val = (line >> 6 & mask) + offset;
|
||||
((unaligned_uint32_t*) p) [1].val = (line >> 2 & mask) + offset;
|
||||
p += row_bytes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lines += fine_y >> 1;
|
||||
|
||||
if ( fine_y & 1 )
|
||||
{
|
||||
unsigned long line = *lines++;
|
||||
((unaligned_uint32_t*) p) [0].val = (line >> 6 & mask) + offset;
|
||||
((unaligned_uint32_t*) p) [1].val = (line >> 2 & mask) + offset;
|
||||
p += row_bytes;
|
||||
}
|
||||
|
||||
for ( int n = height >> 1; n--; )
|
||||
{
|
||||
unsigned long line = *lines++;
|
||||
((unaligned_uint32_t*) p) [0].val = (line >> 4 & mask) + offset;
|
||||
((unaligned_uint32_t*) p) [1].val = (line & mask) + offset;
|
||||
p += row_bytes;
|
||||
((unaligned_uint32_t*) p) [0].val = (line >> 6 & mask) + offset;
|
||||
((unaligned_uint32_t*) p) [1].val = (line >> 2 & mask) + offset;
|
||||
p += row_bytes;
|
||||
}
|
||||
|
||||
if ( height & 1 )
|
||||
{
|
||||
unsigned long line = *lines;
|
||||
((unaligned_uint32_t*) p) [0].val = (line >> 4 & mask) + offset;
|
||||
((unaligned_uint32_t*) p) [1].val = (line & mask) + offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
count = count2;
|
||||
count2 = 0;
|
||||
addr -= 32;
|
||||
attr_table = attr_table - nametable + nametable2;
|
||||
nametable = nametable2;
|
||||
if ( !count )
|
||||
break;
|
||||
}
|
|
@ -37,6 +37,14 @@ Nes_Ppu_Impl::Nes_Ppu_Impl()
|
|||
mmc24_enabled = false;
|
||||
mmc24_latched[0] = 0;
|
||||
mmc24_latched[1] = 0;
|
||||
|
||||
#if !defined(NDEBUG) && !defined(PSP) && !defined(PS2)
|
||||
// verify that unaligned accesses work
|
||||
static unsigned char b [19] = { 0 };
|
||||
static unsigned char b2 [19] = { 1,2,3,4,0,5,6,7,8,0,9,0,1,2,0,3,4,5,6 };
|
||||
for ( int i = 0; i < 19; i += 5 )
|
||||
*(volatile uint32_t*) &b [i] = *(volatile uint32_t*) &b2 [i];
|
||||
#endif
|
||||
}
|
||||
|
||||
Nes_Ppu_Impl::~Nes_Ppu_Impl()
|
||||
|
|
|
@ -3,9 +3,8 @@
|
|||
|
||||
#include "Nes_Ppu_Rendering.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <cstddef>
|
||||
#include <string.h>
|
||||
#include <stddef.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
|
||||
|
@ -20,6 +19,16 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|||
|
||||
#include "blargg_source.h"
|
||||
|
||||
#ifdef BLARGG_ENABLE_OPTIMIZER
|
||||
#include BLARGG_ENABLE_OPTIMIZER
|
||||
#endif
|
||||
|
||||
#ifdef __MWERKS__
|
||||
static unsigned zero = 0; // helps CodeWarrior optimizer when added to constants
|
||||
#else
|
||||
const unsigned zero = 0; // compile-time constant on other compilers
|
||||
#endif
|
||||
|
||||
// Nes_Ppu_Impl
|
||||
|
||||
inline Nes_Ppu_Impl::cached_tile_t const&
|
||||
|
@ -178,83 +187,26 @@ void Nes_Ppu_Rendering::draw_background_( int remain )
|
|||
uint8_t* pixels = row_pixels;
|
||||
row_pixels += height * row_bytes;
|
||||
|
||||
unsigned long const mask = 0x03030303;
|
||||
unsigned long const attrib_factor = 0x04040404;
|
||||
unsigned long const mask = 0x03030303 + zero;
|
||||
unsigned long const attrib_factor = 0x04040404 + zero;
|
||||
|
||||
const int fine_y = (height == 8) ? 0 : addr >> 12;
|
||||
const int clipped = (height == 8) ? false : true;
|
||||
if ( height == 8 )
|
||||
{
|
||||
// unclipped
|
||||
addr &= 0x03ff;
|
||||
if (height == 8) height -= fine_y & 1;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
while ( count-- )
|
||||
{
|
||||
int attrib = attr_table [addr >> 2 & 0x07];
|
||||
attrib >>= (addr >> 4 & 4) | (addr & 2);
|
||||
unsigned long offset = (attrib & 3) * attrib_factor + this->palette_offset;
|
||||
|
||||
// draw one tile
|
||||
cache_t const* lines = this->get_bg_tile( nametable [addr] + bg_bank );
|
||||
uint8_t* p = pixels;
|
||||
addr++;
|
||||
pixels += 8; // next tile
|
||||
|
||||
if ( !clipped )
|
||||
{
|
||||
// optimal case: no clipping
|
||||
for ( int n = 4; n--; )
|
||||
{
|
||||
unsigned long line = *lines++;
|
||||
((unaligned_uint32_t*) p) [0].val = (line >> 4 & mask) + offset;
|
||||
((unaligned_uint32_t*) p) [1].val = (line & mask) + offset;
|
||||
p += row_bytes;
|
||||
((unaligned_uint32_t*) p) [0].val = (line >> 6 & mask) + offset;
|
||||
((unaligned_uint32_t*) p) [1].val = (line >> 2 & mask) + offset;
|
||||
p += row_bytes;
|
||||
}
|
||||
int const fine_y = 0;
|
||||
int const clipped = false;
|
||||
#include "Nes_Ppu_Bg.h"
|
||||
}
|
||||
else
|
||||
{
|
||||
lines += fine_y >> 1;
|
||||
|
||||
if ( fine_y & 1 )
|
||||
{
|
||||
unsigned long line = *lines++;
|
||||
((unaligned_uint32_t*) p) [0].val = (line >> 6 & mask) + offset;
|
||||
((unaligned_uint32_t*) p) [1].val = (line >> 2 & mask) + offset;
|
||||
p += row_bytes;
|
||||
// clipped
|
||||
int const fine_y = addr >> 12;
|
||||
addr &= 0x03ff;
|
||||
height -= fine_y & 1;
|
||||
int const clipped = true;
|
||||
#include "Nes_Ppu_Bg.h"
|
||||
}
|
||||
|
||||
for ( int n = height >> 1; n--; )
|
||||
{
|
||||
unsigned long line = *lines++;
|
||||
((unaligned_uint32_t*) p) [0].val = (line >> 4 & mask) + offset;
|
||||
((unaligned_uint32_t*) p) [1].val = (line & mask) + offset;
|
||||
p += row_bytes;
|
||||
((unaligned_uint32_t*) p) [0].val = (line >> 6 & mask) + offset;
|
||||
((unaligned_uint32_t*) p) [1].val = (line >> 2 & mask) + offset;
|
||||
p += row_bytes;
|
||||
}
|
||||
|
||||
if ( height & 1 )
|
||||
{
|
||||
unsigned long line = *lines;
|
||||
((unaligned_uint32_t*) p) [0].val = (line >> 4 & mask) + offset;
|
||||
((unaligned_uint32_t*) p) [1].val = (line & mask) + offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
count = count2;
|
||||
count2 = 0;
|
||||
addr -= 32;
|
||||
attr_table = attr_table - nametable + nametable2;
|
||||
nametable = nametable2;
|
||||
if ( !count )
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
while ( remain );
|
||||
}
|
||||
|
@ -363,7 +315,7 @@ void Nes_Ppu_Rendering::check_sprite_hit( int begin, int end )
|
|||
}
|
||||
|
||||
// check each line
|
||||
unsigned long const mask = 0x01010101;
|
||||
unsigned long const mask = 0x01010101 + zero;
|
||||
do
|
||||
{
|
||||
// get pixels for line
|
||||
|
@ -500,8 +452,8 @@ void Nes_Ppu_Rendering::draw_background( int start, int count )
|
|||
{
|
||||
// not rendering, but still handle sprite hit using mini graphics buffer
|
||||
int y = spr_ram [0] + 1;
|
||||
int skip = std::min( count, std::max( y - start, 0 ) );
|
||||
int visible = std::min( count - skip, sprite_height() );
|
||||
int skip = min( count, max( y - start, 0 ) );
|
||||
int visible = min( count - skip, sprite_height() );
|
||||
|
||||
if ( visible > 0 )
|
||||
{
|
||||
|
|
|
@ -27,8 +27,8 @@ if ( sprite_2 & 0x80 )
|
|||
// attributes
|
||||
unsigned long offset = (sprite_2 & 3) * 0x04040404 + (this->palette_offset + 0x10101010);
|
||||
|
||||
unsigned long const mask = 0x03030303;
|
||||
unsigned long const maskgen = 0x80808080;
|
||||
unsigned long const mask = 0x03030303 + zero;
|
||||
unsigned long const maskgen = 0x80808080 + zero;
|
||||
|
||||
#define DRAW_PAIR( shift ) { \
|
||||
int sprite_count = *scanlines; \
|
||||
|
@ -48,7 +48,7 @@ unsigned long const maskgen = 0x80808080;
|
|||
if ( !(sprite_2 & 0x20) )
|
||||
{
|
||||
// front
|
||||
unsigned long const maskgen2 = 0x7f7f7f7f;
|
||||
unsigned long const maskgen2 = 0x7f7f7f7f + zero;
|
||||
|
||||
#define CALC_FOUR( in, line, out ) \
|
||||
unsigned long out; \
|
||||
|
@ -88,8 +88,8 @@ if ( !(sprite_2 & 0x20) )
|
|||
else
|
||||
{
|
||||
// behind
|
||||
unsigned long const omask = 0x20202020;
|
||||
unsigned long const bg_or = 0xc3c3c3c3;
|
||||
unsigned long const omask = 0x20202020 + zero;
|
||||
unsigned long const bg_or = 0xc3c3c3c3 + zero;
|
||||
|
||||
#define CALC_FOUR( in, line, out ) \
|
||||
unsigned long out; \
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
void volume( double );
|
||||
void treble_eq( blip_eq_t const& );
|
||||
void output( Blip_Buffer* );
|
||||
static const uint8_t osc_count = 6;
|
||||
enum { osc_count = 6 };
|
||||
void osc_output( int index, Blip_Buffer* );
|
||||
void end_frame( nes_time_t );
|
||||
void save_snapshot(vrc7_snapshot_t*);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
#include "abstract_file.h"
|
||||
|
||||
#include "blargg_config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include "blargg_common.h"
|
||||
#include "blargg_endian.h"
|
||||
|
||||
struct apu_state_t
|
||||
{
|
||||
|
@ -71,19 +70,7 @@ struct apu_state_t
|
|||
//uint8_t length_counters [4];
|
||||
|
||||
enum { tag = 0x41505552 }; // 'APUR'
|
||||
void swap()
|
||||
{
|
||||
SWAP_LE( apu.frame_delay );
|
||||
SWAP_LE( square1.delay );
|
||||
SWAP_LE( square2.delay );
|
||||
SWAP_LE( triangle.delay );
|
||||
SWAP_LE( noise.delay );
|
||||
SWAP_LE( noise.shift_reg );
|
||||
SWAP_LE( dmc.delay );
|
||||
SWAP_LE( dmc.remain );
|
||||
SWAP_LE( dmc.addr );
|
||||
}
|
||||
|
||||
void swap();
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (apu_state_t) == 72 );
|
||||
|
||||
|
|
|
@ -34,6 +34,9 @@ arithmetic on smaller types. */
|
|||
// In case compiler doesn't support these properly. Used rarely.
|
||||
#define STATIC_CAST(T,expr) static_cast<T> (expr)
|
||||
|
||||
// User configuration can override the above macros if necessary
|
||||
#include "blargg_config.h"
|
||||
|
||||
// BOOST_STATIC_ASSERT( expr ): Generates compile error if expr is 0.
|
||||
#ifndef BOOST_STATIC_ASSERT
|
||||
#ifdef _MSC_VER
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// Library configuration. Modify this file as necessary.
|
||||
|
||||
// File_Extractor 1.0.0
|
||||
#ifndef BLARGG_CONFIG_H
|
||||
#define BLARGG_CONFIG_H
|
||||
|
||||
#ifndef HAVE_STDINT_H
|
||||
#define HAVE_STDINT_H
|
||||
#endif
|
||||
|
||||
// Use standard config.h if present
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -105,7 +105,4 @@ inline void set_be( uint32_t* p, unsigned long n ) { SET_BE32( p, n ); }
|
|||
inline unsigned get_be( uint16_t* p ) { return GET_BE16( p ); }
|
||||
inline unsigned long get_be( uint32_t* p ) { return GET_BE32( p ); }
|
||||
|
||||
#define SWAP_BE( n ) (void) (set_be( &(n), (n) ))
|
||||
#define SWAP_LE( n ) (void) (set_le( &(n), (n) ))
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,4 +32,9 @@ otherwise continues normally. */
|
|||
return "Out of memory";\
|
||||
} while ( 0 )
|
||||
|
||||
/* The usual min/max functions for built-in types. */
|
||||
|
||||
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; }
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,10 @@ int Nes_Core::cpu_read( nes_addr_t addr, nes_time_t time )
|
|||
if ( addr < lrom_readable )
|
||||
return *cpu::get_code( addr );
|
||||
|
||||
#ifndef NDEBUG
|
||||
log_unmapped( addr );
|
||||
#endif
|
||||
|
||||
return addr >> 8; // simulate open bus
|
||||
}
|
||||
|
||||
|
@ -75,7 +79,7 @@ void Nes_Core::cpu_write_2007( int data )
|
|||
mapper->a12_clocked();
|
||||
}
|
||||
|
||||
inline void Nes_Core::cpu_write( nes_addr_t addr, int data, nes_time_t time )
|
||||
void Nes_Core::cpu_write( nes_addr_t addr, int data, nes_time_t time )
|
||||
{
|
||||
//LOG_FREQ( "cpu_write", 16, addr >> 12 );
|
||||
|
||||
|
@ -116,4 +120,24 @@ inline void Nes_Core::cpu_write( nes_addr_t addr, int data, nes_time_t time )
|
|||
mapper->write( clock_, addr, data );
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
log_unmapped( addr, data );
|
||||
#endif
|
||||
}
|
||||
|
||||
#define NES_CPU_READ_PPU( cpu, addr, time ) \
|
||||
STATIC_CAST(Nes_Core&,*cpu).cpu_read_ppu( addr, time )
|
||||
|
||||
#define NES_CPU_READ( cpu, addr, time ) \
|
||||
STATIC_CAST(Nes_Core&,*cpu).cpu_read( addr, time )
|
||||
|
||||
#define NES_CPU_WRITEX( cpu, addr, data, time ){\
|
||||
STATIC_CAST(Nes_Core&,*cpu).cpu_write( addr, data, time );\
|
||||
}
|
||||
|
||||
#define NES_CPU_WRITE( cpu, addr, data, time ){\
|
||||
if ( addr < 0x800 ) cpu->low_mem [addr] = data;\
|
||||
else if ( addr == 0x2007 ) STATIC_CAST(Nes_Core&,*cpu).cpu_write_2007( data );\
|
||||
else STATIC_CAST(Nes_Core&,*cpu).cpu_write( addr, data, time );\
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
|
||||
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "nes_data.h"
|
||||
|
||||
#include "blargg_endian.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"
|
||||
|
||||
#define SWAP_BE( n ) (void) (set_be( &(n), (n) ))
|
||||
#define SWAP_LE( n ) (void) (set_le( &(n), (n) ))
|
||||
|
||||
void nes_block_t::swap()
|
||||
{
|
||||
SWAP_BE( tag );
|
||||
SWAP_LE( size );
|
||||
}
|
||||
|
||||
void nes_state_t::swap()
|
||||
{
|
||||
SWAP_LE( timestamp );
|
||||
SWAP_LE( frame_count );
|
||||
}
|
||||
|
||||
void cpu_state_t::swap()
|
||||
{
|
||||
SWAP_LE( pc );
|
||||
}
|
||||
|
||||
void ppu_state_t::swap()
|
||||
{
|
||||
SWAP_LE( vram_addr );
|
||||
SWAP_LE( vram_temp );
|
||||
SWAP_LE( decay_low );
|
||||
SWAP_LE( decay_high );
|
||||
}
|
||||
|
||||
void apu_state_t::swap()
|
||||
{
|
||||
SWAP_LE( apu.frame_delay );
|
||||
SWAP_LE( square1.delay );
|
||||
SWAP_LE( square2.delay );
|
||||
SWAP_LE( triangle.delay );
|
||||
SWAP_LE( noise.delay );
|
||||
SWAP_LE( noise.shift_reg );
|
||||
SWAP_LE( dmc.delay );
|
||||
SWAP_LE( dmc.remain );
|
||||
SWAP_LE( dmc.addr );
|
||||
}
|
||||
|
||||
void joypad_state_t::swap()
|
||||
{
|
||||
SWAP_LE( joypad_latches [0] );
|
||||
SWAP_LE( joypad_latches [1] );
|
||||
}
|
|
@ -6,10 +6,8 @@
|
|||
#ifndef NES_DATA_H
|
||||
#define NES_DATA_H
|
||||
|
||||
#include "blargg_endian.h"
|
||||
#include "blargg_common.h"
|
||||
#include "apu_state.h"
|
||||
#include <cstring>
|
||||
|
||||
typedef long nes_tag_t;
|
||||
|
||||
|
@ -50,13 +48,8 @@ struct nes_block_t
|
|||
uint32_t tag; // ** stored in big-endian
|
||||
uint32_t size;
|
||||
|
||||
inline void swap()
|
||||
{
|
||||
SWAP_BE( tag );
|
||||
SWAP_LE( size );
|
||||
}
|
||||
void swap();
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof (nes_block_t) == 8 );
|
||||
|
||||
unsigned long const group_begin_size = 0xffffffff; // group block has this size
|
||||
|
@ -70,13 +63,8 @@ struct nes_state_t
|
|||
uint32_t frame_count; // number of frames emulated since power-up
|
||||
|
||||
enum { tag = FOUR_CHAR('TIME') };
|
||||
inline void swap()
|
||||
{
|
||||
SWAP_LE( timestamp );
|
||||
SWAP_LE( frame_count );
|
||||
}
|
||||
void swap();
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof (nes_state_t) == 8 );
|
||||
|
||||
struct joypad_state_t
|
||||
|
@ -86,12 +74,7 @@ struct joypad_state_t
|
|||
uint8_t unused [3];
|
||||
|
||||
enum { tag = FOUR_CHAR('CTRL') };
|
||||
inline void swap()
|
||||
{
|
||||
SWAP_LE( joypad_latches [0] );
|
||||
SWAP_LE( joypad_latches [1] );
|
||||
}
|
||||
|
||||
void swap();
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (joypad_state_t) == 12 );
|
||||
|
||||
|
@ -106,18 +89,8 @@ struct mapper_state_t
|
|||
uint8_t data [max_mapper_state_size];
|
||||
};
|
||||
|
||||
inline void write( const void* p, unsigned long s )
|
||||
{
|
||||
size = s;
|
||||
memcpy( data, p, s );
|
||||
}
|
||||
|
||||
inline int read( void* p, unsigned long s ) const
|
||||
{
|
||||
if ( (long) s > size )s = size;
|
||||
memcpy( p, data, s );
|
||||
return s;
|
||||
}
|
||||
void write( const void* p, unsigned long s );
|
||||
int read( void* p, unsigned long s ) const;
|
||||
};
|
||||
|
||||
struct cpu_state_t
|
||||
|
@ -131,12 +104,8 @@ struct cpu_state_t
|
|||
uint8_t unused [1];
|
||||
|
||||
enum { tag = FOUR_CHAR('CPUR') };
|
||||
inline void swap()
|
||||
{
|
||||
SWAP_LE( pc );
|
||||
}
|
||||
void swap();
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof (cpu_state_t) == 8 );
|
||||
|
||||
struct ppu_state_t
|
||||
|
@ -158,15 +127,8 @@ struct ppu_state_t
|
|||
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 );
|
||||
}
|
||||
void swap();
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof (ppu_state_t) == 20 + 0x20 );
|
||||
|
||||
struct mmc1_state_t
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#define NES_NTSC_H
|
||||
|
||||
#include "nes_ntsc_config.h"
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -47,9 +46,9 @@ extern nes_ntsc_setup_t const nes_ntsc_rgb; /* crisp image */
|
|||
extern nes_ntsc_setup_t const nes_ntsc_monochrome;/* desaturated + artifacts */
|
||||
|
||||
#ifdef NES_NTSC_EMPHASIS
|
||||
static const uint16_t nes_ntsc_palette_size = 64 * 8;
|
||||
enum { nes_ntsc_palette_size = 64 * 8 };
|
||||
#else
|
||||
static const uint16_t { nes_ntsc_palette_size = 64 };
|
||||
enum { nes_ntsc_palette_size = 64 };
|
||||
#endif
|
||||
|
||||
/* Initializes and adjusts parameters. Can be called multiple times on the same
|
||||
|
@ -80,10 +79,10 @@ value. */
|
|||
|
||||
/* Interface for user-defined custom blitters */
|
||||
|
||||
const static uint8_t nes_ntsc_in_chunk = 3; /* number of input pixels read per chunk */
|
||||
const static uint8_t nes_ntsc_out_chunk = 7 ; /* number of output pixels generated per chunk */
|
||||
const static uint8_t nes_ntsc_black = 15; /* palette index for black */
|
||||
const static uint8_t nes_ntsc_burst_count = 3 ; /* burst phase cycles through 0, 1, and 2 */
|
||||
enum { nes_ntsc_in_chunk = 3 }; /* number of input pixels read per chunk */
|
||||
enum { nes_ntsc_out_chunk = 7 }; /* number of output pixels generated per chunk */
|
||||
enum { nes_ntsc_black = 15 }; /* palette index for black */
|
||||
enum { nes_ntsc_burst_count = 3 }; /* burst phase cycles through 0, 1, and 2 */
|
||||
|
||||
/* Begins outputting row and starts three pixels. First pixel will be cut off a bit.
|
||||
Use nes_ntsc_black for unused pixels. Declares variables, so must be before first
|
||||
|
@ -107,13 +106,12 @@ statement in a block (unless you're using C++). */
|
|||
|
||||
|
||||
/* private */
|
||||
const static uint8_t nes_ntsc_entry_size = 128;
|
||||
enum { nes_ntsc_entry_size = 128 };
|
||||
typedef unsigned long nes_ntsc_rgb_t;
|
||||
struct nes_ntsc_t {
|
||||
nes_ntsc_rgb_t table [nes_ntsc_palette_size] [nes_ntsc_entry_size];
|
||||
};
|
||||
|
||||
const static uint8_t nes_ntsc_burst_size = nes_ntsc_entry_size / nes_ntsc_burst_count;
|
||||
enum { nes_ntsc_burst_size = nes_ntsc_entry_size / nes_ntsc_burst_count };
|
||||
|
||||
#define NES_NTSC_ENTRY_( ktable, n ) \
|
||||
(nes_ntsc_rgb_t const*) (ktable + (n) * (nes_ntsc_entry_size * sizeof (nes_ntsc_rgb_t)))
|
||||
|
@ -124,18 +122,18 @@ const static uint8_t nes_ntsc_burst_size = nes_ntsc_entry_size / nes_ntsc_burst_
|
|||
#define NES_NTSC_RGB15_OUT( x, out ) NES_NTSC_RGB_OUT( x, out, 15 )
|
||||
#define NES_NTSC_RAW_OUT( x, out ) NES_NTSC_RGB_OUT( x, out, 0 )
|
||||
|
||||
const static uint16_t nes_ntsc_min_in_width = 256;
|
||||
const static uint16_t nes_ntsc_min_out_width = NES_NTSC_OUT_WIDTH( nes_ntsc_min_in_width );
|
||||
enum { nes_ntsc_min_in_width = 256 };
|
||||
enum { nes_ntsc_min_out_width = NES_NTSC_OUT_WIDTH( nes_ntsc_min_in_width ) };
|
||||
|
||||
const static uint16_t nes_ntsc_640_in_width = 271;
|
||||
const static uint16_t nes_ntsc_640_out_width = NES_NTSC_OUT_WIDTH( nes_ntsc_640_in_width );
|
||||
const static uint16_t nes_ntsc_640_overscan_left = 8;
|
||||
const static uint16_t nes_ntsc_640_overscan_right = nes_ntsc_640_in_width - 256 - nes_ntsc_640_overscan_left;
|
||||
enum { nes_ntsc_640_in_width = 271 };
|
||||
enum { nes_ntsc_640_out_width = NES_NTSC_OUT_WIDTH( nes_ntsc_640_in_width ) };
|
||||
enum { nes_ntsc_640_overscan_left = 8 };
|
||||
enum { nes_ntsc_640_overscan_right = nes_ntsc_640_in_width - 256 - nes_ntsc_640_overscan_left };
|
||||
|
||||
const static uint16_t nes_ntsc_full_in_width = 283;
|
||||
const static uint16_t nes_ntsc_full_out_width = NES_NTSC_OUT_WIDTH( nes_ntsc_full_in_width );
|
||||
const static uint16_t nes_ntsc_full_overscan_left = 16;
|
||||
const static uint16_t nes_ntsc_full_overscan_right = nes_ntsc_full_in_width - 256 - nes_ntsc_full_overscan_left;
|
||||
enum { nes_ntsc_full_in_width = 283 };
|
||||
enum { nes_ntsc_full_out_width = NES_NTSC_OUT_WIDTH( nes_ntsc_full_in_width ) };
|
||||
enum { nes_ntsc_full_overscan_left = 16 };
|
||||
enum { nes_ntsc_full_overscan_right = nes_ntsc_full_in_width - 256 - nes_ntsc_full_overscan_left };
|
||||
|
||||
/* common 3->7 ntsc macros */
|
||||
#define NES_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, ENTRY, table ) \
|
||||
|
|
|
@ -44,9 +44,9 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|||
#define rgb_unit (1 << rgb_bits)
|
||||
#define rgb_offset (rgb_unit * 2 + 0.5f)
|
||||
|
||||
const static uint16_t burst_size = nes_ntsc_entry_size / burst_count;
|
||||
const static uint8_t kernel_half = 16;
|
||||
const static uint8_t kernel_size = kernel_half * 2 + 1;
|
||||
enum { burst_size = nes_ntsc_entry_size / burst_count };
|
||||
enum { kernel_half = 16 };
|
||||
enum { kernel_size = kernel_half * 2 + 1 };
|
||||
|
||||
typedef struct init_t
|
||||
{
|
||||
|
@ -284,8 +284,8 @@ static void init( init_t* impl, nes_ntsc_setup_t const* setup )
|
|||
|
||||
#define PACK_RGB( r, g, b ) ((r) << 21 | (g) << 11 | (b) << 1)
|
||||
|
||||
const static uint16_t rgb_kernel_size = burst_size / alignment_count;
|
||||
const static uint32_t rgb_bias = rgb_unit * 2 * nes_ntsc_rgb_builder;
|
||||
enum { rgb_kernel_size = burst_size / alignment_count };
|
||||
enum { rgb_bias = rgb_unit * 2 * nes_ntsc_rgb_builder };
|
||||
|
||||
typedef struct pixel_info_t
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Git revision: main:d023e639c3ac3ad84cffba52d5645b81a501c4d4
|
||||
Git revision: main:95a95df8e17630200c2f9741786b1abd9159c7a3
|
||||
Getting system information
|
||||
Architecture: x86_64
|
||||
CPU op-mode(s): 32-bit, 64-bit
|
||||
|
@ -52,8 +52,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0xB1413A628D2B1D1B79B4F07B3E70AE83
|
||||
[] State Size: 12793 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.413s
|
||||
[] Performance: 38227.178 steps / s
|
||||
[] Elapsed time: 0.371s
|
||||
[] Performance: 42603.262 steps / s
|
||||
[] Final State Hash: 0x1FA0AE49927B0C7485B8A8931F14A57A
|
||||
[] Verification Hash: 0x1FA0AE49927B0C7485B8A8931F14A57A (Passed)
|
||||
[] -----------------------------------------
|
||||
|
@ -66,8 +66,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0xB1413A628D2B1D1B79B4F07B3E70AE83
|
||||
[] State Size: 12793 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.162s
|
||||
[] Performance: 33942.159 steps / s
|
||||
[] Elapsed time: 1.055s
|
||||
[] Performance: 37366.389 steps / s
|
||||
[] Final State Hash: 0xCDD173D996245BF7133375B2217A01C
|
||||
[] Verification Hash: 0xCDD173D996245BF7133375B2217A01C (Passed)
|
||||
~/quickerNES/tests/games
|
||||
|
@ -82,8 +82,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0x3CA9F26CF6511A0694C15C1FF876FCC
|
||||
[] State Size: 12807 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.334s
|
||||
[] Performance: 27443.872 steps / s
|
||||
[] Elapsed time: 1.305s
|
||||
[] Performance: 28064.077 steps / s
|
||||
[] Final State Hash: 0xB6A66050EB4D7445D6A84A76D7B2BB65
|
||||
[] Verification Hash: 0xB6A66050EB4D7445D6A84A76D7B2BB65 (Passed)
|
||||
[] -----------------------------------------
|
||||
|
@ -97,7 +97,7 @@ Running Tests sequentially...
|
|||
[] State Size: 12807 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.242s
|
||||
[] Performance: 27916.811 steps / s
|
||||
[] Performance: 27902.635 steps / s
|
||||
[] Final State Hash: 0xDF97F201F54959948D4C4B89C4D220FC
|
||||
[] Verification Hash: 0xDF97F201F54959948D4C4B89C4D220FC (Passed)
|
||||
~/quickerNES/tests/games
|
||||
|
@ -112,8 +112,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 7.240s
|
||||
[] Performance: 25162.227 steps / s
|
||||
[] Elapsed time: 7.480s
|
||||
[] Performance: 24355.534 steps / s
|
||||
[] Final State Hash: 0xF0F317E40A902D175E6902B49500DF4B
|
||||
[] Verification Hash: 0xF0F317E40A902D175E6902B49500DF4B (Passed)
|
||||
~/quickerNES/tests/games
|
||||
|
@ -128,8 +128,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0xB6C7EB1C577108C7C0E045D00EC73DDC
|
||||
[] State Size: 12798 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 10.556s
|
||||
[] Performance: 28096.433 steps / s
|
||||
[] Elapsed time: 10.656s
|
||||
[] Performance: 27832.552 steps / s
|
||||
[] Final State Hash: 0x407AA16502BE4D678916D218B1310132
|
||||
[] Verification Hash: 0x407AA16502BE4D678916D218B1310132 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
|
@ -144,8 +144,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.601s
|
||||
[] Performance: 24709.686 steps / s
|
||||
[] Elapsed time: 1.318s
|
||||
[] Performance: 30011.572 steps / s
|
||||
[] Final State Hash: 0x65214803DC4559ABBED8C449F04D4C91
|
||||
[] Verification Hash: 0x65214803DC4559ABBED8C449F04D4C91 (Passed)
|
||||
[] -----------------------------------------
|
||||
|
@ -158,8 +158,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.527s
|
||||
[] Performance: 24456.475 steps / s
|
||||
[] Elapsed time: 1.198s
|
||||
[] Performance: 31170.751 steps / s
|
||||
[] Final State Hash: 0x9042C9EFA138F36E505AA33BF50436
|
||||
[] Verification Hash: 0x9042C9EFA138F36E505AA33BF50436 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
|
@ -174,8 +174,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0x7BE2D5D63A0545DF3D44A5881CA69E9D
|
||||
[] State Size: 12798 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 2.353s
|
||||
[] Performance: 36618.048 steps / s
|
||||
[] Elapsed time: 2.292s
|
||||
[] Performance: 37588.356 steps / s
|
||||
[] Final State Hash: 0xFFB8ABEE93CDEA838DB6B69470AC819A
|
||||
[] Verification Hash: 0xFFB8ABEE93CDEA838DB6B69470AC819A (Passed)
|
||||
~/quickerNES/tests/games
|
||||
|
@ -190,8 +190,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0x43443FDD057BBE517B4CDA12736CAD67
|
||||
[] State Size: 12792 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.075s
|
||||
[] Performance: 37795.958 steps / s
|
||||
[] Elapsed time: 1.008s
|
||||
[] Performance: 40292.895 steps / s
|
||||
[] Final State Hash: 0x926C1D6B031E5BD739B13B5734C3D500
|
||||
[] Verification Hash: 0x926C1D6B031E5BD739B13B5734C3D500 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
|
@ -206,8 +206,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0x1F405ED3A13732A3DBEDC4C54A50AC79
|
||||
[] State Size: 12792 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.713s
|
||||
[] Performance: 25064.892 steps / s
|
||||
[] Elapsed time: 0.737s
|
||||
[] Performance: 24225.342 steps / s
|
||||
[] Final State Hash: 0xFBB1BE4D99BB17041747DF056C079D57
|
||||
[] Verification Hash: 0xFBB1BE4D99BB17041747DF056C079D57 (Passed)
|
||||
[] -----------------------------------------
|
||||
|
@ -220,8 +220,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0x1F405ED3A13732A3DBEDC4C54A50AC79
|
||||
[] State Size: 12792 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 2.690s
|
||||
[] Performance: 24953.019 steps / s
|
||||
[] Elapsed time: 2.803s
|
||||
[] Performance: 23939.753 steps / s
|
||||
[] Final State Hash: 0xDC3A45216E64D193849B0B248D18E0C3
|
||||
[] Verification Hash: 0xDC3A45216E64D193849B0B248D18E0C3 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
|
@ -236,8 +236,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0x7CC865ED649238B850937BAE9DCADC5
|
||||
[] State Size: 12798 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.406s
|
||||
[] Performance: 28927.321 steps / s
|
||||
[] Elapsed time: 1.381s
|
||||
[] Performance: 29450.401 steps / s
|
||||
[] Final State Hash: 0x358165AE6BC7A3EAE0E08D24F9A19BC6
|
||||
[] Verification Hash: 0x358165AE6BC7A3EAE0E08D24F9A19BC6 (Passed)
|
||||
[] -----------------------------------------
|
||||
|
@ -250,8 +250,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0x7CC865ED649238B850937BAE9DCADC5
|
||||
[] State Size: 12798 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.327s
|
||||
[] Performance: 29464.084 steps / s
|
||||
[] Elapsed time: 1.287s
|
||||
[] Performance: 30400.721 steps / s
|
||||
[] Final State Hash: 0x5527602EE5679B55EC45BA654B704477
|
||||
[] Verification Hash: 0x5527602EE5679B55EC45BA654B704477 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
|
@ -266,8 +266,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.901s
|
||||
[] Performance: 28617.890 steps / s
|
||||
[] Elapsed time: 0.895s
|
||||
[] Performance: 28805.919 steps / s
|
||||
[] Final State Hash: 0xCCB65DF6BED258071A720C5FA2FE4FB9
|
||||
[] Verification Hash: 0xCCB65DF6BED258071A720C5FA2FE4FB9 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
|
@ -282,8 +282,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0xA1482537F260939E3E0059719CD723AD
|
||||
[] State Size: 12793 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 2.328s
|
||||
[] Performance: 32959.393 steps / s
|
||||
[] Elapsed time: 2.365s
|
||||
[] Performance: 32439.480 steps / s
|
||||
[] Final State Hash: 0xC988A4BDCB3B44DA54AD97D2F2E0F4AF
|
||||
[] Verification Hash: 0xC988A4BDCB3B44DA54AD97D2F2E0F4AF (Passed)
|
||||
~/quickerNES/tests/games
|
||||
|
@ -298,8 +298,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.736s
|
||||
[] Performance: 35346.699 steps / s
|
||||
[] Elapsed time: 0.684s
|
||||
[] Performance: 38036.181 steps / s
|
||||
[] Final State Hash: 0x3D0ACE9B9D592AE6922354DDC3682BAB
|
||||
[] Verification Hash: 0x3D0ACE9B9D592AE6922354DDC3682BAB (Passed)
|
||||
~/quickerNES/tests/games
|
||||
|
@ -314,8 +314,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0x6FE586095495B63F2EFD6B69C5560FC9
|
||||
[] State Size: 20993 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 1.768s
|
||||
[] Performance: 26014.717 steps / s
|
||||
[] Elapsed time: 1.780s
|
||||
[] Performance: 25838.636 steps / s
|
||||
[] Final State Hash: 0x1E08CEBDE3EC56B659D54328D3D9E344
|
||||
[] Verification Hash: 0x1E08CEBDE3EC56B659D54328D3D9E344 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
|
@ -330,8 +330,8 @@ Running Tests sequentially...
|
|||
[] Initial State Hash: 0x4BB3E8B61F496038D8A01894B8B824F
|
||||
[] State Size: 12792 bytes
|
||||
[] ********** Running Test **********
|
||||
[] Elapsed time: 0.890s
|
||||
[] Performance: 33617.789 steps / s
|
||||
[] Elapsed time: 0.888s
|
||||
[] Performance: 33704.677 steps / s
|
||||
[] Final State Hash: 0x4E40A40820C188009A061C5C7FC7DB29
|
||||
[] Verification Hash: 0x4E40A40820C188009A061C5C7FC7DB29 (Passed)
|
||||
~/quickerNES/tests/games
|
||||
|
|
Loading…
Reference in New Issue