diff --git a/source/core/Nes_Cpu.cpp b/source/core/Nes_Cpu.cpp index 2eaa396..06a103e 100644 --- a/source/core/Nes_Cpu.cpp +++ b/source/core/Nes_Cpu.cpp @@ -21,7 +21,100 @@ 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" +// Macros + +#define GET_OPERAND( addr ) page [addr] +#define GET_OPERAND16( addr ) GET_LE16( &page [addr] ) + +#define ADD_PAGE (pc++, data += 0x100 * GET_OPERAND( pc )); +#define GET_ADDR() GET_OPERAND16( pc ) + +#define HANDLE_PAGE_CROSSING( lsb ) clock_count += (lsb) >> 8; + +#define INC_DEC_XY( reg, n ) reg = uint8_t (nz = reg + n); goto loop; + +#define IND_Y(r,c) { \ + int temp = READ_LOW( data ) + y; \ + data = temp + 0x100 * READ_LOW( uint8_t (data + 1) ); \ + if (c) HANDLE_PAGE_CROSSING( temp ); \ + if (!(r) || (temp & 0x100)) \ + READ( data - ( temp & 0x100 ) ); \ + } + +#define IND_X { \ + int temp = data + x; \ + data = 0x100 * READ_LOW( uint8_t (temp + 1) ) + READ_LOW( uint8_t (temp) ); \ + } + +#define ARITH_ADDR_MODES( op ) \ +case op - 0x04: /* (ind,x) */ \ + IND_X \ + goto ptr##op; \ +case op + 0x0C: /* (ind),y */ \ + IND_Y(true,true) \ + goto ptr##op; \ +case op + 0x10: /* zp,X */ \ + data = uint8_t (data + x); \ +case op + 0x00: /* zp */ \ + data = READ_LOW( data ); \ + goto imm##op; \ +case op + 0x14: /* abs,Y */ \ + data += y; \ + goto ind##op; \ +case op + 0x18: /* abs,X */ \ + data += x; \ +ind##op: { \ + HANDLE_PAGE_CROSSING( data ); \ + int temp = data; \ + ADD_PAGE \ + if ( temp & 0x100 ) \ + READ( data - 0x100 ); \ + goto ptr##op; \ +} \ +case op + 0x08: /* abs */ \ + ADD_PAGE \ +ptr##op: \ + data = READ( data ); \ +case op + 0x04: /* imm */ \ +imm##op: \ + +#define ARITH_ADDR_MODES_PTR( op ) \ +case op - 0x04: /* (ind,x) */ \ + IND_X \ + goto imm##op; \ +case op + 0x0C: \ + IND_Y(false,false) \ + goto imm##op; \ +case op + 0x10: /* zp,X */ \ + data = uint8_t (data + x); \ + goto imm##op; \ +case op + 0x14: /* abs,Y */ \ + data += y; \ + goto ind##op; \ +case op + 0x18: /* abs,X */ \ + data += x; \ +ind##op: { \ + int temp = data; \ + ADD_PAGE \ + READ( data - ( temp & 0x100 ) ); \ + goto imm##op; \ +} \ +case op + 0x08: /* abs */ \ + ADD_PAGE \ +case op + 0x00: /* zp */ \ +imm##op: \ + +#define BRANCH( cond ) \ +{ \ + pc++; \ + int offset = (int8_t) data; \ + int extra_clock = (pc & 0xFF) + offset; \ + if ( !(cond) ) goto dec_clock_loop; \ + pc += offset; \ + pc = uint16_t( pc ); \ + clock_count += (extra_clock >> 8) & 1; \ + goto loop; \ +} inline void Nes_Cpu::set_code_page( int i, uint8_t const* p ) { @@ -118,7 +211,7 @@ enum { st_c = 0x01, }; -static const unsigned char clock_table [256] = { +constexpr uint8_t clock_table [256] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 7,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,// 0 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 1 @@ -174,7 +267,7 @@ dec_clock_loop: loop: uint8_t const* page = code_map [pc >> page_bits]; - unsigned opcode = page [pc]; + uint8_t opcode = page [pc]; pc++; if ( clock_count >= clock_limit ) @@ -187,104 +280,6 @@ loop: switch ( opcode ) { -// Macros - -#define GET_OPERAND( addr ) page [addr] -#define GET_OPERAND16( addr ) GET_LE16( &page [addr] ) - -//#define GET_OPERAND( addr ) READ_PROG( addr ) -//#define GET_OPERAND16( addr ) READ_PROG16( addr ) - -#define ADD_PAGE (pc++, data += 0x100 * GET_OPERAND( pc )); -#define GET_ADDR() GET_OPERAND16( pc ) - -#define HANDLE_PAGE_CROSSING( lsb ) clock_count += (lsb) >> 8; - -#define INC_DEC_XY( reg, n ) reg = uint8_t (nz = reg + n); goto loop; - -#define IND_Y(r,c) { \ - int temp = READ_LOW( data ) + y; \ - data = temp + 0x100 * READ_LOW( uint8_t (data + 1) ); \ - if (c) HANDLE_PAGE_CROSSING( temp ); \ - if (!(r) || (temp & 0x100)) \ - READ( data - ( temp & 0x100 ) ); \ - } - -#define IND_X { \ - int temp = data + x; \ - data = 0x100 * READ_LOW( uint8_t (temp + 1) ) + READ_LOW( uint8_t (temp) ); \ - } - -#define ARITH_ADDR_MODES( op ) \ -case op - 0x04: /* (ind,x) */ \ - IND_X \ - goto ptr##op; \ -case op + 0x0C: /* (ind),y */ \ - IND_Y(true,true) \ - goto ptr##op; \ -case op + 0x10: /* zp,X */ \ - data = uint8_t (data + x); \ -case op + 0x00: /* zp */ \ - data = READ_LOW( data ); \ - goto imm##op; \ -case op + 0x14: /* abs,Y */ \ - data += y; \ - goto ind##op; \ -case op + 0x18: /* abs,X */ \ - data += x; \ -ind##op: { \ - HANDLE_PAGE_CROSSING( data ); \ - int temp = data; \ - ADD_PAGE \ - if ( temp & 0x100 ) \ - READ( data - 0x100 ); \ - goto ptr##op; \ -} \ -case op + 0x08: /* abs */ \ - ADD_PAGE \ -ptr##op: \ - data = READ( data ); \ -case op + 0x04: /* imm */ \ -imm##op: \ - -#define ARITH_ADDR_MODES_PTR( op ) \ -case op - 0x04: /* (ind,x) */ \ - IND_X \ - goto imm##op; \ -case op + 0x0C: \ - IND_Y(false,false) \ - goto imm##op; \ -case op + 0x10: /* zp,X */ \ - data = uint8_t (data + x); \ - goto imm##op; \ -case op + 0x14: /* abs,Y */ \ - data += y; \ - goto ind##op; \ -case op + 0x18: /* abs,X */ \ - data += x; \ -ind##op: { \ - int temp = data; \ - ADD_PAGE \ - READ( data - ( temp & 0x100 ) ); \ - goto imm##op; \ -} \ -case op + 0x08: /* abs */ \ - ADD_PAGE \ -case op + 0x00: /* zp */ \ -imm##op: \ - -#define BRANCH( cond ) \ -{ \ - pc++; \ - int offset = (int8_t) data; \ - int extra_clock = (pc & 0xFF) + offset; \ - if ( !(cond) ) goto dec_clock_loop; \ - pc += offset; \ - pc = uint16_t( pc ); \ - clock_count += (extra_clock >> 8) & 1; \ - goto loop; \ -} - // Often-Used case 0xB5: // LDA zp,x diff --git a/source/core/Nes_Ppu_Rendering.cpp b/source/core/Nes_Ppu_Rendering.cpp index 2abef34..ef69d32 100644 --- a/source/core/Nes_Ppu_Rendering.cpp +++ b/source/core/Nes_Ppu_Rendering.cpp @@ -190,23 +190,80 @@ void Nes_Ppu_Rendering::draw_background_( int remain ) unsigned long const mask = 0x03030303 + zero; unsigned long const attrib_factor = 0x04040404 + zero; - if ( height == 8 ) + const int fine_y = (height == 8) ? 0 : addr >> 12; + const int clipped = (height == 8) ? false : true; + addr &= 0x03ff; + if (height == 8) height -= fine_y & 1; + + while ( true ) + { + while ( count-- ) { - // unclipped - addr &= 0x03ff; - int const fine_y = 0; - int const clipped = false; - #include "Nes_Ppu_Bg.h" - } - else - { - // clipped - int const fine_y = addr >> 12; - addr &= 0x03ff; - height -= fine_y & 1; - int const clipped = true; - #include "Nes_Ppu_Bg.h" + 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; + } + } while ( remain ); } diff --git a/source/core/blargg_source.h b/source/core/blargg_source.h index 68942c4..eef730a 100644 --- a/source/core/blargg_source.h +++ b/source/core/blargg_source.h @@ -32,8 +32,6 @@ otherwise continues normally. */ return "Out of memory";\ } while ( 0 ) -/* The usual min/max functions for built-in types. */ - template T min( T x, T y ) { return x < y ? x : y; } template T max( T x, T y ) { return x > y ? x : y; }