/*
 *      Interactive disassembler (IDA).
 *      Version 2.05
 *      Copyright (c) 1990-93 by Ilfak Guilfanov. (2:5020/209@fidonet)
 *      ALL RIGHTS RESERVED.
 *
 */

#pragma option -d       // Merge equal strings

#include <ida.hpp>
#include <idp.hpp>
#include "ins.hpp"

instruc_t Instructions[] = {

{ "",           0                               },              // Unknown Operation

//
//      Intel 8080/8085 instructions
//

{ "aci",        CF_USE1 | CF_CHG1 | CF_USE2     },              // Add immediate to A with carry
{ "adc",        CF_USE1 | CF_CHG1 | CF_USE2     },              // Add reg to A with carry
{ "add",        CF_USE1 | CF_CHG1 | CF_USE2     },              // Add <reg> to A
{ "adi",        CF_USE1 | CF_CHG1 | CF_USE2     },              // Add immediate to A
{ "ana",        CF_USE1 | CF_CHG1 | CF_USE2     },              // And reg to A
{ "ani",        CF_USE1 | CF_CHG1 | CF_USE2     },              // And immediate to A
{ "call",       CF_USE1 | CF_CALL               },              // Call subroutine at <addr>
{ "cnz",        CF_USE1 | CF_CALL               },              // Call subroutine if non zero
{ "cz",         CF_USE1 | CF_CALL               },              // Call subroutine if zero
{ "cnc",        CF_USE1 | CF_CALL               },              // Call subroutine if carry clear
{ "cc",         CF_USE1 | CF_CALL               },              // Call subroutine if carry set
{ "cpo",        CF_USE1 | CF_CALL               },              // Call subroutine if odd  parity
{ "cpe",        CF_USE1 | CF_CALL               },              // Call subroutine if even parity
{ "cp",         CF_USE1 | CF_CALL               },              // Call subroutine if positive
{ "cm",         CF_USE1 | CF_CALL               },              // Call subroutine if negative
{ "cmc",        0                               },              // Complement carry
{ "cmp",        CF_USE1 | CF_USE2               },              // Compare register with A
{ "cpi",        CF_USE1 | CF_USE2               },              // Compare immediate data with A
{ "cma",        0                               },              // Complement A
{ "daa",        0                               },              // Decimal adjust A
{ "dad",        CF_USE1 | CF_CHG1 | CF_USE2     },              // Add register pair to HL
{ "dcr",        CF_USE1 | CF_CHG1               },              // Decrement register
{ "dcx",        CF_USE1 | CF_CHG1               },              // Decrement register pair
{ "di",         0                               },              // Disable interrupts
{ "ei",         0                               },              // Enable interrupts
{ "hlt",        0                               },              // Halt
{ "in",         CF_CHG1 | CF_USE2               },              // Input from port to A
{ "inr",        CF_USE1 | CF_CHG1               },              // Increment register
{ "inx",        CF_USE1 | CF_CHG1               },              // Increment register pair
{ "jmp",        CF_USE1                         },              // Jump
{ "jnz",        CF_USE1                         },              // Jump if not zero
{ "jz",         CF_USE1                         },              // Jump if zero
{ "jnc",        CF_USE1                         },              // Jump if carry clear
{ "jc",         CF_USE1                         },              // Jump if carry set
{ "jpo",        CF_USE1                         },              // Jump if parity odd
{ "jpe",        CF_USE1                         },              // Jump if parity even
{ "jp",         CF_USE1                         },              // Jump if plus
{ "jm",         CF_USE1                         },              // Jump if minus
{ "lda",        CF_CHG1 | CF_USE2               },              // Load A direct from memory
{ "ldax",       CF_CHG1 | CF_USE2               },              // Load A indirect from memory using register pair
{ "lhld",       CF_CHG1 | CF_USE2               },              // Load HL direct from memory
{ "lxi",        CF_CHG1 | CF_USE2               },              // Load register pair with immediate data
{ "mov",        CF_CHG1 | CF_USE2               },              // Move register to register
{ "mvi",        CF_CHG1 | CF_USE2               },              // Move immediate data to register
{ "nop",        0                               },              // No Operation
{ "ora",        CF_USE1 | CF_CHG1 | CF_USE2     },              // Or register with A
{ "ori",        CF_USE1 | CF_CHG1 | CF_USE2     },              // Or immediate data to A
{ "out",        CF_USE1 | CF_USE2               },              // Output to port
{ "pchl",       CF_JUMP | CF_STOP               },              // Jump to instruction at (HL)
{ "pop",        CF_CHG1                         },              // Pop register pair from stack
{ "push",       CF_USE1                         },              // Push register pair onto stack
{ "ret",        CF_STOP                         },              // Return from subroutine
{ "rnz",        0                               },              // Return if non zero
{ "rz",         0                               },              // Return if zero
{ "rnc",        0                               },              // Return if carry clear
{ "rc",         0                               },              // Return if carry set
{ "rpo",        0                               },              // Return if parity odd
{ "rpe",        0                               },              // Return if parity even
{ "rp",         0                               },              // Return if plus
{ "rm",         0                               },              // Return if minus
{ "ral",        0                               },              // Rotate A left with carry
{ "rlc",        0                               },              // Rotate A left with branch carry
{ "rar",        0                               },              // Rotate A right with carry
{ "rrc",        0                               },              // Rotate A right with branch carry
{ "rst",        CF_USE1                         },              // Restart at vector <int>
{ "sbb",        CF_USE1 | CF_CHG1 | CF_USE2     },              // Subtract from A with borrow
{ "sbi",        CF_USE1 | CF_CHG1 | CF_USE2     },              // Subtract immediate from A with borrow
{ "stc",        0                               },              // Set carry
{ "sphl",       0                               },              // Exchange SP with HL
{ "sta",        CF_CHG1 | CF_USE2               },              // Store A direct memory
{ "stax",       CF_CHG1 | CF_USE2               },              // Store A indirect using register pair
{ "shld",       CF_CHG1 | CF_USE2               },              // Store HL
{ "sui",        CF_USE1 | CF_CHG1 | CF_USE2     },              // Subtract immediate from A
{ "sub",        CF_USE1 | CF_CHG1 | CF_USE2     },              // Subtract from A
{ "xra",        CF_USE1 | CF_CHG1 | CF_USE2     },              // XOR with A
{ "xri",        CF_USE1 | CF_CHG1 | CF_USE2     },              // XOR A with immediate data
{ "xchg",       0                               },              // Exchange DE with HL
{ "xthl",       0                               },              // Exchange HL with top of stack
{ "rim",        0                               },              // Read interrupt mask
{ "sim",        0                               },              // Store Interrupt mask

//
//      Z80 instructions
//

{ "and",        CF_USE1 | CF_USE2 | CF_CHG1     },              // And with accumulator
{ "bit",        CF_USE1 | CF_USE2               },              // Test <bit> in operand
{ "call",       CF_USE2 | CF_CALL               },              // call (cond & uncond)
{ "ccf",        0                               },              // Complement carry flag
{ "cp",         CF_USE1 | CF_USE2               },              // Compare with accumulator
{ "cpd",        0                               },              // Compare accumulator with memory and\ndecrement address and byte counters
{ "cpdr",       0                               },              // Compare accumulator with memory and\ndecrement address and byte counter,\ncontinue until match is found or\nbyte counter is zero
{ "cpi",        0                               },              // Compare accumulator with memory and\nincrement address and byte counters
{ "cpir",       0                               },              // Compare accumulator with memory and\nincrement address and byte counter,\ncontinue until match is found or\nbyte counter is zero
{ "cpl",        0                               },              // Complement the accumulator
{ "dec",        CF_USE1 | CF_CHG1               },              // Decrement operand
{ "djnz",       CF_USE1                         },              // Decrement reg B and jump relative if zero
{ "ex",         CF_USE1 | CF_CHG1 | CF_USE2 | CF_CHG2 },        // Exchange operands
{ "exx",        0                               },              // Exchange register pairs and alt reg pairs
{ "halt",       0                               },              // Program execution stops
{ "im",         CF_USE1                         },              // Interrupt mode
{ "inc",        CF_USE1 | CF_CHG1               },              // Increment operand
{ "ind",        0                               },              // Input to memory and decrement pointer
{ "indr",       0                               },              // Input to memory and decrement pointer until\nbyte counter is zero
{ "ini",        0                               },              // Input to memory and increment pointer
{ "inir",       0                               },              // Input to memory and increment pointer until\nbyte counter is zero
{ "jp",         CF_USE2                         },              // Jump (conditional & unconditional)
{ "jr",         CF_USE1 | CF_USE2               },              // Jump relative (conditional & unconditional)
{ "ld",         CF_CHG1 | CF_USE2               },              // Move operand2 to operand1
{ "ldd",        0                               },              // Transfer data between memory and decrement\ndestination and source addresses
{ "lddr",       0                               },              // Transfer data between memory until byte\ncounter is zero, decrement destintation\nand source addresses
{ "ldi",        0                               },              // Transfer data between memory and increment\ndestination and source addresses
{ "ldir",       0                               },              // Transfer data between memory until byte\ncounter is zero, increment destination\nand source addresses
{ "neg",        0                               },              // Negate contents of accumulator
{ "or",         CF_USE1 | CF_CHG1 | CF_USE2     },              // Or with accumulator
{ "otdr",       0                               },              // Output from memory, decrement address\ncontinue until reg B is zero
{ "otir",       0                               },              // Output from memory, increment address\ncontinue until reg B is zero
{ "outd",       0                               },              // Output from memory, decrement address
{ "outi",       0                               },              // Output from memory, increment address
{ "res",        CF_USE1 | CF_CHG2 | CF_USE2     },              // Reset bit
{ "ret",        0                               },              // Return (cond & uncond)
{ "reti",       CF_STOP                         },              // Return from interrupt
{ "retn",       CF_STOP                         },              // Return from non-maskable interrupt
{ "rl",         CF_USE1 | CF_CHG1               },              // Rotate left through carry
{ "rla",        0                               },              // Rotate left through carry accumulator
{ "rlc",        CF_USE1 | CF_CHG1               },              // Rotate left branch carry
{ "rlca",       0                               },              // Rotate left accumulator
{ "rld",        0                               },              // Rotate one BCD digit left between the\naccumulator and memory
{ "rr",         CF_USE1 | CF_CHG1               },              // Rotate right through carry
{ "rra",        0                               },              // Rotate right through carry accumulator
{ "rrc",        CF_USE1 | CF_CHG1               },              // Rotate right branch carry
{ "rrca",       0                               },              // Rotate right branch  carry accumulator
{ "rrd",        0                               },              // Rotate one BCD digit right between the\naccumulator and memory
{ "scf",        0                               },              // Set carry flag
{ "sbc",        CF_USE1 | CF_CHG1 | CF_USE2     },              // Subtract from A with borrow
{ "set",        CF_USE1 | CF_CHG2 | CF_USE2     },              // Set bit
{ "sla",        CF_USE1 | CF_CHG1               },              // Shift left arithmetic
{ "sra",        CF_USE1 | CF_CHG1               },              // Shift right arithmetic
{ "srl",        CF_USE1 | CF_CHG1               },              // Shift right logical
{ "xor",        CF_USE1 | CF_CHG1 | CF_USE2     },              // Exclusive or with accumulator
{ "inp",        CF_USE1                         },              // Input from port (c) into operand
{ "outp",       CF_USE1                         },              // Output operand to port (c)
{ "srr",        CF_USE1                         },              // Shift left filling with 1
//
//      HD64180 extensions
//
{ "in0",        CF_USE1 | CF_CHG1 | CF_USE2     },              // load register with input from port (n)
{ "mlt",        CF_USE1                         },              // multiplication of each half\nof the specified register pair\nwith the 16-bit result going to\nthe specified register pair
{ "otim",       0                               },              // load output port (c) with\nlocation (hl),\nincrement hl and b\ndecrement c
{ "otimr",      0                               },              // load output port (c) with\nlocation (hl),\nincrement hl and c\ndecrement b\nrepeat until b = 0
{ "otdm",       0                               },              // load output port (c) with\nlocation (hl),\ndecrement hl and b\ndecrement c
{ "otdmr",      0                               },              // load output port (c) with\nlocation (hl),\ndecrement hl and c\ndecrement b\nrepeat until b = 0
{ "out0",       CF_USE1                         },              // load output port (n) from register
{ "slp",        0                               },              // enter sleep mode
{ "tst",        CF_USE1                         },              // non-destructive'and' with accumulator and specified operand
{ "tstio",      CF_USE1                         },              // non-destructive 'and' of n and the contents of port (c)
//
//      A80 special instructions
//
{ "lbcd",       CF_CHG1 | CF_USE2               },              // Move operand to BC
{ "lded",       CF_CHG1 | CF_USE2               },              // Move operand to DE
{ "lspd",       CF_CHG1 | CF_USE2               },              // Move operand to SP
{ "lixd",       CF_CHG1 | CF_USE2               },              // Move operand to IX
{ "liyd",       CF_CHG1 | CF_USE2               },              // Move operand to IY
{ "sbcd",       CF_CHG1 | CF_USE2               },              // Move BC to memory
{ "sded",       CF_CHG1 | CF_USE2               },              // Move DE to memory
{ "sspd",       CF_CHG1 | CF_USE2               },              // Move SP to memory
{ "sixd",       CF_CHG1 | CF_USE2               },              // Move IX to memory
{ "siyd",       CF_CHG1 | CF_USE2               },              // Move IY to memory
{ "xtix",       CF_USE1 | CF_CHG1 | CF_USE2 | CF_CHG2 },        // Exchange SP and IX
{ "xtiy",       CF_USE1 | CF_CHG1 | CF_USE2 | CF_CHG2 },        // Exchange SP and IY
{ "spix",       CF_CHG1 | CF_USE2               },              // Move IX to SP
{ "spiy",       CF_CHG1 | CF_USE2               },              // Move IY to SP
{ "pcix",       CF_USE2 | CF_STOP               },              // Jump indirect by IX
{ "pciy",       CF_USE2 | CF_STOP               },              // Jump indirect by IY
{ "mvra",       CF_CHG1 | CF_USE2               },              // Move A to R
{ "mvia",       CF_CHG1 | CF_USE2               },              // Move A to I
{ "mvar",       CF_CHG1 | CF_USE2               },              // Move R to A
{ "mvai",       CF_CHG1 | CF_USE2               },              // Move I to A
{ "dadix",      CF_USE1 | CF_CHG1 | CF_USE2     },              // Add operand to IX
{ "dadiy",      CF_USE1 | CF_CHG1 | CF_USE2     },              // Add operand to IY
{ "addc",       CF_USE1 | CF_CHG1 | CF_USE2     },              // Add operand to HL with carry
{ "addcix",     CF_USE1 | CF_CHG1 | CF_USE2     },              // Add operand to IX with carry
{ "addciy",     CF_USE1 | CF_CHG1 | CF_USE2     },              // Add operand to IY with carry
{ "subc",       CF_USE1 | CF_CHG1 | CF_USE2     },              // Subtract from HL with borrow
{ "subcix",     CF_USE1 | CF_CHG1 | CF_USE2     },              // Subtract from IX with borrow
{ "subciy",     CF_USE1 | CF_CHG1 | CF_USE2     },              // Subtract from IY with borrow
{ "jrc",        CF_USE2                         },              // Jump relative if carry
{ "jrnc",       CF_USE2                         },              // Jump relative if not carry
{ "jrz",        CF_USE2                         },              // Jump relative if zero
{ "jrnz",       CF_USE2                         },              // Jump relative if not zero
{ "cmpi",       0                               },              // Compare accumulator with memory and\nincrement address and byte counters
{ "cmpd",       0                               },              // Compare accumulator with memory and\ndecrement address and byte counters
{ "im0",        CF_USE1                         },              // Interrupt mode 0
{ "im1",        CF_USE1                         },              // Interrupt mode 1
{ "im2",        CF_USE1                         },              // Interrupt mode 2
{ "otd",        0                               },              // Output from memory, decrement address
{ "oti",        0                               },              // Output from memory, increment address

// Intel 8085 undocumented instructions
// (info from http://oak.oakland.edu/pub/cpm/maclib/i8085.lib)

{ "dsub",       0                               },               // (HL) <- (HL)-(BC), affects all flags
{ "arhl",       0                               },               // SHIFT HL RIGHT ONE BIT, (H7 IS DUPLICATED, L0 IS SHIFTED INTO CY)
{ "rdel",       0                               },               // ROTATE DE LEFT ONE BIT THRU CY, (E0 RECEIVES CY, CY RECEIVES D7)
{ "ldhi",       CF_USE1                         },               // (DE) <- (HL)+arg
{ "ldsi",       CF_USE1                         },               // (DE) <- (SP)+arg
{ "shlx",       0                               },               // ((DE)) <- (HL)
{ "lhlx",       0                               },               // (HL) <- ((DE))
{ "rstv",       0                               },               // RESTART 40H ON V (OVERFLOW)
{ "jx5",        CF_USE1                         },               // JUMP IF X5 SET
{ "jnx5",       CF_USE1                         },               // JUMP IF NOT X5 SET

// Z380 instructions

{ "cplw",       CF_USE1                         },               // Complement HL register
{ "swap",       CF_USE1                         },               // Swap upper register word with lower register word
{ "inw",        CF_CHG1|CF_USE2                 },               // Input word
{ "outw",       CF_CHG1|CF_USE2                 },               // Output word
{ "ldw",        CF_CHG1|CF_USE2                 },               // Load word
{ "addw",       CF_CHG1|CF_USE2                 },               // Add word
{ "subw",       CF_CHG1|CF_USE2                 },               // Subtract word
{ "adcw",       CF_CHG1|CF_USE2                 },               // Add with carry word
{ "sbcw",       CF_CHG1|CF_USE2                 },               // Subtract with borrow word
{ "andw",       CF_CHG1|CF_USE2                 },               // AND logical word
{ "xorw",       CF_CHG1|CF_USE2                 },               // XOR logical word
{ "orw",        CF_CHG1|CF_USE2                 },               // OR logical word
{ "cpw",        CF_CHG1|CF_USE2                 },               // Compare word
{ "ddir",       CF_USE1                         },               // Decoder directive
{ "calr",       CF_USE1|CF_USE2                 },               // Call relative
{ "ldctl",      CF_CHG1|CF_USE2                 },               // Load control register
{ "mtest",      CF_USE1                         },               // Mode test
{ "exxx",       CF_USE1                         },               // Exchange Index Register with Alternate Bank
{ "exxy",       CF_USE1                         },               // Exchange Index Register with Alternate Bank
{ "exall",      CF_USE1                         },               // Exchange all registers with Alternate Bank
{ "setc",       CF_USE1                         },               // Set control bit
{ "resc",       CF_USE1                         },               // Reset control bit
{ "rlcw",       CF_USE1                         },               // Rotate Left Circular Word
{ "rrcw",       CF_USE1                         },               // Rotate Right Circular Word
{ "rlw",        CF_USE1                         },               // Rotate Left Word
{ "rrw",        CF_USE1                         },               // Rotate Right Word
{ "slaw",       CF_USE1                         },               // Shift Left Arithmetic Word
{ "sraw",       CF_USE1                         },               // Shift Right Arithmetic Word
{ "srlw",       CF_USE1                         },               // Shift Right Logical Word
{ "multw",      CF_USE1                         },               // Multiply Word
{ "multuw",     CF_USE1                         },               // Multiply Word Unsigned
{ "divuw",      CF_USE1                         },               // Divide unsigned
{ "outaw",      CF_CHG1|CF_USE1                 },               // Output word direct to port address
{ "inaw",       CF_CHG1|CF_USE1                 },               // Input word direct from port address
{ "outa",       CF_CHG1|CF_USE1                 },               // Output byte direct to port address
{ "ina",        CF_CHG1|CF_USE1                 },               // Input byte direct from port address
{ "negw",       CF_CHG1                         },               // Negate word
{ "exts",       CF_CHG1                         },               // Extend byte sign
{ "extsw",      CF_CHG1                         },               // Extend word sign
{ "btest",      0                               },               // Bank test
{ "ldiw",       0                               },               // Load and increment (word)
{ "ldirw",      0                               },               // Load and increment, repeat (word)
{ "lddw",       0                               },               // Load and decrement (word)
{ "lddrw",      0                               },               // Load and decrement, repeat (word)
{ "iniw",       0                               },               // Input and increment (word)
{ "inirw",      0                               },               // Input and increment, repeat (word)
{ "indw",       0                               },               // Input and decrement (word)
{ "indrw",      0                               },               // Input and decrement, repeat (word)
{ "outiw",      0                               },               // Output and increment (word)
{ "otirw",      0                               },               // Output and increment, repeat (word)
{ "outdw",      0                               },               // Output and decrement (word)
{ "otdrw",      0                               },               // Output and decrement, repeat (word)

  };

#ifdef __BORLANDC__
#if sizeof(Instructions)/sizeof(Instructions[0]) != I5_last
#error          No match:  sizeof(InstrNames) !!!
#endif
#endif
