?login_element?

Subversion Repositories NedoOS

Rev

Rev 539 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  
  3.   SjASMPlus Z80 Cross Compiler
  4.  
  5.   Copyright (c) 2004-2008 Aprisobal
  6.  
  7.   This software is provided 'as-is', without any express or implied warranty.
  8.   In no event will the authors be held liable for any damages arising from the
  9.   use of this software.
  10.  
  11.   Permission is granted to anyone to use this software for any purpose,
  12.   including commercial applications, and to alter it and redistribute it freely,
  13.   subject to the following restrictions:
  14.  
  15.   1. The origin of this software must not be misrepresented; you must not claim
  16.          that you wrote the original software. If you use this software in a product,
  17.          an acknowledgment in the product documentation would be appreciated but is
  18.          not required.
  19.  
  20.   2. Altered source versions must be plainly marked as such, and must not be
  21.          misrepresented as being the original software.
  22.  
  23.   3. This notice may not be removed or altered from any source distribution.
  24.  
  25. */
  26.  
  27. #include "sjdefs.h"
  28.  
  29. namespace Z80 {
  30.         enum Z80Reg { Z80_B = 0, Z80_C, Z80_D, Z80_E, Z80_H, Z80_L, Z80_MEM_HL, Z80_A, Z80_I, Z80_R, Z80_F,
  31.                 Z80_BC = 0x10, Z80_DE = 0x20, Z80_HL = 0x30, Z80_SP = 0x40, Z80_AF = 0x50,
  32.                 LR35902_MEM_HL_I = 0x22, LR35902_MEM_HL_D = 0x32,
  33.                 Z80_IX = 0xdd, Z80_IY = 0xfd, Z80_MEM_IX = Z80_IX|(Z80_MEM_HL<<8), Z80_MEM_IY = Z80_IY|(Z80_MEM_HL<<8),
  34.                 Z80_IXH = Z80_IX|(Z80_H<<8), Z80_IXL = Z80_IX|(Z80_L<<8),
  35.                 Z80_IYH = Z80_IY|(Z80_H<<8), Z80_IYL = Z80_IY|(Z80_L<<8), Z80_UNK = -1 };
  36.         enum Z80Cond {  // also used to calculate instruction opcode, so do not edit values
  37.                 Z80C_NZ = 0x00, Z80C_Z  = 0x08, Z80C_NC = 0x10, Z80C_C = 0x18,
  38.                 Z80C_PO = 0x20, Z80C_PE = 0x28, Z80C_P  = 0x30, Z80C_M = 0x38, Z80C_UNK };
  39.  
  40.         static char* lastDisplacementParsedP = nullptr;         // helper variable to prevent double warnings about displacements
  41.  
  42.         static CFunctionTable OpCodeTable;
  43.  
  44.         void GetOpCode() {
  45.                 char* n;
  46.                 // reset alternate result flag in ParseExpression part of code
  47.                 lastDisplacementParsedP = nullptr;
  48.                 Relocation::isResultAffected = false;
  49.                 bp = lp;
  50.                 if (!(n = getinstr(lp)) || !OpCodeTable.zoek(n)) {
  51.                         Error("Unrecognized instruction", bp);
  52.                         SkipToEol(lp);
  53.                         return;
  54.                 }
  55.                 // recognized instruction
  56.                 // relocation: check if some expression is "affected", but not processed by instruction
  57.                 Relocation::checkAndWarn();
  58.         }
  59.  
  60.         static byte GetByte(char*& p, bool signedCheck = false) {
  61.                 aint val;
  62.                 if (!ParseExpression(p, val)) {
  63.                         Error("Operand expected", nullptr, IF_FIRST); return 0;
  64.                 }
  65.                 if (signedCheck) check8o(val);
  66.                 else check8(val);
  67.                 return val & 255;
  68.         }
  69.  
  70.         static byte GetByteNoMem(char*& p, bool signedCheck = false) {
  71.                 if (0 == Options::syx.MemoryBrackets) return GetByte(p, signedCheck); // legacy behaviour => don't care
  72.                 aint val; char* const oldP = p;
  73.                 switch (ParseExpressionMemAccess(p, val)) {
  74.                 case 1:                                 // valid constant (not a memory access) => return value
  75.                         if (signedCheck) check8o(val);
  76.                         else check8(val);
  77.                         return val & 255;
  78.                 case 2:                                 // valid memory access => report error
  79.                         Error("Illegal instruction (can't access memory)", oldP);
  80.                         return 0;
  81.                 default:                                // parsing failed, report syntax error
  82.                         Error("Operand expected", oldP, IF_FIRST);
  83.                         return 0;
  84.                 }
  85.         }
  86.  
  87.         static word GetWord(char*& p) {
  88.                 aint val;
  89.                 if (!ParseExpression(p, val)) {
  90.                         Error("Operand expected", nullptr, IF_FIRST); return 0;
  91.                 }
  92.                 check16(val);
  93.                 return val & 65535;
  94.         }
  95.  
  96.         static word GetWordNoMem(char*& p) {
  97.                 if (0 == Options::syx.MemoryBrackets) return GetWord(p); // legacy behaviour => don't care
  98.                 aint val; char* const oldP = p;
  99.                 switch (ParseExpressionMemAccess(p, val)) {
  100.                 case 1:                                 // valid constant (not a memory access) => return value
  101.                         check16(val);
  102.                         return val & 65535;
  103.                 case 2:                                 // valid memory access => report error
  104.                         Error("Illegal instruction (can't access memory)", oldP);
  105.                         return 0;
  106.                 default:                                // parsing failed, report syntax error
  107.                         Error("Operand expected", oldP, IF_FIRST);
  108.                         return 0;
  109.                 }
  110.         }
  111.  
  112.         static byte z80GetIDxoffset(char*& p) {
  113.                 aint val;
  114.                 char* pp = p;
  115.                 SkipBlanks(pp);
  116.                 const bool parsingFirstTime = (pp != lastDisplacementParsedP);
  117.                 lastDisplacementParsedP = pp;
  118.                 if (')' == *pp || ']' == *pp) return 0;
  119.                 if (!ParseExpression(p, val)) {
  120.                         Error("Operand expected", nullptr, IF_FIRST); return 0;
  121.                 }
  122.                 check8o(val);
  123.                 if (parsingFirstTime) Relocation::checkAndWarn();       // displacement offset is never relocatable
  124.                 else Relocation::isResultAffected = false;                      // hide displacement warnings second time
  125.                 return val & 255;
  126.         }
  127.  
  128.         static int GetAddress(char*& p, aint& ad) {
  129.                 if (GetTemporaryLabelValue(p, ad) || ParseExpression(p, ad)) return 1;
  130.                 Error("Operand expected", nullptr, IF_FIRST);
  131.                 return (ad = 0);        // set "ad" to zero and return zero
  132.         }
  133.  
  134.         static Z80Cond getz80cond_Z80(char*& p) {
  135.                 if (SkipBlanks(p)) return Z80C_UNK;     // EOL detected
  136.                 char * const pp = p;
  137.                 const char p0 = 0x20|p[0];              // lowercase ASCII conversion
  138.                 if (!islabchar(p[1])) {                 // can be only single letter condition at most
  139.                         ++p;
  140.                         switch (p0) {
  141.                                 case 'z': return Z80C_Z;
  142.                                 case 'c': return Z80C_C;
  143.                                 case 'p': return Z80C_P;
  144.                                 case 'm': return Z80C_M;
  145.                                 case 's': return Z80C_M;
  146.                         }
  147.                         p = pp;
  148.                         return Z80C_UNK;
  149.                 }
  150.                 // ## p0 != 0 && p1 is label character
  151.                 if ((p[0]^p[1])&0x20) return Z80C_UNK;  // different case of the letters detected
  152.                 if (islabchar(p[2])) return Z80C_UNK;   // p2 is also label character = too many
  153.                 const char p1 = 0x20|p[1];              // lowercase ASCII conversion
  154.                 p += 2;
  155.                 if ('n' == p0) {
  156.                         switch (p1) {
  157.                                 case 'z': return Z80C_NZ;       // nz
  158.                                 case 'c': return Z80C_NC;       // nc
  159.                                 case 's': return Z80C_P;        // ns
  160.                         }
  161.                 } else if ('p' == p0) {
  162.                         switch (p1) {
  163.                                 case 'o': return Z80C_PO;       // po
  164.                                 case 'e': return Z80C_PE;       // pe
  165.                         }
  166.                 }
  167.                 p = pp;
  168.                 return Z80C_UNK;
  169.         }
  170.  
  171.         static Z80Cond getz80cond(char*& p) {
  172.                 if (!Options::IsLR35902) return getz80cond_Z80(p);
  173.                 // Sharp LR35902 has only nz|z|nc|c condition variants of ret|jp|jr|call
  174.                 char * const pp = p;
  175.                 Z80Cond cc = getz80cond_Z80(p);
  176.                 switch (cc) {
  177.                 case Z80C_NZ:   case Z80C_Z:
  178.                 case Z80C_NC:   case Z80C_C:
  179.                         return cc;
  180.                 default:
  181.                         p = pp;                 // restore source ptr
  182.                         return Z80C_UNK;
  183.                 }
  184.         }
  185.  
  186.         static Z80Reg GetRegister_r16High(const Z80Reg r16) {
  187.                 switch (r16) {
  188.                 case Z80_BC: return Z80_B;
  189.                 case Z80_DE: return Z80_D;
  190.                 case Z80_HL: return Z80_H;
  191.                 case Z80_AF: return Z80_A;
  192.                 case Z80_IX: return Z80_IXH;
  193.                 case Z80_IY: return Z80_IYH;
  194.                 default:
  195.                         return Z80_UNK;
  196.                 }
  197.         }
  198.  
  199.         static Z80Reg GetRegister_r16Low(const Z80Reg r16) {
  200.                 switch (r16) {
  201.                 case Z80_BC: return Z80_C;
  202.                 case Z80_DE: return Z80_E;
  203.                 case Z80_HL: return Z80_L;
  204.                 case Z80_AF: return Z80_F;
  205.                 case Z80_IX: return Z80_IXL;
  206.                 case Z80_IY: return Z80_IYL;
  207.                 default:
  208.                         return Z80_UNK;
  209.                 }
  210.         }
  211.  
  212.         static bool GetRegister_pair(char*& p, const char expect) {
  213.                 const char forceCase = Options::syx.CaseInsensitiveInstructions ? 0x20 : 0x00;
  214.                 if ((expect | forceCase) != (p[0] | forceCase) || islabchar(p[1])) return false;
  215.                 ++p;
  216.                 return true;
  217.         }
  218.  
  219.         static bool GetRegister_3letter(char*& p, const char expect1, const char expect2) {
  220.                 if (islabchar(p[2])) return false;
  221.                 const char e1 = Options::syx.CaseInsensitiveInstructions ? (expect1 | 0x20) : expect1;
  222.                 const char e2 = Options::syx.CaseInsensitiveInstructions ? (expect2 | 0x20) : expect2;
  223.                 const char p1 = Options::syx.CaseInsensitiveInstructions ? (p[0] | 0x20) : p[0];
  224.                 const char p2 = Options::syx.CaseInsensitiveInstructions ? (p[1] | 0x20) : p[1];
  225.                 if (e1 != p1 || e2 != p2) return false;
  226.                 p += 2;
  227.                 return true;
  228.         }
  229.  
  230.         static int GetRegister_lastIxyD = 0;    //z80GetIDxoffset(lp)
  231.  
  232.         // fast lookup table for single letters 'a'..'r' ('gjkmnopq' will produce Z80_UNK instantly)
  233.         static Z80Reg r8[] {
  234.                 // a   b      c      d      e      f      g        h      i      j        k        l
  235.                 Z80_A, Z80_B, Z80_C, Z80_D, Z80_E, Z80_F, Z80_UNK, Z80_H, Z80_I, Z80_UNK, Z80_UNK, Z80_L,
  236.                 // m     n        o        p        q        r
  237.                 Z80_UNK, Z80_UNK, Z80_UNK, Z80_UNK, Z80_UNK, Z80_R
  238.         };
  239.  
  240.         static Z80Reg GetRegister(char*& p) {
  241.                 const bool nonZ80CPU = Options::IsI8080 || Options::IsLR35902;
  242.                 char* pp = p;
  243.                 SkipBlanks(p);
  244.                 // adjust the single letter look-up-table by current options (CPU modes and syntax modes)
  245.                 r8['m'-'a'] = Options::syx.Is_M_Memory ? Z80_MEM_HL : Z80_UNK;  // extra alias "M" for "(HL)" enabled?
  246.                 r8['i'-'a'] = nonZ80CPU ? Z80_UNK : Z80_I;      // i8080/LR35902 doesn't have I
  247.                 r8['r'-'a'] = nonZ80CPU ? Z80_UNK : Z80_R;      // i8080/LR35902 doesn't have R
  248.                 char oneLetter = p[0] | 0x20;           // force it lowercase, in case it's ASCII letter
  249.                 if ('a' <= oneLetter && oneLetter <= 'r' && !islabchar(p[1])) {
  250.                         const Z80Reg lutResult = r8[oneLetter - 'a'];
  251.                         if (Z80_UNK == lutResult) p = pp;       // not a register, restore "p"
  252.                         else ++p;       // reg8 found, advance pointer
  253.                         return lutResult;
  254.                 }
  255.                 // high/low operators can be used on register pair
  256.                 if (cmphstr(p, "high")) {
  257.                         const Z80Reg reg = GetRegister(p);
  258.                         if (Z80_UNK == reg) {
  259.                                 p = pp;
  260.                                 return Z80_UNK;
  261.                         }
  262.                         return GetRegister_r16High(reg);
  263.                 }
  264.                 if (cmphstr(p, "low")) {
  265.                         const Z80Reg reg = GetRegister(p);
  266.                         if (Z80_UNK == reg) {
  267.                                 p = pp;
  268.                                 return Z80_UNK;
  269.                         }
  270.                         return GetRegister_r16Low(reg);
  271.                 }
  272.                 // remaining two+ letter registers
  273.                 char memClose = 0;
  274.                 switch (*(p++)) {
  275.                 case 'a':
  276.                         if (GetRegister_pair(p, 'f')) return Z80_AF;
  277.                         break;
  278.                 case 'b':
  279.                         if (GetRegister_pair(p, 'c')) return Z80_BC;
  280.                         break;
  281.                 case 'd':
  282.                         if (GetRegister_pair(p, 'e')) return Z80_DE;
  283.                         break;
  284.                 case 'h':
  285.                         if (GetRegister_pair(p, 'l')) return Z80_HL;
  286.                         if (nonZ80CPU) break;
  287.                         if (GetRegister_pair(p, 'x')) return Z80_IXH;
  288.                         if (GetRegister_pair(p, 'y')) return Z80_IYH;
  289.                         break;
  290.                 case 'i':
  291.                         if (nonZ80CPU) break;
  292.                         if (GetRegister_pair(p, 'x')) return Z80_IX;
  293.                         if (GetRegister_pair(p, 'y')) return Z80_IY;
  294.                         if (GetRegister_3letter(p, 'x', 'h')) return Z80_IXH;
  295.                         if (GetRegister_3letter(p, 'x', 'l')) return Z80_IXL;
  296.                         if (GetRegister_3letter(p, 'y', 'h')) return Z80_IYH;
  297.                         if (GetRegister_3letter(p, 'y', 'l')) return Z80_IYL;
  298.                         break;
  299.                 case 'x':
  300.                         if (nonZ80CPU) break;
  301.                         if (GetRegister_pair(p, 'h')) return Z80_IXH;
  302.                         if (GetRegister_pair(p, 'l')) return Z80_IXL;
  303.                         break;
  304.                 case 'y':
  305.                         if (nonZ80CPU) break;
  306.                         if (GetRegister_pair(p, 'h')) return Z80_IYH;
  307.                         if (GetRegister_pair(p, 'l')) return Z80_IYL;
  308.                         break;
  309.                 case 'l':
  310.                         if (nonZ80CPU) break;
  311.                         if (GetRegister_pair(p, 'x')) return Z80_IXL;
  312.                         if (GetRegister_pair(p, 'y')) return Z80_IYL;
  313.                         break;
  314.                 case 's':
  315.                         if (GetRegister_pair(p, 'p')) return Z80_SP;
  316.                         break;
  317.                 case 'A':
  318.                         if (GetRegister_pair(p, 'F')) return Z80_AF;
  319.                         break;
  320.                 case 'B':
  321.                         if (GetRegister_pair(p, 'C')) return Z80_BC;
  322.                         break;
  323.                 case 'D':
  324.                         if (GetRegister_pair(p, 'E')) return Z80_DE;
  325.                         break;
  326.                 case 'H':
  327.                         if (GetRegister_pair(p, 'L')) return Z80_HL;
  328.                         if (nonZ80CPU) break;
  329.                         if (GetRegister_pair(p, 'X')) return Z80_IXH;
  330.                         if (GetRegister_pair(p, 'Y')) return Z80_IYH;
  331.                         break;
  332.                 case 'I':
  333.                         if (nonZ80CPU) break;
  334.                         if (GetRegister_pair(p, 'X')) return Z80_IX;
  335.                         if (GetRegister_pair(p, 'Y')) return Z80_IY;
  336.                         if (GetRegister_3letter(p, 'X', 'H')) return Z80_IXH;
  337.                         if (GetRegister_3letter(p, 'X', 'L')) return Z80_IXL;
  338.                         if (GetRegister_3letter(p, 'Y', 'H')) return Z80_IYH;
  339.                         if (GetRegister_3letter(p, 'Y', 'L')) return Z80_IYL;
  340.                         break;
  341.                 case 'X':
  342.                         if (nonZ80CPU) break;
  343.                         if (GetRegister_pair(p, 'H')) return Z80_IXH;
  344.                         if (GetRegister_pair(p, 'L')) return Z80_IXL;
  345.                         break;
  346.                 case 'Y':
  347.                         if (nonZ80CPU) break;
  348.                         if (GetRegister_pair(p, 'H')) return Z80_IYH;
  349.                         if (GetRegister_pair(p, 'L')) return Z80_IYL;
  350.                         break;
  351.                 case 'L':
  352.                         if (nonZ80CPU) break;
  353.                         if (GetRegister_pair(p, 'X')) return Z80_IXL;
  354.                         if (GetRegister_pair(p, 'Y')) return Z80_IYL;
  355.                         break;
  356.                 case 'S':
  357.                         if (GetRegister_pair(p, 'P')) return Z80_SP;
  358.                         break;
  359.                 case '(': memClose = (2 != Options::syx.MemoryBrackets) ? ')' : 0;      break;
  360.                 case '[': memClose = ']'; break;
  361.                 default:        break;
  362.                 }
  363.                 if (memClose) {
  364.                         Z80Reg memReg = GetRegister(p);
  365.                         if (Options::IsLR35902 && Z80_HL == memReg) {
  366.                                 if ('+' == *p) {
  367.                                         memReg = LR35902_MEM_HL_I;
  368.                                         ++p;
  369.                                 } else if ('-' == *p) {
  370.                                         memReg = LR35902_MEM_HL_D;
  371.                                         ++p;
  372.                                 }
  373.                         }
  374.                         if (Z80_IX == memReg || Z80_IY == memReg) GetRegister_lastIxyD = z80GetIDxoffset(p);
  375.                         SkipBlanks(p);
  376.                         if (memClose == *p++) {
  377.                                 switch (memReg) {
  378.                                 case Z80_HL:    return Z80_MEM_HL;
  379.                                 case Z80_IX:    return Z80_MEM_IX;
  380.                                 case Z80_IY:    return Z80_MEM_IY;
  381.                                 case LR35902_MEM_HL_I:
  382.                                 case LR35902_MEM_HL_D:
  383.                                         return memReg;
  384.                                 default:                break;
  385.                                 }
  386.                         }
  387.                 }
  388.                 p = pp;
  389.                 return Z80_UNK;
  390.         }
  391.  
  392.         static bool CommonAluOpcode(const int opcodeBase, int* e, bool hasNonRegA = false, bool nonMultiArgComma = true) {
  393.                 Z80Reg reg;
  394.                 char* oldLp = lp;
  395.                 switch (reg = GetRegister(lp)) {
  396.                 case Z80_BC:    case Z80_DE:    case Z80_HL:    case Z80_IX:    case Z80_IY:
  397.                         if (hasNonRegA) lp = oldLp;     // try to parse it one more time if non-A variants exist
  398.                         return !hasNonRegA;                     // invalid first register if only "A" is allowed
  399.                 case Z80_SP:
  400.                         if (Options::IsLR35902) lp = oldLp;
  401.                         return !Options::IsLR35902;     // LR35902 has "add sp,r8"
  402.                 case Z80_AF:    case Z80_I:             case Z80_R:             case Z80_F:
  403.                 case LR35902_MEM_HL_I:  case LR35902_MEM_HL_D:
  404.                         return true;                            // invalid first register
  405.                 case Z80_A:             // deal with optional shortened/prolonged form "add a" vs "and a,a", etc..
  406.                         if (nonMultiArgComma) { // "AND|SUB|... a,b" is possible only when multi-arg is not-comma
  407.                                 if (nonMaComma(lp)) reg = GetRegister(lp);
  408.                         } else {
  409.                                 if (comma(lp)) reg = GetRegister(lp);
  410.                         }
  411.                 default:
  412.                         // with optional "a," dealt with, do the argument recognition and machine code emitting
  413.                         switch (reg) {
  414.                         case Z80_IXH: case Z80_IXL: case Z80_IYH: case Z80_IYL: case Z80_MEM_IX: case Z80_MEM_IY:
  415.                                 *e++ = reg&0xFF;                // add prefix
  416.                                 reg = Z80Reg(reg>>8);   // convert reg into H, L or MEM_HL and continue
  417.                                 if (Z80_MEM_HL == reg) e[1] = GetRegister_lastIxyD;     // add "+d" byte for (ixy+d)
  418.                         case Z80_B: case Z80_C: case Z80_D: case Z80_E:
  419.                         case Z80_H: case Z80_L: case Z80_MEM_HL: case Z80_A:
  420.                                 e[0] = opcodeBase + reg;
  421.                                 return true;                    // successfully assembled
  422.                         case Z80_UNK:
  423.                                 e[0] = opcodeBase + 0x46; e[1] = GetByteNoMem(lp);      // imm8 variants
  424.                                 resolveRelocationAndSmartSmc(1, Relocation::HIGH);
  425.                                 return true;
  426.                         default:
  427.                                 break;
  428.                         }
  429.                 }
  430.                 return true;
  431.         }
  432.  
  433.         // handling all the simple ALU opcodes like and/or/xor/... which have no extras
  434.         static void OpCode_SimpleAlu(const int opcodeBase) {
  435.                 do {
  436.                         int e[] { -1, -1, -1, -1};
  437.                         CommonAluOpcode(opcodeBase, e);
  438.                         EmitBytes(e, true);
  439.                 } while (Options::syx.MultiArg(lp));
  440.         }
  441.  
  442.         // returns "Z80_A" when successfully finished, otherwise returns result of "GetRegister(lp)"
  443.         static Z80Reg OpCode_CbFamily(const int baseOpcode, int* e, bool canHaveDstRegForIxy = true) {
  444.                 Z80Reg reg;
  445.                 switch (reg = GetRegister(lp)) {
  446.                 case Z80_B: case Z80_C: case Z80_D: case Z80_E:
  447.                 case Z80_H: case Z80_L: case Z80_MEM_HL: case Z80_A:
  448.                         e[0] = 0xcb; e[1] = baseOpcode + reg;
  449.                         return Z80_A;
  450.                 case Z80_MEM_IX: case Z80_MEM_IY:
  451.                         e[0] = reg&0xFF; e[1] = 0xcb; e[2] = GetRegister_lastIxyD; e[3] = baseOpcode + (reg>>8);
  452.                         if (canHaveDstRegForIxy && comma(lp)) {
  453.                                 switch (reg = GetRegister(lp)) {
  454.                                 case Z80_B: case Z80_C: case Z80_D: case Z80_E: case Z80_H: case Z80_L: case Z80_A:
  455.                                         e[3] = baseOpcode + reg;
  456.                                         break;
  457.                                 default:
  458.                                         Error("Illegal destination register", line);
  459.                                 }
  460.                         }
  461.                         return Z80_A;
  462.                 default: break;
  463.                 }
  464.                 return reg;
  465.         }
  466.  
  467.         static void OpCode_ADC() {
  468.                 const bool nonZ80CPU = Options::IsI8080 || Options::IsLR35902;
  469.                 Z80Reg reg, reg2;
  470.                 int reg2ex;
  471.                 do {
  472.                         int e[] { -1, -1, -1, -1, -1, -1, -1 };
  473.                         if (!CommonAluOpcode(0x88, e, true, false)) {   // handle common 8-bit variants
  474.                                 reg = GetRegister(lp);  if (Z80_UNK == reg) break;
  475.                                 if (!comma(lp)) {
  476.                                         Error("[ADC] Comma expected");
  477.                                         break;
  478.                                 }
  479.                                 reg2 = GetRegister(lp);
  480.                                 if (Z80_HL == reg && !nonZ80CPU) {
  481.                                         switch (reg2) {
  482.                                         case Z80_BC:    case Z80_DE:    case Z80_HL:    case Z80_SP:
  483.                                                 e[0] = 0xed; e[1] = 0x4a + reg2 - Z80_BC; break;
  484.                                         default: break;
  485.                                         }
  486.                                 } else if (Z80_DE == reg) {             // fake adc de,bc|de|hl|sp
  487.                                         switch (reg2) {
  488.                                         case Z80_BC:    case Z80_DE:    case Z80_HL:    case Z80_SP:
  489.                                                 if (Options::noFakes()) break;
  490.                                                 reg2ex = (Z80_DE == reg2 || Z80_HL == reg2) ? (reg2^0x10) : reg2;
  491.                                                 e[0] = 0xEB;
  492.                                                 e[1] = INSTRUCTION_START_MARKER; e[2] = 0xED; e[3] = 0x4A + reg2ex - Z80_BC;
  493.                                                 e[4] = INSTRUCTION_START_MARKER; e[5] = 0xEB;
  494.                                                 break;
  495.                                         default: break;
  496.                                         }
  497.                                 }
  498.                         }
  499.                         EmitBytes(e, true);
  500.                 } while (Options::syx.MultiArg(lp));
  501.         }
  502.  
  503.         static void OpCode_ADD() {
  504.                 Z80Reg reg, reg2;
  505.                 int reg2ex;
  506.                 do {
  507.                         int e[] { -1, -1, -1, -1, -1, -1 };
  508.                         if (!CommonAluOpcode(0x80, e, true, false)) {   // handle common 8-bit variants
  509.                                 // add hl|ixy|bc|de|sp,... variants
  510.                                 reg = GetRegister(lp);  if (Z80_UNK == reg) break;
  511.                                 if (!comma(lp)) {
  512.                                         Error("[ADD] Comma expected");
  513.                                         break;
  514.                                 }
  515.                                 reg2 = GetRegister(lp);
  516.                                 switch (reg) {
  517.                                 case Z80_HL:
  518.                                         switch (reg2) {
  519.                                         case Z80_BC:    case Z80_DE:    case Z80_HL:    case Z80_SP:
  520.                                                 e[0] = 0x09 + reg2 - Z80_BC; break;
  521.                                         case Z80_A:
  522.                                                 if(!Options::syx.IsNextEnabled) break;
  523.                                                 e[0] = 0xED; e[1] = 0x31; break;
  524.                                         default:
  525.                                                 if(!Options::syx.IsNextEnabled) break;
  526.                                                 word b = GetWordNoMem(lp);
  527.                                                 e[0] = 0xED; e[1] = 0x34 ;
  528.                                                 e[2] = b & 255; e[3] = (b >> 8);
  529.                                                 resolveRelocationAndSmartSmc(2);
  530.                                                 break;
  531.                                         }
  532.                                         break;
  533.                                 case Z80_IX:
  534.                                 case Z80_IY:
  535.                                         switch (reg2) {
  536.                                         case Z80_BC:    case Z80_DE:    case Z80_SP:
  537.                                                 e[0] = reg; e[1] = 0x09 + reg2 - Z80_BC; break;
  538.                                         case Z80_IX:
  539.                                         case Z80_IY:
  540.                                                 if (reg != reg2) break;
  541.                                                 e[0] = reg; e[1] = 0x29; break;
  542.                                         default:
  543.                                                 break;
  544.                                         }
  545.                                         break;
  546.                                 case Z80_DE:    // fake add de,bc|de|hl|sp
  547.                                         switch (reg2) {
  548.                                         case Z80_BC:    case Z80_DE:    case Z80_HL:    case Z80_SP:
  549.                                                 if (Options::noFakes()) break;
  550.                                                 reg2ex = (Z80_DE == reg2 || Z80_HL == reg2) ? (reg2^0x10) : reg2;
  551.                                                 e[0] = 0xEB;
  552.                                                 e[1] = INSTRUCTION_START_MARKER; e[2] = 0x09 + reg2ex - Z80_BC;
  553.                                                 e[3] = INSTRUCTION_START_MARKER; e[4] = 0xEB;
  554.                                                 break;
  555.                                         default: break;
  556.                                         }
  557.                                         //continue into `case Z80_BC` for Z80N variants
  558.                                 case Z80_BC:
  559.                                         if (!Options::syx.IsNextEnabled) break;   // DE|BC is valid first operand only for Z80N
  560.                                         if (Z80_A == reg2) {
  561.                                                 e[0] = 0xED; e[1] = 0x32 + (Z80_BC == reg);
  562.                                         } else if (Z80_UNK == reg2) {
  563.                                                 word b = GetWordNoMem(lp);
  564.                                                 e[0] = 0xED; e[1] = 0x35 + (Z80_BC == reg);
  565.                                                 e[2] = b & 255; e[3] = (b >> 8);
  566.                                                 resolveRelocationAndSmartSmc(2);
  567.                                         }
  568.                                         break;
  569.                                 case Z80_SP:                    // Sharp LR35902 "add sp,r8"
  570.                                         if (!Options::IsLR35902 || Z80_UNK != reg2) break;
  571.                                         e[0] = 0xE8;
  572.                                         e[1] = GetByteNoMem(lp, true);
  573.                                         break;
  574.                                 default:        break;          // unreachable (already validated by `CommonAluOpcode` call)
  575.                                 }
  576.                         }
  577.                         EmitBytes(e, true);
  578.                 } while (Options::syx.MultiArg(lp));
  579.         }
  580.  
  581.         static void OpCode_AND() {
  582.                 OpCode_SimpleAlu(0xa0);
  583.         }
  584.  
  585.         static void OpCode_BIT() {
  586.                 do {
  587.                         int e[] { -1, -1, -1, -1, -1 };
  588.                         byte bit = GetByteNoMem(lp);
  589.                         if (comma(lp) && bit <= 7) OpCode_CbFamily(8 * bit + 0x40, e, false);
  590.                         EmitBytes(e, true);
  591.                 } while (Options::syx.MultiArg(lp));
  592.         }
  593.  
  594.         static void OpCode_Next_BREAK() {       // this is fake instruction for CSpect emulator, not for real Z80N
  595.                 if (Options::syx.IsNextEnabled < 2) {
  596.                         Error("[BREAK] fake instruction \"break\" must be specifically enabled by --zxnext=cspect option");
  597.                         return;
  598.                 }
  599.                 EmitByte(0xDD, true);
  600.                 EmitByte(0x01);
  601.         }
  602.  
  603.         // helper function for BRLC, BSLA, BSRA, BSRF, BSRL, as all need identical operand validation
  604.         static void OpCode_Z80N_BarrelShifts(int mainOpcode) {
  605.                 if (Options::syx.IsNextEnabled < 1) {
  606.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  607.                         return;
  608.                 }
  609.                 int e[] { -1, -1, -1 };
  610.                 // verify the operands are "de,b" (only valid ones)
  611.                 if (Z80_DE == GetRegister(lp) && comma(lp) && Z80_B == GetRegister(lp)) {
  612.                         e[0]=0xED;
  613.                         e[1]=mainOpcode;
  614.                 } else {
  615.                         Error("Z80N barrel shifts exist only with \"DE,B\" arguments", bp, SUPPRESS);
  616.                 }
  617.                 EmitBytes(e, true);
  618.         }
  619.  
  620.         static void OpCode_Next_BRLC() {
  621.                 OpCode_Z80N_BarrelShifts(0x2C);
  622.         }
  623.  
  624.         static void OpCode_Next_BSLA() {
  625.                 OpCode_Z80N_BarrelShifts(0x28);
  626.         }
  627.  
  628.         static void OpCode_Next_BSRA() {
  629.                 OpCode_Z80N_BarrelShifts(0x29);
  630.         }
  631.  
  632.         static void OpCode_Next_BSRF() {
  633.                 OpCode_Z80N_BarrelShifts(0x2B);
  634.         }
  635.  
  636.         static void OpCode_Next_BSRL() {
  637.                 OpCode_Z80N_BarrelShifts(0x2A);
  638.         }
  639.  
  640.         static void OpCode_CALL() {
  641.                 do {
  642.                         int e[] { -1, -1, -1, -1 };
  643.                         Z80Cond cc = getz80cond(lp);
  644.                         if (Z80C_UNK == cc) {
  645.                                 e[0] = 0xcd;
  646.                         } else if (comma(lp)) {
  647.                                 e[0] = 0xC4 + cc;
  648.                         } else {
  649.                                 Error("[CALL cc] Comma expected", bp);
  650.                         }
  651.                         // UNK != cc + no-comma leaves e[0] == -1 (invalid instruction)
  652.                         aint callad;
  653.                         GetAddress(lp, callad);
  654.                         check16(callad);
  655.                         e[1] = callad & 255; e[2] = (callad >> 8) & 255;
  656.                         resolveRelocationAndSmartSmc(1);
  657.                         EmitBytes(e, true);
  658.                 } while (Options::syx.MultiArg(lp));
  659.         }
  660.  
  661.         static void OpCode_CCF() {
  662.                 EmitByte(0x3f, true);
  663.         }
  664.  
  665.         static void OpCode_CP() {
  666.                 OpCode_SimpleAlu(0xb8);
  667.         }
  668.  
  669.         static void OpCode_CPD() {
  670.                 EmitByte(0xED, true);
  671.                 EmitByte(0xA9);
  672.         }
  673.  
  674.         static void OpCode_CPDR() {
  675.                 EmitByte(0xED, true);
  676.                 EmitByte(0xB9);
  677.         }
  678.  
  679.         static void OpCode_CPI() {
  680.                 EmitByte(0xED, true);
  681.                 EmitByte(0xA1);
  682.         }
  683.  
  684.         static void OpCode_CPIR() {
  685.                 EmitByte(0xED, true);
  686.                 EmitByte(0xB1);
  687.         }
  688.  
  689.         static void OpCode_CPL() {
  690.                 EmitByte(0x2f, true);
  691.         }
  692.  
  693.         static void OpCode_DAA() {
  694.                 EmitByte(0x27, true);
  695.         }
  696.  
  697.         static void OpCode_DecInc(const int base8bOpcode, const int base16bOpcode, int* e) {
  698.                 Z80Reg reg;
  699.                 switch (reg = GetRegister(lp)) {
  700.                 case Z80_MEM_IX: case Z80_MEM_IY:
  701.                         e[2] = GetRegister_lastIxyD;    // set up the +d byte and fallthrough for other bytes
  702.                 case Z80_IXH: case Z80_IXL: case Z80_IYH: case Z80_IYL:
  703.                         *e++ = reg&0xFF;        reg = Z80Reg(reg>>8);
  704.                 case Z80_B: case Z80_C: case Z80_D: case Z80_E:
  705.                 case Z80_H: case Z80_L: case Z80_MEM_HL: case Z80_A:
  706.                         *e++ = base8bOpcode + 8 * reg;
  707.                         break;
  708.                 case Z80_IX: case Z80_IY:
  709.                         *e++ = reg;     reg = Z80_HL;
  710.                 case Z80_BC: case Z80_DE: case Z80_HL: case Z80_SP:
  711.                         *e++ = base16bOpcode + reg - Z80_BC;
  712.                         break;
  713.                 default:
  714.                         break;
  715.                 }
  716.         }
  717.  
  718.         static void OpCode_DEC() {
  719.                 do {
  720.                         int e[] { -1, -1, -1, -1 };
  721.                         OpCode_DecInc(0x05, 0x0B, e);
  722.                         EmitBytes(e, true);
  723.                 } while (relaxedMaComma(lp));
  724.         }
  725.  
  726.         static void OpCode_DI() {
  727.                 EmitByte(0xf3, true);
  728.         }
  729.  
  730.         static void OpCode_DJNZ() {
  731.                 int jmp;
  732.                 aint nad;
  733.                 int e[3];
  734.                 do {
  735.                         e[0] = e[1] = e[2] = -1;
  736.                         if (!GetAddress(lp, nad)) {
  737.                                 nad = CurAddress + 2;
  738.                         }
  739.                         jmp = nad - CurAddress - 2;
  740.                         if (jmp < -128 || jmp > 127) {
  741.                                 char el[LINEMAX];
  742.                                 SPRINTF1(el, LINEMAX, "[DJNZ] Target out of range (%+i)", jmp);
  743.                                 Error(el); jmp = 0;
  744.                         }
  745.                         e[0] = 0x10; e[1] = jmp & 0xFF;
  746.                         EmitBytes(e, true);
  747.                 } while (Options::syx.MultiArg(lp));
  748.                 Relocation::isResultAffected = false;   // DJNZ is always relocatable
  749.         }
  750.  
  751.         static void OpCode_EI() {
  752.                 EmitByte(0xfb, true);
  753.         }
  754.  
  755.         static void OpCode_EX() {
  756.                 int e[] { -1, -1, -1, -1 };
  757.                 // parse first and optional second register, swap them for "(sp)" to have sp always first
  758.                 Z80Reg reg1 = GetRegister(lp), reg2 = Z80_UNK;
  759.                 if (Z80_SP == reg1) {
  760.                         reg1 = Z80_UNK;         // naked SP should not work, must be in brackets
  761.                 } else if (Z80_UNK == reg1 && BT_NONE != OpenBracket(lp) && Z80_SP == GetRegister(lp) && CloseBracket(lp)) {
  762.                         reg1 = Z80_SP;                                          // using SP register constant for MEM_SP situation
  763.                 }
  764.                 bool has_comma = comma(lp);
  765.                 if (has_comma) {
  766.                         reg2 = GetRegister(lp);
  767.                         if (Z80_AF == reg2 && *lp == '\'') ++lp;
  768.                         if (Z80_UNK == reg2 && BT_NONE != OpenBracket(lp) && Z80_SP == GetRegister(lp) && CloseBracket(lp)) {
  769.                                 // "(sp)" at right side, swap it with reg1 (official Zilog syntax)
  770.                                 reg2 = reg1;
  771.                                 reg1 = Z80_SP;                                  // using SP register constant for MEM_SP situation
  772.                         }
  773.                 }
  774.                 switch (reg1) {
  775.                 case Z80_AF:
  776.                         if (Options::IsI8080) break;
  777.                         if (has_comma && Z80_AF != reg2) break;
  778.                         e[0] = 0x08;
  779.                         break;
  780.                 case Z80_DE:
  781.                 case Z80_HL:
  782.                         if (!has_comma) {
  783.                                 Error("[EX] Comma expected");
  784.                                 break;
  785.                         }
  786.                         if (Z80Reg(reg1 ^ Z80_DE ^ Z80_HL) != reg2) break;      // check for the other one: DE <-> HL
  787.                         e[0] = 0xeb;
  788.                         break;
  789.                 case Z80_SP:
  790.                         if (!has_comma) {
  791.                                 Error("[EX] Comma expected");
  792.                                 break;
  793.                         }
  794.                         switch (reg2) {
  795.                         case Z80_HL:
  796.                                 e[0] = 0xe3; break;
  797.                         case Z80_IX:
  798.                         case Z80_IY:
  799.                                 e[0] = reg2; e[1] = 0xe3; break;
  800.                         default:
  801.                                 break;
  802.                         }
  803.                         break;
  804.                 default:
  805.                         break;
  806.                 }
  807.                 EmitBytes(e, true);
  808.         }
  809.  
  810.         static void OpCode_EXA() {
  811.                 EmitByte(0x08, true);
  812.         }
  813.  
  814.         static void OpCode_EXD() {
  815.                 EmitByte(0xeb, true);
  816.         }
  817.  
  818.         static void OpCode_Next_EXIT() {        // this is fake instruction for CSpect emulator, not for real Z80N
  819.                 if (Options::syx.IsNextEnabled < 2) {
  820.                         Error("[EXIT] fake instruction \"exit\" must be specifically enabled by --zxnext=cspect option");
  821.                         return;
  822.                 }
  823.                 EmitByte(0xDD, true);
  824.                 EmitByte(0x00);
  825.         }
  826.  
  827.         static void OpCode_EXX() {
  828.                 EmitByte(0xd9, true);
  829.         }
  830.  
  831.         static void OpCode_HALT() {
  832.                 EmitByte(0x76, true);
  833.         }
  834.  
  835.         static void OpCode_IM() {
  836.                 int e[] { -1, -1, -1 }, machineCode[] { 0x46, 0x56, 0x5e };
  837.                 byte mode = GetByteNoMem(lp);
  838.                 if (mode <= 2) {
  839.                         e[0] = 0xed;
  840.                         e[1] = machineCode[mode];
  841.                 }
  842.                 EmitBytes(e, true);
  843.         }
  844.  
  845.         static void OpCode_IN() {
  846.                 do {
  847.                         int e[] { -1, -1, -1 };
  848.                         Z80Reg reg = GetRegister(lp);
  849.                         if (Z80_UNK == reg || comma(lp)) {
  850.                                 if (Z80_UNK == reg) reg = Z80_F;        // if there was no register, it may be "IN (C)"
  851.                                 if ((!Options::IsI8080) && NeedIoC()) {
  852.                                         e[0] = 0xed;
  853.                                         switch (reg) {
  854.                                                 case Z80_B: case Z80_C: case Z80_D: case Z80_E: case Z80_H: case Z80_L: case Z80_A:
  855.                                                         e[1] = 0x40 + reg*8;    // regular IN reg,(C)
  856.                                                         break;
  857.                                                 case Z80_F:
  858.                                                         e[1] = 0x70;                    // unofficial IN F,(C)
  859.                                                         break;
  860.                                                 default:
  861.                                                         e[0] = -1;                              // invalid combination
  862.                                                         break;
  863.                                         }
  864.                                 } else {
  865.                                         e[1] = GetByte(lp);
  866.                                         if (Z80_A == reg) e[0] = 0xdb;  // IN A,(n)
  867.                                 }
  868.                         }
  869.                         EmitBytes(e, true);
  870.                 } while (Options::syx.MultiArg(lp));
  871.         }
  872.  
  873.         static void OpCode_INC() {
  874.                 do {
  875.                         int e[] { -1, -1, -1, -1 };
  876.                         OpCode_DecInc(0x04, 0x03, e);
  877.                         EmitBytes(e, true);
  878.                 } while (relaxedMaComma(lp));
  879.         }
  880.  
  881.         static void OpCode_IND() {
  882.                 EmitByte(0xED, true);
  883.                 EmitByte(0xAA);
  884.         }
  885.  
  886.         static void OpCode_INDR() {
  887.                 EmitByte(0xED, true);
  888.                 EmitByte(0xBA);
  889.         }
  890.  
  891.         static void OpCode_INI() {
  892.                 EmitByte(0xED, true);
  893.                 EmitByte(0xA2);
  894.         }
  895.  
  896.         static void OpCode_INIR() {
  897.                 EmitByte(0xED, true);
  898.                 EmitByte(0xB2);
  899.         }
  900.  
  901.         static void OpCode_INF() {
  902.                 EmitByte(0xED, true);
  903.                 EmitByte(0x70);
  904.         }
  905.  
  906.         static void OpCode_JP() {
  907.                 do {
  908.                         int e[] { -1, -1, -1, -1 };
  909.                         Z80Reg reg = Z80_UNK;
  910.                         Z80Cond cc = getz80cond(lp);
  911.                         if (Z80C_UNK == cc) {   // no condition, check for: jp (hl),... and Z80N jp (c)
  912.                                 char* expLp = lp;
  913.                                 if (Options::syx.IsNextEnabled && NeedIoC()) {
  914.                                         e[0] = 0xED; e[1] = 0x98;       // only "(C)" form with parentheses is legal syntax for Z80N "jp (C)"
  915.                                         reg = Z80_C;    // suppress "jp imm16" parser
  916.                                 } else {
  917.                                         EBracketType bt = OpenBracket(lp);
  918.                                         switch (reg = GetRegister(lp)) {
  919.                                         case Z80_HL: case Z80_IX: case Z80_IY:
  920.                                                 if (BT_NONE != bt && !CloseBracket(lp)) break;  // check [optional] brackets
  921.                                                 e[0] = reg;
  922.                                                 e[Z80_IX <= reg] = 0xe9;        // e[1] for IX/IY, e[0] overwritten for HL/MEM_HL
  923.                                                 break;
  924.                                         case Z80_MEM_HL: case Z80_MEM_IX: case Z80_MEM_IY:      // MEM_xx was handled manually, should NOT happen
  925.                                                 reg = Z80_UNK;                          // try to treat it like expression in following code
  926.                                         case Z80_UNK:
  927.                                                 if (BT_SQUARE == bt) break;     // "[" has no chance, report it
  928.                                                 if (BT_ROUND == bt) lp = expLp; // give "(" another chance to evaluate as expression
  929.                                                 e[0] = 0xc3;                            // jp imm16
  930.                                                 break;
  931.                                         default:                                                // any other register is illegal
  932.                                                 break;
  933.                                         }
  934.                                 }
  935.                         } else {        // if (Z80C_UNK == cc)
  936.                                 if (comma(lp)) e[0] = 0xC2 + cc;        // jp cc,imm16
  937.                                 else Error("[JP cc] Comma expected", bp);
  938.                         }
  939.                         // calculate the imm16 data
  940.                         if (Z80_UNK == reg) {
  941.                                 aint jpad;
  942.                                 GetAddress(lp, jpad);
  943.                                 check16(jpad);
  944.                                 e[1] = jpad & 255; e[2] = (jpad >> 8) & 255;
  945.                                 resolveRelocationAndSmartSmc(1);
  946.                         }
  947.                         EmitBytes(e, true);
  948.                 } while (Options::syx.MultiArg(lp));
  949.         }
  950.  
  951.         static void OpCode_JR() {
  952.                 do {
  953.                         int e[] { -1, -1, -1, -1 };
  954.                         Z80Cond cc = getz80cond(lp);
  955.                         if (Z80C_UNK == cc) e[0] = 0x18;
  956.                         else if (cc <= Z80C_C) {
  957.                                 if (comma(lp)) e[0] = 0x20 + cc;
  958.                                 else Error("[JR cc] Comma expected", bp);
  959.                         } else {
  960.                                 Error("[JR] Illegal condition", bp);
  961.                                 SkipToEol(lp);
  962.                                 break;
  963.                         }
  964.                         aint jrad=0;
  965.                         if (GetAddress(lp, jrad)) jrad -= CurAddress + 2;
  966.                         if (jrad < -128 || jrad > 127) {
  967.                                 char el[LINEMAX];
  968.                                 SPRINTF1(el, LINEMAX, "[JR] Target out of range (%+i)", jrad);
  969.                                 Error(el);
  970.                                 jrad = 0;
  971.                         }
  972.                         e[1] = jrad & 0xFF;
  973.                         EmitBytes(e, true);
  974.                 } while (Options::syx.MultiArg(lp));
  975.                 Relocation::isResultAffected = false;   // relative jump is always relocatable
  976.         }
  977.  
  978.         static bool LD_simple_r_r(int* e, Z80Reg r1) {
  979.                 int prefix1 = 0, prefix2 = 0;
  980.                 bool eightBit = true;
  981.                 switch (r1) {
  982.                 case Z80_IXH:   case Z80_IXL:   case Z80_IYH:   case Z80_IYL:   case Z80_MEM_IX:        case Z80_MEM_IY:
  983.                         prefix1 = r1&0xFF;
  984.                         r1 = Z80Reg(r1>>8);
  985.                 case Z80_I:             case Z80_R:             case Z80_A:             case Z80_MEM_HL:
  986.                 case Z80_B:             case Z80_C:             case Z80_D:             case Z80_E:             case Z80_H:             case Z80_L:
  987.                 case LR35902_MEM_HL_I:  case LR35902_MEM_HL_D:
  988.                         break;
  989.                 case Z80_IY:    case Z80_IX:
  990.                         prefix1 = r1;
  991.                         r1 = Z80_HL;
  992.                 case Z80_BC:    case Z80_DE:    case Z80_HL:    case Z80_SP:
  993.                         eightBit = false;
  994.                         break;
  995.                 default:                // destination is not simple valid register
  996.                         return false;
  997.                 }
  998.                 if (!comma(lp)) return true;    // resolved as error
  999.                 char* olp = lp;
  1000.                 Z80Reg r2 = GetRegister(lp);
  1001.                 switch (r2) {
  1002.                 case Z80_IXH:   case Z80_IXL:   case Z80_IYH:   case Z80_IYL:
  1003.                         if (!eightBit || Z80_MEM_HL == r1) return true; // invalid combination
  1004.                         prefix2 = r2&0xFF;
  1005.                         r2 = Z80Reg(r2>>8);
  1006.                         break;
  1007.                 case Z80_I:             case Z80_R:             // resolve specials early
  1008.                         if (Z80_A != r1) return true; // invalid combination
  1009.                         *e++ = 0xED;    *e++ = Z80_I == r2 ? 0x57 : 0x5F;
  1010.                         return true;
  1011.                 case Z80_MEM_IX:        case Z80_MEM_IY:
  1012.                         prefix2 = r2&0xFF;
  1013.                         r2 = Z80Reg(r2>>8);                     // ,(ixy+d) has same logic as ,(hl) => fallthrough
  1014.                 case Z80_MEM_HL:
  1015.                         if (Z80_MEM_HL == r1 || prefix1) return true;   // (hl),(hl) is invalid, ixy,(hl) too
  1016.                         if (Z80_BC == r1 || Z80_DE == r1 || (Z80_HL == r1 && prefix2)) {
  1017.                                 lp = olp;
  1018.                                 return false;   // ld bc|de,(hl) is possible fake ins., ld hl,(ixy) is possible fake
  1019.                         }
  1020.                 case Z80_A:
  1021.                 case Z80_B:             case Z80_C:             case Z80_D:             case Z80_E:             case Z80_H:             case Z80_L:
  1022.                         if (!eightBit) return true; // invalid combination
  1023.                         if (LR35902_MEM_HL_I == r1 || LR35902_MEM_HL_D == r1) {
  1024.                                 if (Z80_A == r2) *e = r1;       // `ld (hl+),a` or `ld (hl-),a`
  1025.                                 return true;
  1026.                         }
  1027.                         break;
  1028.                 case Z80_IY:    case Z80_IX:
  1029.                         prefix2 = r2;
  1030.                         r2 = Z80_HL;
  1031.                 case Z80_BC:    case Z80_DE:
  1032.                         if (!eightBit) break;           // ld r16, r16 -> resolve it
  1033.                         if (Z80_MEM_HL == r1) lp = olp; // ld (hl),bc|de are possible fake instructions
  1034.                         return (Z80_MEM_HL != r1);      // other 8b vs 16b are invalid combinations
  1035.                 case Z80_HL:
  1036.                         if (Z80_MEM_HL == r1 && prefix1) {
  1037.                                 lp = olp;
  1038.                                 return false;                   // ld (ixy),hl is possible fake instruction
  1039.                         }
  1040.                         if (!eightBit) break;           // ld r16, r16 -> resolve it
  1041.                 case Z80_SP:
  1042.                         if (Options::IsLR35902 && Z80_HL == r1) {
  1043.                                 lp = olp;
  1044.                                 return false;                   // LR35902 has "ld hl,sp+r8" syntax = check!
  1045.                         }
  1046.                         return true;                            // no other "ld r,SP" is valid (on other CPUs)
  1047.                 case Z80_AF: case Z80_F:
  1048.                         return true;                            // no simple "ld r,AF|F" (all invalid)
  1049.                 case LR35902_MEM_HL_I:  case LR35902_MEM_HL_D:
  1050.                         if (Z80_A == r1) *e = r2 + 0x08;
  1051.                         return true;
  1052.                 case Z80_UNK:           // source is not simple register
  1053.                         lp = olp;
  1054.                         return false;
  1055.                 }
  1056.                 //// r1 and r2 are now H/L/HL/MEM_HL for IXH/IXL/../IX/IY/MEM_IXY (only prefix1/prefix2 holds IXY info)
  1057.                 // resolve more specials early
  1058.                 if (Z80_I == r1 || Z80_R == r1) {       // ld i,a | ld r,a
  1059.                         if (Z80_A != r2) return true; // invalid combination
  1060.                         *e++ = 0xED;    *e++ = Z80_I == r1 ? 0x47 : 0x4F;
  1061.                         return true;
  1062.                 }
  1063.                 if (Z80_SP == r1) {                                     // ld sp,hl|ix|iy
  1064.                         if (Z80_HL == r2) {
  1065.                                 if (prefix2) *e++ = prefix2;
  1066.                                 *e++ = 0xF9;
  1067.                         }
  1068.                         return true;
  1069.                 }
  1070.                 if (!eightBit) {                                        // all possible ld r16,r16 (are fakes)
  1071.                         if (Options::noFakes()) return true;
  1072.                         // ld ix,iy | ld iy,ix | ld hl,ixy | ld ixy,hl => push + pop
  1073.                         if ((prefix1^prefix2) && (r1 == r2)) {
  1074.                                 if (prefix2) *e++ = prefix2;
  1075.                                 *e++ = 0xE5;
  1076.                                 *e++ = INSTRUCTION_START_MARKER;
  1077.                                 if (prefix1) *e++ = prefix1;
  1078.                                 *e++ = 0xE1;
  1079.                                 return true;
  1080.                         }
  1081.                         // remaining standard "ld r16,r16"
  1082.                         if (prefix2) prefix1 = prefix2;         // any non-zero prefix is relevant here
  1083.                         if (prefix1) *e++ = prefix1;
  1084.                         *e++ = GetRegister_r16High(r2) + GetRegister_r16High(r1)*8 + 0x40;
  1085.                         *e++ = INSTRUCTION_START_MARKER;
  1086.                         if (prefix1) *e++ = prefix1;
  1087.                         *e++ = GetRegister_r16Low(r2) + GetRegister_r16Low(r1)*8 + 0x40;
  1088.                         return true;
  1089.                 }
  1090.                 // only eight bit simple "ld r8,r8" remains, but verify validity of IXY combinations
  1091.                 if ((prefix1 != prefix2) && (Z80_H == r1 || Z80_L == r1) && (Z80_H == r2 || Z80_L == r2)) {
  1092.                         return true;    // ld h|l|ixyhl,h|l|ixyhl is valid only when prefix1 == prefix2
  1093.                 }
  1094.                 if (prefix1|prefix2) {                                  // any non-zero prefix is relevant here
  1095.                         if (Z80_MEM_HL == r1 || Z80_MEM_HL == r2) e[2] = GetRegister_lastIxyD;  // "+d" byte
  1096.                         *e++ = prefix1|prefix2;
  1097.                 }
  1098.                 *e++ = r2 + r1*8 + 0x40;
  1099.                 return true;
  1100.         }
  1101.  
  1102.         static void LD_LR35902(int *e, const Z80Reg r2, const aint a16) {
  1103.                 // ld (a16),a|sp cases
  1104.                 e[1] = a16 & 255;                       // in any valid case this is correct
  1105.                 if (Z80_A == r2 && 0xFF00 <= a16 && a16 <= 0xFFFF) {    // "ldh a,(a8)" auto-magic detection
  1106.                         e[0] = 0xE0;
  1107.                         return;
  1108.                 }
  1109.                 e[2] = (a16 >> 8) & 255;        // in any remaining valid case this is correct
  1110.                 if (Z80_SP == r2) e[0] = 0x08;
  1111.                 else if (Z80_A == r2) e[0] = 0xEA;
  1112.         }
  1113.  
  1114.         static void OpCode_LD() {
  1115.                 aint b;
  1116.                 EBracketType bt;
  1117.                 do {
  1118.                         int e[] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, pemaRes;
  1119.                         Z80Reg reg2 = Z80_UNK, reg1 = GetRegister(lp);
  1120.                         // resolve all register to register cases or fixed memory literals
  1121.                         // "(hl)|(ixy+d)|(hl+)|(hl-)" (but not other memory or constant)
  1122.                         if (Z80_UNK != reg1 && LD_simple_r_r(e, reg1)) {
  1123.                                 EmitBytes(e, true);
  1124.                                 continue;
  1125.                         }
  1126.                         // memory, constant, fake instruction or syntax error is involved
  1127.                         // (!!! comma is already parsed for all destination=register cases)
  1128.                         switch (reg1) {
  1129.                         case Z80_A:
  1130.                                 if (BT_NONE != (bt = OpenBracket(lp))) {
  1131.                                         reg2 = GetRegister(lp);
  1132.                                         if ((Z80_BC == reg2 || Z80_DE == reg2) && CloseBracket(lp)) e[0] = reg2-6;
  1133.                                         else if (Z80_C == reg2 && Options::IsLR35902 && CloseBracket(lp)) {
  1134.                                                 e[0] = 0xF2;    // Sharp LR35902 `ld a,(c)` (targetting [$ff00+c])
  1135.                                         }
  1136.                                         if (Z80_UNK != reg2) break;     //"(register": emit instruction || bug
  1137.                                         // give non-register another chance to parse as value expression
  1138.                                         --lp;
  1139.                                 }
  1140.                                 switch (ParseExpressionMemAccess(lp, b)) {
  1141.                                         // LD a,imm8
  1142.                                         case 1:
  1143.                                                 check8(b); e[0] = 0x06 + 8*reg1; e[1] = b & 255;
  1144.                                                 resolveRelocationAndSmartSmc(1, Relocation::HIGH);
  1145.                                                 break;
  1146.                                         // LD a,(mem8)
  1147.                                         case 2:
  1148.                                                 check16(b);
  1149.                                                 if (Options::IsLR35902) {
  1150.                                                         if (0xFF00 <= b && b <= 0xFFFF) {
  1151.                                                                 e[0] = 0xF0; e[1] = b & 255;
  1152.                                                         } else {
  1153.                                                                 e[0] = 0xFA; e[1] = b & 255; e[2] = (b >> 8) & 255;
  1154.                                                                 resolveRelocationAndSmartSmc(1);
  1155.                                                         }
  1156.                                                         break;
  1157.                                                 }
  1158.                                                 e[0] = 0x3a; e[1] = b & 255; e[2] = (b >> 8) & 255;
  1159.                                                 resolveRelocationAndSmartSmc(1);
  1160.                                                 if (BT_ROUND == bt) checkLowMemory(e[2], e[1]);
  1161.                                                 break;
  1162.                                 }
  1163.                                 break;
  1164.  
  1165.                         case Z80_B: case Z80_C: case Z80_D: case Z80_E: case Z80_H: case Z80_L:
  1166.                                 e[0] = 0x06 + 8*reg1; e[1] = GetByteNoMem(lp);
  1167.                                 resolveRelocationAndSmartSmc(1, Relocation::HIGH);
  1168.                                 break;
  1169.  
  1170.                         case Z80_MEM_HL:
  1171.                                 switch (reg2 = GetRegister(lp)) {
  1172.                                 case Z80_BC: case Z80_DE:       // fake ld (hl),bc|de
  1173.                                         if (Options::noFakes()) break;
  1174.                                         e[0] = 0x70 + GetRegister_r16Low(reg2);         e[1] = INSTRUCTION_START_MARKER;
  1175.                                         e[2] = 0x23;                                                            e[3] = INSTRUCTION_START_MARKER;
  1176.                                         e[4] = 0x70 + GetRegister_r16High(reg2);        e[5] = INSTRUCTION_START_MARKER;
  1177.                                         e[6] = 0x2b;
  1178.                                         break;
  1179.                                 case Z80_UNK:   // ld (hl),n
  1180.                                         e[0] = 0x36; e[1] = GetByteNoMem(lp);
  1181.                                         resolveRelocationAndSmartSmc(1, Relocation::HIGH);
  1182.                                         break;
  1183.                                 default:
  1184.                                         break;
  1185.                                 }
  1186.                                 break;
  1187.  
  1188.                         case Z80_MEM_IX: case Z80_MEM_IY:
  1189.                                 e[2] = GetRegister_lastIxyD;
  1190.                                 switch (reg2 = GetRegister(lp)) {
  1191.                                 case Z80_BC: case Z80_DE: case Z80_HL:
  1192.                                         if (Options::noFakes()) break;          //fake LD (ixy+#),r16
  1193.                                         if (e[2] == 127) Error("Offset out of range", nullptr, IF_FIRST);
  1194.                                         else e[0] = reg1&0xFF;
  1195.                                         e[1] = 0x70+GetRegister_r16Low(reg2);
  1196.                                         e[3] = INSTRUCTION_START_MARKER;
  1197.                                         e[4] = reg1&0xFF;
  1198.                                         e[5] = 0x70+GetRegister_r16High(reg2);
  1199.                                         e[6] = e[2] + 1;
  1200.                                         break;
  1201.                                 case Z80_UNK:
  1202.                                         e[0] = reg1&0xFF; e[1] = 0x36; e[3] = GetByteNoMem(lp); // LD (ixy+#),imm8
  1203.                                         resolveRelocationAndSmartSmc(3, Relocation::HIGH);
  1204.                                         break;
  1205.                                 default:
  1206.                                         break;
  1207.                                 }
  1208.                                 break;
  1209.  
  1210.                         case Z80_IXH: case Z80_IXL: case Z80_IYH: case Z80_IYL:
  1211.                                 e[0] = reg1&0xFF; e[1] = 0x06 + 8*(reg1>>8); e[2] = GetByteNoMem(lp);
  1212.                                 resolveRelocationAndSmartSmc(2, Relocation::HIGH);
  1213.                                 break;
  1214.  
  1215.                         case Z80_BC: case Z80_DE: case Z80_HL: case Z80_SP:
  1216.                                 switch (reg2 = GetRegister(lp)) {
  1217.                                 case Z80_MEM_HL:        // invalid combinations filtered already by LD_simple_r_r
  1218.                                         if (Options::noFakes()) break;  // fake ld bc|de,(hl)
  1219.                                         e[0] = reg1+0x3e;
  1220.                                         e[1] = INSTRUCTION_START_MARKER;
  1221.                                         e[2] = 0x23;
  1222.                                         e[3] = INSTRUCTION_START_MARKER;
  1223.                                         e[4] = reg1+0x36;
  1224.                                         e[5] = INSTRUCTION_START_MARKER;
  1225.                                         e[6] = 0x2b;
  1226.                                         break;
  1227.                                 case Z80_MEM_IX: case Z80_MEM_IY:       // invalid combinations NOT filtered -> validate
  1228.                                         if (Z80_SP == reg1 || Options::noFakes()) break;        // fake bc|de|hl,(ix+#)
  1229.                                         e[1] = reg1+0x3e;
  1230.                                         e[5] = reg1+0x36;
  1231.                                         e[2] = GetRegister_lastIxyD;
  1232.                                         e[6] = e[2]+1;
  1233.                                         if (e[2] == 127) Error("Offset out of range", nullptr, IF_FIRST);
  1234.                                         else e[0] = e[4] = reg2&0xFF;
  1235.                                         e[3] = INSTRUCTION_START_MARKER;
  1236.                                         break;
  1237.                                 case Z80_SP:
  1238.                                         if (Options::IsLR35902 && Z80_HL == reg1) {             // "ld hl,sp+r8" syntax = "F8 r8"
  1239.                                                 b = 0;
  1240.                                                 // "sp" must be followed by + or - (or nothing: "ld hl,sp" = +0)
  1241.                                                 if (!SkipBlanks(lp) && ',' != *lp ) {           // comma is probably multi-arg
  1242.                                                         if ('+' != *lp && '-' != *lp) {
  1243.                                                                 Error("[LD] `ld hl,sp+r8` expects + or - after sp, found", lp);
  1244.                                                                 break;
  1245.                                                         }
  1246.                                                         b = GetByteNoMem(lp, true);
  1247.                                                 }
  1248.                                                 e[0] = 0xF8;
  1249.                                                 e[1] = b;
  1250.                                         }
  1251.                                         break;
  1252.                                 default:
  1253.                                         break;
  1254.                                 }
  1255.                                 if (Z80_UNK != reg2) break;     //"(register": emit instruction || bug
  1256.                                 switch (ParseExpressionMemAccess(lp, b)) {
  1257.                                         // ld bc|de|hl|sp,imm16
  1258.                                         case 1: check16(b); e[0] = reg1-0x0F; e[1] = b & 255; e[2] = (b >> 8) & 255;
  1259.                                                 resolveRelocationAndSmartSmc(1);
  1260.                                                 break;
  1261.                                         // LD r16,(mem16)
  1262.                                         case 2:
  1263.                                                 if (Options::IsLR35902) break;  // no "ld r16,(a16)" instruction on LR35902
  1264.                                                 check16(b);
  1265.                                                 if (Z80_HL == reg1) {           // ld hl,(mem16)
  1266.                                                         e[0] = 0x2a; e[1] = b & 255; e[2] = (b >> 8) & 255;
  1267.                                                         resolveRelocationAndSmartSmc(1);
  1268.                                                 } else {                                        // ld bc|de|sp,(mem16)
  1269.                                                         if (Options::IsI8080) break;
  1270.                                                         e[0] = 0xed; e[1] = reg1+0x3b; e[2] = b & 255; e[3] = (b >> 8) & 255;
  1271.                                                         resolveRelocationAndSmartSmc(2);
  1272.                                                 }
  1273.                                                 if (')' == lp[-1]) checkLowMemory(b>>8, b);
  1274.                                 }
  1275.                                 break;
  1276.  
  1277.                         case Z80_IX:
  1278.                         case Z80_IY:
  1279.                                 if (0 < (pemaRes = ParseExpressionMemAccess(lp, b))) {
  1280.                                         e[0] = reg1; e[1] = (1 == pemaRes) ? 0x21 : 0x2a;       // ld ix|iy,imm16  ||  ld ix|iy,(mem16)
  1281.                                         check16(b); e[2] = b & 255; e[3] = (b >> 8) & 255;
  1282.                                         resolveRelocationAndSmartSmc(2);
  1283.                                         if ((2 == pemaRes) && ')' == lp[-1]) checkLowMemory(e[3], e[2]);
  1284.                                 }
  1285.                                 break;
  1286.  
  1287.                         case Z80_UNK:
  1288.                                 if (BT_NONE == OpenBracket(lp)) break;
  1289.                                 reg1 = GetRegister(lp);
  1290.                                 if (Z80_UNK == reg1) b = GetWord(lp);
  1291.                                 if (!CloseBracket(lp) || !comma(lp)) break;
  1292.                                 reg2 = GetRegister(lp);
  1293.                                 switch (reg1) {
  1294.                                 case Z80_C:
  1295.                                         if (Options::IsLR35902 && Z80_A == reg2) {      // Sharp LR35902 `ld (c),a` (targetting [$ff00+c])
  1296.                                                 e[0] = 0xE2;
  1297.                                         }
  1298.                                         break;
  1299.                                 case Z80_BC:
  1300.                                 case Z80_DE:
  1301.                                         if (Z80_A == reg2) e[0] = reg1-14;      // LD (bc|de),a
  1302.                                         break;
  1303.                                 case Z80_UNK:
  1304.                                         if (Options::IsLR35902) {       // Sharp LR35902 has quite different opcodes for these
  1305.                                                 LD_LR35902(e, reg2, b);
  1306.                                                 break;
  1307.                                         }
  1308.                                         // Standard Z80 and i8080 opcodes for ld (nn),reg
  1309.                                         switch (reg2) {
  1310.                                         case Z80_A:             // LD (nnnn),a|hl
  1311.                                         case Z80_HL:
  1312.                                                 e[0] = (Z80_A == reg2) ? 0x32 : 0x22; e[1] = b & 255; e[2] = (b >> 8) & 255;
  1313.                                                 resolveRelocationAndSmartSmc(1);
  1314.                                                 break;
  1315.                                         case Z80_BC:    // LD (nnnn),bc|de|sp
  1316.                                         case Z80_DE:
  1317.                                         case Z80_SP:
  1318.                                                 if (Options::IsI8080) break;
  1319.                                                 e[0] = 0xed; e[1] = 0x33+reg2; e[2] = b & 255; e[3] = (b >> 8) & 255;
  1320.                                                 resolveRelocationAndSmartSmc(2);
  1321.                                                 break;
  1322.                                         case Z80_IX:    // LD (nnnn),ix|iy
  1323.                                         case Z80_IY:
  1324.                                                 e[0] = reg2; e[1] = 0x22; e[2] = b & 255; e[3] = (b >> 8) & 255;
  1325.                                                 resolveRelocationAndSmartSmc(2);
  1326.                                                 break;
  1327.                                         default:
  1328.                                                 break;
  1329.                                         }
  1330.                                         break;
  1331.                                 default:
  1332.                                         break;
  1333.                                 }
  1334.                                 break;
  1335.                         default:
  1336.                                 break;
  1337.                         }
  1338.                         EmitBytes(e, true);
  1339.                 } while (Options::syx.MultiArg(lp));
  1340.         }
  1341.  
  1342.         static void OpCode_LR35902_LDD() {
  1343.                 // ldd (hl),a = ld (hl-),a = 0x32
  1344.                 // ldd a,(hl) = ld a,(hl-) = 0x3A
  1345.                 do {
  1346.                         int e[] { -1, -1 };
  1347.                         const Z80Reg r1 = GetRegister(lp);
  1348.                         const bool comma_ok = comma(lp);
  1349.                         const Z80Reg r2 = comma_ok ? GetRegister(lp) : Z80_UNK;
  1350.                         if (Z80_MEM_HL == r1 && Z80_A == r2) e[0] = 0x32;
  1351.                         if (Z80_A == r1 && Z80_MEM_HL == r2) e[0] = 0x3A;
  1352.                         EmitBytes(e, true);
  1353.                 } while (Options::syx.MultiArg(lp));
  1354.         }
  1355.  
  1356.         static void OpCode_LDD() {
  1357.                 if (Options::noFakes(false)) {
  1358.                         EmitByte(0xED, true);
  1359.                         EmitByte(0xA8);
  1360.                         return;
  1361.                 }
  1362.  
  1363.                 // only when fakes are enabled (but they may be silent/warning enabled, so extra checks needed)
  1364.                 do {
  1365.                         int e[] { -1, -1, -1, -1, -1, -1, -1, -1 };
  1366.                         Z80Reg reg2 = Z80_UNK, reg = GetRegister(lp);
  1367.                         switch (reg) {
  1368.                         case Z80_A:
  1369.                                 if (!comma(lp)) break;
  1370.                                 if (BT_NONE == OpenBracket(lp)) break;
  1371.                                 Options::noFakes();             // to display warning if "-f"
  1372.                                 switch (reg = GetRegister(lp)) {
  1373.                                 case Z80_BC:    // 0x0A 0x0B
  1374.                                 case Z80_DE:    // 0x1A 0x1B
  1375.                                         if (CloseBracket(lp)) e[0] = reg-6;
  1376.                                         e[1] = INSTRUCTION_START_MARKER;
  1377.                                         e[2] = reg-5;
  1378.                                         break;
  1379.                                 case Z80_HL:    // 0x7E 0x2B
  1380.                                         if (CloseBracket(lp)) e[0] = 0x7e;
  1381.                                         e[1] = INSTRUCTION_START_MARKER;
  1382.                                         e[2] = 0x2b;
  1383.                                         break;
  1384.                                 case Z80_IX: case Z80_IY:
  1385.                                         e[1] = 0x7e; e[2] = z80GetIDxoffset(lp);
  1386.                                         e[3] = INSTRUCTION_START_MARKER;
  1387.                                         e[5] = 0x2b;
  1388.                                         if (CloseBracket(lp)) e[0] = e[4] = reg;
  1389.                                         break;
  1390.                                 default:
  1391.                                         break;
  1392.                                 }
  1393.                                 break;
  1394.                         case Z80_B: case Z80_C: case Z80_D: case Z80_E: case Z80_H: case Z80_L:
  1395.                                 if (!comma(lp)) break;
  1396.                                 switch (reg2 = GetRegister(lp)) {
  1397.                                 case Z80_MEM_HL:
  1398.                                         Options::noFakes();             // to display warning if "-f"
  1399.                                         e[0] = 0x46 + reg * 8;
  1400.                                         e[1] = INSTRUCTION_START_MARKER;
  1401.                                         e[2] = 0x2b;
  1402.                                         break;
  1403.                                 case Z80_MEM_IX: case Z80_MEM_IY:
  1404.                                         Options::noFakes();             // to display warning if "-f"
  1405.                                         e[0] = e[4] = reg2&0xFF;
  1406.                                         e[1] = 0x46 + reg * 8;
  1407.                                         e[2] = GetRegister_lastIxyD;
  1408.                                         e[3] = INSTRUCTION_START_MARKER;
  1409.                                         e[5] = 0x2b;
  1410.                                         break;
  1411.                                 default:
  1412.                                         break;
  1413.                                 }
  1414.                                 break;
  1415.                         case Z80_MEM_HL:
  1416.                                 if (!comma(lp)) break;
  1417.                                 switch (reg = GetRegister(lp)) {
  1418.                                 case Z80_A: case Z80_B: case Z80_C: case Z80_D: case Z80_E: case Z80_H: case Z80_L:
  1419.                                         Options::noFakes();             // to display warning if "-f"
  1420.                                         e[0] = 0x70 + reg;
  1421.                                         e[1] = INSTRUCTION_START_MARKER;
  1422.                                         e[2] = 0x2b;
  1423.                                         break;
  1424.                                 case Z80_UNK:
  1425.                                         Options::noFakes();             // to display warning if "-f"
  1426.                                         e[0] = 0x36; e[1] = GetByteNoMem(lp);
  1427.                                         e[2] = INSTRUCTION_START_MARKER;
  1428.                                         e[3] = 0x2b;
  1429.                                         break;
  1430.                                 default:
  1431.                                         break;
  1432.                                 }
  1433.                                 break;
  1434.                         case Z80_MEM_IX: case Z80_MEM_IY:
  1435.                                 if (!comma(lp)) break;
  1436.                                 switch (reg2 = GetRegister(lp)) {
  1437.                                 case Z80_A: case Z80_B: case Z80_C: case Z80_D: case Z80_E: case Z80_H: case Z80_L:
  1438.                                         Options::noFakes();             // to display warning if "-f"
  1439.                                         e[0] = e[4] = reg&0xFF;
  1440.                                         e[2] = GetRegister_lastIxyD;
  1441.                                         e[1] = 0x70 + reg2;
  1442.                                         e[3] = INSTRUCTION_START_MARKER;
  1443.                                         e[5] = 0x2b;
  1444.                                         break;
  1445.                                 case Z80_UNK:
  1446.                                         Options::noFakes();             // to display warning if "-f"
  1447.                                         e[0] = e[5] = reg&0xFF;
  1448.                                         e[1] = 0x36;
  1449.                                         e[2] = GetRegister_lastIxyD;
  1450.                                         e[3] = GetByteNoMem(lp);
  1451.                                         e[4] = INSTRUCTION_START_MARKER;
  1452.                                         e[6] = 0x2b;
  1453.                                         break;
  1454.                                 default:
  1455.                                         break;
  1456.                                 }
  1457.                                 break;
  1458.                         default:
  1459.                                 if (BT_NONE != OpenBracket(lp)) {
  1460.                                         reg = GetRegister(lp);
  1461.                                         if (!CloseBracket(lp) || !comma(lp)) break;
  1462.                                         if ((Z80_BC != reg && Z80_DE != reg) || Z80_A != GetRegister(lp)) break;
  1463.                                         Options::noFakes();             // to display warning if "-f"
  1464.                                         e[0] = reg - 14;
  1465.                                         e[1] = INSTRUCTION_START_MARKER;
  1466.                                         e[2] = reg - 5; // LDD (bc|de),a
  1467.                                 } else {
  1468.                                         e[0] = 0xed; e[1] = 0xa8;                       // regular LDD
  1469.                                 }
  1470.                         }
  1471.                         EmitBytes(e, true);
  1472.                 } while (Options::syx.MultiArg(lp));
  1473.         }
  1474.  
  1475.         static void OpCode_LDDR() {
  1476.                 EmitByte(0xED, true);
  1477.                 EmitByte(0xB8);
  1478.         }
  1479.  
  1480.         static void OpCode_Next_LDDRX() {
  1481.                 if (Options::syx.IsNextEnabled < 1) {
  1482.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  1483.                         return;
  1484.                 }
  1485.                 EmitByte(0xED, true);
  1486.                 EmitByte(0xBC);
  1487.         }
  1488.  
  1489.         static void OpCode_Next_LDDX() {
  1490.                 if (Options::syx.IsNextEnabled < 1) {
  1491.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  1492.                         return;
  1493.                 }
  1494.                 EmitByte(0xED, true);
  1495.                 EmitByte(0xAC);
  1496.         }
  1497.  
  1498.         static void OpCode_LR35902_LDH() {
  1499.                 // ldh (a8),a = ld ($FF00+a8),a = "E0 a8"
  1500.                 // ldh a,(a8) = ld a,($FF00+a8) = "F0 a8"
  1501.                 do {
  1502.                         int e[] { -1, -1, -1 }, pemaRes = 0;
  1503.                         aint a8 = -1;
  1504.                         // parse two arguments, expected are "a,(n)" or "(n),a", others will fail in some stage
  1505.                         const Z80Reg r1 = GetRegister(lp);
  1506.                         if (Z80_UNK == r1) pemaRes = ParseExpressionMemAccess(lp, a8);
  1507.                         const bool comma_ok = (Z80_A == r1 || 0 < pemaRes) && comma(lp);
  1508.                         const Z80Reg r2 = comma_ok ? GetRegister(lp) : Z80_F;   // "F" as fail (UNK is legit result)
  1509.                         if (Z80_UNK == r2 && Z80_A == r1) pemaRes = ParseExpressionMemAccess(lp, a8);
  1510.                         else if (Z80_A != r2) pemaRes = 0;
  1511.                         // here pemaRes must be non-zero when valid combination was parsed
  1512.                         switch (pemaRes) {
  1513.                                 case 0:         // syntax error, or wrong registers combined with "ldh"
  1514.                                 case 1:         // immediate is also error, should have been memory
  1515.                                         Error("[LDH] only valid combinations: `ldh a,(a8)` or `ldh (a8),a`", lp, SUPPRESS);
  1516.                                         break;
  1517.                                 case 2:
  1518.                                         if (0xFF00 <= a8 && a8 <= 0xFFFF) a8 -= 0xFF00; // normalize a8 if "ldh a,($FFxx)" was used
  1519.                                         check8(a8);
  1520.                                         e[0] = (Z80_A == r2) ? 0xE0 : 0xF0;
  1521.                                         e[1] = a8 & 0xFF;
  1522.                                         break;
  1523.                         }
  1524.                         EmitBytes(e, true);
  1525.                 } while (Options::syx.MultiArg(lp));
  1526.         }
  1527.  
  1528.         static void OpCode_LR35902_LDI() {
  1529.                 // ldi (hl),a = ld (hl+),a = 0x22
  1530.                 // ldi a,(hl) = ld a,(hl+) = 0x2A
  1531.                 do {
  1532.                         int e[] { -1, -1 };
  1533.                         const Z80Reg r1 = GetRegister(lp);
  1534.                         const bool comma_ok = comma(lp);
  1535.                         const Z80Reg r2 = comma_ok ? GetRegister(lp) : Z80_UNK;
  1536.                         if (Z80_MEM_HL == r1 && Z80_A == r2) e[0] = 0x22;
  1537.                         if (Z80_A == r1 && Z80_MEM_HL == r2) e[0] = 0x2A;
  1538.                         EmitBytes(e, true);
  1539.                 } while (Options::syx.MultiArg(lp));
  1540.         }
  1541.  
  1542.         static void OpCode_LDI() {
  1543.                 if (Options::noFakes(false)) {
  1544.                         EmitByte(0xED, true);
  1545.                         EmitByte(0xA0);
  1546.                         return;
  1547.                 }
  1548.  
  1549.                 // only when fakes are enabled (but they may be silent/warning enabled, so extra checks needed)
  1550.                 do {
  1551.                         int e[] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
  1552.                         Z80Reg reg2 = Z80_UNK, reg = GetRegister(lp);
  1553.                         switch (reg) {
  1554.                         case Z80_A:
  1555.                                 if (!comma(lp)) break;
  1556.                                 if (BT_NONE == OpenBracket(lp)) break;
  1557.                                 Options::noFakes();             // to display warning if "-f"
  1558.                                 switch (reg = GetRegister(lp)) {
  1559.                                 case Z80_BC:    // 0A 03
  1560.                                 case Z80_DE:    // 1A 13
  1561.                                         if (CloseBracket(lp)) e[0] = reg - Z80_BC + 0x0a;
  1562.                                         e[1] = INSTRUCTION_START_MARKER;
  1563.                                         e[2] = reg - Z80_BC + 0x03;
  1564.                                         break;
  1565.                                 case Z80_HL:
  1566.                                         e[1] = INSTRUCTION_START_MARKER;
  1567.                                         e[2] = 0x23;
  1568.                                         if (CloseBracket(lp)) e[0] = 0x7e;
  1569.                                         break;
  1570.                                 case Z80_IX:
  1571.                                 case Z80_IY:
  1572.                                         e[3] = INSTRUCTION_START_MARKER;
  1573.                                         e[1] = 0x7e; e[5] = 0x23; e[2] = z80GetIDxoffset(lp);
  1574.                                         if (CloseBracket(lp)) e[0] = e[4] = reg;
  1575.                                         break;
  1576.                                 default:
  1577.                                         break;
  1578.                                 }
  1579.                                 break;
  1580.                         case Z80_B: case Z80_C: case Z80_D: case Z80_E: case Z80_H: case Z80_L:
  1581.                                 if (!comma(lp)) break;
  1582.                                 if (BT_NONE == OpenBracket(lp)) break;
  1583.                                 Options::noFakes();             // to display warning if "-f"
  1584.                                 switch (reg2 = GetRegister(lp)) {
  1585.                                 case Z80_HL:
  1586.                                         e[1] = INSTRUCTION_START_MARKER;
  1587.                                         e[2] = 0x23; if (CloseBracket(lp)) e[0] = 0x46 + reg * 8;
  1588.                                         break;
  1589.                                 case Z80_IX:
  1590.                                 case Z80_IY:
  1591.                                         e[3] = INSTRUCTION_START_MARKER;
  1592.                                         e[1] = 0x46 + reg * 8; e[5] = 0x23; e[2] = z80GetIDxoffset(lp);
  1593.                                         if (CloseBracket(lp)) e[0] = e[4] = reg2;
  1594.                                         break;
  1595.                                 default:
  1596.                                         break;
  1597.                                 }
  1598.                                 break;
  1599.                         case Z80_BC: case Z80_DE: case Z80_HL:
  1600.                                 if (!comma(lp)) break;
  1601.                                 switch (reg2 = GetRegister(lp)) {
  1602.                                 case Z80_MEM_HL:
  1603.                                         if (Z80_HL == reg) break;
  1604.                                         Options::noFakes();             // to display warning if "-f"
  1605.                                         e[1] = e[3] = e[5] = INSTRUCTION_START_MARKER;
  1606.                                         e[0] = 0x3e + reg;
  1607.                                         e[2] = 0x23;
  1608.                                         e[4] = 0x36 + reg;
  1609.                                         e[6] = 0x23;
  1610.                                         break;
  1611.                                 case Z80_MEM_IX: case Z80_MEM_IY:
  1612.                                         Options::noFakes();             // to display warning if "-f"
  1613.                                         e[3] = e[6] = e[10] = INSTRUCTION_START_MARKER;
  1614.                                         e[2] = e[9] = GetRegister_lastIxyD;
  1615.                                         e[0] = e[4] = e[7] = e[11] = reg2&0xFF;
  1616.                                         e[1] = 0x3e + reg; e[8] = 0x36 + reg; e[5] = e[12] = 0x23;
  1617.                                         break;
  1618.                                 default:
  1619.                                         break;
  1620.                                 }
  1621.                                 break;
  1622.                         case Z80_MEM_HL:
  1623.                                 if (!comma(lp)) break;
  1624.                                 switch (reg = GetRegister(lp)) {
  1625.                                 case Z80_A: case Z80_B: case Z80_C: case Z80_D: case Z80_E: case Z80_H: case Z80_L:
  1626.                                         Options::noFakes();             // to display warning if "-f"
  1627.                                         e[1] = INSTRUCTION_START_MARKER;
  1628.                                         e[0] = 0x70 + reg; e[2] = 0x23; break;
  1629.                                 case Z80_BC: case Z80_DE:
  1630.                                         Options::noFakes();             // to display warning if "-f"
  1631.                                         e[1] = e[3] = e[5] = INSTRUCTION_START_MARKER;
  1632.                                         e[0] = 0x70 + GetRegister_r16Low(reg); e[4] = 0x70 + GetRegister_r16High(reg);
  1633.                                         e[2] = e[6] = 0x23; break;
  1634.                                 case Z80_UNK:
  1635.                                         Options::noFakes();             // to display warning if "-f"
  1636.                                         e[2] = INSTRUCTION_START_MARKER;
  1637.                                         e[0] = 0x36; e[1] = GetByteNoMem(lp); e[3] = 0x23; break;
  1638.                                 default:
  1639.                                         break;
  1640.                                 }
  1641.                                 break;
  1642.                         case Z80_MEM_IX: case Z80_MEM_IY:
  1643.                                 if (!comma(lp)) break;
  1644.                                 switch (reg2 = GetRegister(lp)) {
  1645.                                 case Z80_A: case Z80_B: case Z80_C: case Z80_D: case Z80_E: case Z80_H: case Z80_L:
  1646.                                         Options::noFakes();             // to display warning if "-f"
  1647.                                         e[3] = INSTRUCTION_START_MARKER;
  1648.                                         e[0] = e[4] = reg&0xFF; e[2] = GetRegister_lastIxyD; e[1] = 0x70 + reg2; e[5] = 0x23; break;
  1649.                                 case Z80_BC: case Z80_DE: case Z80_HL:
  1650.                                         Options::noFakes();             // to display warning if "-f"
  1651.                                         e[3] = e[6] = e[10] = INSTRUCTION_START_MARKER;
  1652.                                         e[0] = e[4] = e[7] = e[11] = reg&0xFF; e[5] = e[12] = 0x23; e[2] = e[9] = GetRegister_lastIxyD;
  1653.                                         e[1] = 0x70 + GetRegister_r16Low(reg2); e[8] = 0x70 + GetRegister_r16High(reg2); break;
  1654.                                 case Z80_UNK:
  1655.                                         Options::noFakes();             // to display warning if "-f"
  1656.                                         e[0] = e[5] = reg&0xFF; e[1] = 0x36; e[2] = GetRegister_lastIxyD; e[3] = GetByteNoMem(lp);
  1657.                                         e[4] = INSTRUCTION_START_MARKER;
  1658.                                         e[6] = 0x23; break;
  1659.                                 default:
  1660.                                         break;
  1661.                                 }
  1662.                                 break;
  1663.                         default:
  1664.                                 if (BT_NONE != OpenBracket(lp)) {
  1665.                                         reg = GetRegister(lp);
  1666.                                         if (!CloseBracket(lp) || !comma(lp)) break;
  1667.                                         if ((Z80_BC != reg && Z80_DE != reg) || Z80_A != GetRegister(lp)) break;
  1668.                                         Options::noFakes();
  1669.                                         e[1] = INSTRUCTION_START_MARKER;
  1670.                                         e[0] = reg - 14; e[2] = reg - 13;       // LDI (bc|de),a
  1671.                                 } else {
  1672.                                         e[0] = 0xed; e[1] = 0xa0;                       // regular LDI
  1673.                                 }
  1674.                         }
  1675.  
  1676.                         EmitBytes(e, true);
  1677.                 } while (Options::syx.MultiArg(lp));
  1678.         }
  1679.  
  1680.         static void OpCode_LDIR() {
  1681.                 EmitByte(0xED, true);
  1682.                 EmitByte(0xB0);
  1683.         }
  1684.  
  1685. // LDIRSCALE is now very unlikely to happen, there's ~1% chance it may be introduced within the cased-Next release
  1686. //      static void OpCode_Next_LDIRSCALE() {
  1687. //              if (Options::syx.IsNextEnabled < 1) {
  1688. //                      Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  1689. //                      return;
  1690. //              }
  1691. //              EmitByte(0xED, true);
  1692. //              EmitByte(0xB6);
  1693. //      }
  1694.  
  1695.         static void OpCode_Next_LDIRX() {
  1696.                 if (Options::syx.IsNextEnabled < 1) {
  1697.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  1698.                         return;
  1699.                 }
  1700.                 EmitByte(0xED, true);
  1701.                 EmitByte(0xB4);
  1702.         }
  1703.  
  1704.         static void OpCode_Next_LDIX() {
  1705.                 if (Options::syx.IsNextEnabled < 1) {
  1706.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  1707.                         return;
  1708.                 }
  1709.                 EmitByte(0xED, true);
  1710.                 EmitByte(0xA4);
  1711.         }
  1712.  
  1713.         static void OpCode_Next_LDPIRX() {
  1714.                 if (Options::syx.IsNextEnabled < 1) {
  1715.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  1716.                         return;
  1717.                 }
  1718.                 EmitByte(0xED, true);
  1719.                 EmitByte(0xB7);
  1720.         }
  1721.  
  1722.         static void OpCode_Next_LDWS() {
  1723.                 if (Options::syx.IsNextEnabled < 1) {
  1724.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  1725.                         return;
  1726.                 }
  1727.                 EmitByte(0xED, true);
  1728.                 EmitByte(0xA5);
  1729.         }
  1730.  
  1731.         static void OpCode_Next_MIRROR() {
  1732.                 if (Options::syx.IsNextEnabled < 1) {
  1733.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  1734.                         return;
  1735.                 }
  1736.                 Z80Reg reg = GetRegister(lp);
  1737.                 if (Z80_UNK != reg && Z80_A != reg) {
  1738.                         Error("[MIRROR] Illegal operand (can be only register A)", line);
  1739.                         return;
  1740.                 }
  1741.                 EmitByte(0xED, true);
  1742.                 EmitByte(0x24);
  1743.         }
  1744.  
  1745.         static void OpCode_Next_MUL() {
  1746.                 if (Options::syx.IsNextEnabled < 1) {
  1747.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  1748.                         return;
  1749.                 }
  1750.                 int e[3] { -1, -1, -1 };
  1751.                 Z80Reg r1 = GetRegister(lp);
  1752.                 if (Z80_UNK == r1 && SkipBlanks(lp) && !Options::noFakes()) {
  1753.                         r1 = Z80_DE;    // "mul" without arguments is treated as "fake" "mul de"
  1754.                 }
  1755.                 // "mul de" and "mul d,e" are both valid syntax options
  1756.                 if ((Z80_DE==r1) || (Z80_D==r1 && comma(lp) && Z80_E==GetRegister(lp))) {
  1757.                         e[0]=0xED;
  1758.                         e[1]=0x30;
  1759.                 } else {
  1760.                         Error("Z80N MUL exist only with \"D,E\" arguments", bp, SUPPRESS);
  1761.                         return;
  1762.                 }
  1763.                 EmitBytes(e, true);
  1764.         }
  1765.  
  1766.         static void OpCode_MULUB() {
  1767.                 Z80Reg reg;
  1768.                 int e[3];
  1769.                 e[0] = e[1] = e[2] = -1;
  1770.                 if ((reg = GetRegister(lp)) == Z80_A && comma(lp)) {
  1771.                         reg = GetRegister(lp);
  1772.                 }
  1773.                 switch (reg) {
  1774.                 case Z80_B:
  1775.                         e[0] = 0xed; e[1] = 0xc1; break;
  1776.                 case Z80_C:
  1777.                         e[0] = 0xed; e[1] = 0xc9; break;
  1778.                 case Z80_D:
  1779.                         e[0] = 0xed; e[1] = 0xd1; break;
  1780.                 case Z80_E:
  1781.                         e[0] = 0xed; e[1] = 0xd9; break;
  1782.                 default:
  1783.                         ;
  1784.                 }
  1785.                 EmitBytes(e, true);
  1786.         }
  1787.  
  1788.         static void OpCode_MULUW() {
  1789.                 Z80Reg reg;
  1790.                 int e[3];
  1791.                 e[0] = e[1] = e[2] = -1;
  1792.                 if ((reg = GetRegister(lp)) == Z80_HL && comma(lp)) {
  1793.                         reg = GetRegister(lp);
  1794.                 }
  1795.                 switch (reg) {
  1796.                 case Z80_BC:
  1797.                         e[0] = 0xed; e[1] = 0xc3; break;
  1798.                 case Z80_SP:
  1799.                         e[0] = 0xed; e[1] = 0xf3; break;
  1800.                 default:
  1801.                         ;
  1802.                 }
  1803.                 EmitBytes(e, true);
  1804.         }
  1805.  
  1806.         static void OpCode_NEG() {
  1807.                 EmitByte(0xED, true);
  1808.                 EmitByte(0x44);
  1809.         }
  1810.  
  1811.         static void OpCode_Next_NEXTREG() {
  1812.                 if (Options::syx.IsNextEnabled < 1) {
  1813.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  1814.                         return;
  1815.                 }
  1816.                 Z80Reg reg;
  1817.                 int e[5];
  1818.                 do {
  1819.                         e[0] = e[1] = e[2] = e[3] = e[4] = -1;
  1820.                         // is operand1 register? (to give more precise error message to people using wrong `nextreg a,$nn`)
  1821.                         reg = GetRegister(lp);
  1822.                         if (Z80_UNK != reg) {
  1823.                                 Error("[NEXTREG] first operand should be register number", line, SUPPRESS); break;
  1824.                         }
  1825.                         // this code would be enough to get correct assembling, the test above is "extra"
  1826.                         e[2] = GetByteNoMem(lp);
  1827.                         Relocation::checkAndWarn();             // display warning if register number is trying to be relocatable (impossible)
  1828.                         if (!comma(lp)) {
  1829.                                 Error("[NEXTREG] Comma expected"); break;
  1830.                         }
  1831.                         switch (reg = GetRegister(lp)) {
  1832.                                 case Z80_A:
  1833.                                         e[0] = 0xED; e[1] = 0x92;
  1834.                                         break;
  1835.                                 case Z80_UNK:
  1836.                                         e[0] = 0xED; e[1] = 0x91;
  1837.                                         e[3] = GetByteNoMem(lp);
  1838.                                         resolveRelocationAndSmartSmc(3, Relocation::HIGH);
  1839.                                         break;
  1840.                                 default:
  1841.                                         break;
  1842.                         }
  1843.                         EmitBytes(e, true);
  1844.                 } while (Options::syx.MultiArg(lp));
  1845.         }
  1846.  
  1847.         static void OpCode_NOP() {
  1848.                 EmitByte(0x0, true);
  1849.         }
  1850.  
  1851.         static void OpCode_OR() {
  1852.                 OpCode_SimpleAlu(0xb0);
  1853.         }
  1854.  
  1855.         static void OpCode_OTDR() {
  1856.                 EmitByte(0xED, true);
  1857.                 EmitByte(0xBB);
  1858.         }
  1859.  
  1860.         static void OpCode_OTIR() {
  1861.                 EmitByte(0xED, true);
  1862.                 EmitByte(0xB3);
  1863.         }
  1864.  
  1865.         static void OpCode_OUT() {
  1866.                 Z80Reg reg;
  1867.                 do {
  1868.                         int e[] { -1, -1, -1 };
  1869.                         if ((!Options::IsI8080) && NeedIoC()) {
  1870.                                 if (comma(lp)) {
  1871.                                         switch (reg = GetRegister(lp)) {
  1872.                                         case Z80_B: case Z80_C: case Z80_D: case Z80_E: case Z80_H: case Z80_L: case Z80_A:
  1873.                                                 e[0] = 0xed; e[1] = 0x41 + 8 * reg; break;
  1874.                                         case Z80_UNK:
  1875.                                                 if (0 == GetByteNoMem(lp)) {
  1876.                                                         // out (c),0 - warn about it as unstable
  1877.                                                         WarningById(W_OUT0);
  1878.                                                         e[0] = 0xed;
  1879.                                                 }
  1880.                                                 e[1] = 0x71; break;
  1881.                                         default:
  1882.                                                 break;
  1883.                                         }
  1884.                                 }
  1885.                         } else {
  1886.                                 e[1] = GetByte(lp);             // out ($n),a
  1887.                                 if (comma(lp) && GetRegister(lp) == Z80_A) e[0] = 0xd3;
  1888.                         }
  1889.                         EmitBytes(e, true);
  1890.                 } while (Options::syx.MultiArg(lp));
  1891.         }
  1892.  
  1893.         static void OpCode_OUTD() {
  1894.                 EmitByte(0xED, true);
  1895.                 EmitByte(0xAB);
  1896.         }
  1897.  
  1898.         static void OpCode_OUTI() {
  1899.                 EmitByte(0xED, true);
  1900.                 EmitByte(0xA3);
  1901.         }
  1902.  
  1903.         static void OpCode_Next_OUTINB() {
  1904.                 if (Options::syx.IsNextEnabled < 1) {
  1905.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  1906.                         return;
  1907.                 }
  1908.                 EmitByte(0xED, true);
  1909.                 EmitByte(0x90);
  1910.         }
  1911.  
  1912.         static void OpCode_Next_PIXELAD() {
  1913.                 if (Options::syx.IsNextEnabled < 1) {
  1914.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  1915.                         return;
  1916.                 }
  1917.                 char *oldLp = lp;
  1918.                 if (Z80_HL != GetRegister(lp)) lp = oldLp;              // "eat" explicit HL argument
  1919.                 EmitByte(0xED, true);
  1920.                 EmitByte(0x94);
  1921.         }
  1922.  
  1923.         static void OpCode_Next_PIXELDN() {
  1924.                 if (Options::syx.IsNextEnabled < 1) {
  1925.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  1926.                         return;
  1927.                 }
  1928.                 char *oldLp = lp;
  1929.                 if (Z80_HL != GetRegister(lp)) lp = oldLp;              // "eat" explicit HL argument
  1930.                 EmitByte(0xED, true);
  1931.                 EmitByte(0x93);
  1932.         }
  1933.  
  1934.         static void OpCode_POPone(const Z80Reg r16) {
  1935.                 int e[] { -1, -1, -1 };
  1936.                 switch (r16) {
  1937.                 case Z80_AF:
  1938.                         e[0] = 0xf1; break;
  1939.                 case Z80_BC:
  1940.                         e[0] = 0xc1; break;
  1941.                 case Z80_DE:
  1942.                         e[0] = 0xd1; break;
  1943.                 case Z80_HL:
  1944.                         e[0] = 0xe1; break;
  1945.                 case Z80_IX:
  1946.                 case Z80_IY:
  1947.                         e[0] = r16; e[1] = 0xe1; break;
  1948.                 default:
  1949.                         break;
  1950.                 }
  1951.                 EmitBytes(e, true);
  1952.         }
  1953.  
  1954.         static void OpCode_POPreverse() {
  1955.                 constexpr int MAX_POP_REGS = 30;
  1956.                 Z80Reg regs[MAX_POP_REGS];
  1957.                 int rn = 0;
  1958.                 do {
  1959.                         regs[rn++] = GetRegister(lp);
  1960.                         // GetRegister_r16Low(regs[rn-1]) works as validator for regular push/pop reg-pairs
  1961.                         if (Z80_UNK == GetRegister_r16Low(regs[rn-1]) || MAX_POP_REGS == rn) break;
  1962.                 } while (relaxedMaComma(lp));
  1963.                 // registers parsed, emit pop instructions in reversed order
  1964.                 while (0 <= --rn) {
  1965.                         OpCode_POPone(regs[rn]);
  1966.                 }
  1967.         }
  1968.  
  1969.         static void OpCode_POPnormal() {
  1970.                 do {
  1971.                         OpCode_POPone(GetRegister(lp));
  1972.                 } while (relaxedMaComma(lp));
  1973.         }
  1974.  
  1975.         static void OpCode_POP() {
  1976.                 if (Options::syx.IsReversePOP) OpCode_POPreverse();
  1977.                 else OpCode_POPnormal();
  1978.         }
  1979.  
  1980.         static void OpCode_PUSH() {
  1981.                 Z80Reg reg;
  1982.                 do {
  1983.                         int e[5];
  1984.                         e[0] = e[1] = e[2] = e[3] = e[4] = -1;
  1985.                         switch (reg = GetRegister(lp)) {
  1986.                         case Z80_AF:
  1987.                                 e[0] = 0xf5; break;
  1988.                         case Z80_BC:
  1989.                                 e[0] = 0xc5; break;
  1990.                         case Z80_DE:
  1991.                                 e[0] = 0xd5; break;
  1992.                         case Z80_HL:
  1993.                                 e[0] = 0xe5; break;
  1994.                         case Z80_IX:
  1995.                         case Z80_IY:
  1996.                                 e[0] = reg; e[1] = 0xe5; break;
  1997.                         case Z80_UNK:
  1998.                         {
  1999.                                 if(!Options::syx.IsNextEnabled) break;
  2000.                                 word imm16 = GetWordNoMem(lp);
  2001.                                 e[0] = 0xED; e[1] = 0x8A;
  2002.                                 e[2] = (imm16 >> 8);  // push opcode is big-endian!
  2003.                                 e[3] = imm16 & 255;
  2004.                                 // no support for smart-SMC (too much hassle)
  2005.                                 if (Relocation::isResultAffected) {
  2006.                                         if (Relocation::HIGH == Relocation::type) {
  2007.                                                 // push imm16 is big-endian, so the offsets for regular/high value are different and explicit
  2008.                                                 Relocation::resolveRelocationAffected(Relocation::REGULAR == Relocation::deltaType ? 1 : 3);
  2009.                                         } else {
  2010.                                                 // the `push imm16` of Z80N can't be relocated, because it's big-endian encoded
  2011.                                                 Error("PUSH imm16 is big-endian encoded and can't be part of RELOCATE_TABLE", bp);
  2012.                                                 Relocation::isResultAffected = false;
  2013.                                         }
  2014.                                 }
  2015.                         }
  2016.                         default:
  2017.                                 break;
  2018.                         }
  2019.                         EmitBytes(e, true);
  2020.                 } while (relaxedMaComma(lp));
  2021.         }
  2022.  
  2023.         static void OpCode_RES() {
  2024.                 do {
  2025.                         int e[] { -1, -1, -1, -1, -1 };
  2026.                         byte bit = GetByteNoMem(lp);
  2027.                         if (comma(lp) && bit <= 7) OpCode_CbFamily(8 * bit + 0x80, e);
  2028.                         EmitBytes(e, true);
  2029.                 } while (Options::syx.MultiArg(lp));
  2030.         }
  2031.  
  2032.         static void OpCode_RET() {
  2033.                 Z80Cond cc = getz80cond(lp);
  2034.                 if (Z80C_UNK == cc) EmitByte(0xc9, true);
  2035.                 else                            EmitByte(0xc0 + cc, true);
  2036.                 // multi-argument was intetionally removed by Ped7g (explain in issue why you want *that*?)
  2037.         }
  2038.  
  2039.         static void OpCode_RETI() {
  2040.                 EmitByte(0xED, true);
  2041.                 EmitByte(0x4D);
  2042.         }
  2043.  
  2044.         static void OpCode_RETN() {
  2045.                 EmitByte(0xED, true);
  2046.                 EmitByte(0x45);
  2047.         }
  2048.  
  2049.         static void OpCode_RL() {
  2050.                 Z80Reg reg;
  2051.                 do {
  2052.                         int e[] { -1, -1, -1, -1, -1, -1 };
  2053.                         switch (reg = OpCode_CbFamily(0x10, e)) {
  2054.                         case Z80_A:             break;                  // fully processed by the helper function
  2055.                         case Z80_BC:    case Z80_DE:    case Z80_HL:
  2056.                                 if (Options::noFakes()) break;
  2057.                                 e[2] = INSTRUCTION_START_MARKER;
  2058.                                 e[0] = e[3] = 0xcb;
  2059.                                 e[1] = 0x10 + GetRegister_r16Low(reg);
  2060.                                 e[4] = 0x10 + GetRegister_r16High(reg);
  2061.                                 break;
  2062.                         default:                break;
  2063.                         }
  2064.                         EmitBytes(e, true);
  2065.                 } while (Options::syx.MultiArg(lp));
  2066.         }
  2067.  
  2068.         static void OpCode_RLA() {
  2069.                 EmitByte(0x17, true);
  2070.         }
  2071.  
  2072.         static void OpCode_RLC() {
  2073.                 do {
  2074.                         int e[] { -1, -1, -1, -1, -1 };
  2075.                         OpCode_CbFamily(0x00, e);
  2076.                         EmitBytes(e, true);
  2077.                 } while (Options::syx.MultiArg(lp));
  2078.         }
  2079.  
  2080.         static void OpCode_RLCA() {
  2081.                 EmitByte(0x7, true);
  2082.         }
  2083.  
  2084.         static void OpCode_RLD() {
  2085.                 EmitByte(0xED, true);
  2086.                 EmitByte(0x6F);
  2087.         }
  2088.  
  2089.         static void OpCode_RR() {
  2090.                 Z80Reg reg;
  2091.                 do {
  2092.                         int e[] { -1, -1, -1, -1, -1, -1 };
  2093.                         switch (reg = OpCode_CbFamily(0x18, e)) {
  2094.                         case Z80_A:             break;                  // fully processed by the helper function
  2095.                         case Z80_BC:    case Z80_DE:    case Z80_HL:
  2096.                                 if (Options::noFakes()) break;
  2097.                                 e[2] = INSTRUCTION_START_MARKER;
  2098.                                 e[0] = e[3] = 0xcb;
  2099.                                 e[1] = 0x18 + GetRegister_r16High(reg);
  2100.                                 e[4] = 0x18 + GetRegister_r16Low(reg);
  2101.                                 break;
  2102.                         default:                break;
  2103.                         }
  2104.                         EmitBytes(e, true);
  2105.                 } while (Options::syx.MultiArg(lp));
  2106.         }
  2107.  
  2108.         static void OpCode_RRA() {
  2109.                 EmitByte(0x1f, true);
  2110.         }
  2111.  
  2112.         static void OpCode_RRC() {
  2113.                 do {
  2114.                         int e[] { -1, -1, -1, -1, -1 };
  2115.                         OpCode_CbFamily(0x08, e);
  2116.                         EmitBytes(e, true);
  2117.                 } while (Options::syx.MultiArg(lp));
  2118.         }
  2119.  
  2120.         static void OpCode_RRCA() {
  2121.                 EmitByte(0xf, true);
  2122.         }
  2123.  
  2124.         static void OpCode_RRD() {
  2125.                 EmitByte(0xED, true);
  2126.                 EmitByte(0x67);
  2127.         }
  2128.  
  2129.         static void OpCode_RST() {
  2130.                 do {
  2131.                         byte e = GetByteNoMem(lp);
  2132.                         if (e&(~0x38)) {        // some bit is set which should be not
  2133.                                 Error("[RST] Illegal operand", line); SkipToEol(lp);
  2134.                                 return;
  2135.                         } else {                        // e == { $00, $08, $10, $18, $20, $28, $30, $38 }
  2136.                                 EmitByte(0xC7 + e, true);
  2137.                         }
  2138.                 } while (Options::syx.MultiArg(lp));
  2139.         }
  2140.  
  2141.         static void OpCode_SBC() {
  2142.                 const bool nonZ80CPU = Options::IsI8080 || Options::IsLR35902;
  2143.                 Z80Reg reg, reg2;
  2144.                 int reg2ex;
  2145.                 do {
  2146.                         int e[] { -1, -1, -1, -1, -1, -1, -1 };
  2147.                         if (!CommonAluOpcode(0x98, e, true, false)) {   // handle common 8-bit variants
  2148.                                 reg = GetRegister(lp);  if (Z80_UNK == reg) break;
  2149.                                 if (!comma(lp)) {
  2150.                                         Error("[SBC] Comma expected");
  2151.                                         break;
  2152.                                 }
  2153.                                 reg2 = GetRegister(lp);
  2154.                                 if (Z80_HL == reg && !nonZ80CPU) {
  2155.                                         switch (reg2) {
  2156.                                         case Z80_BC:    case Z80_DE:    case Z80_HL:    case Z80_SP:
  2157.                                                 e[0] = 0xed; e[1] = 0x32 + reg2; break;
  2158.                                         default: break;
  2159.                                         }
  2160.                                 } else if (Z80_DE == reg) {             // fake sbc de,bc|de|hl|sp
  2161.                                         switch (reg2) {
  2162.                                         case Z80_BC:    case Z80_DE:    case Z80_HL:    case Z80_SP:
  2163.                                                 if (Options::noFakes()) break;
  2164.                                                 reg2ex = (Z80_DE == reg2 || Z80_HL == reg2) ? (reg2^0x10) : reg2;
  2165.                                                 e[0] = 0xEB;
  2166.                                                 e[1] = INSTRUCTION_START_MARKER; e[2] = 0xED; e[3] = 0x32 + reg2ex;
  2167.                                                 e[4] = INSTRUCTION_START_MARKER; e[5] = 0xEB;
  2168.                                                 break;
  2169.                                         default: break;
  2170.                                         }
  2171.                                 }
  2172.                         }
  2173.                         EmitBytes(e, true);
  2174.                 } while (Options::syx.MultiArg(lp));
  2175.         }
  2176.  
  2177.         static void OpCode_SCF() {
  2178.                 EmitByte(0x37, true);
  2179.         }
  2180.  
  2181.         static void OpCode_SET() {
  2182.                 do {
  2183.                         int e[] { -1, -1, -1, -1, -1 };
  2184.                         byte bit = GetByteNoMem(lp);
  2185.                         if (comma(lp) && bit <= 7) OpCode_CbFamily(8 * bit + 0xc0, e);
  2186.                         EmitBytes(e, true);
  2187.                 } while (Options::syx.MultiArg(lp));
  2188.         }
  2189.  
  2190.         static void OpCode_Next_SETAE() {
  2191.                 if (Options::syx.IsNextEnabled < 1) {
  2192.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  2193.                         return;
  2194.                 }
  2195.                 EmitByte(0xED, true);
  2196.                 EmitByte(0x95);
  2197.         }
  2198.  
  2199.         static void OpCode_SLA() {
  2200.                 Z80Reg reg;
  2201.                 do {
  2202.                         int e[] { -1, -1, -1, -1, -1, -1 };
  2203.                         switch (reg = OpCode_CbFamily(0x20, e)) {
  2204.                         case Z80_A:             break;                  // fully processed by the helper function
  2205.                         case Z80_HL:
  2206.                                 if (Options::noFakes()) break;
  2207.                                 e[0] = 0x29; break;
  2208.                         case Z80_BC:    case Z80_DE:
  2209.                                 if (Options::noFakes()) break;
  2210.                                 e[2] = INSTRUCTION_START_MARKER;
  2211.                                 e[0] = e[3] = 0xcb;
  2212.                                 e[1] = 0x20 + GetRegister_r16Low(reg);
  2213.                                 e[4] = 0x10 + GetRegister_r16High(reg);
  2214.                                 break;
  2215.                         default:                break;
  2216.                         }
  2217.                         EmitBytes(e, true);
  2218.                 } while (Options::syx.MultiArg(lp));
  2219.         }
  2220.  
  2221.         static void OpCode_SLL() {
  2222.                 Z80Reg reg;
  2223.                 do {
  2224.                         int e[] { -1, -1, -1, -1, -1, -1 };
  2225.                         switch (reg = OpCode_CbFamily(0x30, e)) {
  2226.                         case Z80_A:             break;                  // fully processed by the helper function
  2227.                         case Z80_BC:    case Z80_DE:    case Z80_HL:
  2228.                                 if (Options::noFakes()) break;
  2229.                                 e[2] = INSTRUCTION_START_MARKER;
  2230.                                 e[0] = e[3] = 0xcb;
  2231.                                 e[1] = 0x30 + GetRegister_r16Low(reg);
  2232.                                 e[4] = 0x10 + GetRegister_r16High(reg);
  2233.                                 break;
  2234.                         default:                break;
  2235.                         }
  2236.                         EmitBytes(e, true);
  2237.                 } while (Options::syx.MultiArg(lp));
  2238.         }
  2239.  
  2240.         static void OpCode_SRA() {
  2241.                 Z80Reg reg;
  2242.                 do {
  2243.                         int e[] { -1, -1, -1, -1, -1, -1 };
  2244.                         switch (reg = OpCode_CbFamily(0x28, e)) {
  2245.                         case Z80_A:             break;                  // fully processed by the helper function
  2246.                         case Z80_BC:    case Z80_DE:    case Z80_HL:
  2247.                                 if (Options::noFakes()) break;
  2248.                                 e[2] = INSTRUCTION_START_MARKER;
  2249.                                 e[0] = e[3] = 0xcb;
  2250.                                 e[1] = 0x28 + GetRegister_r16High(reg);
  2251.                                 e[4] = 0x18 + GetRegister_r16Low(reg);
  2252.                                 break;
  2253.                         default:                break;
  2254.                         }
  2255.                         EmitBytes(e, true);
  2256.                 } while (Options::syx.MultiArg(lp));
  2257.         }
  2258.  
  2259.         static void OpCode_SRL() {
  2260.                 Z80Reg reg;
  2261.                 do {
  2262.                         int e[] { -1, -1, -1, -1, -1, -1 };
  2263.                         switch (reg = OpCode_CbFamily(0x38, e)) {
  2264.                         case Z80_A:             break;                  // fully processed by the helper function
  2265.                         case Z80_BC:    case Z80_DE:    case Z80_HL:
  2266.                                 if (Options::noFakes()) break;
  2267.                                 e[2] = INSTRUCTION_START_MARKER;
  2268.                                 e[0] = e[3] = 0xcb;
  2269.                                 e[1] = 0x38 + GetRegister_r16High(reg);
  2270.                                 e[4] = 0x18 + GetRegister_r16Low(reg);
  2271.                                 break;
  2272.                         default:                break;
  2273.                         }
  2274.                         EmitBytes(e, true);
  2275.                 } while (Options::syx.MultiArg(lp));
  2276.         }
  2277.  
  2278.         static void OpCode_LR35902_STOP() {     // syntax: STOP [byte_value = 0] = opcode "10 byte_value"
  2279.                 EmitByte(0x10, true);
  2280.                 if (SkipBlanks(lp)) {           // is optional byte provided? (if not, default value is zero)
  2281.                         EmitByte(0x00);
  2282.                 } else {
  2283.                         EmitByte(GetByteNoMem(lp));
  2284.                 }
  2285.         }
  2286.  
  2287.         static void OpCode_SUB() {
  2288.                 Z80Reg reg, reg2;
  2289.                 int reg2ex;
  2290.                 do {
  2291.                         int e[] { -1, -1, -1, -1, -1, -1, -1, -1, -1 };
  2292.                         if (!CommonAluOpcode(0x90, e, true, true)) {    // handle common 8-bit variants
  2293.                                 reg = GetRegister(lp);  if (Z80_UNK == reg) break;
  2294.                                 if (!comma(lp)) {
  2295.                                         Error("[SUB] Comma expected");
  2296.                                         break;
  2297.                                 }
  2298.                                 reg2 = GetRegister(lp);
  2299.                                 if (Z80_HL == reg) {                    // fake sub hl,bc|de|hl|sp
  2300.                                         switch (reg2) {
  2301.                                         case Z80_BC:    case Z80_DE:    case Z80_HL:    case Z80_SP:
  2302.                                                 if (Options::noFakes()) break;
  2303.                                                 e[0] = 0xB7;
  2304.                                                 e[1] = INSTRUCTION_START_MARKER; e[2] = 0xed; e[3] = 0x32 + reg2;
  2305.                                                 break;
  2306.                                         default: break;
  2307.                                         }
  2308.                                 } else if (Z80_DE == reg) {             // fake sub de,bc|de|hl|sp
  2309.                                         switch (reg2) {
  2310.                                         case Z80_BC:    case Z80_DE:    case Z80_HL:    case Z80_SP:
  2311.                                                 if (Options::noFakes()) break;
  2312.                                                 reg2ex = (Z80_DE == reg2 || Z80_HL == reg2) ? (reg2^0x10) : reg2;
  2313.                                                 e[0] = 0xB7;
  2314.                                                 e[1] = INSTRUCTION_START_MARKER; e[2] = 0xEB;
  2315.                                                 e[3] = INSTRUCTION_START_MARKER; e[4] = 0xED; e[5] = 0x32 + reg2ex;
  2316.                                                 e[6] = INSTRUCTION_START_MARKER; e[7] = 0xEB;
  2317.                                                 break;
  2318.                                         default: break;
  2319.                                         }
  2320.                                 }
  2321.                         }
  2322.                         EmitBytes(e, true);
  2323.                 } while (Options::syx.MultiArg(lp));
  2324.         }
  2325.  
  2326.         //Swaps the high and low nibbles of the accumulator.
  2327.         static void OpCode_Next_SWAPNIB() {
  2328.                 if (Options::syx.IsNextEnabled < 1) {
  2329.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  2330.                         return;
  2331.                 }
  2332.                 Z80Reg reg = GetRegister(lp);
  2333.                 if (Z80_UNK != reg && Z80_A != reg) {
  2334.                         Error("[SWAPNIB] Illegal operand (can be only register A)", line);
  2335.                         return;
  2336.                 }
  2337.                 EmitByte(0xED, true);
  2338.                 EmitByte(0x23);
  2339.         }
  2340.  
  2341.         static void OpCode_Next_TEST() {
  2342.                 if (Options::syx.IsNextEnabled < 1) {
  2343.                         Error("Z80N instructions are currently disabled", bp, SUPPRESS);
  2344.                         return;
  2345.                 }
  2346.                 int e[] { 0xED, 0x27, GetByteNoMem(lp), -1 };
  2347.                 resolveRelocationAndSmartSmc(2, Relocation::HIGH);
  2348.                 EmitBytes(e, true);
  2349.         }
  2350.  
  2351.         static void OpCode_XOR() {
  2352.                 OpCode_SimpleAlu(0xa8);
  2353.         }
  2354.  
  2355.         void Init() {
  2356.                 // Z80, i8080 and LR35902 shared instructions first
  2357.                 OpCodeTable.Insert("adc", OpCode_ADC);
  2358.                 OpCodeTable.Insert("add", OpCode_ADD);
  2359.                 OpCodeTable.Insert("and", OpCode_AND);
  2360.                 OpCodeTable.Insert("call", OpCode_CALL);
  2361.                 OpCodeTable.Insert("ccf", OpCode_CCF);
  2362.                 OpCodeTable.Insert("cp", OpCode_CP);
  2363.                 OpCodeTable.Insert("cpl", OpCode_CPL);
  2364.                 OpCodeTable.Insert("daa", OpCode_DAA);
  2365.                 OpCodeTable.Insert("dec", OpCode_DEC);
  2366.                 OpCodeTable.Insert("di", OpCode_DI);
  2367.                 OpCodeTable.Insert("ei", OpCode_EI);
  2368.                 if (!Options::IsLR35902) OpCodeTable.Insert("ex", OpCode_EX);
  2369.                 OpCodeTable.Insert("exd", OpCode_EXD);
  2370.                 OpCodeTable.Insert("halt", OpCode_HALT);
  2371.                 if (!Options::IsLR35902) OpCodeTable.Insert("in", OpCode_IN);
  2372.                 OpCodeTable.Insert("inc", OpCode_INC);
  2373.                 OpCodeTable.Insert("jp", OpCode_JP);
  2374.                 OpCodeTable.Insert("ld", OpCode_LD);
  2375.                 OpCodeTable.Insert("nop", OpCode_NOP);
  2376.                 OpCodeTable.Insert("or", OpCode_OR);
  2377.                 if (!Options::IsLR35902) OpCodeTable.Insert("out", OpCode_OUT);
  2378.                 OpCodeTable.Insert("pop", OpCode_POP);
  2379.                 OpCodeTable.Insert("push", OpCode_PUSH);
  2380.                 OpCodeTable.Insert("ret", OpCode_RET);
  2381.                 OpCodeTable.Insert("rla", OpCode_RLA);
  2382.                 OpCodeTable.Insert("rlca", OpCode_RLCA);
  2383.                 OpCodeTable.Insert("rra", OpCode_RRA);
  2384.                 OpCodeTable.Insert("rrca", OpCode_RRCA);
  2385.                 OpCodeTable.Insert("rst", OpCode_RST);
  2386.                 OpCodeTable.Insert("sbc", OpCode_SBC);
  2387.                 OpCodeTable.Insert("scf", OpCode_SCF);
  2388.                 OpCodeTable.Insert("sub", OpCode_SUB);
  2389.                 OpCodeTable.Insert("xor", OpCode_XOR);
  2390.  
  2391.                 if (Options::IsI8080) return;   // all i8080 instructions defined
  2392.  
  2393.                 // Z80 and LR35902 shared instructions
  2394.                 OpCodeTable.Insert("bit", OpCode_BIT);
  2395.                 OpCodeTable.Insert("jr", OpCode_JR);
  2396.                 OpCodeTable.Insert("res", OpCode_RES);
  2397.                 OpCodeTable.Insert("rl", OpCode_RL);
  2398.                 OpCodeTable.Insert("rlc", OpCode_RLC);
  2399.                 OpCodeTable.Insert("rr", OpCode_RR);
  2400.                 OpCodeTable.Insert("rrc", OpCode_RRC);
  2401.                 OpCodeTable.Insert("set", OpCode_SET);
  2402.                 OpCodeTable.Insert("sla", OpCode_SLA);
  2403.                 OpCodeTable.Insert("sra", OpCode_SRA);
  2404.                 OpCodeTable.Insert("srl", OpCode_SRL);
  2405.  
  2406.                 if (Options::IsLR35902) {
  2407.                         //INIT LR35902 extras
  2408.                         OpCodeTable.Insert("ldd", OpCode_LR35902_LDD);
  2409.                         OpCodeTable.Insert("ldh", OpCode_LR35902_LDH);
  2410.                         OpCodeTable.Insert("ldi", OpCode_LR35902_LDI);
  2411.                         OpCodeTable.Insert("reti", OpCode_EXX);         // RETI has same opcode as EXX on Z80
  2412.                         OpCodeTable.Insert("stop", OpCode_LR35902_STOP);
  2413.                         OpCodeTable.Insert("swap", OpCode_SLL);         // SWAP has same opcodes as SLI on Z80
  2414.                         return;                                         // all LR35902 instructions defined
  2415.                 }
  2416.  
  2417.                 // Z80 instructions
  2418.                 OpCodeTable.Insert("cpd", OpCode_CPD);
  2419.                 OpCodeTable.Insert("cpdr", OpCode_CPDR);
  2420.                 OpCodeTable.Insert("cpi", OpCode_CPI);
  2421.                 OpCodeTable.Insert("cpir", OpCode_CPIR);
  2422.                 OpCodeTable.Insert("djnz", OpCode_DJNZ);
  2423.                 OpCodeTable.Insert("exa", OpCode_EXA);
  2424.                 OpCodeTable.Insert("exx", OpCode_EXX);
  2425.                 OpCodeTable.Insert("im", OpCode_IM);
  2426.                 OpCodeTable.Insert("ind", OpCode_IND);
  2427.                 OpCodeTable.Insert("indr", OpCode_INDR);
  2428.                 OpCodeTable.Insert("inf", OpCode_INF); // thanks to BREEZE
  2429.                 OpCodeTable.Insert("ini", OpCode_INI);
  2430.                 OpCodeTable.Insert("inir", OpCode_INIR);
  2431.                 OpCodeTable.Insert("ldd", OpCode_LDD);
  2432.                 OpCodeTable.Insert("lddr", OpCode_LDDR);
  2433.                 OpCodeTable.Insert("ldi", OpCode_LDI);
  2434.                 OpCodeTable.Insert("ldir", OpCode_LDIR);
  2435.                 OpCodeTable.Insert("mulub", OpCode_MULUB);
  2436.                 OpCodeTable.Insert("muluw", OpCode_MULUW);
  2437.                 OpCodeTable.Insert("neg", OpCode_NEG);
  2438.                 OpCodeTable.Insert("otdr", OpCode_OTDR);
  2439.                 OpCodeTable.Insert("otir", OpCode_OTIR);
  2440.                 OpCodeTable.Insert("outd", OpCode_OUTD);
  2441.                 OpCodeTable.Insert("outi", OpCode_OUTI);
  2442.                 OpCodeTable.Insert("reti", OpCode_RETI);
  2443.                 OpCodeTable.Insert("retn", OpCode_RETN);
  2444.                 OpCodeTable.Insert("rld", OpCode_RLD);
  2445.                 OpCodeTable.Insert("rrd", OpCode_RRD);
  2446.                 OpCodeTable.Insert("sli", OpCode_SLL);
  2447.                 OpCodeTable.Insert("sll", OpCode_SLL);
  2448.  
  2449.                 InitNextExtensions();
  2450.         }
  2451.  
  2452.         void InitNextExtensions() {
  2453.                 static bool nextWasInitialized = false;
  2454.                 if (!Options::syx.IsNextEnabled || nextWasInitialized) return;
  2455.                 nextWasInitialized = true;
  2456.                 // Next extended opcodes
  2457.                 OpCodeTable.Insert("brlc",              OpCode_Next_BRLC);
  2458.                 OpCodeTable.Insert("bsla",              OpCode_Next_BSLA);
  2459.                 OpCodeTable.Insert("bsra",              OpCode_Next_BSRA);
  2460.                 OpCodeTable.Insert("bsrf",              OpCode_Next_BSRF);
  2461.                 OpCodeTable.Insert("bsrl",              OpCode_Next_BSRL);
  2462.                 OpCodeTable.Insert("lddrx",             OpCode_Next_LDDRX);
  2463.                 OpCodeTable.Insert("lddx",              OpCode_Next_LDDX);
  2464.                 //OpCodeTable.Insert("ldirscale",       OpCode_Next_LDIRSCALE);
  2465.                 OpCodeTable.Insert("ldirx",             OpCode_Next_LDIRX);
  2466.                 OpCodeTable.Insert("ldix",              OpCode_Next_LDIX);
  2467.                 OpCodeTable.Insert("ldpirx",    OpCode_Next_LDPIRX);
  2468.                 OpCodeTable.Insert("ldws",              OpCode_Next_LDWS);
  2469.                 OpCodeTable.Insert("mirror",    OpCode_Next_MIRROR);
  2470.                 OpCodeTable.Insert("mul",               OpCode_Next_MUL);
  2471.                 OpCodeTable.Insert("nextreg",   OpCode_Next_NEXTREG);
  2472.                 OpCodeTable.Insert("outinb",    OpCode_Next_OUTINB);
  2473.                 OpCodeTable.Insert("pixelad",   OpCode_Next_PIXELAD);
  2474.                 OpCodeTable.Insert("pixeldn",   OpCode_Next_PIXELDN);
  2475.                 OpCodeTable.Insert("setae",             OpCode_Next_SETAE);
  2476.                 OpCodeTable.Insert("swapnib",   OpCode_Next_SWAPNIB);
  2477.                 OpCodeTable.Insert("test",              OpCode_Next_TEST);
  2478.                 // CSpect emulator extensions, fake instructions "exit" and "break"
  2479.                 OpCodeTable.Insert("exit",              OpCode_Next_EXIT);
  2480.                 OpCodeTable.Insert("break",             OpCode_Next_BREAK);
  2481.         }
  2482. } // eof namespace Z80
  2483.  
  2484.  
  2485. void InitCPU() {
  2486.         Z80::Init();
  2487.         InsertDirectives();
  2488. }
  2489. //eof z80.cpp
  2490.