More simplfiications

This commit is contained in:
Sergio Martin 2024-01-13 20:12:03 +01:00
parent 78414cfb6c
commit e40e0c7888
3 changed files with 168 additions and 118 deletions

View File

@ -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

View File

@ -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 );
} }

View File

@ -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; }