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