More simplifications
This commit is contained in:
parent
13561dc134
commit
95a95df8e1
|
@ -26,7 +26,6 @@ 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',
|
||||
|
|
|
@ -1,12 +1,4 @@
|
|||
|
||||
// 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"
|
||||
|
||||
/* 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
|
||||
|
@ -17,9 +9,76 @@ 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;
|
||||
|
@ -70,9 +129,79 @@ const char * Nes_Core::open( Nes_Cart const* new_cart )
|
|||
|
||||
RETURN_ERR( init() );
|
||||
|
||||
mapper = Nes_Mapper::create( new_cart, this );
|
||||
if ( !mapper )
|
||||
return unsupported_mapper;
|
||||
// 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);
|
||||
|
||||
RETURN_ERR( ppu.open_chr( new_cart->chr(), new_cart->chr_size() ) );
|
||||
|
||||
|
@ -205,13 +334,6 @@ void Nes_Core::enable_sram( bool b, bool read_only )
|
|||
}
|
||||
}
|
||||
|
||||
// Unmapped memory
|
||||
|
||||
|
||||
void Nes_Core::log_unmapped( nes_addr_t addr, int data )
|
||||
{
|
||||
}
|
||||
|
||||
inline void Nes_Core::cpu_adjust_time( int n )
|
||||
{
|
||||
ppu_2002_time -= n;
|
||||
|
@ -273,10 +395,6 @@ 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 )
|
||||
|
@ -295,10 +413,6 @@ 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
|
||||
}
|
||||
|
||||
|
|
|
@ -104,6 +104,7 @@ 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,7 +1,4 @@
|
|||
|
||||
// Nes_Emu 0.7.0. http://www.slack.net/~ant/nes-emu/
|
||||
|
||||
|
||||
#include "Nes_Cpu.h"
|
||||
|
||||
#include <string.h>
|
||||
|
@ -11,55 +8,17 @@
|
|||
|
||||
#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 */
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
inline void Nes_Cpu::set_code_page( int i, uint8_t const* p )
|
||||
{
|
||||
code_map [i] = p - (unsigned) i * page_size;
|
||||
#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 );\
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -80,10 +39,6 @@ void Nes_Cpu::map_code( nes_addr_t start, unsigned size, const void* data )
|
|||
#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,6 +1,19 @@
|
|||
|
||||
// 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
|
||||
|
@ -14,15 +27,50 @@ 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 );
|
||||
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;
|
||||
}
|
||||
|
||||
// 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 );
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
// Access memory as the emulated CPU does.
|
||||
int read( nes_addr_t );
|
||||
|
@ -73,7 +121,6 @@ public:
|
|||
unsigned long error_count_;
|
||||
|
||||
static const uint8_t irq_inhibit = 0x04;
|
||||
void set_code_page( int, uint8_t const* );
|
||||
void update_clock_limit();
|
||||
|
||||
registers_t r;
|
||||
|
|
|
@ -6,297 +6,8 @@
|
|||
#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,15 +1,27 @@
|
|||
#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;
|
||||
|
@ -23,30 +35,43 @@ public:
|
|||
// Register optional mappers included with Nes_Emu
|
||||
void register_optional_mappers();
|
||||
|
||||
// Create mapper appropriate for cartridge. Returns NULL if it uses unsupported mapper.
|
||||
static Nes_Mapper* create( Nes_Cart const*, Nes_Core* );
|
||||
|
||||
virtual ~Nes_Mapper();
|
||||
virtual ~Nes_Mapper() = default;
|
||||
|
||||
// Reset mapper to power-up state.
|
||||
virtual void reset();
|
||||
virtual inline void reset()
|
||||
{
|
||||
default_reset_state();
|
||||
reset_state();
|
||||
apply_mapping();
|
||||
}
|
||||
|
||||
// Save snapshot of mapper state. Default saves registered state.
|
||||
virtual void save_state( mapper_state_t& );
|
||||
virtual inline void save_state( mapper_state_t& out )
|
||||
{
|
||||
out.write( state, state_size );
|
||||
}
|
||||
|
||||
// Resets mapper, loads state, then applies it
|
||||
virtual void load_state( mapper_state_t const& );
|
||||
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; }
|
||||
|
||||
// I/O
|
||||
|
||||
// Read from memory
|
||||
virtual int read( nes_time_t, nes_addr_t );
|
||||
virtual inline int read( nes_time_t, nes_addr_t ) { return -1; } ;
|
||||
|
||||
// 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 bool write_intercepted( nes_time_t, nes_addr_t, int data );
|
||||
virtual inline bool write_intercepted( nes_time_t, nes_addr_t, int data ) { return false; }
|
||||
|
||||
// Timing
|
||||
|
||||
|
@ -54,53 +79,66 @@ public:
|
|||
enum { no_irq = LONG_MAX / 2 };
|
||||
|
||||
// Time next IRQ will occur at
|
||||
virtual nes_time_t next_irq( nes_time_t present );
|
||||
virtual inline nes_time_t next_irq( nes_time_t present ) { return no_irq; };
|
||||
|
||||
// Run mapper until given time
|
||||
virtual void run_until( nes_time_t );
|
||||
virtual inline void run_until( nes_time_t ) { };
|
||||
|
||||
// End video frame of given length
|
||||
virtual void end_frame( nes_time_t length );
|
||||
|
||||
virtual inline void end_frame( nes_time_t length ) { };
|
||||
|
||||
// Sound
|
||||
|
||||
// Number of sound channels
|
||||
virtual int channel_count() const;
|
||||
virtual inline int channel_count() const { return 0; };
|
||||
|
||||
// Set sound buffer for channel to output to, or NULL to silence channel.
|
||||
virtual void set_channel_buf( int index, Blip_Buffer* );
|
||||
virtual inline void set_channel_buf( int index, Blip_Buffer* ) { };
|
||||
|
||||
// Set treble equalization
|
||||
virtual void set_treble( blip_eq_t const& );
|
||||
|
||||
virtual inline 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 void a12_clocked();
|
||||
virtual inline void a12_clocked() {};
|
||||
|
||||
protected:
|
||||
// Services provided for derived mapper classes
|
||||
Nes_Mapper();
|
||||
Nes_Mapper()
|
||||
{
|
||||
emu_ = NULL;
|
||||
static char c;
|
||||
state = &c; // TODO: state must not be null?
|
||||
state_size = 0;
|
||||
}
|
||||
|
||||
// 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().
|
||||
void register_state( void*, unsigned );
|
||||
inline void register_state(void* p, unsigned s)
|
||||
{
|
||||
state = p;
|
||||
state_size = s;
|
||||
}
|
||||
|
||||
// Enable 8K of RAM at 0x6000-0x7FFF, optionally read-only.
|
||||
void enable_sram( bool enabled = true, bool read_only = false );
|
||||
inline void enable_sram( bool enabled = true, bool read_only = false ) { emu_->enable_sram( enabled, read_only ); }
|
||||
|
||||
// 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.
|
||||
void intercept_writes( nes_addr_t addr, unsigned size );
|
||||
inline void intercept_writes( nes_addr_t addr, unsigned size ) { emu().add_mapper_intercept( addr, size, false, true ); }
|
||||
|
||||
// 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.
|
||||
void intercept_reads( nes_addr_t addr, unsigned size );
|
||||
inline void intercept_reads( nes_addr_t addr, unsigned size )
|
||||
{
|
||||
emu().add_mapper_intercept( addr, size, true, false );
|
||||
}
|
||||
|
||||
// Bank sizes for mapping
|
||||
enum bank_size_t { // 1 << bank_Xk = X * 1024
|
||||
|
@ -117,22 +155,51 @@ 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 size, int bank );
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
// Map 'size' bytes from 'CHR + bank * size' to PPU address space starting at 'addr'
|
||||
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 );
|
||||
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 );
|
||||
}
|
||||
|
||||
// Set PPU mirroring. All mappings implemented using mirror_manual().
|
||||
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();
|
||||
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 ); }
|
||||
|
||||
// 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.
|
||||
bool ppu_enabled() const;
|
||||
inline bool ppu_enabled() const { return emu().ppu.w2001 & 0x08; }
|
||||
|
||||
// Cartridge being emulated
|
||||
Nes_Cart const& cart() const { return *cart_; }
|
||||
|
@ -140,13 +207,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).
|
||||
void irq_changed();
|
||||
inline void irq_changed() { emu_->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 );
|
||||
int handle_bus_conflict( nes_addr_t addr, int data ) { return data; }
|
||||
|
||||
// Reference to emulator that uses this mapper.
|
||||
Nes_Core& emu() const { return *emu_; }
|
||||
|
@ -156,7 +223,12 @@ protected:
|
|||
|
||||
// Read state from snapshot. Default reads data into registered state, then calls
|
||||
// apply_mapping().
|
||||
virtual void read_state( mapper_state_t const& );
|
||||
inline void read_state( mapper_state_t const& in )
|
||||
{
|
||||
memset( state, 0, state_size );
|
||||
in.read( state, state_size );
|
||||
apply_mapping();
|
||||
}
|
||||
|
||||
// Apply current mapping state to hardware. Called after reading mapper state
|
||||
// from a snapshot.
|
||||
|
@ -172,42 +244,26 @@ private:
|
|||
unsigned state_size;
|
||||
Nes_Cart const* cart_;
|
||||
|
||||
void default_reset_state();
|
||||
// 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 );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#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
|
||||
|
|
|
@ -37,14 +37,6 @@ 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()
|
||||
|
|
|
@ -20,16 +20,6 @@ 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&
|
||||
|
@ -188,8 +178,8 @@ void Nes_Ppu_Rendering::draw_background_( int remain )
|
|||
uint8_t* pixels = row_pixels;
|
||||
row_pixels += height * row_bytes;
|
||||
|
||||
unsigned long const mask = 0x03030303 + zero;
|
||||
unsigned long const attrib_factor = 0x04040404 + zero;
|
||||
unsigned long const mask = 0x03030303;
|
||||
unsigned long const attrib_factor = 0x04040404;
|
||||
|
||||
const int fine_y = (height == 8) ? 0 : addr >> 12;
|
||||
const int clipped = (height == 8) ? false : true;
|
||||
|
@ -373,7 +363,7 @@ void Nes_Ppu_Rendering::check_sprite_hit( int begin, int end )
|
|||
}
|
||||
|
||||
// check each line
|
||||
unsigned long const mask = 0x01010101 + zero;
|
||||
unsigned long const mask = 0x01010101;
|
||||
do
|
||||
{
|
||||
// get pixels for line
|
||||
|
|
|
@ -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 + zero;
|
||||
unsigned long const maskgen = 0x80808080 + zero;
|
||||
unsigned long const mask = 0x03030303;
|
||||
unsigned long const maskgen = 0x80808080;
|
||||
|
||||
#define DRAW_PAIR( shift ) { \
|
||||
int sprite_count = *scanlines; \
|
||||
|
@ -48,7 +48,7 @@ unsigned long const maskgen = 0x80808080 + zero;
|
|||
if ( !(sprite_2 & 0x20) )
|
||||
{
|
||||
// front
|
||||
unsigned long const maskgen2 = 0x7f7f7f7f + zero;
|
||||
unsigned long const maskgen2 = 0x7f7f7f7f;
|
||||
|
||||
#define CALC_FOUR( in, line, out ) \
|
||||
unsigned long out; \
|
||||
|
@ -88,8 +88,8 @@ if ( !(sprite_2 & 0x20) )
|
|||
else
|
||||
{
|
||||
// behind
|
||||
unsigned long const omask = 0x20202020 + zero;
|
||||
unsigned long const bg_or = 0xc3c3c3c3 + zero;
|
||||
unsigned long const omask = 0x20202020;
|
||||
unsigned long const bg_or = 0xc3c3c3c3;
|
||||
|
||||
#define CALC_FOUR( in, line, out ) \
|
||||
unsigned long out; \
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include "blargg_common.h"
|
||||
#include "blargg_endian.h"
|
||||
|
||||
struct apu_state_t
|
||||
{
|
||||
|
@ -70,7 +71,19 @@ struct apu_state_t
|
|||
//uint8_t length_counters [4];
|
||||
|
||||
enum { tag = 0x41505552 }; // 'APUR'
|
||||
void swap();
|
||||
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 );
|
||||
}
|
||||
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (apu_state_t) == 72 );
|
||||
|
||||
|
|
|
@ -105,4 +105,7 @@ 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
|
||||
|
|
|
@ -41,10 +41,6 @@ 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
|
||||
}
|
||||
|
||||
|
@ -79,7 +75,7 @@ void Nes_Core::cpu_write_2007( int data )
|
|||
mapper->a12_clocked();
|
||||
}
|
||||
|
||||
void Nes_Core::cpu_write( nes_addr_t addr, int data, nes_time_t time )
|
||||
inline void Nes_Core::cpu_write( nes_addr_t addr, int data, nes_time_t time )
|
||||
{
|
||||
//LOG_FREQ( "cpu_write", 16, addr >> 12 );
|
||||
|
||||
|
@ -120,24 +116,4 @@ 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 );\
|
||||
}
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
#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;
|
||||
|
||||
|
@ -48,8 +50,13 @@ struct nes_block_t
|
|||
uint32_t tag; // ** stored in big-endian
|
||||
uint32_t size;
|
||||
|
||||
void swap();
|
||||
inline 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
|
||||
|
@ -63,8 +70,13 @@ struct nes_state_t
|
|||
uint32_t frame_count; // number of frames emulated since power-up
|
||||
|
||||
enum { tag = FOUR_CHAR('TIME') };
|
||||
void swap();
|
||||
inline void swap()
|
||||
{
|
||||
SWAP_LE( timestamp );
|
||||
SWAP_LE( frame_count );
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof (nes_state_t) == 8 );
|
||||
|
||||
struct joypad_state_t
|
||||
|
@ -74,7 +86,12 @@ struct joypad_state_t
|
|||
uint8_t unused [3];
|
||||
|
||||
enum { tag = FOUR_CHAR('CTRL') };
|
||||
void swap();
|
||||
inline void swap()
|
||||
{
|
||||
SWAP_LE( joypad_latches [0] );
|
||||
SWAP_LE( joypad_latches [1] );
|
||||
}
|
||||
|
||||
};
|
||||
BOOST_STATIC_ASSERT( sizeof (joypad_state_t) == 12 );
|
||||
|
||||
|
@ -89,8 +106,18 @@ struct mapper_state_t
|
|||
uint8_t data [max_mapper_state_size];
|
||||
};
|
||||
|
||||
void write( const void* p, unsigned long s );
|
||||
int read( void* p, unsigned long s ) const;
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
struct cpu_state_t
|
||||
|
@ -104,8 +131,12 @@ struct cpu_state_t
|
|||
uint8_t unused [1];
|
||||
|
||||
enum { tag = FOUR_CHAR('CPUR') };
|
||||
void swap();
|
||||
inline void swap()
|
||||
{
|
||||
SWAP_LE( pc );
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof (cpu_state_t) == 8 );
|
||||
|
||||
struct ppu_state_t
|
||||
|
@ -127,8 +158,15 @@ struct ppu_state_t
|
|||
uint8_t unused2[3];
|
||||
|
||||
enum { tag = FOUR_CHAR('PPUR') };
|
||||
void swap();
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue