Mercurial > audlegacy-plugins
diff src/console/Kss_Cpu.cxx @ 341:986f098da058 trunk
[svn] - merge in blargg's changes
author | nenolod |
---|---|
date | Thu, 07 Dec 2006 15:20:41 -0800 |
parents | fb513e10174e |
children |
line wrap: on
line diff
--- a/src/console/Kss_Cpu.cxx Wed Dec 06 07:57:05 2006 -0800 +++ b/src/console/Kss_Cpu.cxx Thu Dec 07 15:20:41 2006 -0800 @@ -1,8 +1,10 @@ -// Game_Music_Emu 0.5.1. http://www.slack.net/~ant/ +// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ -// Last validated with zexall 2006.11.14 2:19 PM -// Doesn't implement interrupts or the R register, though both would be -// easy to support. +/* +Last validated with zexall 2006.11.14 2:19 PM +* Doesn't implement the R register or immediate interrupt after EI. +* Address wrap-around isn't completely correct, but is prevented from crashing emulator. +*/ #include "Kss_Cpu.h" @@ -27,13 +29,13 @@ // Callbacks to emulator -#define CPU_OUT( cpu, addr, data, time ) \ +#define CPU_OUT( cpu, addr, data, time )\ kss_cpu_out( this, time, addr, data ) -#define CPU_IN( cpu, addr, time ) \ +#define CPU_IN( cpu, addr, time )\ kss_cpu_in( this, time, addr ) -#define CPU_WRITE( cpu, addr, data, time ) \ +#define CPU_WRITE( cpu, addr, data, time )\ (SYNC_TIME(), kss_cpu_write( this, addr, data )) #include "blargg_source.h" @@ -59,7 +61,7 @@ Kss_Cpu::Kss_Cpu() { - state = &state_; + state = &state_; for ( int i = 0x100; --i >= 0; ) { @@ -130,8 +132,8 @@ //#define R16( n, shift, offset ) (r16_ [((n) >> shift) - (offset >> shift)]) -// help compiler see that it can adjust stack offset -#define R16( n, shift, offset ) \ +// help compiler see that it can just adjust stack offset, saving an extra instruction +#define R16( n, shift, offset )\ (*(uint16_t*) ((char*) r16_ - (offset >> (shift - 1)) + ((n) >> (shift - 1)))) #define CASE5( a, b, c, d, e ) case 0x##a:case 0x##b:case 0x##c:case 0x##d:case 0x##e @@ -311,12 +313,13 @@ #define MINUS (flags & S80) // JR +// TODO: more efficient way to handle negative branch that wraps PC around #define JR( cond ) {\ - int disp = (BOOST::int8_t) data;\ + int offset = (BOOST::int8_t) data;\ pc++;\ if ( !(cond) )\ goto jr_not_taken;\ - pc += disp;\ + pc = uint16_t (pc + offset);\ goto loop;\ } @@ -1340,6 +1343,10 @@ s_time += ed_dd_timing [data] & 0x0F; switch ( data ) { + // TODO: more efficient way of avoid negative address + // TODO: avoid using this as argument to READ() since it is evaluated twice + #define IXY_DISP( ixy, disp ) uint16_t ((ixy) + (disp)) + #define SET_IXY( in ) if ( opcode == 0xDD ) ix = in; else iy = in; // ADD/ADC/SUB/SBC @@ -1351,7 +1358,7 @@ case 0x8E: // ADC (IXY+disp) pc++; opcode = data; - data = READ( ixy + (int8_t) data2 ); + data = READ( IXY_DISP( ixy, (int8_t) data2 ) ); goto adc_data; case 0x94: // SUB HXY @@ -1373,26 +1380,26 @@ goto adc_data; { - unsigned data2; + unsigned temp; case 0x39: // ADD IXY,SP - data2 = sp; + temp = sp; goto add_ixy_data; case 0x29: // ADD IXY,HL - data2 = ixy; + temp = ixy; goto add_ixy_data; case 0x09: // ADD IXY,BC case 0x19: // ADD IXY,DE - data2 = R16( data, 4, 0x09 ); + temp = R16( data, 4, 0x09 ); add_ixy_data: { - blargg_ulong sum = ixy + data2; - data2 ^= ixy; + blargg_ulong sum = ixy + temp; + temp ^= ixy; ixy = (uint16_t) sum; flags = (flags & (S80 | Z40 | V04)) | (sum >> 16) | (sum >> 8 & (F20 | F08)) | - ((data2 ^ sum) >> 8 & H10); + ((temp ^ sum) >> 8 & H10); goto set_ixy; } } @@ -1400,7 +1407,7 @@ // AND case 0xA6: // AND (IXY+disp) pc++; - data = READ( ixy + (int8_t) data2 ); + data = READ( IXY_DISP( ixy, (int8_t) data2 ) ); goto and_data; case 0xA4: // AND HXY @@ -1414,7 +1421,7 @@ // OR case 0xB6: // OR (IXY+disp) pc++; - data = READ( ixy + (int8_t) data2 ); + data = READ( IXY_DISP( ixy, (int8_t) data2 ) ); goto or_data; case 0xB4: // OR HXY @@ -1428,7 +1435,7 @@ // XOR case 0xAE: // XOR (IXY+disp) pc++; - data = READ( ixy + (int8_t) data2 ); + data = READ( IXY_DISP( ixy, (int8_t) data2 ) ); goto xor_data; case 0xAC: // XOR HXY @@ -1442,7 +1449,7 @@ // CP case 0xBE: // CP (IXY+disp) pc++; - data = READ( ixy + (int8_t) data2 ); + data = READ( IXY_DISP( ixy, (int8_t) data2 ) ); goto cp_data; case 0xBC: // CP HXY @@ -1460,7 +1467,7 @@ case 0x36: // LD (IXY+disp),imm pc++, data = READ_PROG( pc ); pc++; - WRITE( ixy + (int8_t) data2, data ); + WRITE( IXY_DISP( ixy, (int8_t) data2 ), data ); goto loop; CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY @@ -1477,7 +1484,7 @@ CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp) pc++; - R8( data >> 3, 8 ) = READ( ixy + (int8_t) data2 ); + R8( data >> 3, 8 ) = READ( IXY_DISP( ixy, (int8_t) data2 ) ); goto loop; case 0x26: // LD HXY,imm @@ -1540,7 +1547,7 @@ // DD/FD CB prefix case 0xCB: { - data = ixy + (int8_t) data2; + data = IXY_DISP( ixy, (int8_t) data2 ); pc++; data2 = READ_PROG( pc ); pc++; @@ -1593,14 +1600,14 @@ goto set_ixy; case 0x34: // INC (IXY+disp) - ixy += (int8_t) data2; + ixy = IXY_DISP( ixy, (int8_t) data2 ); pc++; data = READ( ixy ) + 1; WRITE( ixy, data ); goto inc_set_flags; case 0x35: // DEC (IXY+disp) - ixy += (int8_t) data2; + ixy = IXY_DISP( ixy, (int8_t) data2 ); pc++; data = READ( ixy ) - 1; WRITE( ixy, data );