More simplfiications
This commit is contained in:
parent
78414cfb6c
commit
e40e0c7888
|
@ -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
|
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 */
|
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 )
|
inline void Nes_Cpu::set_code_page( int i, uint8_t const* p )
|
||||||
{
|
{
|
||||||
|
@ -118,7 +211,7 @@ enum {
|
||||||
st_c = 0x01,
|
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
|
// 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
|
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
|
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:
|
loop:
|
||||||
|
|
||||||
uint8_t const* page = code_map [pc >> page_bits];
|
uint8_t const* page = code_map [pc >> page_bits];
|
||||||
unsigned opcode = page [pc];
|
uint8_t opcode = page [pc];
|
||||||
pc++;
|
pc++;
|
||||||
|
|
||||||
if ( clock_count >= clock_limit )
|
if ( clock_count >= clock_limit )
|
||||||
|
@ -187,104 +280,6 @@ loop:
|
||||||
switch ( opcode )
|
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
|
// Often-Used
|
||||||
|
|
||||||
case 0xB5: // LDA zp,x
|
case 0xB5: // LDA zp,x
|
||||||
|
|
|
@ -190,23 +190,80 @@ void Nes_Ppu_Rendering::draw_background_( int remain )
|
||||||
unsigned long const mask = 0x03030303 + zero;
|
unsigned long const mask = 0x03030303 + zero;
|
||||||
unsigned long const attrib_factor = 0x04040404 + 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
|
int attrib = attr_table [addr >> 2 & 0x07];
|
||||||
addr &= 0x03ff;
|
attrib >>= (addr >> 4 & 4) | (addr & 2);
|
||||||
int const fine_y = 0;
|
unsigned long offset = (attrib & 3) * attrib_factor + this->palette_offset;
|
||||||
int const clipped = false;
|
|
||||||
#include "Nes_Ppu_Bg.h"
|
// draw one tile
|
||||||
}
|
cache_t const* lines = this->get_bg_tile( nametable [addr] + bg_bank );
|
||||||
else
|
uint8_t* p = pixels;
|
||||||
{
|
addr++;
|
||||||
// clipped
|
pixels += 8; // next tile
|
||||||
int const fine_y = addr >> 12;
|
|
||||||
addr &= 0x03ff;
|
if ( !clipped )
|
||||||
height -= fine_y & 1;
|
{
|
||||||
int const clipped = true;
|
// optimal case: no clipping
|
||||||
#include "Nes_Ppu_Bg.h"
|
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 );
|
while ( remain );
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,6 @@ otherwise continues normally. */
|
||||||
return "Out of memory";\
|
return "Out of memory";\
|
||||||
} while ( 0 )
|
} 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 min( T x, T y ) { return x < y ? x : y; }
|
||||||
template<typename T> T max( T x, T y ) { return x > y ? x : y; }
|
template<typename T> T max( T x, T y ) { return x > y ? x : y; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue