doom_py/src/vizdoom/game-music-emu/gme/Ay_Cpu.cpp [810:1648]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		(void) data2; // TODO is this the same as data in all cases?
		pc++;
		switch ( data )
		{
	
	// Rotate left
		
	#define RLC( read, write ) {\
		fuint8 result = read;\
		result = uint8_t (result << 1) | (result >> 7);\
		flags = SZ28P( result ) | (result & C01);\
		write;\
		goto loop;\
	}
		
		case 0x06: // RLC (HL)
			s_time += 7;
			data = rp.hl;
		rlc_data_addr:
			RLC( READ( data ), WRITE( data, result ) )
		
		CASE7( 00, 01, 02, 03, 04, 05, 07 ):{// RLC r
			uint8_t& reg = R8( data, 0 );
			RLC( reg, reg = result )
		}
		
	#define RL( read, write ) {\
		fuint16 result = (read << 1) | (flags & C01);\
		flags = SZ28PC( result );\
		write;\
		goto loop;\
	}
		
		case 0x16: // RL (HL)
			s_time += 7;
			data = rp.hl;
		rl_data_addr:
			RL( READ( data ), WRITE( data, result ) )
		
		CASE7( 10, 11, 12, 13, 14, 15, 17 ):{// RL r
			uint8_t& reg = R8( data, 0x10 );
			RL( reg, reg = result )
		}
		
	#define SLA( read, add, write ) {\
		fuint16 result = (read << 1) | add;\
		flags = SZ28PC( result );\
		write;\
		goto loop;\
	}
		
		case 0x26: // SLA (HL)
			s_time += 7;
			data = rp.hl;
		sla_data_addr:
			SLA( READ( data ), 0, WRITE( data, result ) )
		
		CASE7( 20, 21, 22, 23, 24, 25, 27 ):{// SLA r
			uint8_t& reg = R8( data, 0x20 );
			SLA( reg, 0, reg = result )
		}
		
		case 0x36: // SLL (HL)
			s_time += 7;
			data = rp.hl;
		sll_data_addr:
			SLA( READ( data ), 1, WRITE( data, result ) )
		
		CASE7( 30, 31, 32, 33, 34, 35, 37 ):{// SLL r
			uint8_t& reg = R8( data, 0x30 );
			SLA( reg, 1, reg = result )
		}
		
	// Rotate right
		
	#define RRC( read, write ) {\
		fuint8 result = read;\
		flags = result & C01;\
		result = uint8_t (result << 7) | (result >> 1);\
		flags |= SZ28P( result );\
		write;\
		goto loop;\
	}
		
		case 0x0E: // RRC (HL)
			s_time += 7;
			data = rp.hl;
		rrc_data_addr:
			RRC( READ( data ), WRITE( data, result ) )
		
		CASE7( 08, 09, 0A, 0B, 0C, 0D, 0F ):{// RRC r
			uint8_t& reg = R8( data, 0x08 );
			RRC( reg, reg = result )
		}
		
	#define RR( read, write ) {\
		fuint8 result = read;\
		fuint8 temp = result & C01;\
		result = uint8_t (flags << 7) | (result >> 1);\
		flags = SZ28P( result ) | temp;\
		write;\
		goto loop;\
	}
		
		case 0x1E: // RR (HL)
			s_time += 7;
			data = rp.hl;
		rr_data_addr:
			RR( READ( data ), WRITE( data, result ) )
		
		CASE7( 18, 19, 1A, 1B, 1C, 1D, 1F ):{// RR r
			uint8_t& reg = R8( data, 0x18 );
			RR( reg, reg = result )
		}
		
	#define SRA( read, write ) {\
		fuint8 result = read;\
		flags = result & C01;\
		result = (result & 0x80) | (result >> 1);\
		flags |= SZ28P( result );\
		write;\
		goto loop;\
	}
		
		case 0x2E: // SRA (HL)
			data = rp.hl;
			s_time += 7;
		sra_data_addr:
			SRA( READ( data ), WRITE( data, result ) )
		
		CASE7( 28, 29, 2A, 2B, 2C, 2D, 2F ):{// SRA r
			uint8_t& reg = R8( data, 0x28 );
			SRA( reg, reg = result )
		}
		
	#define SRL( read, write ) {\
		fuint8 result = read;\
		flags = result & C01;\
		result >>= 1;\
		flags |= SZ28P( result );\
		write;\
		goto loop;\
	}
		
		case 0x3E: // SRL (HL)
			s_time += 7;
			data = rp.hl;
		srl_data_addr:
			SRL( READ( data ), WRITE( data, result ) )
		
		CASE7( 38, 39, 3A, 3B, 3C, 3D, 3F ):{// SRL r
			uint8_t& reg = R8( data, 0x38 );
			SRL( reg, reg = result )
		}
		
	// BIT
		{
			unsigned temp;
		CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ): // BIT b,(HL)
			s_time += 4;
			temp = READ( rp.hl );
			flags &= C01;
			goto bit_temp;
		CASE7( 40, 41, 42, 43, 44, 45, 47 ): // BIT 0,r
		CASE7( 48, 49, 4A, 4B, 4C, 4D, 4F ): // BIT 1,r
		CASE7( 50, 51, 52, 53, 54, 55, 57 ): // BIT 2,r
		CASE7( 58, 59, 5A, 5B, 5C, 5D, 5F ): // BIT 3,r
		CASE7( 60, 61, 62, 63, 64, 65, 67 ): // BIT 4,r
		CASE7( 68, 69, 6A, 6B, 6C, 6D, 6F ): // BIT 5,r
		CASE7( 70, 71, 72, 73, 74, 75, 77 ): // BIT 6,r
		CASE7( 78, 79, 7A, 7B, 7C, 7D, 7F ): // BIT 7,r
			temp = R8( data & 7, 0 );
			flags = (flags & C01) | (temp & (F20 | F08));
		bit_temp:
			int masked = temp & 1 << (data >> 3 & 7);
			flags |=(masked & S80) | H10 |
					((masked - 1) >> 8 & (Z40 | P04));
			goto loop;
		}
		
	// SET/RES
		CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(HL)
		CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(HL)
			s_time += 7;
			int temp = READ( rp.hl );
			int bit = 1 << (data >> 3 & 7);
			temp |= bit; // SET
			if ( !(data & 0x40) )
				temp ^= bit; // RES
			WRITE( rp.hl, temp );
			goto loop;
		}
		
		CASE7( C0, C1, C2, C3, C4, C5, C7 ): // SET 0,r
		CASE7( C8, C9, CA, CB, CC, CD, CF ): // SET 1,r
		CASE7( D0, D1, D2, D3, D4, D5, D7 ): // SET 2,r
		CASE7( D8, D9, DA, DB, DC, DD, DF ): // SET 3,r
		CASE7( E0, E1, E2, E3, E4, E5, E7 ): // SET 4,r
		CASE7( E8, E9, EA, EB, EC, ED, EF ): // SET 5,r
		CASE7( F0, F1, F2, F3, F4, F5, F7 ): // SET 6,r
		CASE7( F8, F9, FA, FB, FC, FD, FF ): // SET 7,r
			R8( data & 7, 0 ) |= 1 << (data >> 3 & 7);
			goto loop;
		
		CASE7( 80, 81, 82, 83, 84, 85, 87 ): // RES 0,r
		CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // RES 1,r
		CASE7( 90, 91, 92, 93, 94, 95, 97 ): // RES 2,r
		CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // RES 3,r
		CASE7( A0, A1, A2, A3, A4, A5, A7 ): // RES 4,r
		CASE7( A8, A9, AA, AB, AC, AD, AF ): // RES 5,r
		CASE7( B0, B1, B2, B3, B4, B5, B7 ): // RES 6,r
		CASE7( B8, B9, BA, BB, BC, BD, BF ): // RES 7,r
			R8( data & 7, 0 ) &= ~(1 << (data >> 3 & 7));
			goto loop;
		}
		assert( false );
	}

//////////////////////////////////////// ED prefix
	{
	case 0xED:
		pc++;
		s_time += ed_dd_timing [data] >> 4;
		switch ( data )
		{
		{
			blargg_ulong temp;
		case 0x72: // SBC HL,SP
		case 0x7A: // ADC HL,SP
			temp = sp;
			if ( 0 )
		case 0x42: // SBC HL,BC
		case 0x52: // SBC HL,DE
		case 0x62: // SBC HL,HL
		case 0x4A: // ADC HL,BC
		case 0x5A: // ADC HL,DE
		case 0x6A: // ADC HL,HL
				temp = R16( data >> 3 & 6, 1, 0 );
			blargg_ulong sum = temp + (flags & C01);
			flags = ~data >> 2 & N02;
			if ( flags )
				sum = (blargg_ulong)-(blargg_long)sum;
			sum += rp.hl;
			temp ^= rp.hl;
			temp ^= sum;
			flags |=(sum >> 16 & C01) |
					(temp >> 8 & H10) |
					(sum >> 8 & (S80 | F20 | F08)) |
					((temp - -0x8000) >> 14 & V04);
			rp.hl = (uint16_t)sum;
			if ( (uint16_t) sum )
				goto loop;
			flags |= Z40;
			goto loop;
		}
		
		CASE8( 40, 48, 50, 58, 60, 68, 70, 78 ):{// IN r,(C)
			int temp = IN( rp.bc );
			R8( data >> 3, 8 ) = temp;
			flags = (flags & C01) | SZ28P( temp );
			goto loop;
		}
		
		case 0x71: // OUT (C),0
			rg.flags = 0;
		CASE7( 41, 49, 51, 59, 61, 69, 79 ): // OUT (C),r
			OUT( rp.bc, R8( data >> 3, 8 ) );
			goto loop;
		
		{
			unsigned temp;
		case 0x73: // LD (ADDR),SP
			temp = sp;
			if ( 0 )
		case 0x43: // LD (ADDR),BC
		case 0x53: // LD (ADDR),DE
				temp = R16( data, 4, 0x43 );
			fuint16 addr = GET_ADDR();
			pc += 2;
			WRITE_WORD( addr, temp );
			goto loop;
		}
		
		case 0x4B: // LD BC,(ADDR)
		case 0x5B:{// LD DE,(ADDR)
			fuint16 addr = GET_ADDR();
			pc += 2;
			R16( data, 4, 0x4B ) = READ_WORD( addr );
			goto loop;
		}
		
		case 0x7B:{// LD SP,(ADDR)
			fuint16 addr = GET_ADDR();
			pc += 2;
			sp = READ_WORD( addr );
			goto loop;
		}
		
		case 0x67:{// RRD
			fuint8 temp = READ( rp.hl );
			WRITE( rp.hl, (rg.a << 4) | (temp >> 4) );
			temp = (rg.a & 0xF0) | (temp & 0x0F);
			flags = (flags & C01) | SZ28P( temp );
			rg.a = temp;
			goto loop;
		}
		
		case 0x6F:{// RLD
			fuint8 temp = READ( rp.hl );
			WRITE( rp.hl, (temp << 4) | (rg.a & 0x0F) );
			temp = (rg.a & 0xF0) | (temp >> 4);
			flags = (flags & C01) | SZ28P( temp );
			rg.a = temp;
			goto loop;
		}
		
		CASE8( 44, 4C, 54, 5C, 64, 6C, 74, 7C ): // NEG
			opcode = 0x10; // flag to do SBC instead of ADC
			flags &= ~C01;
			data = rg.a;
			rg.a = 0;
			goto adc_data;
		
		{
			int inc;
		case 0xA9: // CPD
		case 0xB9: // CPDR
			inc = -1;
			if ( 0 )
		case 0xA1: // CPI
		case 0xB1: // CPIR
				inc = +1;
			fuint16 addr = rp.hl;
			rp.hl = addr + inc;
			int temp = READ( addr );
			
			int result = rg.a - temp;
			flags = (flags & C01) | N02 |
					((((temp ^ rg.a) & H10) ^ result) & (S80 | H10));
			
			if ( !(uint8_t) result ) flags |= Z40;
			result -= (flags & H10) >> 4;
			flags |= result & F08;
			flags |= result << 4 & F20;
			if ( !--rp.bc )
				goto loop;
			
			flags |= V04;
			if ( flags & Z40 || data < 0xB0 )
				goto loop;
			
			pc -= 2;
			s_time += 5;
			goto loop;
		}
		
		{
			int inc;
		case 0xA8: // LDD
		case 0xB8: // LDDR
			inc = -1;
			if ( 0 )
		case 0xA0: // LDI
		case 0xB0: // LDIR
				inc = +1;
			fuint16 addr = rp.hl;
			rp.hl = addr + inc;
			int temp = READ( addr );
			
			addr = rp.de;
			rp.de = addr + inc;
			WRITE( addr, temp );
			
			temp += rg.a;
			flags = (flags & (S80 | Z40 | C01)) |
					(temp & F08) | (temp << 4 & F20);
			if ( !--rp.bc )
				goto loop;
			
			flags |= V04;
			if ( data < 0xB0 )
				goto loop;
			
			pc -= 2;
			s_time += 5;
			goto loop;
		}
		
		{
			int inc;
		case 0xAB: // OUTD
		case 0xBB: // OTDR
			inc = -1;
			if ( 0 )
		case 0xA3: // OUTI
		case 0xB3: // OTIR
				inc = +1;
			fuint16 addr = rp.hl;
			rp.hl = addr + inc;
			int temp = READ( addr );
			
			int b = --rg.b;
			flags = (temp >> 6 & N02) | SZ28( b );
			if ( b && data >= 0xB0 )
			{
				pc -= 2;
				s_time += 5;
			}
			
			OUT( rp.bc, temp );
			goto loop;
		}
		
		{
			int inc;
		case 0xAA: // IND
		case 0xBA: // INDR
			inc = -1;
			if ( 0 )
		case 0xA2: // INI
		case 0xB2: // INIR
				inc = +1;
			
			fuint16 addr = rp.hl;
			rp.hl = addr + inc;
			
			int temp = IN( rp.bc );
			
			int b = --rg.b;
			flags = (temp >> 6 & N02) | SZ28( b );
			if ( b && data >= 0xB0 )
			{
				pc -= 2;
				s_time += 5;
			}
			
			WRITE( addr, temp );
			goto loop;
		}
		
		case 0x47: // LD I,A
			r.i = rg.a;
			goto loop;
		
		case 0x4F: // LD R,A
			SET_R( rg.a );
			debug_printf( "LD R,A not supported\n" );
			warning = true;
			goto loop;
		
		case 0x57: // LD A,I
			rg.a = r.i;
			goto ld_ai_common;
		
		case 0x5F: // LD A,R
			rg.a = GET_R();
			debug_printf( "LD A,R not supported\n" );
			warning = true;
		ld_ai_common:
			flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
			goto loop;
		
		CASE8( 45, 4D, 55, 5D, 65, 6D, 75, 7D ): // RETI/RETN
			r.iff1 = r.iff2;
			goto ret_taken;
		
		case 0x46: case 0x4E: case 0x66: case 0x6E: // IM 0
			r.im = 0;
			goto loop;
		
		case 0x56: case 0x76: // IM 1
			r.im = 1;
			goto loop;
		
		case 0x5E: case 0x7E: // IM 2
			r.im = 2;
			goto loop;
		
		default:
			debug_printf( "Opcode $ED $%02X not supported\n", data );
			warning = true;
			goto loop;
		}
		assert( false );
	}

//////////////////////////////////////// DD/FD prefix
	{
	fuint16 ixy;
	case 0xDD:
		ixy = ix;
		goto ix_prefix;
	case 0xFD:
		ixy = iy;
	ix_prefix:
		pc++;
		unsigned data2 = READ_PROG( pc );
		s_time += ed_dd_timing [data] & 0x0F;
		switch ( data )
		{
	// TODO: more efficient way of avoid negative address
	#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
	
		case 0x96: // SUB (IXY+disp)
		case 0x86: // ADD (IXY+disp)
			flags &= ~C01;
		case 0x9E: // SBC (IXY+disp)
		case 0x8E: // ADC (IXY+disp)
			pc++;
			opcode = data;
			data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
			goto adc_data;
		
		case 0x94: // SUB HXY
		case 0x84: // ADD HXY
			flags &= ~C01;
		case 0x9C: // SBC HXY
		case 0x8C: // ADC HXY
			opcode = data;
			data = ixy >> 8;
			goto adc_data;
		
		case 0x95: // SUB LXY
		case 0x85: // ADD LXY
			flags &= ~C01;
		case 0x9D: // SBC LXY
		case 0x8D: // ADC LXY
			opcode = data;
			data = (uint8_t) ixy;
			goto adc_data;
		
		{
			unsigned temp;
		case 0x39: // ADD IXY,SP
			temp = sp;
			goto add_ixy_data;
		
		case 0x29: // ADD IXY,HL
			temp = ixy;
			goto add_ixy_data;
		
		case 0x09: // ADD IXY,BC
		case 0x19: // ADD IXY,DE
			temp = R16( data, 4, 0x09 );
		add_ixy_data: {
			blargg_ulong sum = ixy + temp;
			temp ^= ixy;
			ixy = (uint16_t) sum;
			flags = (flags & (S80 | Z40 | V04)) |
					(sum >> 16) |
					(sum >> 8 & (F20 | F08)) |
					((temp ^ sum) >> 8 & H10);
			goto set_ixy;
		}
		}
	
	// AND
		case 0xA6: // AND (IXY+disp)
			pc++;
			data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
			goto and_data;
		
		case 0xA4: // AND HXY
			data = ixy >> 8;
			goto and_data;
		
		case 0xA5: // AND LXY
			data = (uint8_t) ixy;
			goto and_data;
	
	// OR
		case 0xB6: // OR (IXY+disp)
			pc++;
			data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
			goto or_data;
		
		case 0xB4: // OR HXY
			data = ixy >> 8;
			goto or_data;
		
		case 0xB5: // OR LXY
			data = (uint8_t) ixy;
			goto or_data;
	
	// XOR
		case 0xAE: // XOR (IXY+disp)
			pc++;
			data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
			goto xor_data;
		
		case 0xAC: // XOR HXY
			data = ixy >> 8;
			goto xor_data;
		
		case 0xAD: // XOR LXY
			data = (uint8_t) ixy;
			goto xor_data;
	
	// CP
		case 0xBE: // CP (IXY+disp)
			pc++;
			data = READ( IXY_DISP( ixy, (int8_t) data2 )  );
			goto cp_data;
		
		case 0xBC: // CP HXY
			data = ixy >> 8;
			goto cp_data;
		
		case 0xBD: // CP LXY
			data = (uint8_t) ixy;
			goto cp_data;
		
	// LD
		CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (IXY+disp),r
			data = R8( data, 0x70 );
			if ( 0 )
		case 0x36: // LD (IXY+disp),imm
				pc++, data = READ_PROG( pc );
			pc++;
			WRITE( IXY_DISP( ixy, (int8_t) data2 ), data );
			goto loop;

		CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY
			R8( data >> 3, 8 ) = ixy >> 8;
			goto loop;
		
		case 0x64: // LD HXY,HXY
		case 0x6D: // LD LXY,LXY
			goto loop;
		
		CASE5( 45, 4D, 55, 5D, 7D ): // LD r,LXY
			R8( data >> 3, 8 ) = ixy;
			goto loop;
		
		CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp)
			pc++;
			R8( data >> 3, 8 ) = READ( IXY_DISP( ixy, (int8_t) data2 ) );
			goto loop;
		
		case 0x26: // LD HXY,imm
			pc++;
			goto ld_hxy_data;
			
		case 0x65: // LD HXY,LXY
			data2 = (uint8_t) ixy;
			goto ld_hxy_data;
		
		CASE5( 60, 61, 62, 63, 67 ): // LD HXY,r
			data2 = R8( data, 0x60 );
		ld_hxy_data:
			ixy = (uint8_t) ixy | (data2 << 8);
			goto set_ixy;
		
		case 0x2E: // LD LXY,imm
			pc++;
			goto ld_lxy_data;
			
		case 0x6C: // LD LXY,HXY
			data2 = ixy >> 8;
			goto ld_lxy_data;
		
		CASE5( 68, 69, 6A, 6B, 6F ): // LD LXY,r
			data2 = R8( data, 0x68 );
		ld_lxy_data:
			ixy = (ixy & 0xFF00) | data2;
		set_ixy:
			if ( opcode == 0xDD )
			{
				ix = ixy;
				goto loop;
			}
			iy = ixy;
			goto loop;

		case 0xF9: // LD SP,IXY
			sp = ixy;
			goto loop;
	
		case 0x22:{// LD (ADDR),IXY
			fuint16 addr = GET_ADDR();
			pc += 2;
			WRITE_WORD( addr, ixy );
			goto loop;
		}
		
		case 0x21: // LD IXY,imm
			ixy = GET_ADDR();
			pc += 2;
			goto set_ixy;
		
		case 0x2A:{// LD IXY,(addr)
			fuint16 addr = GET_ADDR();
			ixy = READ_WORD( addr );
			pc += 2;
			goto set_ixy;
		}
		
	// DD/FD CB prefix
		case 0xCB: {
			data = IXY_DISP( ixy, (int8_t) data2 );
			pc++;
			data2 = READ_PROG( pc );
			pc++;
			switch ( data2 )
			{
			case 0x06: goto rlc_data_addr; // RLC (IXY)
			case 0x16: goto rl_data_addr;  // RL (IXY)
			case 0x26: goto sla_data_addr; // SLA (IXY)
			case 0x36: goto sll_data_addr; // SLL (IXY)
			case 0x0E: goto rrc_data_addr; // RRC (IXY)
			case 0x1E: goto rr_data_addr;  // RR (IXY)
			case 0x2E: goto sra_data_addr; // SRA (IXY)
			case 0x3E: goto srl_data_addr; // SRL (IXY)
			
			CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp)
				fuint8 temp = READ( data );
				int masked = temp & 1 << (data2 >> 3 & 7);
				flags = (flags & C01) | H10 |
						(masked & S80) |
						((masked - 1) >> 8 & (Z40 | P04));
				goto loop;
			}
			
			CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(IXY+disp)
			CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(IXY+disp)
				int temp = READ( data );
				int bit = 1 << (data2 >> 3 & 7);
				temp |= bit; // SET
				if ( !(data2 & 0x40) )
					temp ^= bit; // RES
				WRITE( data, temp );
				goto loop;
			}
			
			default:
				debug_printf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
				warning = true;
				goto loop;
			}
			assert( false );
		}
		
	// INC/DEC
		case 0x23: // INC IXY
			ixy = uint16_t (ixy + 1);
			goto set_ixy;
		
		case 0x2B: // DEC IXY
			ixy = uint16_t (ixy - 1);
			goto set_ixy;
		
		case 0x34: // INC (IXY+disp)
			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 = IXY_DISP( ixy, (int8_t) data2 );
			pc++;
			data = READ( ixy ) - 1;
			WRITE( ixy, data );
			goto dec_set_flags;
		
		case 0x24: // INC HXY
			ixy = uint16_t (ixy + 0x100);
			data = ixy >> 8;
			goto inc_xy_common;
		
		case 0x2C: // INC LXY
			data = uint8_t (ixy + 1);
			ixy = (ixy & 0xFF00) | data;
		inc_xy_common:
			if ( opcode == 0xDD )
			{
				ix = ixy;
				goto inc_set_flags;
			}
			iy = ixy;
			goto inc_set_flags;
		
		case 0x25: // DEC HXY
			ixy = uint16_t (ixy - 0x100);
			data = ixy >> 8;
			goto dec_xy_common;
		
		case 0x2D: // DEC LXY
			data = uint8_t (ixy - 1);
			ixy = (ixy & 0xFF00) | data;
		dec_xy_common:
			if ( opcode == 0xDD )
			{
				ix = ixy;
				goto dec_set_flags;
			}
			iy = ixy;
			goto dec_set_flags;
		
	// PUSH/POP
		case 0xE5: // PUSH IXY
			data = ixy;
			goto push_data;
		
		case 0xE1:{// POP IXY
			ixy = READ_WORD( sp );
			sp = uint16_t (sp + 2);
			goto set_ixy;
		}
	
	// Misc
		
		case 0xE9: // JP (IXY)
			pc = ixy;
			goto loop;
		
		case 0xE3:{// EX (SP),IXY
			fuint16 temp = READ_WORD( sp );
			WRITE_WORD( sp, ixy );
			ixy = temp;
			goto set_ixy;
		}
		
		default:
			debug_printf( "Unnecessary DD/FD prefix encountered\n" );
			warning = true;
			pc--;
			goto loop;
		}
		assert( false );
	}
	
	}
	debug_printf( "Unhandled main opcode: $%02X\n", opcode );
	assert( false );
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



doom_py/src/vizdoom/game-music-emu/gme/Kss_Cpu.cpp [844:1686]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		(void) data2; // TODO is this the same as data in all cases?
		pc++;
		switch ( data )
		{
	
	// Rotate left
		
	#define RLC( read, write ) {\
		fuint8 result = read;\
		result = uint8_t (result << 1) | (result >> 7);\
		flags = SZ28P( result ) | (result & C01);\
		write;\
		goto loop;\
	}
		
		case 0x06: // RLC (HL)
			s_time += 7;
			data = rp.hl;
		rlc_data_addr:
			RLC( READ( data ), WRITE( data, result ) )
		
		CASE7( 00, 01, 02, 03, 04, 05, 07 ):{// RLC r
			uint8_t& reg = R8( data, 0 );
			RLC( reg, reg = result )
		}
		
	#define RL( read, write ) {\
		fuint16 result = (read << 1) | (flags & C01);\
		flags = SZ28PC( result );\
		write;\
		goto loop;\
	}
		
		case 0x16: // RL (HL)
			s_time += 7;
			data = rp.hl;
		rl_data_addr:
			RL( READ( data ), WRITE( data, result ) )
		
		CASE7( 10, 11, 12, 13, 14, 15, 17 ):{// RL r
			uint8_t& reg = R8( data, 0x10 );
			RL( reg, reg = result )
		}
		
	#define SLA( read, add, write ) {\
		fuint16 result = (read << 1) | add;\
		flags = SZ28PC( result );\
		write;\
		goto loop;\
	}
		
		case 0x26: // SLA (HL)
			s_time += 7;
			data = rp.hl;
		sla_data_addr:
			SLA( READ( data ), 0, WRITE( data, result ) )
		
		CASE7( 20, 21, 22, 23, 24, 25, 27 ):{// SLA r
			uint8_t& reg = R8( data, 0x20 );
			SLA( reg, 0, reg = result )
		}
		
		case 0x36: // SLL (HL)
			s_time += 7;
			data = rp.hl;
		sll_data_addr:
			SLA( READ( data ), 1, WRITE( data, result ) )
		
		CASE7( 30, 31, 32, 33, 34, 35, 37 ):{// SLL r
			uint8_t& reg = R8( data, 0x30 );
			SLA( reg, 1, reg = result )
		}
		
	// Rotate right
		
	#define RRC( read, write ) {\
		fuint8 result = read;\
		flags = result & C01;\
		result = uint8_t (result << 7) | (result >> 1);\
		flags |= SZ28P( result );\
		write;\
		goto loop;\
	}
		
		case 0x0E: // RRC (HL)
			s_time += 7;
			data = rp.hl;
		rrc_data_addr:
			RRC( READ( data ), WRITE( data, result ) )
		
		CASE7( 08, 09, 0A, 0B, 0C, 0D, 0F ):{// RRC r
			uint8_t& reg = R8( data, 0x08 );
			RRC( reg, reg = result )
		}
		
	#define RR( read, write ) {\
		fuint8 result = read;\
		fuint8 temp = result & C01;\
		result = uint8_t (flags << 7) | (result >> 1);\
		flags = SZ28P( result ) | temp;\
		write;\
		goto loop;\
	}
		
		case 0x1E: // RR (HL)
			s_time += 7;
			data = rp.hl;
		rr_data_addr:
			RR( READ( data ), WRITE( data, result ) )
		
		CASE7( 18, 19, 1A, 1B, 1C, 1D, 1F ):{// RR r
			uint8_t& reg = R8( data, 0x18 );
			RR( reg, reg = result )
		}
		
	#define SRA( read, write ) {\
		fuint8 result = read;\
		flags = result & C01;\
		result = (result & 0x80) | (result >> 1);\
		flags |= SZ28P( result );\
		write;\
		goto loop;\
	}
		
		case 0x2E: // SRA (HL)
			data = rp.hl;
			s_time += 7;
		sra_data_addr:
			SRA( READ( data ), WRITE( data, result ) )
		
		CASE7( 28, 29, 2A, 2B, 2C, 2D, 2F ):{// SRA r
			uint8_t& reg = R8( data, 0x28 );
			SRA( reg, reg = result )
		}
		
	#define SRL( read, write ) {\
		fuint8 result = read;\
		flags = result & C01;\
		result >>= 1;\
		flags |= SZ28P( result );\
		write;\
		goto loop;\
	}
		
		case 0x3E: // SRL (HL)
			s_time += 7;
			data = rp.hl;
		srl_data_addr:
			SRL( READ( data ), WRITE( data, result ) )
		
		CASE7( 38, 39, 3A, 3B, 3C, 3D, 3F ):{// SRL r
			uint8_t& reg = R8( data, 0x38 );
			SRL( reg, reg = result )
		}
		
	// BIT
		{
			unsigned temp;
		CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ): // BIT b,(HL)
			s_time += 4;
			temp = READ( rp.hl );
			flags &= C01;
			goto bit_temp;
		CASE7( 40, 41, 42, 43, 44, 45, 47 ): // BIT 0,r
		CASE7( 48, 49, 4A, 4B, 4C, 4D, 4F ): // BIT 1,r
		CASE7( 50, 51, 52, 53, 54, 55, 57 ): // BIT 2,r
		CASE7( 58, 59, 5A, 5B, 5C, 5D, 5F ): // BIT 3,r
		CASE7( 60, 61, 62, 63, 64, 65, 67 ): // BIT 4,r
		CASE7( 68, 69, 6A, 6B, 6C, 6D, 6F ): // BIT 5,r
		CASE7( 70, 71, 72, 73, 74, 75, 77 ): // BIT 6,r
		CASE7( 78, 79, 7A, 7B, 7C, 7D, 7F ): // BIT 7,r
			temp = R8( data & 7, 0 );
			flags = (flags & C01) | (temp & (F20 | F08));
		bit_temp:
			int masked = temp & 1 << (data >> 3 & 7);
			flags |=(masked & S80) | H10 |
					((masked - 1) >> 8 & (Z40 | P04));
			goto loop;
		}
		
	// SET/RES
		CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(HL)
		CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(HL)
			s_time += 7;
			int temp = READ( rp.hl );
			int bit = 1 << (data >> 3 & 7);
			temp |= bit; // SET
			if ( !(data & 0x40) )
				temp ^= bit; // RES
			WRITE( rp.hl, temp );
			goto loop;
		}
		
		CASE7( C0, C1, C2, C3, C4, C5, C7 ): // SET 0,r
		CASE7( C8, C9, CA, CB, CC, CD, CF ): // SET 1,r
		CASE7( D0, D1, D2, D3, D4, D5, D7 ): // SET 2,r
		CASE7( D8, D9, DA, DB, DC, DD, DF ): // SET 3,r
		CASE7( E0, E1, E2, E3, E4, E5, E7 ): // SET 4,r
		CASE7( E8, E9, EA, EB, EC, ED, EF ): // SET 5,r
		CASE7( F0, F1, F2, F3, F4, F5, F7 ): // SET 6,r
		CASE7( F8, F9, FA, FB, FC, FD, FF ): // SET 7,r
			R8( data & 7, 0 ) |= 1 << (data >> 3 & 7);
			goto loop;
		
		CASE7( 80, 81, 82, 83, 84, 85, 87 ): // RES 0,r
		CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // RES 1,r
		CASE7( 90, 91, 92, 93, 94, 95, 97 ): // RES 2,r
		CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // RES 3,r
		CASE7( A0, A1, A2, A3, A4, A5, A7 ): // RES 4,r
		CASE7( A8, A9, AA, AB, AC, AD, AF ): // RES 5,r
		CASE7( B0, B1, B2, B3, B4, B5, B7 ): // RES 6,r
		CASE7( B8, B9, BA, BB, BC, BD, BF ): // RES 7,r
			R8( data & 7, 0 ) &= ~(1 << (data >> 3 & 7));
			goto loop;
		}
		assert( false );
	}

#undef GET_ADDR
#define GET_ADDR()  GET_LE16( instr + 1 )

//////////////////////////////////////// ED prefix
	{
	case 0xED:
		pc++;
		s_time += ed_dd_timing [data] >> 4;
		switch ( data )
		{
		{
			blargg_ulong temp;
		case 0x72: // SBC HL,SP
		case 0x7A: // ADC HL,SP
			temp = sp;
			if ( 0 )
		case 0x42: // SBC HL,BC
		case 0x52: // SBC HL,DE
		case 0x62: // SBC HL,HL
		case 0x4A: // ADC HL,BC
		case 0x5A: // ADC HL,DE
		case 0x6A: // ADC HL,HL
				temp = R16( data >> 3 & 6, 1, 0 );
			blargg_ulong sum = temp + (flags & C01);
			flags = ~data >> 2 & N02;
			if ( flags )
				sum = (blargg_ulong)-(blargg_long)sum;
			sum += rp.hl;
			temp ^= rp.hl;
			temp ^= sum;
			flags |=(sum >> 16 & C01) |
					(temp >> 8 & H10) |
					(sum >> 8 & (S80 | F20 | F08)) |
					((temp - -0x8000) >> 14 & V04);
			rp.hl = (uint16_t)sum;
			if ( (uint16_t) sum )
				goto loop;
			flags |= Z40;
			goto loop;
		}
		
		CASE8( 40, 48, 50, 58, 60, 68, 70, 78 ):{// IN r,(C)
			int temp = IN( rp.bc );
			R8( data >> 3, 8 ) = temp;
			flags = (flags & C01) | SZ28P( temp );
			goto loop;
		}
		
		case 0x71: // OUT (C),0
			rg.flags = 0;
		CASE7( 41, 49, 51, 59, 61, 69, 79 ): // OUT (C),r
			OUT( rp.bc, R8( data >> 3, 8 ) );
			goto loop;
		
		{
			unsigned temp;
		case 0x73: // LD (ADDR),SP
			temp = sp;
			if ( 0 )
		case 0x43: // LD (ADDR),BC
		case 0x53: // LD (ADDR),DE
				temp = R16( data, 4, 0x43 );
			fuint16 addr = GET_ADDR();
			pc += 2;
			WRITE_WORD( addr, temp );
			goto loop;
		}
		
		case 0x4B: // LD BC,(ADDR)
		case 0x5B:{// LD DE,(ADDR)
			fuint16 addr = GET_ADDR();
			pc += 2;
			R16( data, 4, 0x4B ) = READ_WORD( addr );
			goto loop;
		}
		
		case 0x7B:{// LD SP,(ADDR)
			fuint16 addr = GET_ADDR();
			pc += 2;
			sp = READ_WORD( addr );
			goto loop;
		}
		
		case 0x67:{// RRD
			fuint8 temp = READ( rp.hl );
			WRITE( rp.hl, (rg.a << 4) | (temp >> 4) );
			temp = (rg.a & 0xF0) | (temp & 0x0F);
			flags = (flags & C01) | SZ28P( temp );
			rg.a = temp;
			goto loop;
		}
		
		case 0x6F:{// RLD
			fuint8 temp = READ( rp.hl );
			WRITE( rp.hl, (temp << 4) | (rg.a & 0x0F) );
			temp = (rg.a & 0xF0) | (temp >> 4);
			flags = (flags & C01) | SZ28P( temp );
			rg.a = temp;
			goto loop;
		}
		
		CASE8( 44, 4C, 54, 5C, 64, 6C, 74, 7C ): // NEG
			opcode = 0x10; // flag to do SBC instead of ADC
			flags &= ~C01;
			data = rg.a;
			rg.a = 0;
			goto adc_data;
		
		{
			int inc;
		case 0xA9: // CPD
		case 0xB9: // CPDR
			inc = -1;
			if ( 0 )
		case 0xA1: // CPI
		case 0xB1: // CPIR
				inc = +1;
			fuint16 addr = rp.hl;
			rp.hl = addr + inc;
			int temp = READ( addr );
			
			int result = rg.a - temp;
			flags = (flags & C01) | N02 |
					((((temp ^ rg.a) & H10) ^ result) & (S80 | H10));
			
			if ( !(uint8_t) result ) flags |= Z40;
			result -= (flags & H10) >> 4;
			flags |= result & F08;
			flags |= result << 4 & F20;
			if ( !--rp.bc )
				goto loop;
			
			flags |= V04;
			if ( flags & Z40 || data < 0xB0 )
				goto loop;
			
			pc -= 2;
			s_time += 5;
			goto loop;
		}
		
		{
			int inc;
		case 0xA8: // LDD
		case 0xB8: // LDDR
			inc = -1;
			if ( 0 )
		case 0xA0: // LDI
		case 0xB0: // LDIR
				inc = +1;
			fuint16 addr = rp.hl;
			rp.hl = addr + inc;
			int temp = READ( addr );
			
			addr = rp.de;
			rp.de = addr + inc;
			WRITE( addr, temp );
			
			temp += rg.a;
			flags = (flags & (S80 | Z40 | C01)) |
					(temp & F08) | (temp << 4 & F20);
			if ( !--rp.bc )
				goto loop;
			
			flags |= V04;
			if ( data < 0xB0 )
				goto loop;
			
			pc -= 2;
			s_time += 5;
			goto loop;
		}
		
		{
			int inc;
		case 0xAB: // OUTD
		case 0xBB: // OTDR
			inc = -1;
			if ( 0 )
		case 0xA3: // OUTI
		case 0xB3: // OTIR
				inc = +1;
			fuint16 addr = rp.hl;
			rp.hl = addr + inc;
			int temp = READ( addr );
			
			int b = --rg.b;
			flags = (temp >> 6 & N02) | SZ28( b );
			if ( b && data >= 0xB0 )
			{
				pc -= 2;
				s_time += 5;
			}
			
			OUT( rp.bc, temp );
			goto loop;
		}
		
		{
			int inc;
		case 0xAA: // IND
		case 0xBA: // INDR
			inc = -1;
			if ( 0 )
		case 0xA2: // INI
		case 0xB2: // INIR
				inc = +1;
			
			fuint16 addr = rp.hl;
			rp.hl = addr + inc;
			
			int temp = IN( rp.bc );
			
			int b = --rg.b;
			flags = (temp >> 6 & N02) | SZ28( b );
			if ( b && data >= 0xB0 )
			{
				pc -= 2;
				s_time += 5;
			}
			
			WRITE( addr, temp );
			goto loop;
		}
		
		case 0x47: // LD I,A
			r.i = rg.a;
			goto loop;
		
		case 0x4F: // LD R,A
			SET_R( rg.a );
			debug_printf( "LD R,A not supported\n" );
			warning = true;
			goto loop;
		
		case 0x57: // LD A,I
			rg.a = r.i;
			goto ld_ai_common;
		
		case 0x5F: // LD A,R
			rg.a = GET_R();
			debug_printf( "LD A,R not supported\n" );
			warning = true;
		ld_ai_common:
			flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
			goto loop;
		
		CASE8( 45, 4D, 55, 5D, 65, 6D, 75, 7D ): // RETI/RETN
			r.iff1 = r.iff2;
			goto ret_taken;
		
		case 0x46: case 0x4E: case 0x66: case 0x6E: // IM 0
			r.im = 0;
			goto loop;
		
		case 0x56: case 0x76: // IM 1
			r.im = 1;
			goto loop;
		
		case 0x5E: case 0x7E: // IM 2
			r.im = 2;
			goto loop;
		
		default:
			debug_printf( "Opcode $ED $%02X not supported\n", data );
			warning = true;
			goto loop;
		}
		assert( false );
	}

//////////////////////////////////////// DD/FD prefix
	{
	fuint16 ixy;
	case 0xDD:
		ixy = ix;
		goto ix_prefix;
	case 0xFD:
		ixy = iy;
	ix_prefix:
		pc++;
		unsigned data2 = READ_PROG( pc );
		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
	
		case 0x96: // SUB (IXY+disp)
		case 0x86: // ADD (IXY+disp)
			flags &= ~C01;
		case 0x9E: // SBC (IXY+disp)
		case 0x8E: // ADC (IXY+disp)
			pc++;
			opcode = data;
			data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
			goto adc_data;
		
		case 0x94: // SUB HXY
		case 0x84: // ADD HXY
			flags &= ~C01;
		case 0x9C: // SBC HXY
		case 0x8C: // ADC HXY
			opcode = data;
			data = ixy >> 8;
			goto adc_data;
		
		case 0x95: // SUB LXY
		case 0x85: // ADD LXY
			flags &= ~C01;
		case 0x9D: // SBC LXY
		case 0x8D: // ADC LXY
			opcode = data;
			data = (uint8_t) ixy;
			goto adc_data;
		
		{
			unsigned temp;
		case 0x39: // ADD IXY,SP
			temp = sp;
			goto add_ixy_data;
		
		case 0x29: // ADD IXY,HL
			temp = ixy;
			goto add_ixy_data;
		
		case 0x09: // ADD IXY,BC
		case 0x19: // ADD IXY,DE
			temp = R16( data, 4, 0x09 );
		add_ixy_data: {
			blargg_ulong sum = ixy + temp;
			temp ^= ixy;
			ixy = (uint16_t) sum;
			flags = (flags & (S80 | Z40 | V04)) |
					(sum >> 16) |
					(sum >> 8 & (F20 | F08)) |
					((temp ^ sum) >> 8 & H10);
			goto set_ixy;
		}
		}
	
	// AND
		case 0xA6: // AND (IXY+disp)
			pc++;
			data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
			goto and_data;
		
		case 0xA4: // AND HXY
			data = ixy >> 8;
			goto and_data;
		
		case 0xA5: // AND LXY
			data = (uint8_t) ixy;
			goto and_data;
	
	// OR
		case 0xB6: // OR (IXY+disp)
			pc++;
			data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
			goto or_data;
		
		case 0xB4: // OR HXY
			data = ixy >> 8;
			goto or_data;
		
		case 0xB5: // OR LXY
			data = (uint8_t) ixy;
			goto or_data;
	
	// XOR
		case 0xAE: // XOR (IXY+disp)
			pc++;
			data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
			goto xor_data;
		
		case 0xAC: // XOR HXY
			data = ixy >> 8;
			goto xor_data;
		
		case 0xAD: // XOR LXY
			data = (uint8_t) ixy;
			goto xor_data;
	
	// CP
		case 0xBE: // CP (IXY+disp)
			pc++;
			data = READ( IXY_DISP( ixy, (int8_t) data2 )  );
			goto cp_data;
		
		case 0xBC: // CP HXY
			data = ixy >> 8;
			goto cp_data;
		
		case 0xBD: // CP LXY
			data = (uint8_t) ixy;
			goto cp_data;
		
	// LD
		CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (IXY+disp),r
			data = R8( data, 0x70 );
			if ( 0 )
		case 0x36: // LD (IXY+disp),imm
				pc++, data = READ_PROG( pc );
			pc++;
			WRITE( IXY_DISP( ixy, (int8_t) data2 ), data );
			goto loop;

		CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY
			R8( data >> 3, 8 ) = ixy >> 8;
			goto loop;
		
		case 0x64: // LD HXY,HXY
		case 0x6D: // LD LXY,LXY
			goto loop;
		
		CASE5( 45, 4D, 55, 5D, 7D ): // LD r,LXY
			R8( data >> 3, 8 ) = ixy;
			goto loop;
		
		CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp)
			pc++;
			R8( data >> 3, 8 ) = READ( IXY_DISP( ixy, (int8_t) data2 ) );
			goto loop;
		
		case 0x26: // LD HXY,imm
			pc++;
			goto ld_hxy_data;
			
		case 0x65: // LD HXY,LXY
			data2 = (uint8_t) ixy;
			goto ld_hxy_data;
		
		CASE5( 60, 61, 62, 63, 67 ): // LD HXY,r
			data2 = R8( data, 0x60 );
		ld_hxy_data:
			ixy = (uint8_t) ixy | (data2 << 8);
			goto set_ixy;
		
		case 0x2E: // LD LXY,imm
			pc++;
			goto ld_lxy_data;
			
		case 0x6C: // LD LXY,HXY
			data2 = ixy >> 8;
			goto ld_lxy_data;
		
		CASE5( 68, 69, 6A, 6B, 6F ): // LD LXY,r
			data2 = R8( data, 0x68 );
		ld_lxy_data:
			ixy = (ixy & 0xFF00) | data2;
		set_ixy:
			if ( opcode == 0xDD )
			{
				ix = ixy;
				goto loop;
			}
			iy = ixy;
			goto loop;

		case 0xF9: // LD SP,IXY
			sp = ixy;
			goto loop;
	
		case 0x22:{// LD (ADDR),IXY
			fuint16 addr = GET_ADDR();
			pc += 2;
			WRITE_WORD( addr, ixy );
			goto loop;
		}
		
		case 0x21: // LD IXY,imm
			ixy = GET_ADDR();
			pc += 2;
			goto set_ixy;
		
		case 0x2A:{// LD IXY,(addr)
			fuint16 addr = GET_ADDR();
			ixy = READ_WORD( addr );
			pc += 2;
			goto set_ixy;
		}
		
	// DD/FD CB prefix
		case 0xCB: {
			data = IXY_DISP( ixy, (int8_t) data2 );
			pc++;
			data2 = READ_PROG( pc );
			pc++;
			switch ( data2 )
			{
			case 0x06: goto rlc_data_addr; // RLC (IXY)
			case 0x16: goto rl_data_addr;  // RL (IXY)
			case 0x26: goto sla_data_addr; // SLA (IXY)
			case 0x36: goto sll_data_addr; // SLL (IXY)
			case 0x0E: goto rrc_data_addr; // RRC (IXY)
			case 0x1E: goto rr_data_addr;  // RR (IXY)
			case 0x2E: goto sra_data_addr; // SRA (IXY)
			case 0x3E: goto srl_data_addr; // SRL (IXY)
			
			CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp)
				fuint8 temp = READ( data );
				int masked = temp & 1 << (data2 >> 3 & 7);
				flags = (flags & C01) | H10 |
						(masked & S80) |
						((masked - 1) >> 8 & (Z40 | P04));
				goto loop;
			}
			
			CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(IXY+disp)
			CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(IXY+disp)
				int temp = READ( data );
				int bit = 1 << (data2 >> 3 & 7);
				temp |= bit; // SET
				if ( !(data2 & 0x40) )
					temp ^= bit; // RES
				WRITE( data, temp );
				goto loop;
			}
			
			default:
				debug_printf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
				warning = true;
				goto loop;
			}
			assert( false );
		}
		
	// INC/DEC
		case 0x23: // INC IXY
			ixy = uint16_t (ixy + 1);
			goto set_ixy;
		
		case 0x2B: // DEC IXY
			ixy = uint16_t (ixy - 1);
			goto set_ixy;
		
		case 0x34: // INC (IXY+disp)
			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 = IXY_DISP( ixy, (int8_t) data2 );
			pc++;
			data = READ( ixy ) - 1;
			WRITE( ixy, data );
			goto dec_set_flags;
		
		case 0x24: // INC HXY
			ixy = uint16_t (ixy + 0x100);
			data = ixy >> 8;
			goto inc_xy_common;
		
		case 0x2C: // INC LXY
			data = uint8_t (ixy + 1);
			ixy = (ixy & 0xFF00) | data;
		inc_xy_common:
			if ( opcode == 0xDD )
			{
				ix = ixy;
				goto inc_set_flags;
			}
			iy = ixy;
			goto inc_set_flags;
		
		case 0x25: // DEC HXY
			ixy = uint16_t (ixy - 0x100);
			data = ixy >> 8;
			goto dec_xy_common;
		
		case 0x2D: // DEC LXY
			data = uint8_t (ixy - 1);
			ixy = (ixy & 0xFF00) | data;
		dec_xy_common:
			if ( opcode == 0xDD )
			{
				ix = ixy;
				goto dec_set_flags;
			}
			iy = ixy;
			goto dec_set_flags;
		
	// PUSH/POP
		case 0xE5: // PUSH IXY
			data = ixy;
			goto push_data;
		
		case 0xE1:{// POP IXY
			ixy = READ_WORD( sp );
			sp = uint16_t (sp + 2);
			goto set_ixy;
		}
	
	// Misc
		
		case 0xE9: // JP (IXY)
			pc = ixy;
			goto loop;
		
		case 0xE3:{// EX (SP),IXY
			fuint16 temp = READ_WORD( sp );
			WRITE_WORD( sp, ixy );
			ixy = temp;
			goto set_ixy;
		}
		
		default:
			debug_printf( "Unnecessary DD/FD prefix encountered\n" );
			warning = true;
			pc--;
			goto loop;
		}
		assert( false );
	}
	
	}
	debug_printf( "Unhandled main opcode: $%02X\n", opcode );
	assert( false );
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



