mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 07:12:16 +00:00
GME update with bug-fixes
- True fix for infinite loops [please verify!] - True fix for KSS silence - Fix for HES distorted and unstable/random tempo
This commit is contained in:
parent
7d73616fda
commit
1a070d12a1
7 changed files with 318 additions and 287 deletions
|
@ -94,14 +94,14 @@ bool Hes_Cpu::run( hes_time_t end_time )
|
||||||
state_t s = this->state_;
|
state_t s = this->state_;
|
||||||
this->state = &s;
|
this->state = &s;
|
||||||
// even on x86, using s.time in place of s_time was slower
|
// even on x86, using s.time in place of s_time was slower
|
||||||
int16_t s_time = s.time;
|
blargg_long s_time = s.time;
|
||||||
|
|
||||||
// registers
|
// registers
|
||||||
uint16_t pc = r.pc;
|
uint_fast16_t pc = r.pc;
|
||||||
uint8_t a = r.a;
|
uint_fast8_t a = r.a;
|
||||||
uint8_t x = r.x;
|
uint_fast8_t x = r.x;
|
||||||
uint8_t y = r.y;
|
uint_fast8_t y = r.y;
|
||||||
uint16_t sp;
|
uint_fast16_t sp;
|
||||||
SET_SP( r.sp );
|
SET_SP( r.sp );
|
||||||
|
|
||||||
#define IS_NEG (nz & 0x8080)
|
#define IS_NEG (nz & 0x8080)
|
||||||
|
@ -120,11 +120,11 @@ bool Hes_Cpu::run( hes_time_t end_time )
|
||||||
nz |= ~in & st_z;\
|
nz |= ~in & st_z;\
|
||||||
} while ( 0 )
|
} while ( 0 )
|
||||||
|
|
||||||
uint8_t status;
|
uint_fast8_t status;
|
||||||
uint16_t c; // carry set if (c & 0x100) != 0
|
uint_fast16_t c; // carry set if (c & 0x100) != 0
|
||||||
uint16_t nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0
|
uint_fast16_t nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0
|
||||||
{
|
{
|
||||||
uint8_t temp = r.status;
|
uint_fast8_t temp = r.status;
|
||||||
SET_STATUS( temp );
|
SET_STATUS( temp );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ loop:
|
||||||
check( (unsigned) x < 0x100 );
|
check( (unsigned) x < 0x100 );
|
||||||
|
|
||||||
uint8_t const* instr = s.code_map [pc >> page_shift];
|
uint8_t const* instr = s.code_map [pc >> page_shift];
|
||||||
uint8_t opcode;
|
uint_fast8_t opcode;
|
||||||
|
|
||||||
// TODO: eliminate this special case
|
// TODO: eliminate this special case
|
||||||
#if BLARGG_NONPORTABLE
|
#if BLARGG_NONPORTABLE
|
||||||
|
@ -187,7 +187,7 @@ loop:
|
||||||
4,7,7,17,2,4,6,7,2,5,4,2,2,5,7,6 // F
|
4,7,7,17,2,4,6,7,2,5,4,2,2,5,7,6 // F
|
||||||
}; // 0x00 was 8
|
}; // 0x00 was 8
|
||||||
|
|
||||||
uint16_t data;
|
uint_fast16_t data;
|
||||||
data = clock_table [opcode];
|
data = clock_table [opcode];
|
||||||
if ( (s_time += data) >= 0 )
|
if ( (s_time += data) >= 0 )
|
||||||
goto possibly_out_of_time;
|
goto possibly_out_of_time;
|
||||||
|
@ -224,7 +224,7 @@ possibly_out_of_time:
|
||||||
// TODO: more efficient way to handle negative branch that wraps PC around
|
// TODO: more efficient way to handle negative branch that wraps PC around
|
||||||
#define BRANCH( cond )\
|
#define BRANCH( cond )\
|
||||||
{\
|
{\
|
||||||
int16_t offset = (int8_t) data;\
|
int_fast16_t offset = (int8_t) data;\
|
||||||
pc++;\
|
pc++;\
|
||||||
if ( !(cond) ) goto branch_not_taken;\
|
if ( !(cond) ) goto branch_not_taken;\
|
||||||
pc = uint16_t (pc + offset);\
|
pc = uint16_t (pc + offset);\
|
||||||
|
@ -277,7 +277,7 @@ possibly_out_of_time:
|
||||||
case 0xCF:
|
case 0xCF:
|
||||||
case 0xDF:
|
case 0xDF:
|
||||||
case 0xEF: {
|
case 0xEF: {
|
||||||
uint16_t t = 0x101 * READ_LOW( data );
|
uint_fast16_t t = 0x101 * READ_LOW( data );
|
||||||
t ^= 0xFF;
|
t ^= 0xFF;
|
||||||
pc++;
|
pc++;
|
||||||
data = GET_MSB();
|
data = GET_MSB();
|
||||||
|
@ -305,7 +305,7 @@ possibly_out_of_time:
|
||||||
goto branch_taken;
|
goto branch_taken;
|
||||||
|
|
||||||
case 0x20: { // JSR
|
case 0x20: { // JSR
|
||||||
uint16_t temp = pc + 1;
|
uint_fast16_t temp = pc + 1;
|
||||||
pc = GET_ADDR();
|
pc = GET_ADDR();
|
||||||
WRITE_LOW( 0x100 | (sp - 1), temp >> 8 );
|
WRITE_LOW( 0x100 | (sp - 1), temp >> 8 );
|
||||||
sp = (sp - 2) | 0x100;
|
sp = (sp - 2) | 0x100;
|
||||||
|
@ -326,7 +326,7 @@ possibly_out_of_time:
|
||||||
|
|
||||||
case 0xBD:{// LDA abs,X
|
case 0xBD:{// LDA abs,X
|
||||||
PAGE_CROSS_PENALTY( data + x );
|
PAGE_CROSS_PENALTY( data + x );
|
||||||
uint16_t addr = GET_ADDR() + x;
|
uint_fast16_t addr = GET_ADDR() + x;
|
||||||
pc += 2;
|
pc += 2;
|
||||||
CPU_READ_FAST( this, addr, TIME, nz );
|
CPU_READ_FAST( this, addr, TIME, nz );
|
||||||
a = nz;
|
a = nz;
|
||||||
|
@ -334,7 +334,7 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x9D:{// STA abs,X
|
case 0x9D:{// STA abs,X
|
||||||
uint16_t addr = GET_ADDR() + x;
|
uint_fast16_t addr = GET_ADDR() + x;
|
||||||
pc += 2;
|
pc += 2;
|
||||||
CPU_WRITE_FAST( this, addr, a, TIME );
|
CPU_WRITE_FAST( this, addr, a, TIME );
|
||||||
goto loop;
|
goto loop;
|
||||||
|
@ -348,7 +348,7 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
case 0xAE:{// LDX abs
|
case 0xAE:{// LDX abs
|
||||||
uint16_t addr = GET_ADDR();
|
uint_fast16_t addr = GET_ADDR();
|
||||||
pc += 2;
|
pc += 2;
|
||||||
CPU_READ_FAST( this, addr, TIME, nz );
|
CPU_READ_FAST( this, addr, TIME, nz );
|
||||||
x = nz;
|
x = nz;
|
||||||
|
@ -363,7 +363,7 @@ possibly_out_of_time:
|
||||||
// Load/store
|
// Load/store
|
||||||
|
|
||||||
{
|
{
|
||||||
uint16_t addr;
|
uint_fast16_t addr;
|
||||||
case 0x91: // STA (ind),Y
|
case 0x91: // STA (ind),Y
|
||||||
addr = 0x100 * READ_LOW( uint8_t (data + 1) );
|
addr = 0x100 * READ_LOW( uint8_t (data + 1) );
|
||||||
addr += READ_LOW( data ) + y;
|
addr += READ_LOW( data ) + y;
|
||||||
|
@ -389,7 +389,7 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
uint16_t addr;
|
uint_fast16_t addr;
|
||||||
case 0xA1: // LDA (ind,X)
|
case 0xA1: // LDA (ind,X)
|
||||||
data = uint8_t (data + x);
|
data = uint8_t (data + x);
|
||||||
case 0xB2: // LDA (ind)
|
case 0xB2: // LDA (ind)
|
||||||
|
@ -419,7 +419,7 @@ possibly_out_of_time:
|
||||||
|
|
||||||
case 0xBE:{// LDX abs,y
|
case 0xBE:{// LDX abs,y
|
||||||
PAGE_CROSS_PENALTY( data + y );
|
PAGE_CROSS_PENALTY( data + y );
|
||||||
uint16_t addr = GET_ADDR() + y;
|
uint_fast16_t addr = GET_ADDR() + y;
|
||||||
pc += 2;
|
pc += 2;
|
||||||
FLUSH_TIME();
|
FLUSH_TIME();
|
||||||
x = nz = READ( addr );
|
x = nz = READ( addr );
|
||||||
|
@ -443,7 +443,7 @@ possibly_out_of_time:
|
||||||
case 0x3C: // BIT abs,x
|
case 0x3C: // BIT abs,x
|
||||||
data += x;
|
data += x;
|
||||||
case 0x2C:{// BIT abs
|
case 0x2C:{// BIT abs
|
||||||
uint16_t addr;
|
uint_fast16_t addr;
|
||||||
ADD_PAGE( addr );
|
ADD_PAGE( addr );
|
||||||
FLUSH_TIME();
|
FLUSH_TIME();
|
||||||
nz = READ( addr );
|
nz = READ( addr );
|
||||||
|
@ -466,7 +466,7 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
{
|
{
|
||||||
uint16_t addr;
|
uint_fast16_t addr;
|
||||||
|
|
||||||
case 0xB3: // TST abs,x
|
case 0xB3: // TST abs,x
|
||||||
addr = GET_MSB() + x;
|
addr = GET_MSB() + x;
|
||||||
|
@ -499,7 +499,7 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
{
|
{
|
||||||
uint16_t addr;
|
uint_fast16_t addr;
|
||||||
case 0x0C: // TSB abs
|
case 0x0C: // TSB abs
|
||||||
case 0x1C: // TRB abs
|
case 0x1C: // TRB abs
|
||||||
addr = GET_ADDR();
|
addr = GET_ADDR();
|
||||||
|
@ -604,7 +604,7 @@ possibly_out_of_time:
|
||||||
data += x;
|
data += x;
|
||||||
PAGE_CROSS_PENALTY( data );
|
PAGE_CROSS_PENALTY( data );
|
||||||
case 0xAC:{// LDY abs
|
case 0xAC:{// LDY abs
|
||||||
uint16_t addr = data + 0x100 * GET_MSB();
|
uint_fast16_t addr = data + 0x100 * GET_MSB();
|
||||||
pc += 2;
|
pc += 2;
|
||||||
FLUSH_TIME();
|
FLUSH_TIME();
|
||||||
y = nz = READ( addr );
|
y = nz = READ( addr );
|
||||||
|
@ -613,7 +613,7 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
uint8_t temp;
|
uint_fast8_t temp;
|
||||||
case 0x8C: // STY abs
|
case 0x8C: // STY abs
|
||||||
temp = y;
|
temp = y;
|
||||||
goto store_abs;
|
goto store_abs;
|
||||||
|
@ -621,7 +621,7 @@ possibly_out_of_time:
|
||||||
case 0x8E: // STX abs
|
case 0x8E: // STX abs
|
||||||
temp = x;
|
temp = x;
|
||||||
store_abs:
|
store_abs:
|
||||||
uint16_t addr = GET_ADDR();
|
uint_fast16_t addr = GET_ADDR();
|
||||||
pc += 2;
|
pc += 2;
|
||||||
FLUSH_TIME();
|
FLUSH_TIME();
|
||||||
WRITE( addr, temp );
|
WRITE( addr, temp );
|
||||||
|
@ -632,7 +632,7 @@ possibly_out_of_time:
|
||||||
// Compare
|
// Compare
|
||||||
|
|
||||||
case 0xEC:{// CPX abs
|
case 0xEC:{// CPX abs
|
||||||
uint16_t addr = GET_ADDR();
|
uint_fast16_t addr = GET_ADDR();
|
||||||
pc++;
|
pc++;
|
||||||
FLUSH_TIME();
|
FLUSH_TIME();
|
||||||
data = READ( addr );
|
data = READ( addr );
|
||||||
|
@ -651,7 +651,7 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
case 0xCC:{// CPY abs
|
case 0xCC:{// CPY abs
|
||||||
uint16_t addr = GET_ADDR();
|
uint_fast16_t addr = GET_ADDR();
|
||||||
pc++;
|
pc++;
|
||||||
FLUSH_TIME();
|
FLUSH_TIME();
|
||||||
data = READ( addr );
|
data = READ( addr );
|
||||||
|
@ -678,7 +678,7 @@ possibly_out_of_time:
|
||||||
data = 0x100 * READ_LOW( uint8_t (data + 1) ) + READ_LOW( data );\
|
data = 0x100 * READ_LOW( uint8_t (data + 1) ) + READ_LOW( data );\
|
||||||
goto ptr##op;\
|
goto ptr##op;\
|
||||||
case op + 0x0C:{/* (ind),y */\
|
case op + 0x0C:{/* (ind),y */\
|
||||||
uint16_t temp = READ_LOW( data ) + y;\
|
uint_fast16_t temp = READ_LOW( data ) + y;\
|
||||||
PAGE_CROSS_PENALTY( temp );\
|
PAGE_CROSS_PENALTY( temp );\
|
||||||
data = temp + 0x100 * READ_LOW( uint8_t (data + 1) );\
|
data = temp + 0x100 * READ_LOW( uint8_t (data + 1) );\
|
||||||
goto ptr##op;\
|
goto ptr##op;\
|
||||||
|
@ -736,8 +736,8 @@ possibly_out_of_time:
|
||||||
adc_imm: {
|
adc_imm: {
|
||||||
if ( status & st_d )
|
if ( status & st_d )
|
||||||
debug_printf( "Decimal mode not supported\n" );
|
debug_printf( "Decimal mode not supported\n" );
|
||||||
int16_t carry = c >> 8 & 1;
|
int_fast16_t carry = c >> 8 & 1;
|
||||||
int16_t ov = (a ^ 0x80) + carry + (int8_t) data; // sign-extend
|
int_fast16_t ov = (a ^ 0x80) + carry + (int8_t) data; // sign-extend
|
||||||
status &= ~st_v;
|
status &= ~st_v;
|
||||||
status |= ov >> 2 & 0x40;
|
status |= ov >> 2 & 0x40;
|
||||||
c = nz = a + data + carry;
|
c = nz = a + data + carry;
|
||||||
|
@ -765,7 +765,7 @@ possibly_out_of_time:
|
||||||
|
|
||||||
case 0x2A: { // ROL A
|
case 0x2A: { // ROL A
|
||||||
nz = a << 1;
|
nz = a << 1;
|
||||||
int16_t temp = c >> 8 & 1;
|
int_fast16_t temp = c >> 8 & 1;
|
||||||
c = nz;
|
c = nz;
|
||||||
nz |= temp;
|
nz |= temp;
|
||||||
a = (uint8_t) nz;
|
a = (uint8_t) nz;
|
||||||
|
@ -871,7 +871,7 @@ possibly_out_of_time:
|
||||||
case 0xD6: // DEC zp,x
|
case 0xD6: // DEC zp,x
|
||||||
data = uint8_t (data + x);
|
data = uint8_t (data + x);
|
||||||
case 0xC6: // DEC zp
|
case 0xC6: // DEC zp
|
||||||
nz = (uint16_t) -1;
|
nz = (unsigned) -1;
|
||||||
add_nz_zp:
|
add_nz_zp:
|
||||||
nz += READ_LOW( data );
|
nz += READ_LOW( data );
|
||||||
write_nz_zp:
|
write_nz_zp:
|
||||||
|
@ -896,7 +896,7 @@ possibly_out_of_time:
|
||||||
case 0xCE: // DEC abs
|
case 0xCE: // DEC abs
|
||||||
data = GET_ADDR();
|
data = GET_ADDR();
|
||||||
dec_ptr:
|
dec_ptr:
|
||||||
nz = (uint16_t) -1;
|
nz = (unsigned) -1;
|
||||||
inc_common:
|
inc_common:
|
||||||
FLUSH_TIME();
|
FLUSH_TIME();
|
||||||
nz += READ( data );
|
nz += READ( data );
|
||||||
|
@ -936,7 +936,7 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
#define SWAP_REGS( r1, r2 ) {\
|
#define SWAP_REGS( r1, r2 ) {\
|
||||||
uint8_t t = r1;\
|
uint_fast8_t t = r1;\
|
||||||
r1 = r2;\
|
r1 = r2;\
|
||||||
r2 = t;\
|
r2 = t;\
|
||||||
goto loop;\
|
goto loop;\
|
||||||
|
@ -978,7 +978,7 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
case 0x40:{// RTI
|
case 0x40:{// RTI
|
||||||
uint8_t temp = READ_LOW( sp );
|
uint_fast8_t temp = READ_LOW( sp );
|
||||||
pc = READ_LOW( 0x100 | (sp - 0xFF) );
|
pc = READ_LOW( 0x100 | (sp - 0xFF) );
|
||||||
pc |= READ_LOW( 0x100 | (sp - 0xFE) ) * 0x100;
|
pc |= READ_LOW( 0x100 | (sp - 0xFE) ) * 0x100;
|
||||||
sp = (sp - 0xFD) | 0x100;
|
sp = (sp - 0xFD) | 0x100;
|
||||||
|
@ -1012,8 +1012,8 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
case 0x28:{// PLP
|
case 0x28:{// PLP
|
||||||
uint8_t temp = POP();
|
uint_fast8_t temp = POP();
|
||||||
uint8_t changed = status ^ temp;
|
uint_fast8_t changed = status ^ temp;
|
||||||
SET_STATUS( temp );
|
SET_STATUS( temp );
|
||||||
if ( !(changed & st_i) )
|
if ( !(changed & st_i) )
|
||||||
goto loop; // I flag didn't change
|
goto loop; // I flag didn't change
|
||||||
|
@ -1024,7 +1024,7 @@ possibly_out_of_time:
|
||||||
#undef POP
|
#undef POP
|
||||||
|
|
||||||
case 0x08: { // PHP
|
case 0x08: { // PHP
|
||||||
uint8_t temp;
|
uint_fast8_t temp;
|
||||||
CALC_STATUS( temp );
|
CALC_STATUS( temp );
|
||||||
PUSH( temp | st_b );
|
PUSH( temp | st_b );
|
||||||
goto loop;
|
goto loop;
|
||||||
|
@ -1033,7 +1033,7 @@ possibly_out_of_time:
|
||||||
// Flags
|
// Flags
|
||||||
|
|
||||||
case 0x38: // SEC
|
case 0x38: // SEC
|
||||||
c = (uint16_t) ~0;
|
c = (unsigned) ~0;
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
case 0x18: // CLC
|
case 0x18: // CLC
|
||||||
|
@ -1101,7 +1101,7 @@ possibly_out_of_time:
|
||||||
// Special
|
// Special
|
||||||
|
|
||||||
case 0x53:{// TAM
|
case 0x53:{// TAM
|
||||||
uint8_t const bits = data; // avoid using data across function call
|
uint_fast8_t const bits = data; // avoid using data across function call
|
||||||
pc++;
|
pc++;
|
||||||
for ( int i = 0; i < 8; i++ )
|
for ( int i = 0; i < 8; i++ )
|
||||||
if ( bits & (1 << i) )
|
if ( bits & (1 << i) )
|
||||||
|
@ -1125,7 +1125,7 @@ possibly_out_of_time:
|
||||||
case 0x03: // ST0
|
case 0x03: // ST0
|
||||||
case 0x13: // ST1
|
case 0x13: // ST1
|
||||||
case 0x23:{// ST2
|
case 0x23:{// ST2
|
||||||
uint16_t addr = opcode >> 4;
|
uint_fast16_t addr = opcode >> 4;
|
||||||
if ( addr )
|
if ( addr )
|
||||||
addr++;
|
addr++;
|
||||||
pc++;
|
pc++;
|
||||||
|
@ -1147,7 +1147,7 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
case 0xF4: { // SET
|
case 0xF4: { // SET
|
||||||
//uint16_t operand = GET_MSB();
|
//fuint16 operand = GET_MSB();
|
||||||
debug_printf( "SET not handled\n" );
|
debug_printf( "SET not handled\n" );
|
||||||
//switch ( data )
|
//switch ( data )
|
||||||
//{
|
//{
|
||||||
|
@ -1159,10 +1159,10 @@ possibly_out_of_time:
|
||||||
// Block transfer
|
// Block transfer
|
||||||
|
|
||||||
{
|
{
|
||||||
uint16_t in_alt;
|
uint_fast16_t in_alt;
|
||||||
int16_t in_inc;
|
int_fast16_t in_inc;
|
||||||
uint16_t out_alt;
|
uint_fast16_t out_alt;
|
||||||
int16_t out_inc;
|
int_fast16_t out_inc;
|
||||||
|
|
||||||
case 0xE3: // TIA
|
case 0xE3: // TIA
|
||||||
in_alt = 0;
|
in_alt = 0;
|
||||||
|
@ -1193,8 +1193,8 @@ possibly_out_of_time:
|
||||||
in_alt = 0;
|
in_alt = 0;
|
||||||
out_alt = 0;
|
out_alt = 0;
|
||||||
bxfer:
|
bxfer:
|
||||||
uint16_t in = GET_LE16( instr + 0 );
|
uint_fast16_t in = GET_LE16( instr + 0 );
|
||||||
uint16_t out = GET_LE16( instr + 2 );
|
uint_fast16_t out = GET_LE16( instr + 2 );
|
||||||
int count = GET_LE16( instr + 4 );
|
int count = GET_LE16( instr + 4 );
|
||||||
if ( !count )
|
if ( !count )
|
||||||
count = 0x10000;
|
count = 0x10000;
|
||||||
|
@ -1206,7 +1206,7 @@ possibly_out_of_time:
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// TODO: reads from $0800-$1400 in I/O page return 0 and don't access I/O
|
// TODO: reads from $0800-$1400 in I/O page return 0 and don't access I/O
|
||||||
uint8_t t = READ( in );
|
uint_fast8_t t = READ( in );
|
||||||
in += in_inc;
|
in += in_inc;
|
||||||
in &= 0xFFFF;
|
in &= 0xFFFF;
|
||||||
s.time += 6;
|
s.time += 6;
|
||||||
|
@ -1246,7 +1246,7 @@ interrupt:
|
||||||
pc = GET_LE16( &READ_PROG( 0xFFF0 ) + result_ );
|
pc = GET_LE16( &READ_PROG( 0xFFF0 ) + result_ );
|
||||||
|
|
||||||
sp = (sp - 3) | 0x100;
|
sp = (sp - 3) | 0x100;
|
||||||
uint8_t temp;
|
uint_fast8_t temp;
|
||||||
CALC_STATUS( temp );
|
CALC_STATUS( temp );
|
||||||
if ( result_ == 6 )
|
if ( result_ == 6 )
|
||||||
temp |= st_b;
|
temp |= st_b;
|
||||||
|
@ -1283,7 +1283,7 @@ out_of_time:
|
||||||
r.y = y;
|
r.y = y;
|
||||||
|
|
||||||
{
|
{
|
||||||
uint8_t temp;
|
uint_fast8_t temp;
|
||||||
CALC_STATUS( temp );
|
CALC_STATUS( temp );
|
||||||
r.status = temp;
|
r.status = temp;
|
||||||
}
|
}
|
||||||
|
@ -1293,4 +1293,3 @@ out_of_time:
|
||||||
|
|
||||||
return illegal_encountered;
|
return illegal_encountered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
// Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Last validated with zexall 2006.11.14 2:19 PM
|
Last validated with zexall 2006.11.14 2:19 PM
|
||||||
|
@ -162,11 +162,6 @@ static byte const ed_dd_timing [0x100] = {
|
||||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
// even on x86, using short and unsigned char was slower
|
|
||||||
typedef int fint16;
|
|
||||||
typedef unsigned fuint16;
|
|
||||||
typedef unsigned fuint8;
|
|
||||||
|
|
||||||
bool Kss_Cpu::run( cpu_time_t end_time )
|
bool Kss_Cpu::run( cpu_time_t end_time )
|
||||||
{
|
{
|
||||||
set_end_time( end_time );
|
set_end_time( end_time );
|
||||||
|
@ -183,10 +178,10 @@ bool Kss_Cpu::run( cpu_time_t end_time )
|
||||||
rg = this->r.b;
|
rg = this->r.b;
|
||||||
|
|
||||||
cpu_time_t s_time = s.time;
|
cpu_time_t s_time = s.time;
|
||||||
fuint16 pc = r.pc;
|
uint_fast32_t pc = r.pc;
|
||||||
fuint16 sp = r.sp;
|
uint_fast32_t sp = r.sp;
|
||||||
fuint16 ix = r.ix; // TODO: keep in memory for direct access?
|
uint_fast32_t ix = r.ix; // TODO: keep in memory for direct access?
|
||||||
fuint16 iy = r.iy;
|
uint_fast32_t iy = r.iy;
|
||||||
int flags = r.b.flags;
|
int flags = r.b.flags;
|
||||||
|
|
||||||
goto loop;
|
goto loop;
|
||||||
|
@ -208,7 +203,7 @@ loop:
|
||||||
uint8_t const* instr = s.read [pc >> page_shift];
|
uint8_t const* instr = s.read [pc >> page_shift];
|
||||||
#define GET_ADDR() GET_LE16( instr )
|
#define GET_ADDR() GET_LE16( instr )
|
||||||
|
|
||||||
fuint8 opcode;
|
uint_fast8_t opcode;
|
||||||
|
|
||||||
// TODO: eliminate this special case
|
// TODO: eliminate this special case
|
||||||
#if BLARGG_NONPORTABLE
|
#if BLARGG_NONPORTABLE
|
||||||
|
@ -241,7 +236,7 @@ loop:
|
||||||
11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F
|
11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F
|
||||||
};
|
};
|
||||||
|
|
||||||
fuint16 data;
|
uint_fast16_t data;
|
||||||
data = base_timing [opcode];
|
data = base_timing [opcode];
|
||||||
if ( (s_time += data) >= 0 )
|
if ( (s_time += data) >= 0 )
|
||||||
goto possibly_out_of_time;
|
goto possibly_out_of_time;
|
||||||
|
@ -297,7 +292,7 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
case 0x3A:{// LD A,(addr)
|
case 0x3A:{// LD A,(addr)
|
||||||
fuint16 addr = GET_ADDR();
|
uint_fast16_t addr = GET_ADDR();
|
||||||
pc += 2;
|
pc += 2;
|
||||||
rg.a = READ( addr );
|
rg.a = READ( addr );
|
||||||
goto loop;
|
goto loop;
|
||||||
|
@ -385,7 +380,7 @@ possibly_out_of_time:
|
||||||
|
|
||||||
case 0xCD:{// CALL addr
|
case 0xCD:{// CALL addr
|
||||||
call_taken:
|
call_taken:
|
||||||
fuint16 addr = pc + 2;
|
uint_fast16_t addr = pc + 2;
|
||||||
pc = GET_ADDR();
|
pc = GET_ADDR();
|
||||||
sp = uint16_t (sp - 2);
|
sp = uint16_t (sp - 2);
|
||||||
WRITE_WORD( sp, addr );
|
WRITE_WORD( sp, addr );
|
||||||
|
@ -501,7 +496,7 @@ possibly_out_of_time:
|
||||||
add_hl_data: {
|
add_hl_data: {
|
||||||
blargg_ulong sum = rp.hl + data;
|
blargg_ulong sum = rp.hl + data;
|
||||||
data ^= rp.hl;
|
data ^= rp.hl;
|
||||||
rp.hl = (uint16_t)sum;
|
rp.hl = sum;
|
||||||
flags = (flags & (S80 | Z40 | V04)) |
|
flags = (flags & (S80 | Z40 | V04)) |
|
||||||
(sum >> 16) |
|
(sum >> 16) |
|
||||||
(sum >> 8 & (F20 | F08)) |
|
(sum >> 8 & (F20 | F08)) |
|
||||||
|
@ -691,21 +686,21 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
case 0x2A:{// LD HL,(addr)
|
case 0x2A:{// LD HL,(addr)
|
||||||
fuint16 addr = GET_ADDR();
|
uint_fast16_t addr = GET_ADDR();
|
||||||
pc += 2;
|
pc += 2;
|
||||||
rp.hl = READ_WORD( addr );
|
rp.hl = READ_WORD( addr );
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x32:{// LD (addr),A
|
case 0x32:{// LD (addr),A
|
||||||
fuint16 addr = GET_ADDR();
|
uint_fast16_t addr = GET_ADDR();
|
||||||
pc += 2;
|
pc += 2;
|
||||||
WRITE( addr, rg.a );
|
WRITE( addr, rg.a );
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x22:{// LD (addr),HL
|
case 0x22:{// LD (addr),HL
|
||||||
fuint16 addr = GET_ADDR();
|
uint_fast16_t addr = GET_ADDR();
|
||||||
pc += 2;
|
pc += 2;
|
||||||
WRITE_WORD( addr, rp.hl );
|
WRITE_WORD( addr, rp.hl );
|
||||||
goto loop;
|
goto loop;
|
||||||
|
@ -728,7 +723,7 @@ possibly_out_of_time:
|
||||||
// Rotate
|
// Rotate
|
||||||
|
|
||||||
case 0x07:{// RLCA
|
case 0x07:{// RLCA
|
||||||
fuint16 temp = rg.a;
|
uint_fast16_t temp = rg.a;
|
||||||
temp = (temp << 1) | (temp >> 7);
|
temp = (temp << 1) | (temp >> 7);
|
||||||
flags = (flags & (S80 | Z40 | P04)) |
|
flags = (flags & (S80 | Z40 | P04)) |
|
||||||
(temp & (F20 | F08 | C01));
|
(temp & (F20 | F08 | C01));
|
||||||
|
@ -737,7 +732,7 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x0F:{// RRCA
|
case 0x0F:{// RRCA
|
||||||
fuint16 temp = rg.a;
|
uint_fast16_t temp = rg.a;
|
||||||
flags = (flags & (S80 | Z40 | P04)) |
|
flags = (flags & (S80 | Z40 | P04)) |
|
||||||
(temp & C01);
|
(temp & C01);
|
||||||
temp = (temp << 7) | (temp >> 1);
|
temp = (temp << 7) | (temp >> 1);
|
||||||
|
@ -756,7 +751,7 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x1F:{// RRA
|
case 0x1F:{// RRA
|
||||||
fuint16 temp = (flags << 7) | (rg.a >> 1);
|
uint_fast16_t temp = (flags << 7) | (rg.a >> 1);
|
||||||
flags = (flags & (S80 | Z40 | P04)) |
|
flags = (flags & (S80 | Z40 | P04)) |
|
||||||
(temp & (F20 | F08)) |
|
(temp & (F20 | F08)) |
|
||||||
(rg.a & C01);
|
(rg.a & C01);
|
||||||
|
@ -766,7 +761,7 @@ possibly_out_of_time:
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
case 0x2F:{// CPL
|
case 0x2F:{// CPL
|
||||||
fuint16 temp = ~rg.a;
|
uint_fast16_t temp = ~rg.a;
|
||||||
flags = (flags & (S80 | Z40 | P04 | C01)) |
|
flags = (flags & (S80 | Z40 | P04 | C01)) |
|
||||||
(temp & (F20 | F08)) |
|
(temp & (F20 | F08)) |
|
||||||
(H10 | N02);
|
(H10 | N02);
|
||||||
|
@ -792,21 +787,21 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
case 0xE3:{// EX (SP),HL
|
case 0xE3:{// EX (SP),HL
|
||||||
fuint16 temp = READ_WORD( sp );
|
uint_fast16_t temp = READ_WORD( sp );
|
||||||
WRITE_WORD( sp, rp.hl );
|
WRITE_WORD( sp, rp.hl );
|
||||||
rp.hl = temp;
|
rp.hl = temp;
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xEB:{// EX DE,HL
|
case 0xEB:{// EX DE,HL
|
||||||
fuint16 temp = rp.hl;
|
uint_fast16_t temp = rp.hl;
|
||||||
rp.hl = rp.de;
|
rp.hl = rp.de;
|
||||||
rp.de = temp;
|
rp.de = temp;
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xD9:{// EXX DE,HL
|
case 0xD9:{// EXX DE,HL
|
||||||
fuint16 temp = r.alt.w.bc;
|
uint_fast16_t temp = r.alt.w.bc;
|
||||||
r.alt.w.bc = rp.bc;
|
r.alt.w.bc = rp.bc;
|
||||||
rp.bc = temp;
|
rp.bc = temp;
|
||||||
|
|
||||||
|
@ -847,7 +842,7 @@ possibly_out_of_time:
|
||||||
// Rotate left
|
// Rotate left
|
||||||
|
|
||||||
#define RLC( read, write ) {\
|
#define RLC( read, write ) {\
|
||||||
fuint8 result = read;\
|
uint_fast8_t result = read;\
|
||||||
result = uint8_t (result << 1) | (result >> 7);\
|
result = uint8_t (result << 1) | (result >> 7);\
|
||||||
flags = SZ28P( result ) | (result & C01);\
|
flags = SZ28P( result ) | (result & C01);\
|
||||||
write;\
|
write;\
|
||||||
|
@ -866,7 +861,7 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RL( read, write ) {\
|
#define RL( read, write ) {\
|
||||||
fuint16 result = (read << 1) | (flags & C01);\
|
uint_fast16_t result = (read << 1) | (flags & C01);\
|
||||||
flags = SZ28PC( result );\
|
flags = SZ28PC( result );\
|
||||||
write;\
|
write;\
|
||||||
goto loop;\
|
goto loop;\
|
||||||
|
@ -884,7 +879,7 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SLA( read, add, write ) {\
|
#define SLA( read, add, write ) {\
|
||||||
fuint16 result = (read << 1) | add;\
|
uint_fast16_t result = (read << 1) | add;\
|
||||||
flags = SZ28PC( result );\
|
flags = SZ28PC( result );\
|
||||||
write;\
|
write;\
|
||||||
goto loop;\
|
goto loop;\
|
||||||
|
@ -915,7 +910,7 @@ possibly_out_of_time:
|
||||||
// Rotate right
|
// Rotate right
|
||||||
|
|
||||||
#define RRC( read, write ) {\
|
#define RRC( read, write ) {\
|
||||||
fuint8 result = read;\
|
uint_fast8_t result = read;\
|
||||||
flags = result & C01;\
|
flags = result & C01;\
|
||||||
result = uint8_t (result << 7) | (result >> 1);\
|
result = uint8_t (result << 7) | (result >> 1);\
|
||||||
flags |= SZ28P( result );\
|
flags |= SZ28P( result );\
|
||||||
|
@ -935,8 +930,8 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RR( read, write ) {\
|
#define RR( read, write ) {\
|
||||||
fuint8 result = read;\
|
uint_fast8_t result = read;\
|
||||||
fuint8 temp = result & C01;\
|
uint_fast8_t temp = result & C01;\
|
||||||
result = uint8_t (flags << 7) | (result >> 1);\
|
result = uint8_t (flags << 7) | (result >> 1);\
|
||||||
flags = SZ28P( result ) | temp;\
|
flags = SZ28P( result ) | temp;\
|
||||||
write;\
|
write;\
|
||||||
|
@ -955,7 +950,7 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SRA( read, write ) {\
|
#define SRA( read, write ) {\
|
||||||
fuint8 result = read;\
|
uint_fast8_t result = read;\
|
||||||
flags = result & C01;\
|
flags = result & C01;\
|
||||||
result = (result & 0x80) | (result >> 1);\
|
result = (result & 0x80) | (result >> 1);\
|
||||||
flags |= SZ28P( result );\
|
flags |= SZ28P( result );\
|
||||||
|
@ -975,7 +970,7 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SRL( read, write ) {\
|
#define SRL( read, write ) {\
|
||||||
fuint8 result = read;\
|
uint_fast8_t result = read;\
|
||||||
flags = result & C01;\
|
flags = result & C01;\
|
||||||
result >>= 1;\
|
result >>= 1;\
|
||||||
flags |= SZ28P( result );\
|
flags |= SZ28P( result );\
|
||||||
|
@ -1083,7 +1078,7 @@ possibly_out_of_time:
|
||||||
blargg_ulong sum = temp + (flags & C01);
|
blargg_ulong sum = temp + (flags & C01);
|
||||||
flags = ~data >> 2 & N02;
|
flags = ~data >> 2 & N02;
|
||||||
if ( flags )
|
if ( flags )
|
||||||
sum = (blargg_ulong)-(blargg_long)sum;
|
sum = -sum;
|
||||||
sum += rp.hl;
|
sum += rp.hl;
|
||||||
temp ^= rp.hl;
|
temp ^= rp.hl;
|
||||||
temp ^= sum;
|
temp ^= sum;
|
||||||
|
@ -1091,7 +1086,7 @@ possibly_out_of_time:
|
||||||
(temp >> 8 & H10) |
|
(temp >> 8 & H10) |
|
||||||
(sum >> 8 & (S80 | F20 | F08)) |
|
(sum >> 8 & (S80 | F20 | F08)) |
|
||||||
((temp - -0x8000) >> 14 & V04);
|
((temp - -0x8000) >> 14 & V04);
|
||||||
rp.hl = (uint16_t)sum;
|
rp.hl = sum;
|
||||||
if ( (uint16_t) sum )
|
if ( (uint16_t) sum )
|
||||||
goto loop;
|
goto loop;
|
||||||
flags |= Z40;
|
flags |= Z40;
|
||||||
|
@ -1119,7 +1114,7 @@ possibly_out_of_time:
|
||||||
case 0x43: // LD (ADDR),BC
|
case 0x43: // LD (ADDR),BC
|
||||||
case 0x53: // LD (ADDR),DE
|
case 0x53: // LD (ADDR),DE
|
||||||
temp = R16( data, 4, 0x43 );
|
temp = R16( data, 4, 0x43 );
|
||||||
fuint16 addr = GET_ADDR();
|
uint_fast16_t addr = GET_ADDR();
|
||||||
pc += 2;
|
pc += 2;
|
||||||
WRITE_WORD( addr, temp );
|
WRITE_WORD( addr, temp );
|
||||||
goto loop;
|
goto loop;
|
||||||
|
@ -1127,21 +1122,21 @@ possibly_out_of_time:
|
||||||
|
|
||||||
case 0x4B: // LD BC,(ADDR)
|
case 0x4B: // LD BC,(ADDR)
|
||||||
case 0x5B:{// LD DE,(ADDR)
|
case 0x5B:{// LD DE,(ADDR)
|
||||||
fuint16 addr = GET_ADDR();
|
uint_fast16_t addr = GET_ADDR();
|
||||||
pc += 2;
|
pc += 2;
|
||||||
R16( data, 4, 0x4B ) = READ_WORD( addr );
|
R16( data, 4, 0x4B ) = READ_WORD( addr );
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x7B:{// LD SP,(ADDR)
|
case 0x7B:{// LD SP,(ADDR)
|
||||||
fuint16 addr = GET_ADDR();
|
uint_fast16_t addr = GET_ADDR();
|
||||||
pc += 2;
|
pc += 2;
|
||||||
sp = READ_WORD( addr );
|
sp = READ_WORD( addr );
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x67:{// RRD
|
case 0x67:{// RRD
|
||||||
fuint8 temp = READ( rp.hl );
|
uint_fast8_t temp = READ( rp.hl );
|
||||||
WRITE( rp.hl, (rg.a << 4) | (temp >> 4) );
|
WRITE( rp.hl, (rg.a << 4) | (temp >> 4) );
|
||||||
temp = (rg.a & 0xF0) | (temp & 0x0F);
|
temp = (rg.a & 0xF0) | (temp & 0x0F);
|
||||||
flags = (flags & C01) | SZ28P( temp );
|
flags = (flags & C01) | SZ28P( temp );
|
||||||
|
@ -1150,7 +1145,7 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x6F:{// RLD
|
case 0x6F:{// RLD
|
||||||
fuint8 temp = READ( rp.hl );
|
uint_fast8_t temp = READ( rp.hl );
|
||||||
WRITE( rp.hl, (temp << 4) | (rg.a & 0x0F) );
|
WRITE( rp.hl, (temp << 4) | (rg.a & 0x0F) );
|
||||||
temp = (rg.a & 0xF0) | (temp >> 4);
|
temp = (rg.a & 0xF0) | (temp >> 4);
|
||||||
flags = (flags & C01) | SZ28P( temp );
|
flags = (flags & C01) | SZ28P( temp );
|
||||||
|
@ -1174,7 +1169,7 @@ possibly_out_of_time:
|
||||||
case 0xA1: // CPI
|
case 0xA1: // CPI
|
||||||
case 0xB1: // CPIR
|
case 0xB1: // CPIR
|
||||||
inc = +1;
|
inc = +1;
|
||||||
fuint16 addr = rp.hl;
|
uint_fast16_t addr = rp.hl;
|
||||||
rp.hl = addr + inc;
|
rp.hl = addr + inc;
|
||||||
int temp = READ( addr );
|
int temp = READ( addr );
|
||||||
|
|
||||||
|
@ -1207,7 +1202,7 @@ possibly_out_of_time:
|
||||||
case 0xA0: // LDI
|
case 0xA0: // LDI
|
||||||
case 0xB0: // LDIR
|
case 0xB0: // LDIR
|
||||||
inc = +1;
|
inc = +1;
|
||||||
fuint16 addr = rp.hl;
|
uint_fast16_t addr = rp.hl;
|
||||||
rp.hl = addr + inc;
|
rp.hl = addr + inc;
|
||||||
int temp = READ( addr );
|
int temp = READ( addr );
|
||||||
|
|
||||||
|
@ -1239,7 +1234,7 @@ possibly_out_of_time:
|
||||||
case 0xA3: // OUTI
|
case 0xA3: // OUTI
|
||||||
case 0xB3: // OTIR
|
case 0xB3: // OTIR
|
||||||
inc = +1;
|
inc = +1;
|
||||||
fuint16 addr = rp.hl;
|
uint_fast16_t addr = rp.hl;
|
||||||
rp.hl = addr + inc;
|
rp.hl = addr + inc;
|
||||||
int temp = READ( addr );
|
int temp = READ( addr );
|
||||||
|
|
||||||
|
@ -1265,7 +1260,7 @@ possibly_out_of_time:
|
||||||
case 0xB2: // INIR
|
case 0xB2: // INIR
|
||||||
inc = +1;
|
inc = +1;
|
||||||
|
|
||||||
fuint16 addr = rp.hl;
|
uint_fast16_t addr = rp.hl;
|
||||||
rp.hl = addr + inc;
|
rp.hl = addr + inc;
|
||||||
|
|
||||||
int temp = IN( rp.bc );
|
int temp = IN( rp.bc );
|
||||||
|
@ -1330,7 +1325,7 @@ possibly_out_of_time:
|
||||||
|
|
||||||
//////////////////////////////////////// DD/FD prefix
|
//////////////////////////////////////// DD/FD prefix
|
||||||
{
|
{
|
||||||
fuint16 ixy;
|
uint_fast16_t ixy;
|
||||||
case 0xDD:
|
case 0xDD:
|
||||||
ixy = ix;
|
ixy = ix;
|
||||||
goto ix_prefix;
|
goto ix_prefix;
|
||||||
|
@ -1526,7 +1521,7 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
case 0x22:{// LD (ADDR),IXY
|
case 0x22:{// LD (ADDR),IXY
|
||||||
fuint16 addr = GET_ADDR();
|
uint_fast16_t addr = GET_ADDR();
|
||||||
pc += 2;
|
pc += 2;
|
||||||
WRITE_WORD( addr, ixy );
|
WRITE_WORD( addr, ixy );
|
||||||
goto loop;
|
goto loop;
|
||||||
|
@ -1538,7 +1533,7 @@ possibly_out_of_time:
|
||||||
goto set_ixy;
|
goto set_ixy;
|
||||||
|
|
||||||
case 0x2A:{// LD IXY,(addr)
|
case 0x2A:{// LD IXY,(addr)
|
||||||
fuint16 addr = GET_ADDR();
|
uint_fast16_t addr = GET_ADDR();
|
||||||
ixy = READ_WORD( addr );
|
ixy = READ_WORD( addr );
|
||||||
pc += 2;
|
pc += 2;
|
||||||
goto set_ixy;
|
goto set_ixy;
|
||||||
|
@ -1562,7 +1557,7 @@ possibly_out_of_time:
|
||||||
case 0x3E: goto srl_data_addr; // SRL (IXY)
|
case 0x3E: goto srl_data_addr; // SRL (IXY)
|
||||||
|
|
||||||
CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp)
|
CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp)
|
||||||
fuint8 temp = READ( data );
|
uint_fast8_t temp = READ( data );
|
||||||
int masked = temp & 1 << (data2 >> 3 & 7);
|
int masked = temp & 1 << (data2 >> 3 & 7);
|
||||||
flags = (flags & C01) | H10 |
|
flags = (flags & C01) | H10 |
|
||||||
(masked & S80) |
|
(masked & S80) |
|
||||||
|
@ -1664,7 +1659,7 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
case 0xE3:{// EX (SP),IXY
|
case 0xE3:{// EX (SP),IXY
|
||||||
fuint16 temp = READ_WORD( sp );
|
uint_fast16_t temp = READ_WORD( sp );
|
||||||
WRITE_WORD( sp, ixy );
|
WRITE_WORD( sp, ixy );
|
||||||
ixy = temp;
|
ixy = temp;
|
||||||
goto set_ixy;
|
goto set_ixy;
|
||||||
|
|
|
@ -64,6 +64,8 @@ Music_Emu::Music_Emu()
|
||||||
equalizer_.treble = -1.0;
|
equalizer_.treble = -1.0;
|
||||||
equalizer_.bass = 60;
|
equalizer_.bass = 60;
|
||||||
|
|
||||||
|
emu_autoload_playback_limit_ = true;
|
||||||
|
|
||||||
static const char* const names [] = {
|
static const char* const names [] = {
|
||||||
"Voice 1", "Voice 2", "Voice 3", "Voice 4",
|
"Voice 1", "Voice 2", "Voice 3", "Voice 4",
|
||||||
"Voice 5", "Voice 6", "Voice 7", "Voice 8"
|
"Voice 5", "Voice 6", "Voice 7", "Voice 8"
|
||||||
|
@ -187,6 +189,16 @@ void Music_Emu::end_track_if_error( blargg_err_t err )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Music_Emu::autoload_playback_limit() const
|
||||||
|
{
|
||||||
|
return emu_autoload_playback_limit_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Music_Emu::set_autoload_playback_limit( bool do_autoload_limit )
|
||||||
|
{
|
||||||
|
emu_autoload_playback_limit_ = do_autoload_limit;
|
||||||
|
}
|
||||||
|
|
||||||
// Tell/Seek
|
// Tell/Seek
|
||||||
|
|
||||||
blargg_long Music_Emu::msec_to_samples( blargg_long msec ) const
|
blargg_long Music_Emu::msec_to_samples( blargg_long msec ) const
|
||||||
|
|
|
@ -67,6 +67,13 @@ public:
|
||||||
// true. Fade time can be changed while track is playing.
|
// true. Fade time can be changed while track is playing.
|
||||||
void set_fade( long start_msec, long length_msec = 8000 );
|
void set_fade( long start_msec, long length_msec = 8000 );
|
||||||
|
|
||||||
|
// Controls whether or not to automatically load and obey track length
|
||||||
|
// metadata for supported emulators.
|
||||||
|
//
|
||||||
|
// @since 0.6.2.
|
||||||
|
bool autoload_playback_limit() const;
|
||||||
|
void set_autoload_playback_limit( bool do_autoload_limit );
|
||||||
|
|
||||||
// Disable automatic end-of-track detection and skipping of silence at beginning
|
// Disable automatic end-of-track detection and skipping of silence at beginning
|
||||||
void ignore_silence( bool disable = true );
|
void ignore_silence( bool disable = true );
|
||||||
|
|
||||||
|
@ -170,6 +177,7 @@ private:
|
||||||
blargg_long out_time; // number of samples played since start of track
|
blargg_long out_time; // number of samples played since start of track
|
||||||
blargg_long emu_time; // number of samples emulator has generated since start of track
|
blargg_long emu_time; // number of samples emulator has generated since start of track
|
||||||
bool emu_track_ended_; // emulator has reached end of track
|
bool emu_track_ended_; // emulator has reached end of track
|
||||||
|
bool emu_autoload_playback_limit_; // whether to load and obey track length by default
|
||||||
volatile bool track_ended_;
|
volatile bool track_ended_;
|
||||||
void clear_track_vars();
|
void clear_track_vars();
|
||||||
void end_track_if_error( blargg_err_t );
|
void end_track_if_error( blargg_err_t );
|
||||||
|
|
|
@ -299,6 +299,12 @@ blargg_err_t Spc_Emu::start_track_( int track )
|
||||||
RETURN_ERR( apu.load_spc( file_data, file_size ) );
|
RETURN_ERR( apu.load_spc( file_data, file_size ) );
|
||||||
filter.set_gain( (int) (gain() * SPC_Filter::gain_unit) );
|
filter.set_gain( (int) (gain() * SPC_Filter::gain_unit) );
|
||||||
apu.clear_echo();
|
apu.clear_echo();
|
||||||
|
track_info_t spc_info;
|
||||||
|
RETURN_ERR( track_info_( &spc_info, track ) );
|
||||||
|
|
||||||
|
// Set a default track length, need a non-zero fadeout
|
||||||
|
if ( autoload_playback_limit() && ( spc_info.length > 0 ) )
|
||||||
|
set_fade ( spc_info.length, 50 );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,6 +197,16 @@ BLARGG_EXPORT gme_err_t gme_open_file( const char* path, Music_Emu** out, int sa
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BLARGG_EXPORT void gme_set_autoload_playback_limit( Music_Emu *emu, int do_autoload_limit )
|
||||||
|
{
|
||||||
|
emu->set_autoload_playback_limit( do_autoload_limit != 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BLARGG_EXPORT int gme_autoload_playback_limit( Music_Emu *const emu )
|
||||||
|
{
|
||||||
|
return emu->autoload_playback_limit();
|
||||||
|
}
|
||||||
|
|
||||||
// Used to implement gme_new_emu and gme_new_emu_multi_channel
|
// Used to implement gme_new_emu and gme_new_emu_multi_channel
|
||||||
Music_Emu* gme_internal_new_emu_( gme_type_t type, int rate, bool multi_channel )
|
Music_Emu* gme_internal_new_emu_( gme_type_t type, int rate, bool multi_channel )
|
||||||
{
|
{
|
||||||
|
|
|
@ -153,6 +153,7 @@ MusInfo *GME_OpenSong(FileReader &reader, const char *fmt)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
gme_set_stereo_depth(emu, clamp(*gme_stereodepth, 0.f, 1.f));
|
gme_set_stereo_depth(emu, clamp(*gme_stereodepth, 0.f, 1.f));
|
||||||
|
gme_set_fade(emu, -1); // Enable infinite loop
|
||||||
return new GMESong(emu, sample_rate);
|
return new GMESong(emu, sample_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue