summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/tlcs90/tlcs90d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/tlcs90/tlcs90d.cpp')
-rw-r--r--src/devices/cpu/tlcs90/tlcs90d.cpp952
1 files changed, 952 insertions, 0 deletions
diff --git a/src/devices/cpu/tlcs90/tlcs90d.cpp b/src/devices/cpu/tlcs90/tlcs90d.cpp
new file mode 100644
index 00000000000..66787e84528
--- /dev/null
+++ b/src/devices/cpu/tlcs90/tlcs90d.cpp
@@ -0,0 +1,952 @@
+// license:BSD-3-Clause
+// copyright-holders:Luca Elia
+/*************************************************************************************************************
+
+ Toshiba TLCS-90 Series MCU's
+
+ emulation by Luca Elia, based on the Z80 core by Juergen Buchmueller
+
+ ChangeLog:
+
+ 20150517 Fixed TRUN bit masking (timers start/stop handling) [Rainer Keuchel]
+
+*************************************************************************************************************/
+
+#include "emu.h"
+#include "tlcs90d.h"
+
+const char *const tlcs90_disassembler::op_names[] = { "??", "nop", "ex", "exx", "ld", "ldw", "lda", "ldi", "ldir", "ldd", "lddr", "cpi", "cpir", "cpd", "cpdr", "push", "pop", "jp", "jr", "call", "callr", "ret", "reti", "halt", "di", "ei", "swi", "daa", "cpl", "neg", "ldar", "rcf", "scf", "ccf", "tset", "bit", "set", "res", "inc", "dec", "incx", "decx", "incw", "decw", "add", "adc", "sub", "sbc", "and", "xor", "or", "cp", "rlc", "rrc", "rl", "rr", "sla", "sra", "sll", "srl", "rld", "rrd", "djnz", "mul", "div" };
+
+const char *const tlcs90_disassembler::r8_names[] = { "b", "c", "d", "e", "h", "l", "a" };
+const char *const tlcs90_disassembler::r16_names[] = { "bc", "de", "hl", "??", "ix", "iy", "sp", "af", "af'", "pc" };
+
+const char *const tlcs90_disassembler::cc_names[] = { "f", "lt", "le", "ule", "ov", "mi", "z", "c", "", "ge", "gt", "ugt", "nov", "pl", "nz", "nc" };
+
+u32 tlcs90_disassembler::opcode_alignment() const
+{
+ return 1;
+}
+
+const char *const tlcs90_disassembler::ir_names[] = {
+ "P0", "P1", "P01CR/IRFL", "IRFH", "P2", "P2CR", "P3", "P3CR",
+ "P4", "P4CR", "P5", "SMMOD", "P6", "P7", "P67CR", "SMCR",
+ "P8", "P8CR", "WDMOD", "WDCR", "TREG0", "TREG1", "TREG2", "TREG3",
+ "TCLK", "TFFCR", "TMOD", "TRUN", "CAP1L", "CAP1H", "CAP2L", "CAL2H",
+ "TREG4L", "TREG4H", "TREG5L", "TREG5H", "T4MOD", "T4FFCR", "INTEL", "INTEH",
+ "DMAEH", "SCMOD", "SCCR", "SCBUF", "BX", "BY", "ADREG", "ADMOD"
+};
+
+#define T90_IOBASE 0xffc0
+
+const char *tlcs90_disassembler::internal_registers_names(uint16_t x)
+{
+ // FIXME: TMP90PH44 and many other models have completely different SFR maps
+ int ir = x - T90_IOBASE;
+ if ( ir >= 0 && ir < ARRAY_LENGTH(ir_names) )
+ return ir_names[ir];
+ return nullptr;
+}
+
+#define B 0
+#define C 1
+#define D 2
+#define E 3
+#define H 4
+#define L 5
+#define A 6
+
+#define BC 0
+#define DE 1
+#define HL 2
+// 3
+#define IX 4
+#define IY 5
+#define SP 6
+
+#define AF 7
+#define AF2 8
+#define PC 9
+
+#define FLS 0x0
+#define LT 0x1
+#define LE 0x2
+#define ULE 0x3
+#define OV 0x4
+#define PE 0x4
+#define MI 0x5
+#define Z 0x6
+#define EQ 0x6
+#define CR 0x7
+#define ULT 0x7
+#define T 0x8
+#define GE 0x9
+#define GT 0xa
+#define UGT 0xb
+#define NOV 0xc
+#define PO 0xc
+#define PL 0xd
+#define NZ 0xe
+#define NE 0xe
+#define NC 0xf
+#define UGE 0xf
+
+#define CF 0x01
+#define NF 0x02
+#define PF 0x04
+#define VF PF
+#define XCF 0x08
+#define HF 0x10
+#define IF 0x20
+#define ZF 0x40
+#define SF 0x80
+
+#define OP( X,CT ) m_op = X;
+#define OP16( X,CT ) m_op = X;
+
+#define OPCC( X,CF,CT ) m_op = X;
+#define OPCC16( X,CF,CT ) m_op = X;
+
+#define BIT8( N,I ) m_mode##N = e_mode::BIT8; m_r##N = I;
+#define I8( N,I ) m_mode##N = e_mode::I8; m_r##N = I;
+#define D8( N,I ) m_mode##N = e_mode::D8; m_r##N = I;
+#define I16( N,I ) m_mode##N = e_mode::I16; m_r##N = I;
+#define D16( N,I ) m_mode##N = e_mode::D16; m_r##N = I;
+#define R8( N,R ) m_mode##N = e_mode::R8; m_r##N = R;
+#define R16( N,R ) m_mode##N = e_mode::R16; m_r##N = R;
+#define Q16( N,R ) m_mode##N = e_mode::R16; m_r##N = R; if (m_r##N == SP) m_r##N = AF;
+#define MI16( N,I ) m_mode##N = e_mode::MI16; m_r##N = I;
+#define MR16( N,R ) m_mode##N = e_mode::MR16; m_r##N = R;
+#define MR16D8( N,R,I ) m_mode##N = e_mode::MR16D8; m_r##N = R; m_r##N##b = I;
+#define MR16R8( N,R,g ) m_mode##N = e_mode::MR16R8; m_r##N = R; m_r##N##b = g;
+#define NONE( N ) m_mode##N = e_mode::NONE;
+#define CC( N,cc ) m_mode##N = e_mode::CC; m_r##N = cc;
+#define R16D8( N,R,I ) m_mode##N = e_mode::R16D8; m_r##N = R; m_r##N##b = I;
+#define R16R8( N,R,g ) m_mode##N = e_mode::R16R8; m_r##N = R; m_r##N##b = g;
+
+uint8_t tlcs90_disassembler::READ8()
+{
+ uint8_t b0 = m_opcodes->r8( m_addr++ );
+ m_addr &= 0xffff;
+ return b0;
+}
+uint16_t tlcs90_disassembler::READ16()
+{
+ uint8_t b0 = READ8();
+ return b0 | (READ8() << 8);
+}
+
+void tlcs90_disassembler::decode()
+{
+ uint8_t b0, b1, b2, b3;
+ uint16_t imm16;
+
+ b0 = READ8();
+
+ switch ( b0 )
+ {
+ case 0x00:
+ OP( NOP,2 ) NONE( 1 ) NONE( 2 ) return; // NOP
+
+ case 0x01:
+ OP( HALT,4 ) NONE( 1 ) NONE( 2 ) return; // HALT
+ case 0x02:
+ OP( DI,2 ) NONE( 1 ) NONE( 2 ) return; // DI
+ case 0x03:
+ OP( EI,2 ) NONE( 1 ) NONE( 2 ) return; // EI
+
+ case 0x07:
+ OPCC( INCX,6,10 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // INCX ($FF00+n)
+
+ case 0x08:
+ OP( EX,2 ) R16( 1, DE ) R16( 2, HL ) return; // EX DE,HL
+ case 0x09:
+ OP( EX,2 ) R16( 1, AF ) R16( 2, AF2 ) return; // EX AF,AF'
+ case 0x0a:
+ OP( EXX,2 ) NONE( 1 ) NONE( 2 ) return; // EXX
+
+ case 0x0b:
+ OP( DAA,4 ) R8( 1, A ) NONE( 2 ) return; // DAA A
+
+ case 0x0c:
+ OP( RCF,2 ) NONE( 1 ) NONE( 2 ) return; // RCF
+ case 0x0d:
+ OP( SCF,2 ) NONE( 1 ) NONE( 2 ) return; // SCF
+ case 0x0e:
+ OP( CCF,2 ) NONE( 1 ) NONE( 2 ) return; // CCF
+
+ case 0x0f:
+ OPCC( DECX,6,10 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // DECX ($FF00+n)
+
+ case 0x10:
+ OP( CPL,2 ) R8( 1, A ) NONE( 2 ) return; // CPL A
+ case 0x11:
+ OP( NEG,2 ) R8( 1, A ) NONE( 2 ) return; // NEG A
+
+ case 0x12: // MUL HL,n
+ case 0x13: // DIV HL,n
+ OP( MUL+b0-0x12,16) R16( 1, HL ) I8( 2, READ8() ) return;
+
+ case 0x14: case 0x15: case 0x16:
+ OP16( ADD,6 ) R16( 1, IX+b0-0x14 ) I16( 2, READ16() ) return; // ADD ix,mn
+
+ case 0x17:
+ OP( LDAR,8 ) R16( 1, HL ) D16( 2, READ16() ) return; // LDAR HL,+cd
+
+ case 0x18:
+ OP( DJNZ,10 ) D8( 1, READ8() ) NONE( 2 ) return; // DJNZ +d
+ case 0x19:
+ OP16( DJNZ,10 ) R16( 1, BC ) D8( 2, READ8() ) return; // DJNZ BC,+d
+
+ case 0x1a:
+ OPCC( JP,8,8 ) CC( 1, T ) I16( 2, READ16() ) return; // JP T,mn
+ case 0x1b:
+ OPCC16( JR,10,10 ) CC( 1, T ) D16( 2, READ16() ) return; // JR T,+cd
+
+ case 0x1c:
+ OPCC( CALL,14,14 ) CC( 1, T ) I16( 2, READ16() ) return; // CALL T,mn
+ case 0x1d:
+ OP( CALLR,16 ) D16( 1, READ16() ) NONE( 2 ) return; // CALLR +cd
+
+ case 0x1e:
+ OPCC( RET,10,10 ) CC( 1, T ) NONE( 2 ) return; // RET T
+ case 0x1f:
+ OP( RETI,14 ) NONE( 1 ) NONE( 2 ) return; // RETI
+
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26:
+ OP( LD,2 ) R8( 1, A ) R8( 2, b0 - 0x20 ) return; // LD A,r
+
+ case 0x27:
+ OP( LD,8 ) R8( 1, A ) MI16( 2, 0xFF00|READ8() ) return; // LD A,($FF00+n)
+
+ case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e:
+ OP( LD,2 ) R8( 1, b0 - 0x28 ) R8( 2, A ) return; // LD r,A
+
+ case 0x2f:
+ OP( LD,8 ) MI16( 1, 0xFF00|READ8() ) R8( 2, A ) return; // LD ($FF00+n), A
+
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36:
+ OP( LD,4 ) R8( 1, b0 - 0x30 ) I8( 2, READ8() ) return; // LD r,n
+
+ case 0x37:
+ OP( LD,10 ) MI16( 1, 0xFF00|READ8() ) I8( 2, READ8() ) return; // LD ($FF00+w),n
+
+ case 0x38: case 0x39: case 0x3a: /*case 0x3b:*/ case 0x3c: case 0x3d: case 0x3e:
+ OP16( LD,6 ) R16( 1, b0 - 0x38 ) I16( 2, READ16() ) return; // LD rr,nn
+
+ case 0x3f:
+ OP( LDW,14 ) MI16( 1, 0xFF00|READ8() ) I16( 2, READ16() ) return; // LDW ($FF00+w),mn
+
+ case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46:
+ OP16( LD,4 ) R16( 1, HL ) R16( 2, b0 - 0x40 ) return; // LD HL,rr
+
+ case 0x47:
+ OP16( LD,10 ) R16( 1, HL ) MI16( 2, 0xFF00|READ8() ) return; // LD HL,($FF00+n)
+
+ case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e:
+ OP16( LD,4 ) R16( 1, b0 - 0x48 ) R16( 2, HL ) return; // LD rr,HL
+
+ case 0x4f:
+ OP16( LD,10 ) MI16( 1, 0xFF00|READ8() ) R16( 2, HL ) return; // LD ($FF00+n), HL
+
+ case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56:
+ OP( PUSH,8 ) Q16( 1, b0 - 0x50 ) NONE( 2 ) return; // PUSH qq
+ case 0x58: case 0x59: case 0x5a: /*case 0x5b:*/ case 0x5c: case 0x5d: case 0x5e:
+ OP( POP,10 ) Q16( 1, b0 - 0x58 ) NONE( 2 ) return; // POP qq
+
+ case 0x60: // ADD A,($FF00+n)
+ case 0x61: // ADC A,($FF00+n)
+ case 0x62: // SUB A,($FF00+n)
+ case 0x63: // SBC A,($FF00+n)
+ case 0x64: // AND A,($FF00+n)
+ case 0x65: // XOR A,($FF00+n)
+ case 0x66: // OR A,($FF00+n)
+ case 0x67: // CP A,($FF00+n)
+ OP( ADD+b0-0x60,8 ) R8( 1, A ) MI16( 2, 0xFF00|READ8() ) return;
+
+ case 0x68: // ADD A,n
+ case 0x69: // ADC A,n
+ case 0x6a: // SUB A,n
+ case 0x6b: // SBC A,n
+ case 0x6c: // AND A,n
+ case 0x6d: // XOR A,n
+ case 0x6e: // OR A,n
+ case 0x6f: // CP A,n
+ OP( ADD+b0-0x68,4 ) R8( 1, A ) I8( 2, READ8() ) return;
+
+ case 0x70: // ADD HL,($FF00+n)
+ case 0x71: // ADC HL,($FF00+n)
+ case 0x72: // SUB HL,($FF00+n)
+ case 0x73: // SBC HL,($FF00+n)
+ case 0x74: // AND HL,($FF00+n)
+ case 0x75: // XOR HL,($FF00+n)
+ case 0x76: // OR HL,($FF00+n)
+ case 0x77: // CP HL,($FF00+n)
+ OP16( ADD+b0-0x70,10 ) R16( 1, HL ) MI16( 2, 0xFF00|READ8() ) return;
+
+ case 0x78: // ADD HL,mn
+ case 0x79: // ADC HL,mn
+ case 0x7a: // SUB HL,mn
+ case 0x7b: // SBC HL,mn
+ case 0x7c: // AND HL,mn
+ case 0x7d: // XOR HL,mn
+ case 0x7e: // OR HL,mn
+ case 0x7f: // CP HL,mn
+ OP16( ADD+b0-0x78,6 ) R16( 1, HL ) I16( 2, READ16() ) return;
+
+ case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86:
+ OP( INC,2 ) R8( 1, b0 - 0x80 ) NONE( 2 ) return; // INC r
+ case 0x87:
+ OP( INC,10 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // INC ($FF00+n)
+
+ case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e:
+ OP( DEC,2 ) R8( 1, b0 - 0x88 ) NONE( 2 ) return; // DEC r
+ case 0x8f:
+ OP( DEC,10 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // DEC ($FF00+n)
+
+ case 0x90: case 0x91: case 0x92: /*case 0x93:*/ case 0x94: case 0x95: case 0x96:
+ OP16( INC,4 ) R16( 1, b0 - 0x90 ) NONE( 2 ) return; // INC rr
+ case 0x97:
+ OP( INCW,14 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // INCW ($FF00+n)
+ case 0x98: case 0x99: case 0x9a: /*case 0x9b:*/ case 0x9c: case 0x9d: case 0x9e:
+ OP16( DEC,4 ) R16( 1, b0 - 0x98 ) NONE( 2 ) return; // DEC rr
+ case 0x9f:
+ OP( DECW,14 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // DECW ($FF00+n)
+
+ case 0xa0: // RLC A
+ case 0xa1: // RRC A
+ case 0xa2: // RL A
+ case 0xa3: // RR A
+ case 0xa4: // SLA A
+ case 0xa5: // SRA A
+ case 0xa6: // SLL A
+ case 0xa7: // SRL A
+ OP( RLC+b0-0xa0,2 ) R8( 1, A ) NONE( 2 ) return;
+
+ case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
+ OP( BIT,8 ) BIT8( 1, b0 - 0xa8 ) MI16( 2, 0xFF00|READ8() ) return; // BIT b,($FF00+n)
+ case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+ OP( RES,12 ) BIT8( 1, b0 - 0xb0 ) MI16( 2, 0xFF00|READ8() ) return; // RES b,($FF00+n)
+ case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
+ OP( SET,12 ) BIT8( 1, b0 - 0xb8 ) MI16( 2, 0xFF00|READ8() ) return; // SET b,($FF00+n)
+
+ case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+ case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
+ OPCC( JR,4,8 ) CC( 1, b0 - 0xc0 ) D8( 2, READ8() ) return; // JR cc,+d
+
+ case 0xe0: case 0xe1: case 0xe2: /*case 0xe3:*/ case 0xe4: case 0xe5: case 0xe6:
+ b1 = READ8();
+ switch ( b1 ) {
+ case 0x10: // RLD (gg)
+ case 0x11: // RRD (gg)
+ OP( RLD+b1-0x10,12 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return;
+
+ case 0x12: // MUL HL,(gg)
+ case 0x13: // DIV HL,(gg)
+ OP( MUL+b1-0x12,18 ) R16( 1, HL ) MR16( 2, b0 - 0xe0 ) return;
+
+ case 0x14: case 0x15: case 0x16:
+ OP16( ADD,8 ) R16( 1, IX+b1-0x14 ) MR16( 2, b0 - 0xe0 ) return; // ADD ix,(gg)
+
+ case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e:
+ OP( LD,6 ) R8( 1, b1 - 0x28 ) MR16( 2, b0 - 0xe0 ) return; // LD r,(gg)
+ case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e:
+ OP16( LD,8 ) R16( 1, b1 - 0x48 ) MR16( 2, b0 - 0xe0 ) return; // LD rr,(gg)
+
+ case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56:
+ OP( EX,14 ) MR16( 1, b0 - 0xe0 ) R16( 2, b1 - 0x50 ) return; // EX (gg),rr
+
+ case 0x60: // ADD A,(gg)
+ case 0x61: // ADC A,(gg)
+ case 0x62: // SUB A,(gg)
+ case 0x63: // SBC A,(gg)
+ case 0x64: // AND A,(gg)
+ case 0x65: // XOR A,(gg)
+ case 0x66: // OR A,(gg)
+ case 0x67: // CP A,(gg)
+ OP( ADD+b1-0x60,6 ) R8( 1, A ) MR16( 2, b0 - 0xe0 ) return;
+
+ case 0x70: // ADD HL,(gg)
+ case 0x71: // ADC HL,(gg)
+ case 0x72: // SUB HL,(gg)
+ case 0x73: // SBC HL,(gg)
+ case 0x74: // AND HL,(gg)
+ case 0x75: // XOR HL,(gg)
+ case 0x76: // OR HL,(gg)
+ case 0x77: // CP HL,(gg)
+ OP16( ADD+b1-0x70,8 ) R16( 1, HL ) MR16( 2, b0 - 0xe0 ) return;
+
+ case 0x87:
+ OP( INC,8 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; // INC (gg)
+ case 0x8f:
+ OP( DEC,8 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; // DEC (gg)
+
+ case 0x97:
+ OP( INCW,12 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; // INCW (gg)
+ case 0x9f:
+ OP( DECW,12 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; // DECW (gg)
+
+ case 0xa0: // RLC (gg)
+ case 0xa1: // RRC (gg)
+ case 0xa2: // RL (gg)
+ case 0xa3: // RR (gg)
+ case 0xa4: // SLA (gg)
+ case 0xa5: // SRA (gg)
+ case 0xa6: // SLL (gg)
+ case 0xa7: // SRL (gg)
+ OP( RLC+b1-0xa0,8 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return;
+
+ case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+ OP( TSET,12 ) BIT8( 1, b1 - 0x18 ) MR16( 2, b0 - 0xe0 ) return; // TSET b,(gg)
+ case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
+ OP( BIT,6 ) BIT8( 1, b1 - 0xa8 ) MR16( 2, b0 - 0xe0 ) return; // BIT b,(gg)
+ case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+ OP( RES,10 ) BIT8( 1, b1 - 0xb0 ) MR16( 2, b0 - 0xe0 ) return; // RES b,(gg)
+ case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
+ OP( SET,10 ) BIT8( 1, b1 - 0xb8 ) MR16( 2, b0 - 0xe0 ) return; // SET b,(gg)
+ } break;
+ case 0xe3:
+ imm16 = READ16();
+ b3 = READ8();
+ switch ( b3 ) {
+ case 0x10: // RLD (mn)
+ case 0x11: // RRD (mn)
+ OP( RLD+b3-0x10,16 ) MI16( 1, imm16 ) NONE( 2 ) return;
+
+ case 0x12: // MUL HL,(mn)
+ case 0x13: // DIV HL,(mn)
+ OP( MUL+b3-0x12,22 ) R16( 1, HL ) MI16( 2, imm16 ) return;
+
+ case 0x14: case 0x15: case 0x16:
+ OP16( ADD,12 ) R16( 1, IX+b3-0x14 ) MI16( 2, imm16 ) return; // ADD ix,(mn)
+
+ case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e:
+ OP( LD,10 ) R8( 1, b3 - 0x28 ) MI16( 2, imm16 ) return; // LD r,(mn)
+ case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e:
+ OP16( LD,12 ) R16( 1, b3 - 0x48 ) MI16( 2, imm16 ) return; // LD rr,(mn)
+
+ case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56:
+ OP( EX,18 ) MI16( 1, imm16 ) R16( 2, b3 - 0x50 ) return; // EX (mn),rr
+
+ case 0x60: // ADD A,(mn)
+ case 0x61: // ADC A,(mn)
+ case 0x62: // SUB A,(mn)
+ case 0x63: // SBC A,(mn)
+ case 0x64: // AND A,(mn)
+ case 0x65: // XOR A,(mn)
+ case 0x66: // OR A,(mn)
+ case 0x67: // CP A,(mn)
+ OP( ADD+b3-0x60,10 ) R8( 1, A ) MI16( 2, imm16 ) return;
+
+ case 0x70: // ADD HL,(mn)
+ case 0x71: // ADC HL,(mn)
+ case 0x72: // SUB HL,(mn)
+ case 0x73: // SBC HL,(mn)
+ case 0x74: // AND HL,(mn)
+ case 0x75: // XOR HL,(mn)
+ case 0x76: // OR HL,(mn)
+ case 0x77: // CP HL,(mn)
+ OP16( ADD+b3-0x70,12 ) R16( 1, HL ) MI16( 2, imm16 ) return;
+
+ case 0x87:
+ OP( INC,12 ) MI16( 1, imm16 ) NONE( 2 ) return; // INC (mn)
+ case 0x8f:
+ OP( DEC,12 ) MI16( 1, imm16 ) NONE( 2 ) return; // DEC (mn)
+
+ case 0x97:
+ OP( INCW,16 ) MI16( 1, imm16 ) NONE( 2 ) return; // INCW (mn)
+ case 0x9f:
+ OP( DECW,16 ) MI16( 1, imm16 ) NONE( 2 ) return; // DECW (mn)
+
+ case 0xa0: // RLC (mn)
+ case 0xa1: // RRC (mn)
+ case 0xa2: // RL (mn)
+ case 0xa3: // RR (mn)
+ case 0xa4: // SLA (mn)
+ case 0xa5: // SRA (mn)
+ case 0xa6: // SLL (mn)
+ case 0xa7: // SRL (mn)
+ OP( RLC+b3-0xa0,12 ) MI16( 1, imm16 ) NONE( 2 ) return;
+
+ case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+ OP( TSET,16 ) BIT8( 1, b3 - 0x18 ) MI16( 2, imm16 ) return; // TSET b,(mn)
+ case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
+ OP( BIT,10 ) BIT8( 1, b3 - 0xa8 ) MI16( 2, imm16 ) return; // BIT b,(mn)
+ case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+ OP( RES,14 ) BIT8( 1, b3 - 0xb0 ) MI16( 2, imm16 ) return; // RES b,(mn)
+ case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
+ OP( SET,14 ) BIT8( 1, b3 - 0xb8 ) MI16( 2, imm16 ) return; // SET b,(mn)
+ } break;
+
+ case 0xe7:
+ b1 = READ8();
+ b2 = READ8();
+ switch ( b2 ) {
+ case 0x10: // RLD ($FF00+n)
+ case 0x11: // RRD ($FF00+n)
+ OP( RLD+b2-0x10,14 ) MI16( 1, 0xFF00|b1 ) NONE( 2 ) return;
+
+ case 0x12: // MUL HL,($FF00+n)
+ case 0x13: // DIV HL,($FF00+n)
+ OP( MUL+b2-0x12,20 ) R16( 1, HL ) MI16( 2, 0xFF00|b1 ) return;
+
+ case 0x14: case 0x15: case 0x16:
+ OP16( ADD,10 ) R16( 1, IX+b2-0x14 ) MI16( 2, 0xFF00|b1 ) return; // ADD ix,($FF00+n)
+
+ case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+ OP( TSET,14 ) BIT8( 1, b2 - 0x18 ) MI16( 2, 0xFF00|b1 ) return; // TSET b,($FF00+n)
+ case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e:
+ OP( LD,8 ) R8( 1, b2 - 0x28 ) MI16( 2, 0xFF00|b1 ) return; // LD r,($FF00+n)
+ case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e:
+ OP16( LD,10 ) R16( 1, b2 - 0x48 ) MI16( 2, 0xFF00|b1 ) return; // LD rr,($FF00+n)
+
+ case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56:
+ OP( EX,16 ) MI16( 1, 0xFF00|b1 ) R16( 2, b2 - 0x50 ) return; // EX ($FF00+n),rr
+
+ case 0xa0: // RLC ($FF00+n)
+ case 0xa1: // RRC ($FF00+n)
+ case 0xa2: // RL ($FF00+n)
+ case 0xa3: // RR ($FF00+n)
+ case 0xa4: // SLA ($FF00+n)
+ case 0xa5: // SRA ($FF00+n)
+ case 0xa6: // SLL ($FF00+n)
+ case 0xa7: // SRL ($FF00+n)
+ OP( RLC+b2-0xa0,10 ) MI16( 1, 0xFF00|b1 ) NONE( 2 ) return;
+ } break;
+
+ case 0xe8: case 0xe9: case 0xea: /*case 0xeb:*/ case 0xec: case 0xed: case 0xee:
+ b1 = READ8();
+ switch ( b1 ) {
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26:
+ OP( LD,6 ) MR16( 1, b0 - 0xe8 ) R8( 2, b1 - 0x20 ) return; // LD (gg),r
+ case 0x37:
+ OP( LD,8 ) MR16( 1, b0 - 0xe8 ) I8( 2, READ8() ) return; // LD (gg),n
+ case 0x3f:
+ OP( LDW,12 ) MR16( 1, b0 - 0xe8 ) I16( 2, READ16() ) return; // LDW (gg),mn
+ case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46:
+ OP16( LD,8 ) MR16( 1, b0 - 0xe8 ) R16( 2, b1 - 0x40 ) return; // LD (gg),rr
+
+ case 0x68: // ADD (gg),n
+ case 0x69: // ADC (gg),n
+ case 0x6a: // SUB (gg),n
+ case 0x6b: // SBC (gg),n
+ case 0x6c: // AND (gg),n
+ case 0x6d: // XOR (gg),n
+ case 0x6e: // OR (gg),n
+ OP( ADD+b1-0x68,10 ) MR16( 1, b0 - 0xe8 ) I8( 2, READ8() ) return;
+ case 0x6f: // CP (gg),n
+ OP( CP,8 ) MR16( 1, b0 - 0xe8 ) I8( 2, READ8() ) return;
+
+ case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+ case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
+ OPCC( JP,6,8 ) CC( 1, b1 - 0xc0 ) R16( 2, b0 - 0xe8 ) return; // JP [cc,]gg
+ case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+ case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf:
+ OPCC( CALL,6,14 ) CC( 1, b1 - 0xd0 ) R16( 2, b0 - 0xe8 ) return; // CALL [cc,]gg
+ } break;
+ case 0xeb:
+ imm16 = READ16();
+ b3 = READ8();
+ switch ( b3 ) {
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26:
+ OP( LD,10 ) MI16( 1, imm16 ) R8( 2, b3 - 0x20 ) return; // LD (mn),r
+ case 0x37:
+ OP( LD,12 ) MI16( 1, imm16 ) I8( 2, READ8() ) return; // LD (vw),n
+ case 0x3f:
+ OP( LDW,16 ) MI16( 1, imm16 ) I16( 2, READ16() ) return; // LDW (vw),mn
+ case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46:
+ OP16( LD,12 ) MI16( 1, imm16 ) R16( 2, b3 - 0x40 ) return; // LD (mn),rr
+
+ case 0x68: // ADD (vw),n
+ case 0x69: // ADC (vw),n
+ case 0x6a: // SUB (vw),n
+ case 0x6b: // SBC (vw),n
+ case 0x6c: // AND (vw),n
+ case 0x6d: // XOR (vw),n
+ case 0x6e: // OR (vw),n
+ OP( ADD+b3-0x68,14 ) MI16( 1, imm16 ) I8( 2, READ8() ) return;
+ case 0x6f: // CP (vw),n
+ OP( ADD+b3-0x68,12 ) MI16( 1, imm16 ) I8( 2, READ8() ) return;
+
+ case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+ case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
+ OPCC( JP,10,12 ) CC( 1, b3 - 0xc0 ) I16( 2, imm16 ) return; // JP cc,mn
+ case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+ case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf:
+ OPCC( CALL,10,18 ) CC( 1, b3 - 0xd0 ) I16( 2, imm16 ) return; // CALL cc,mn
+ } break;
+
+ case 0xef:
+ b1 = READ8();
+ b2 = READ8();
+ switch ( b2 ) {
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26:
+ OP( LD,8 ) MI16( 1, 0xFF00|b1 ) R8( 2, b2 - 0x20 ) return; // LD ($FF00+n),r
+ case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46:
+ OP16( LD,10 ) MI16( 1, 0xFF00|b1 ) R16( 2, b2 - 0x40 ) return; // LD ($FF00+n),rr
+
+ case 0x68: // ADD ($FF00+w),n
+ case 0x69: // ADC ($FF00+w),n
+ case 0x6a: // SUB ($FF00+w),n
+ case 0x6b: // SBC ($FF00+w),n
+ case 0x6c: // AND ($FF00+w),n
+ case 0x6d: // XOR ($FF00+w),n
+ case 0x6e: // OR ($FF00+w),n
+ OP( ADD+b2-0x68,12 ) MI16( 1, 0xFF00|b1 ) I8( 2, READ8() ) return;
+ case 0x6f: // CP ($FF00+w),n
+ OP( ADD+b2-0x68,10 ) MI16( 1, 0xFF00|b1 ) I8( 2, READ8() ) return;
+ } break;
+
+ case 0xf0: case 0xf1: case 0xf2:
+ b1 = READ8();
+ b2 = READ8();
+ switch ( b2 ) {
+ case 0x10: // RLD (ix+d)
+ case 0x11: // RRD (ix+d)
+ OP( RLD+b2-0x10,16 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return;
+
+ case 0x12: // MUL HL,(ix+d)
+ case 0x13: // DIV HL,(ix+d)
+ OP( MUL+b2-0x12,22 ) R16( 1, HL ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return;
+
+ case 0x14: case 0x15: case 0x16:
+ OP16( ADD,12 ) R16( 1, IX+b2-0x14 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // ADD ix,(jx+d)
+
+ case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e:
+ OP( LD,10 ) R8( 1, b2 - 0x28 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // LD r,(ix+d)
+ case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e:
+ OP16( LD,12 ) R16( 1, b2 - 0x48 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // LD rr,(ix+d)
+
+ case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56:
+ OP( EX,18 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) R16( 2, b2 - 0x50 ) return; // EX (ix+d),rr
+
+ case 0x60: // ADD A,(ix+d)
+ case 0x61: // ADC A,(ix+d)
+ case 0x62: // SUB A,(ix+d)
+ case 0x63: // SBC A,(ix+d)
+ case 0x64: // AND A,(ix+d)
+ case 0x65: // XOR A,(ix+d)
+ case 0x66: // OR A,(ix+d)
+ case 0x67: // CP A,(ix+d)
+ OP( ADD+b2-0x60,10 ) R8( 1, A ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return;
+
+ case 0x70: // ADD HL,(ix+d)
+ case 0x71: // ADC HL,(ix+d)
+ case 0x72: // SUB HL,(ix+d)
+ case 0x73: // SBC HL,(ix+d)
+ case 0x74: // AND HL,(ix+d)
+ case 0x75: // XOR HL,(ix+d)
+ case 0x76: // OR HL,(ix+d)
+ case 0x77: // CP HL,(ix+d)
+ OP16( ADD+b2-0x70,12 ) R16( 1, HL ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return;
+
+ case 0x87:
+ OP( INC,12 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; // INC (ix+d)
+ case 0x8f:
+ OP( DEC,12 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; // DEC (ix+d)
+
+ case 0x97:
+ OP( INCW,16 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; // INCW (ix+d)
+ case 0x9f:
+ OP( DECW,16 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; // DECW (ix+d)
+
+ case 0xa0: // RLC (ix+d)
+ case 0xa1: // RRC (ix+d)
+ case 0xa2: // RL (ix+d)
+ case 0xa3: // RR (ix+d)
+ case 0xa4: // SLA (ix+d)
+ case 0xa5: // SRA (ix+d)
+ case 0xa6: // SLL (ix+d)
+ case 0xa7: // SRL (ix+d)
+ OP( RLC+b2-0xa0,12 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return;
+
+ case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+ OP( TSET,16 ) BIT8( 1, b2 - 0x18 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // TSET b,(ix+d)
+ case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
+ OP( BIT,10 ) BIT8( 1, b2 - 0xa8 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // BIT b,(ix+d)
+ case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+ OP( RES,14 ) BIT8( 1, b2 - 0xb0 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // RES b,(ix+d)
+ case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
+ OP( SET,14 ) BIT8( 1, b2 - 0xb8 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // SET b,(ix+d)
+ } break;
+
+ case 0xf3:
+ b1 = READ8();
+ switch ( b1 ) {
+ case 0x10: // RLD (HL+A)
+ case 0x11: // RRD (HL+A)
+ OP( RLD+b1-0x10,20 ) MR16R8( 1, HL, A ) NONE( 2 ) return;
+
+ case 0x12: // MUL HL,(HL+A)
+ case 0x13: // DIV HL,(HL+A)
+ OP( MUL+b1-0x12,26 ) R16( 1, HL ) MR16R8( 2, HL, A ) return;
+
+ case 0x14: case 0x15: case 0x16:
+ OP16( ADD,16 ) R16( 1, IX+b1-0x14 ) MR16R8( 2, HL, A ) return; // ADD ix,(HL+A)
+
+ case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e:
+ OP( LD,14 ) R8( 1, b1 - 0x28 ) MR16R8( 2, HL, A ) return; // LD r,(HL+A)
+ case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e:
+ OP16( LD,16 ) R16( 1, b1 - 0x48 ) MR16R8( 2, HL, A ) return; // LD rr,(HL+A)
+
+ case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56:
+ OP( EX,22 ) MR16R8( 1, HL, A ) R16( 2, b1 - 0x50 ) return; // EX (HL+A),rr
+
+ case 0x60: // ADD A,(HL+A)
+ case 0x61: // ADC A,(HL+A)
+ case 0x62: // SUB A,(HL+A)
+ case 0x63: // SBC A,(HL+A)
+ case 0x64: // AND A,(HL+A)
+ case 0x65: // XOR A,(HL+A)
+ case 0x66: // OR A,(HL+A)
+ case 0x67: // CP A,(HL+A)
+ OP( ADD+b1-0x60,14 ) R8( 1, A ) MR16R8( 2, HL, A ) return;
+
+ case 0x70: // ADD HL,(HL+A)
+ case 0x71: // ADC HL,(HL+A)
+ case 0x72: // SUB HL,(HL+A)
+ case 0x73: // SBC HL,(HL+A)
+ case 0x74: // AND HL,(HL+A)
+ case 0x75: // XOR HL,(HL+A)
+ case 0x76: // OR HL,(HL+A)
+ case 0x77: // CP HL,(HL+A)
+ OP16( ADD+b1-0x70,16 ) R16( 1, HL ) MR16R8( 2, HL, A ) return;
+
+ case 0x87:
+ OP( INC,16 ) MR16R8( 1, HL, A ) NONE( 2 ) return; // INC (HL+A)
+ case 0x8f:
+ OP( DEC,16 ) MR16R8( 1, HL, A ) NONE( 2 ) return; // DEC (HL+A)
+
+ case 0x97:
+ OP( INCW,20 ) MR16R8( 1, HL, A ) NONE( 2 ) return; // INCW (HL+A)
+ case 0x9f:
+ OP( DECW,20 ) MR16R8( 1, HL, A ) NONE( 2 ) return; // DECW (HL+A)
+
+ case 0xa0: // RLC (HL+A)
+ case 0xa1: // RRC (HL+A)
+ case 0xa2: // RL (HL+A)
+ case 0xa3: // RR (HL+A)
+ case 0xa4: // SLA (HL+A)
+ case 0xa5: // SRA (HL+A)
+ case 0xa6: // SLL (HL+A)
+ case 0xa7: // SRL (HL+A)
+ OP( RLC+b1-0xa0,16 ) MR16R8( 1, HL, A ) NONE( 2 ) return;
+
+ case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+ OP( TSET,20 ) BIT8( 1, b1 - 0x18 ) MR16R8( 2, HL, A ) return; // TSET b,(HL+A)
+ case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
+ OP( BIT,14 ) BIT8( 1, b1 - 0xa8 ) MR16R8( 2, HL, A ) return; // BIT b,(HL+A)
+ case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+ OP( RES,18 ) BIT8( 1, b1 - 0xb0 ) MR16R8( 2, HL, A ) return; // RES b,(HL+A)
+ case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
+ OP( SET,18 ) BIT8( 1, b1 - 0xb8 ) MR16R8( 2, HL, A ) return; // SET b,(HL+A)
+ } break;
+
+ case 0xf4: case 0xf5: case 0xf6:
+ b1 = READ8();
+ b2 = READ8();
+ switch ( b2 ) {
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26:
+ OP( LD,10 ) MR16D8( 1, IX + b0 - 0xf4, b1 ) R8( 2, b2 - 0x20 ) return; // LD (ix+d),r
+ case 0x37:
+ OP( LD,12 ) MR16D8( 1, IX + b0 - 0xf4, b1 ) I8( 2, READ8() ) return; // LD (ix+d),n
+ case 0x38: case 0x39: case 0x3a: /*case 0x3b:*/ case 0x3c: case 0x3d: case 0x3e:
+ OP( LDA,10 ) R16( 1, b2 - 0x38 ) R16D8( 2, IX + b0 - 0xf4, b1 ) return; // LDA rr,ix+d
+ case 0x3f:
+ OP( LDW,16 ) MR16D8( 1, IX + b0 - 0xf4, b1 ) I16( 2, READ16() ) return; // LDW (ix+d),mn
+ case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46:
+ OP16( LD,12 ) MR16D8( 1, IX + b0 - 0xf4, b1 ) R16( 2, b2 - 0x40 ) return; // LD (ix+d),rr
+
+ case 0x68: // ADD (ix+d),n
+ case 0x69: // ADC (ix+d),n
+ case 0x6a: // SUB (ix+d),n
+ case 0x6b: // SBC (ix+d),n
+ case 0x6c: // AND (ix+d),n
+ case 0x6d: // XOR (ix+d),n
+ case 0x6e: // OR (ix+d),n
+ OP( ADD+b2-0x68,14) MR16D8( 1, IX + b0 - 0xf4, b1 ) I8( 2, READ8() ) return;
+ case 0x6f: // CP (ix+d),n
+ OP( ADD+b2-0x68,12) MR16D8( 1, IX + b0 - 0xf4, b1 ) I8( 2, READ8() ) return;
+
+ case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+ case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
+ OPCC( JP,10,12 ) CC( 1, b2 - 0xc0 ) R16D8( 2, IX + b0 - 0xf4, b1 ) return; // JP [cc,]ix+d
+ case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+ case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf:
+ OPCC( CALL,10,18 ) CC( 1, b2 - 0xd0 ) R16D8( 2, IX + b0 - 0xf4, b1 ) return; // CALL [cc,]ix+d
+ } break;
+
+ case 0xf7:
+ b1 = READ8();
+ switch ( b1 ) {
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26:
+ OP( LD,14 ) MR16R8( 1, HL, A ) R8( 2, b1 - 0x20 ) return; // LD (HL+A),r
+ case 0x37:
+ OP( LD,16 ) MR16R8( 1, HL, A ) I8( 2, READ8() ) return; // LD (HL+A),n
+ case 0x38: case 0x39: case 0x3a: /*case 0x3b:*/ case 0x3c: case 0x3d: case 0x3e:
+ OP( LDA,14 ) R16( 1, b1 - 0x38 ) R16R8( 2, HL, A ) return; // LDA rr,HL+A
+ case 0x3f:
+ OP( LDW,20 ) MR16R8( 1, HL, A ) I16( 2, READ16() ) return; // LDW (HL+A),mn
+ case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46:
+ OP16( LD,16 ) MR16R8( 1, HL, A ) R16( 2, b1 - 0x40 ) return; // LD (HL+A),rr
+
+ case 0x68: // ADD (HL+A),n
+ case 0x69: // ADC (HL+A),n
+ case 0x6a: // SUB (HL+A),n
+ case 0x6b: // SBC (HL+A),n
+ case 0x6c: // AND (HL+A),n
+ case 0x6d: // XOR (HL+A),n
+ case 0x6e: // OR (HL+A),n
+ OP( ADD+b1-0x68,18) MR16R8( 1, HL, A ) I8( 2, READ8() ) return;
+ case 0x6f: // CP (HL+A),n
+ OP( ADD+b1-0x68,16) MR16R8( 1, HL, A ) I8( 2, READ8() ) return;
+
+ case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+ case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
+ OPCC( JP,14,16 ) CC( 1, b1 - 0xc0 ) R16R8( 2, HL, A ) return; // JP [cc,]HL+A
+ case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+ case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf:
+ OPCC( CALL,14,22 ) CC( 1, b1 - 0xd0 ) R16R8( 2, HL, A ) return; // CALL [cc,]HL+A
+ } break;
+
+ case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe:
+ b1 = READ8();
+ switch ( b1 ) {
+ case 0x12: // MUL HL,g
+ case 0x13: // DIV HL,g
+ OP( MUL+b1-0x12,18) R16( 1, HL ) R8( 2, b0 - 0xf8 ) return;
+
+ case 0x14: case 0x15: case 0x16:
+ OP16( ADD,8 ) R16( 1, IX+b1-0x14 ) R16( 2, b0 - 0xf8 ) return; // ADD ix,gg
+
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36:
+ OP( LD,4 ) R8( 1, b1 - 0x30 ) R8( 2, b0 - 0xf8 ) return; // LD r,g
+ case 0x38: case 0x39: case 0x3a: /*case 0x3b:*/ case 0x3c: case 0x3d: case 0x3e:
+ OP16( LD,6 ) R16( 1, b1 - 0x38 ) R16( 2, b0 - 0xf8 ) return; // LD rr,gg
+
+ case 0x58: // LDI
+ case 0x59: // LDIR
+ case 0x5a: // LDD
+ case 0x5b: // LDDR
+ case 0x5c: // CPI
+ case 0x5d: // CPIR
+ case 0x5e: // CPD
+ case 0x5f: // CPDR
+ if (b0 == 0xfe) {
+ OPCC( LDI+b1-0x58,14,18 ) NONE( 1 ) NONE( 2 ) return;
+ }
+
+ case 0x60: // ADD A,g
+ case 0x61: // ADC A,g
+ case 0x62: // SUB A,g
+ case 0x63: // SBC A,g
+ case 0x64: // AND A,g
+ case 0x65: // XOR A,g
+ case 0x66: // OR A,g
+ case 0x67: // CP A,g
+ OP( ADD+b1-0x60,4 ) R8( 1, A ) R8( 2, b0 - 0xf8 ) return;
+
+ case 0x68: // ADD g,n
+ case 0x69: // ADC g,n
+ case 0x6a: // SUB g,n
+ case 0x6b: // SBC g,n
+ case 0x6c: // AND g,n
+ case 0x6d: // XOR g,n
+ case 0x6e: // OR g,n
+ case 0x6f: // CP g,n
+ OP( ADD+b1-0x68,6 ) R8( 1, b0 - 0xf8 ) I8( 2, READ8() ) return;
+
+ case 0x70: // ADD HL,gg
+ case 0x71: // ADC HL,gg
+ case 0x72: // SUB HL,gg
+ case 0x73: // SBC HL,gg
+ case 0x74: // AND HL,gg
+ case 0x75: // XOR HL,gg
+ case 0x76: // OR HL,gg
+ case 0x77: // CP HL,gg
+ OP16( ADD+b1-0x70,8 ) R16( 1, HL ) R16( 2, b0 - 0xf8 ) return;
+
+ case 0xa0: // RLC g
+ case 0xa1: // RRC g
+ case 0xa2: // RL g
+ case 0xa3: // RR g
+ case 0xa4: // SLA g
+ case 0xa5: // SRA g
+ case 0xa6: // SLL g
+ case 0xa7: // SRL g
+ OP( RLC+b1-0xa0,4 ) R8( 1, b0 - 0xf8 ) NONE( 2 ) return;
+
+ case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+ OP( TSET,8 ) BIT8( 1, b1 - 0x18 ) R8( 2, b0 - 0xf8 ) return; // TSET b,g
+ case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
+ OP( BIT,4 ) BIT8( 1, b1 - 0xa8 ) R8( 2, b0 - 0xf8 ) return; // BIT b,g
+ case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+ OP( RES,4 ) BIT8( 1, b1 - 0xb0 ) R8( 2, b0 - 0xf8 ) return; // RES b,g
+ case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
+ OP( SET,4 ) BIT8( 1, b1 - 0xb8 ) R8( 2, b0 - 0xf8 ) return; // SET b,g
+
+ case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+ case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf:
+ if (b0 == 0xfe) {
+ OPCC( RET,6,14 ) CC( 1, b1 - 0xd0 ) NONE( 2 ) return; // RET cc
+ }
+ } break;
+
+ case 0xff:
+ OP( SWI,20 ) NONE( 1 ) NONE( 2 ) return; // SWI
+ }
+
+ OP( UNKNOWN,2 ) NONE( 1 ) NONE( 2 )
+}
+
+bool tlcs90_disassembler::stream_arg(std::ostream &stream, uint32_t pc, const char *pre, const e_mode mode, const uint16_t r, const uint16_t rb)
+{
+ const char *reg_name;
+ switch ( mode )
+ {
+ case e_mode::NONE: return false;
+
+ case e_mode::BIT8: util::stream_format(stream, "%s%d", pre, r ); return true;
+ case e_mode::I8: util::stream_format(stream, "%s$%02X", pre, r ); return true;
+ case e_mode::D8: util::stream_format(stream, "%s$%04X", pre, (pc+2+(r&0x7f)-(r&0x80))&0xffff ); return true;
+ case e_mode::I16: util::stream_format(stream, "%s$%04X", pre, r ); return true;
+ case e_mode::D16: util::stream_format(stream, "%s$%04X", pre, (pc+2+(r&0x7fff)-(r&0x8000))&0xffff ); return true;
+ case e_mode::MI16:
+ reg_name = internal_registers_names(r);
+ if (reg_name)
+ util::stream_format(stream, "%s(%s)", pre, reg_name);
+ else
+ util::stream_format(stream, "%s($%04X)", pre, r );
+ return true;
+ case e_mode::R8: util::stream_format(stream, "%s%s", pre, r8_names[r] ); return true;
+ case e_mode::R16: util::stream_format(stream, "%s%s", pre, r16_names[r] ); return true;
+ case e_mode::MR16: util::stream_format(stream, "%s(%s)", pre, r16_names[r] ); return true;
+
+ case e_mode::MR16R8: util::stream_format(stream, "%s(%s+%s)", pre, r16_names[r], r8_names[rb] ); return true;
+ case e_mode::MR16D8: util::stream_format(stream, "%s(%s%c$%02X)", pre, r16_names[r], (rb&0x80)?'-':'+', (rb&0x80)?((rb^0xff)+1):rb ); return true;
+
+ case e_mode::CC: util::stream_format(stream, "%s%s", pre, cc_names[r] ); return true;
+
+ case e_mode::R16R8: util::stream_format(stream, "%s%s+%s", pre, r16_names[r], r8_names[rb] ); return true;
+ case e_mode::R16D8: util::stream_format(stream, "%s%s%c$%02X", pre, r16_names[r], (rb&0x80)?'-':'+', (rb&0x80)?((rb^0xff)+1):rb ); return true;
+
+ default:
+ fatalerror("%04x: unimplemented addr mode = %d\n",pc,std::underlying_type_t<e_mode>(mode));
+ }
+
+ // never executed
+ return false;
+}
+
+offs_t tlcs90_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
+{
+ m_addr = pc;
+ m_opcodes = &opcodes;
+
+ decode();
+
+ util::stream_format (stream, "%-5s", op_names[ m_op ] ); // strlen("callr") == 5
+ bool streamed = stream_arg (stream, pc, " ", m_mode1, m_r1, m_r1b );
+ stream_arg (stream, pc, streamed ?",":"", m_mode2, m_r2, m_r2b );
+
+ return (m_addr - pc) | SUPPORTED;
+}