Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. /* code85.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator 8080/8085                                                   */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "nls.h"
  16. #include "bpemu.h"
  17. #include "strutil.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmallg.h"
  22. #include "codepseudo.h"
  23. #include "intpseudo.h"
  24. #include "asmitree.h"
  25. #include "codevars.h"
  26. #include "errmsg.h"
  27.  
  28. #include "code85.h"
  29.  
  30. /*--------------------------------------------------------------------------------------------------*/
  31.  
  32. typedef enum
  33. {
  34.   ModNone = 0xff,
  35.   ModReg8 = 0,
  36.   ModReg16 = 1,
  37.   ModIReg16 = 2,
  38.   ModAbs = 3,
  39.   ModImm = 4,
  40.   ModIM = 5
  41. } tAdrMode;
  42.  
  43. #define MModReg8 (1 << ModReg8)
  44. #define MModReg16 (1 << ModReg16)
  45. #define MModIReg16 (1 << ModIReg16)
  46. #define MModAbs (1 << ModAbs)
  47. #define MModImm (1 << ModImm)
  48. #define MModIM (1 << ModIM)
  49.  
  50. static CPUVar CPU8080, CPUV30EMU, CPU8085, CPU8085U;
  51. static tAdrMode AdrMode;
  52. static Byte AdrVals[2], OpSize;
  53.  
  54. /*---------------------------------------------------------------------------*/
  55.  
  56. static const Byte AccReg = 7;
  57.  
  58. static Boolean DecodeReg8(const char *Asc, tZ80Syntax Syntax, Byte *Erg)
  59. {
  60.   static const char RegNames[] = "BCDEHLMA";
  61.   const char *p;
  62.  
  63.   if (strlen(Asc) != 1) return False;
  64.   else
  65.   {
  66.     p = strchr(RegNames, as_toupper(*Asc));
  67.     if (!p) return False;
  68.     else
  69.     {
  70.       *Erg = p - RegNames;
  71.       if ((!(Syntax & eSyntax808x)) && (*Erg == 6))
  72.         return False;
  73.       return True;
  74.     }
  75.   }
  76. }
  77.  
  78. static const Byte BCReg = 0;
  79. static const Byte DEReg = 1;
  80. static const Byte HLReg = 2;
  81. static const Byte SPReg = 3;
  82.  
  83. static Boolean DecodeReg16(char *pAsc, tZ80Syntax Syntax, Byte *pResult)
  84. {
  85.   static const char RegNames[8][3] = { "B", "D", "H", "SP", "BC", "DE", "HL", "SP" };
  86.  
  87.   for (*pResult = (Syntax & eSyntax808x) ? 0 : 4;
  88.        *pResult < ((Syntax & eSyntaxZ80) ? 8 : 4);
  89.        (*pResult)++)
  90.     if (!as_strcasecmp(pAsc, RegNames[*pResult]))
  91.     {
  92.       *pResult &= 3;
  93.       break;
  94.     }
  95.  
  96.   return ((*pResult) < 4);
  97. }
  98.  
  99. static const char Conditions[][4] =
  100. {
  101.   "NZ", "Z", "NC", "C", "PO", "PE", "P", "M", "NX5", "X5"
  102. };
  103.  
  104. static Boolean DecodeCondition(const char *pAsc, Byte *pResult, Boolean WithX5)
  105. {
  106.   int ConditionCnt = sizeof(Conditions) / sizeof(*Conditions);
  107.  
  108.   if (!WithX5 || (MomCPU!= CPU8085U))
  109.     ConditionCnt -= 2;
  110.   for (*pResult = 0; *pResult < ConditionCnt; (*pResult)++)
  111.     if (!as_strcasecmp(pAsc, Conditions[*pResult]))
  112.     {
  113.       *pResult = (*pResult < 8) ? (*pResult << 3) : (0x1b + ((*pResult & 1) << 5));
  114.       return True;
  115.     }
  116.   return False;
  117. }
  118.  
  119. static void DecodeAdr_Z80(tStrComp *pArg, Word Mask)
  120. {
  121.   Boolean OK;
  122.   int ArgLen = strlen(pArg->str.p_str);
  123.  
  124.   AdrMode = ModNone; AdrCnt = 0;
  125.  
  126.   if (DecodeReg8(pArg->str.p_str, eSyntaxZ80, &AdrVals[0]))
  127.   {
  128.     AdrMode = ModReg8;
  129.     goto AdrFound;
  130.   }
  131.  
  132.   if ((Mask & MModIM) && !as_strcasecmp(pArg->str.p_str, "IM"))
  133.   {
  134.     AdrMode = ModIM;
  135.     goto AdrFound;
  136.   }
  137.  
  138.   if ((ArgLen == 2) && DecodeReg16(pArg->str.p_str, eSyntaxZ80, &AdrVals[0]))
  139.   {
  140.     AdrMode = ModReg16;
  141.     OpSize = 1;
  142.     goto AdrFound;
  143.   }
  144.  
  145.   if (IsIndirect(pArg->str.p_str))
  146.   {
  147.     tStrComp IArg;
  148.  
  149.     StrCompRefRight(&IArg, pArg, 1);
  150.     StrCompShorten(&IArg, 1);
  151.  
  152.     if (DecodeReg16(IArg.str.p_str, eSyntaxZ80, &AdrVals[0]))
  153.     {
  154.       AdrMode = ModIReg16;
  155.       goto AdrFound;
  156.     }
  157.     else
  158.     {
  159.       Word Addr = EvalStrIntExpression(&IArg, UInt16, &OK);
  160.  
  161.       if (OK)
  162.       {
  163.         AdrVals[0] = Lo(Addr);
  164.         AdrVals[1] = Hi(Addr);
  165.         AdrMode = ModAbs;
  166.       }
  167.     }
  168.   }
  169.   else if (OpSize)
  170.   {
  171.     Word Val = EvalStrIntExpression(pArg, Int16, &OK);
  172.  
  173.     if (OK)
  174.     {
  175.       AdrVals[0] = Lo(Val);
  176.       AdrVals[1] = Hi(Val);
  177.       AdrMode = ModImm;
  178.     }
  179.   }
  180.   else
  181.   {
  182.     AdrVals[0] = EvalStrIntExpression(pArg, Int8, &OK);
  183.     if (OK)
  184.       AdrMode = ModImm;
  185.   }
  186.  
  187. AdrFound:
  188.  
  189.   if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
  190.   {
  191.     WrError(ErrNum_InvAddrMode);
  192.     AdrMode = ModNone; AdrCnt = 0;
  193.   }
  194. }
  195.  
  196. /*---------------------------------------------------------------------------*/
  197.  
  198. /* Anweisungen ohne Operanden */
  199.  
  200. static void DecodeFixed(Word Code)
  201. {
  202.   if (ChkArgCnt(0, 0)
  203.    && ChkZ80Syntax((tZ80Syntax)Hi(Code)))
  204.   {
  205.     CodeLen = 1;
  206.     BAsmCode[0] = Lo(Code);
  207.   }
  208. }
  209.  
  210. /* ein 16-Bit-Operand */
  211.  
  212. static void DecodeOp16(Word Code)
  213. {
  214.   if (ChkArgCnt(1, 1)
  215.    && ChkZ80Syntax((tZ80Syntax)Hi(Code)))
  216.   {
  217.     tEvalResult EvalResult;
  218.     Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], Int16, &EvalResult);
  219.  
  220.     if (EvalResult.OK)
  221.     {
  222.       CodeLen = 3;
  223.       BAsmCode[0] = Lo(Code);
  224.       BAsmCode[1] = Lo(AdrWord);
  225.       BAsmCode[2] = Hi(AdrWord);
  226.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  227.     }
  228.   }
  229. }
  230.  
  231. static void DecodeOp8(Word Code)
  232. {
  233.   Boolean OK;
  234.   Byte AdrByte;
  235.  
  236.   if (ChkArgCnt(1, 1)
  237.    && ChkZ80Syntax((tZ80Syntax)Hi(Code)))
  238.   {
  239.     AdrByte = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
  240.     if (OK)
  241.     {
  242.       CodeLen = 2;
  243.       BAsmCode[0] = Lo(Code);
  244.       BAsmCode[1] = AdrByte;
  245.     }
  246.   }
  247. }
  248.  
  249. static void DecodeALU(Word Code)
  250. {
  251.   Byte Reg;
  252.  
  253.   if (!ChkArgCnt(1, 1));
  254.   else if (!ChkZ80Syntax((tZ80Syntax)Hi(Code)));
  255.   else if (!DecodeReg8(ArgStr[1].str.p_str, (tZ80Syntax)Hi(Code), &Reg)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  256.   else
  257.   {
  258.     CodeLen = 1;
  259.     BAsmCode[0] = Code + Reg;
  260.   }
  261. }
  262.  
  263. static void DecodeMOV(Word Index)
  264. {
  265.   Byte Dest;
  266.  
  267.   UNUSED(Index);
  268.  
  269.   if (!ChkArgCnt(2,  2));
  270.   else if (!ChkZ80Syntax(eSyntax808x));
  271.   else if (!DecodeReg8(ArgStr[1].str.p_str, eSyntax808x, &Dest)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  272.   else if (!DecodeReg8(ArgStr[2].str.p_str, eSyntax808x, BAsmCode + 0)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
  273.   else
  274.   {
  275.     BAsmCode[0] += 0x40 + (Dest << 3);
  276.     if (BAsmCode[0] == 0x76)
  277.       WrError(ErrNum_InvRegPair);
  278.     else
  279.       CodeLen = 1;
  280.   }
  281. }
  282.  
  283. static void DecodeMVI(Word Index)
  284. {
  285.   Boolean OK;
  286.   Byte Reg;
  287.  
  288.   UNUSED(Index);
  289.  
  290.   if (ChkArgCnt(2, 2)
  291.    && ChkZ80Syntax(eSyntax808x))
  292.   {
  293.     BAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  294.     if (OK)
  295.     {
  296.       if (!DecodeReg8(ArgStr[1].str.p_str, eSyntax808x, &Reg)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  297.       else
  298.       {
  299.         BAsmCode[0] = 0x06 + (Reg << 3);
  300.         CodeLen = 2;
  301.       }
  302.     }
  303.   }
  304. }
  305.  
  306. static void DecodeLXI(Word Index)
  307. {
  308.   Boolean OK;
  309.   Word AdrWord;
  310.   Byte Reg;
  311.  
  312.   UNUSED(Index);
  313.  
  314.   if (ChkArgCnt(2, 2)
  315.    && ChkZ80Syntax(eSyntax808x))
  316.   {
  317.     AdrWord = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
  318.     if (OK)
  319.     {
  320.       if (!DecodeReg16(ArgStr[1].str.p_str, CurrZ80Syntax, &Reg)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  321.       else
  322.       {
  323.         BAsmCode[0] = 0x01 + (Reg << 4);
  324.         BAsmCode[1] = Lo(AdrWord);
  325.         BAsmCode[2] = Hi(AdrWord);
  326.         CodeLen = 3;
  327.       }
  328.     }
  329.   }
  330. }
  331.  
  332. static void DecodeLDAX_STAX(Word Index)
  333. {
  334.   Byte Reg;
  335.  
  336.   if (!ChkArgCnt(1, 1));
  337.   else if (!ChkZ80Syntax(eSyntax808x));
  338.   else if (!DecodeReg16(ArgStr[1].str.p_str, CurrZ80Syntax, &Reg)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  339.   else
  340.   {
  341.     switch (Reg)
  342.     {
  343.       case 3:                             /* SP */
  344.         WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  345.         break;
  346.       case 2:                             /* H --> MOV A,M oder M,A */
  347.         CodeLen = 1;
  348.         BAsmCode[0] = 0x77 + (Index * 7);
  349.         break;
  350.       default:
  351.         CodeLen = 1;
  352.         BAsmCode[0] = 0x02 + (Reg << 4) + (Index << 3);
  353.         break;
  354.     }
  355.   }
  356. }
  357.  
  358. static void DecodePUSH_POP(Word Index)
  359. {
  360.   Byte Reg = 0;
  361.   Boolean OK = False;
  362.  
  363.   if (ChkArgCnt(1, 1))
  364.   {
  365.     if (!as_strcasecmp(ArgStr[1].str.p_str, "PSW"))
  366.     {
  367.       if (ChkZ80Syntax(eSyntax808x))
  368.       {
  369.         Reg = 3;
  370.         OK = True;
  371.       }
  372.     }
  373.     else if (!as_strcasecmp(ArgStr[1].str.p_str, "AF"))
  374.     {
  375.       if (ChkZ80Syntax(eSyntaxZ80))
  376.       {
  377.         Reg = 3;
  378.         OK = True;
  379.       }
  380.     }
  381.     else if (DecodeReg16(ArgStr[1].str.p_str, CurrZ80Syntax, &Reg))
  382.       OK = (Reg != 3);
  383.     else
  384.       OK = False;
  385.     if (!OK) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  386.     else
  387.     {
  388.       CodeLen = 1;
  389.       BAsmCode[0] = 0xc1 + (Reg << 4) + Index;
  390.     }
  391.   }
  392. }
  393.  
  394. static void DecodeRST(Word Index)
  395. {
  396.   Byte AdrByte;
  397.   Boolean OK;
  398.  
  399.   UNUSED(Index);
  400.  
  401.   if (!ChkArgCnt(1, 1));
  402.   else if ((MomCPU >= CPU8085U) && (!as_strcasecmp(ArgStr[1].str.p_str, "V")))
  403.   {
  404.     if (ChkZ80Syntax(eSyntaxZ80))
  405.     {
  406.       CodeLen = 1;
  407.       BAsmCode[0] = 0xcb;
  408.     }
  409.   }
  410.   else
  411.   {
  412.     tSymbolFlags Flags;
  413.  
  414.     AdrByte = EvalStrIntExpressionWithFlags(&ArgStr[1], (CurrZ80Syntax & eSyntaxZ80) ? UInt6 : UInt3, &OK, &Flags);
  415.     if (mFirstPassUnknown(Flags))
  416.       AdrByte = 0;
  417.     if (OK)
  418.     {
  419.       tZ80Syntax Syntax = (CurrZ80Syntax == eSyntaxBoth) ? ((AdrByte < 8) ? eSyntax808x : eSyntaxZ80): CurrZ80Syntax;
  420.  
  421.       if (Syntax == eSyntax808x)
  422.         BAsmCode[CodeLen++] = 0xc7 + (AdrByte << 3);
  423.       else if (AdrByte & 7)
  424.         WrStrErrorPos(ErrNum_NotAligned, &ArgStr[1]);
  425.       else
  426.         BAsmCode[CodeLen++] = 0xc7 + (AdrByte & 0x38);
  427.     }
  428.   }
  429. }
  430.  
  431. static void DecodeINR_DCR(Word Index)
  432. {
  433.   Byte Reg;
  434.  
  435.   if (!ChkArgCnt(1, 1));
  436.   else if (!ChkZ80Syntax(eSyntax808x));
  437.   else if (!DecodeReg8(ArgStr[1].str.p_str, eSyntax808x, &Reg)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  438.   else
  439.   {
  440.     CodeLen = 1;
  441.     BAsmCode[0] = 0x04 + (Reg << 3) + Index;
  442.   }
  443. }
  444.  
  445. static void DecodeINX_DCX(Word Index)
  446. {
  447.   Byte Reg;
  448.  
  449.   if (!ChkArgCnt(1, 1));
  450.   else if (!ChkZ80Syntax(eSyntax808x));
  451.   else if (!DecodeReg16(ArgStr[1].str.p_str, CurrZ80Syntax, &Reg)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  452.   else
  453.   {
  454.     CodeLen = 1;
  455.     BAsmCode[0] = 0x03 + (Reg << 4) + Index;
  456.   }
  457. }
  458.  
  459. static void DecodeDAD(Word Index)
  460. {
  461.   Byte Reg;
  462.  
  463.   UNUSED(Index);
  464.  
  465.   if (!ChkArgCnt(1, 1));
  466.   else if (!ChkZ80Syntax(eSyntax808x));
  467.   else if (!DecodeReg16(ArgStr[1].str.p_str, CurrZ80Syntax, &Reg)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  468.   else
  469.   {
  470.     CodeLen = 1;
  471.     BAsmCode[0] = 0x09 + (Reg << 4);
  472.   }
  473. }
  474.  
  475. static void DecodeDSUB(Word Index)
  476. {
  477.   UNUSED(Index);
  478.  
  479.   if (ChkArgCnt(0, 1) && ChkMinCPU(CPU8085U) && ChkZ80Syntax(eSyntax808x))
  480.   {
  481.     Byte Reg;
  482.  
  483.     if ((ArgCnt == 1)
  484.      && (!DecodeReg16(ArgStr[1].str.p_str, CurrZ80Syntax, &Reg) || (Reg != BCReg))) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  485.     else
  486.     {
  487.       CodeLen = 1;
  488.       BAsmCode[0] = 0x08;
  489.     }
  490.   }
  491. }
  492.  
  493. static void DecodeLHLX_SHLX(Word Index)
  494. {
  495.   UNUSED(Index);
  496.  
  497.   if (ChkArgCnt(0, 1) && ChkMinCPU(CPU8085U) && ChkZ80Syntax(eSyntax808x))
  498.   {
  499.     Byte Reg;
  500.  
  501.     if ((ArgCnt == 1)
  502.      && (!DecodeReg16(ArgStr[1].str.p_str, CurrZ80Syntax, &Reg) || (Reg != DEReg))) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  503.     else
  504.     {
  505.       CodeLen = 1;
  506.       BAsmCode[0] = Index ? 0xed: 0xd9;
  507.     }
  508.   }
  509. }
  510.  
  511. static void DecodeLD(Word Code)
  512. {
  513.   Byte HVals[2];
  514.   Word Mask;
  515.   UNUSED(Code);
  516.  
  517.   if (ChkArgCnt(2, 2)
  518.    && ChkZ80Syntax(eSyntaxZ80))
  519.   {
  520.     Mask = MModReg8 | MModIReg16 | MModAbs | MModReg16;
  521.     if (MomCPU >= CPU8085)
  522.       Mask |= MModIM;
  523.     DecodeAdr_Z80(&ArgStr[1], Mask);
  524.     switch (AdrMode)
  525.     {
  526.       case ModReg8:
  527.         HVals[0] = AdrVals[0];
  528.         Mask = MModReg8 | MModIReg16 | MModImm;
  529.         if (HVals[0] == AccReg)
  530.         {
  531.           Mask |= MModAbs;
  532.           if (MomCPU >= CPU8085)
  533.             Mask |= MModIM;
  534.         }
  535.         DecodeAdr_Z80(&ArgStr[2], Mask);
  536.         switch (AdrMode)
  537.         {
  538.           case ModReg8:
  539.             BAsmCode[CodeLen++] = 0x40 | (HVals[0] << 3) | AdrVals[0];
  540.             break;
  541.           case ModIReg16:
  542.             if (AdrVals[0] == HLReg)
  543.               BAsmCode[CodeLen++] = 0x46 | (HVals[0] << 3);
  544.             else if ((HVals[0] == AccReg) && (AdrVals[0] != SPReg))
  545.               BAsmCode[CodeLen++] = 0x0a | (AdrVals[0] << 4);
  546.             else
  547.               WrError(ErrNum_InvAddrMode);
  548.             break;
  549.           case ModAbs:
  550.             BAsmCode[CodeLen++] = 0x3a;
  551.             BAsmCode[CodeLen++] = AdrVals[0];
  552.             BAsmCode[CodeLen++] = AdrVals[1];
  553.             break;
  554.           case ModImm:
  555.             BAsmCode[CodeLen++] = 0x06 | (HVals[0] << 3);
  556.             BAsmCode[CodeLen++] = AdrVals[0];
  557.             break;
  558.           case ModIM:
  559.             BAsmCode[CodeLen++] = 0x20;
  560.             break;
  561.           default:
  562.             break;
  563.         }
  564.         break;
  565.       case ModReg16:
  566.       {
  567.         Byte Dest = AdrVals[0];
  568.         Word Mask = MModImm;
  569.  
  570.         if (Dest == HLReg)
  571.         {
  572.           Mask |= MModAbs;
  573.           if (MomCPU == CPU8085U)
  574.             Mask |= MModIReg16;
  575.         }
  576.         if (Dest == SPReg)
  577.           Mask |= MModReg16;
  578.         DecodeAdr_Z80(&ArgStr[2], Mask);
  579.         switch (AdrMode)
  580.         {
  581.           case ModImm:
  582.             BAsmCode[CodeLen++] = 0x01 | (Dest << 4);
  583.             BAsmCode[CodeLen++] = AdrVals[0];
  584.             BAsmCode[CodeLen++] = AdrVals[1];
  585.             break;
  586.           case ModAbs:
  587.             BAsmCode[CodeLen++] = 0x2a;
  588.             BAsmCode[CodeLen++] = AdrVals[0];
  589.             BAsmCode[CodeLen++] = AdrVals[1];
  590.             break;
  591.           case ModReg16:
  592.             if (AdrVals[0] == HLReg)
  593.               BAsmCode[CodeLen++] = 0xf9;
  594.             else
  595.               WrError(ErrNum_InvAddrMode);
  596.             break;
  597.           case ModIReg16:
  598.             if (AdrVals[0] == DEReg)
  599.               BAsmCode[CodeLen++] = 0xed;
  600.             else
  601.               WrError(ErrNum_InvAddrMode);
  602.             break;
  603.           default:
  604.             break;
  605.         }
  606.         break;
  607.       }
  608.       case ModIReg16:
  609.       {
  610.         Byte Dest = AdrVals[0];
  611.         Word Mask = MModReg8;
  612.  
  613.         if (Dest == HLReg)
  614.           Mask |= MModImm;
  615.         if ((Dest == DEReg) && (MomCPU == CPU8085U))
  616.           Mask |= MModReg16;
  617.         DecodeAdr_Z80(&ArgStr[2], Mask);
  618.         switch (AdrMode)
  619.         {
  620.           case ModReg8:
  621.             if (Dest == HLReg)
  622.               BAsmCode[CodeLen++] = 0x70 | AdrVals[0];
  623.             else if ((AdrVals[0] == AccReg) && (Dest != SPReg))
  624.               BAsmCode[CodeLen++] = 0x02 | (Dest << 4);
  625.             else
  626.               WrError(ErrNum_InvAddrMode);
  627.             break;
  628.           case ModImm:
  629.             BAsmCode[CodeLen++] = 0x36;
  630.             BAsmCode[CodeLen++] = AdrVals[0];
  631.             break;
  632.           case ModReg16:
  633.             if (AdrVals[0] == HLReg)
  634.               BAsmCode[CodeLen++] = 0xd9;
  635.             else
  636.               WrError(ErrNum_InvAddrMode);
  637.             break;
  638.           default:
  639.             break;
  640.         }
  641.         break;
  642.       }
  643.       case ModAbs:
  644.         HVals[0] = AdrVals[0];
  645.         HVals[1] = AdrVals[1];
  646.         DecodeAdr_Z80(&ArgStr[2], MModReg8 | MModReg16);
  647.         switch (AdrMode)
  648.         {
  649.           case ModReg8:
  650.             if (AdrVals[0] != AccReg) WrError(ErrNum_InvAddrMode);
  651.             else
  652.             {
  653.               BAsmCode[CodeLen++] = 0x32;
  654.               BAsmCode[CodeLen++] = HVals[0];
  655.               BAsmCode[CodeLen++] = HVals[1];
  656.             }
  657.             break;
  658.           case ModReg16:
  659.             if (AdrVals[0] != HLReg) WrError(ErrNum_InvAddrMode);
  660.             else
  661.             {
  662.               BAsmCode[CodeLen++] = 0x22;
  663.               BAsmCode[CodeLen++] = HVals[0];
  664.               BAsmCode[CodeLen++] = HVals[1];
  665.             }
  666.             break;
  667.           default:
  668.             break;
  669.         }
  670.         break;
  671.       case ModIM:
  672.         DecodeAdr_Z80(&ArgStr[2], MModReg8);
  673.         switch (AdrMode)
  674.         {
  675.           case ModReg8:
  676.             if (AdrVals[0] != AccReg) WrError(ErrNum_InvAddrMode);
  677.             else
  678.               BAsmCode[CodeLen++] = 0x30;
  679.             break;
  680.           default:
  681.             break;
  682.         }
  683.         break;
  684.       default:
  685.         break;
  686.     }
  687.   }
  688. }
  689.  
  690. static void DecodeEX(Word Code)
  691. {
  692.   Byte HVal;
  693.  
  694.   UNUSED(Code);
  695.  
  696.   if (ChkArgCnt(2, 2)
  697.    && ChkZ80Syntax(eSyntaxZ80))
  698.   {
  699.     DecodeAdr_Z80(&ArgStr[1], MModReg16 | MModIReg16);
  700.     switch (AdrMode)
  701.     {
  702.       case ModReg16:
  703.         HVal = AdrVals[0];
  704.         DecodeAdr_Z80(&ArgStr[2], MModReg16 | MModIReg16);
  705.         switch (AdrMode)
  706.         {
  707.           case ModReg16:
  708.             if (((HVal == DEReg) && (AdrVals[0] == HLReg))
  709.              || ((HVal == HLReg) && (AdrVals[0] == DEReg)))
  710.               BAsmCode[CodeLen++] = 0xeb;
  711.             else
  712.               WrError(ErrNum_InvAddrMode);
  713.             break;
  714.           case ModIReg16:
  715.             if ((HVal == HLReg) && (AdrVals[0] == SPReg))
  716.               BAsmCode[CodeLen++] = 0xe3;
  717.             else
  718.               WrError(ErrNum_InvAddrMode);
  719.             break;
  720.           default:
  721.             break;
  722.         }
  723.         break;
  724.       case ModIReg16:
  725.         HVal = AdrVals[0];
  726.         DecodeAdr_Z80(&ArgStr[2], MModReg16);
  727.         switch (AdrMode)
  728.         {
  729.           case ModReg16:
  730.             if ((HVal == SPReg) && (AdrVals[0] == HLReg))
  731.               BAsmCode[CodeLen++] = 0xe3;
  732.             else
  733.               WrError(ErrNum_InvAddrMode);
  734.             break;
  735.           default:
  736.             break;
  737.         }
  738.         break;
  739.       default:
  740.         break;
  741.     }
  742.   }
  743. }
  744.  
  745. static void DecodeADD(Word Code)
  746. {
  747.   int MinArg, MaxArg;
  748.  
  749.   UNUSED(Code);
  750.  
  751.   MinArg = (CurrZ80Syntax & eSyntax808x) ? 1 : 2;
  752.   if (CurrZ80Syntax & eSyntaxZ80)
  753.     MaxArg = (MomCPU == CPU8085U) ? 3 : 2;
  754.   else
  755.     MaxArg = 1;
  756.   if (!ChkArgCnt(MinArg, MaxArg))
  757.     return;
  758.  
  759.   switch (ArgCnt)
  760.   {
  761.     case 1: /* 8080 style - 8 bit register src only, dst is implicitly ACC */
  762.     {
  763.       Byte Reg;
  764.  
  765.       if (!DecodeReg8(ArgStr[1].str.p_str, eSyntax808x, &Reg)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  766.       else
  767.         BAsmCode[CodeLen++] = 0x80 | Reg;
  768.       break;
  769.     }
  770.     case 2: /* Z80 style - dst may be HL or A and is first arg */
  771.     {
  772.       DecodeAdr_Z80(&ArgStr[1], MModReg8 | MModReg16);
  773.       switch (AdrMode)
  774.       {
  775.         case ModReg8:
  776.           if (AdrVals[0] != AccReg) WrError(ErrNum_InvAddrMode);
  777.           else
  778.           {
  779.             DecodeAdr_Z80(&ArgStr[2], MModReg8 | MModIReg16 | MModImm);
  780.             switch (AdrMode)
  781.             {
  782.               case ModReg8:
  783.                 BAsmCode[CodeLen++] = 0x80 | AdrVals[0];
  784.                 break;
  785.               case ModIReg16:
  786.                 if (AdrVals[0] != HLReg) WrError(ErrNum_InvAddrMode);
  787.                 else
  788.                   BAsmCode[CodeLen++] = 0x86;
  789.                 break;
  790.               case ModImm:
  791.                 BAsmCode[CodeLen++] = 0xc6;
  792.                 BAsmCode[CodeLen++] = AdrVals[0];
  793.                 break;
  794.               default:
  795.                 break;
  796.             }
  797.           }
  798.           break;
  799.         case ModReg16:
  800.           if (AdrVals[0] != HLReg) WrError(ErrNum_InvAddrMode);
  801.           else
  802.           {
  803.             DecodeAdr_Z80(&ArgStr[2], MModReg16);
  804.             switch (AdrMode)
  805.             {
  806.               case ModReg16:
  807.                 BAsmCode[CodeLen++] = 0x09 | (AdrVals[0] << 4);
  808.                 break;
  809.               default:
  810.                 break;
  811.             }
  812.           }
  813.           break;
  814.         default:
  815.           break;
  816.       }
  817.       break;
  818.     }
  819.     case 3: /* Z80 style of undoc 8085 : DE <- (HL,SP) + m */
  820.     {
  821.       Byte Reg;
  822.  
  823.       if (!DecodeReg16(ArgStr[1].str.p_str, CurrZ80Syntax, &Reg) || (Reg != DEReg)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  824.       else if (!DecodeReg16(ArgStr[2].str.p_str, CurrZ80Syntax, &Reg) || (Reg < 2)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  825.       else
  826.       {
  827.         Boolean OK;
  828.  
  829.         BAsmCode[1] = EvalStrIntExpression(&ArgStr[3], UInt8, &OK);
  830.         if (OK)
  831.         {
  832.           BAsmCode[0] = 0x08 | (Reg << 4);
  833.           CodeLen = 2;
  834.         }
  835.       }
  836.       break;
  837.     }
  838.   }
  839. }
  840.  
  841. static void DecodeADC(Word Code)
  842. {
  843.   UNUSED(Code);
  844.  
  845.   if (!ChkArgCnt((CurrZ80Syntax & eSyntax808x) ? 1 : 2, (CurrZ80Syntax & eSyntaxZ80) ? 2 : 1))
  846.       return;
  847.  
  848.   switch (ArgCnt)
  849.   {
  850.     case 1: /* 8080 style - 8 bit register src only */
  851.     {
  852.       Byte Reg;
  853.  
  854.       if (!DecodeReg8(ArgStr[1].str.p_str, eSyntax808x, &Reg)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  855.       else
  856.         BAsmCode[CodeLen++] = 0x88 | Reg;
  857.       break;
  858.     }
  859.     case 2:
  860.     {
  861.       DecodeAdr_Z80(&ArgStr[1], MModReg8);
  862.       switch (AdrMode)
  863.       {
  864.         case ModReg8:
  865.           if (AdrVals[0] != AccReg) WrError(ErrNum_InvAddrMode);
  866.           else
  867.           {
  868.             DecodeAdr_Z80(&ArgStr[2], MModReg8 | MModIReg16 | MModImm);
  869.             switch (AdrMode)
  870.             {
  871.               case ModReg8:
  872.                 BAsmCode[CodeLen++] = 0x88 | AdrVals[0];
  873.                 break;
  874.               case ModIReg16:
  875.                 if (AdrVals[0] != HLReg) WrError(ErrNum_InvAddrMode);
  876.                 else
  877.                   BAsmCode[CodeLen++] = 0x8e;
  878.                 break;
  879.               case ModImm:
  880.                 BAsmCode[CodeLen++] = 0xce;
  881.                 BAsmCode[CodeLen++] = AdrVals[0];
  882.                 break;
  883.               default:
  884.                 break;
  885.             }
  886.           }
  887.           break;
  888.         default:
  889.           break;
  890.       }
  891.       break;
  892.     }
  893.   }
  894. }
  895.  
  896. static void DecodeSUB(Word Code)
  897. {
  898.   Byte Reg;
  899.  
  900.   UNUSED(Code);
  901.  
  902.   /* dest operand is always A and also optional for Z80 mode, so min arg cnt is always 1! */
  903.  
  904.   if (!ChkArgCnt(1, (CurrZ80Syntax & eSyntaxZ80) ? 2 : 1))
  905.     return;
  906.  
  907.   /* For Z80, optionally allow A as dest */
  908.  
  909.   if (ArgCnt == 2)
  910.   {
  911.     DecodeAdr_Z80(&ArgStr[1], MModReg8 | ((MomCPU == CPU8085U) ? MModReg16 : 0));
  912.  
  913.     switch (AdrMode)
  914.     {
  915.       case ModNone:
  916.         return;
  917.       case ModReg8:
  918.         if (AdrVals[0] != AccReg)
  919.           goto error;
  920.         break;
  921.       case ModReg16:
  922.         if (AdrVals[0] != HLReg)
  923.           goto error;
  924.         break;
  925.       default:
  926.       error:
  927.         WrError(ErrNum_InvAddrMode);
  928.         return;
  929.     }
  930.   }
  931.   else
  932.     AdrMode = ModReg8;
  933.  
  934.   if (DecodeReg8(ArgStr[ArgCnt].str.p_str, CurrZ80Syntax, &Reg)) /* 808x style incl. M, Z80 style excl. (HL) */
  935.   {
  936.     BAsmCode[CodeLen++] = 0x90 | Reg;
  937.     return;
  938.   }
  939.  
  940.   /* rest is Z80 style ( (HL) or immediate) */
  941.  
  942.   if (!(CurrZ80Syntax & eSyntaxZ80))
  943.   {
  944.     WrError(ErrNum_InvAddrMode);
  945.     return;
  946.   }
  947.  
  948.   DecodeAdr_Z80(&ArgStr[ArgCnt], MModImm | MModIReg16 | ((AdrMode == ModReg16) ? MModReg16 : 0));
  949.   switch (AdrMode)
  950.   {
  951.     case ModReg16:
  952.       if (AdrVals[0] != BCReg) WrError(ErrNum_InvAddrMode);
  953.       else
  954.         BAsmCode[CodeLen++] = 0x08;
  955.       break;
  956.     case ModIReg16:
  957.       if (AdrVals[0] != HLReg) WrError(ErrNum_InvAddrMode);
  958.       else
  959.         BAsmCode[CodeLen++] = 0x96;
  960.       break;
  961.     case ModImm:
  962.       BAsmCode[CodeLen++] = 0xd6;
  963.       BAsmCode[CodeLen++] = AdrVals[0];
  964.       break;
  965.     default:
  966.       break;
  967.   }
  968. }
  969.  
  970. static void DecodeALU8_Z80(Word Code)
  971. {
  972.   if (!ChkZ80Syntax(eSyntaxZ80)
  973.    || !ChkArgCnt(1, 2))
  974.     return;
  975.  
  976.   if (ArgCnt == 2) /* A as dest */
  977.   {
  978.     DecodeAdr_Z80(&ArgStr[1], MModReg8);
  979.  
  980.     switch (AdrMode)
  981.     {
  982.       case ModNone:
  983.         return;
  984.       case ModReg8:
  985.         if (AdrVals[0] == AccReg)
  986.           break;
  987.         /* else fall-through */
  988.       default:
  989.         WrError(ErrNum_InvAddrMode);
  990.         return;
  991.     }
  992.   }
  993.  
  994.   DecodeAdr_Z80(&ArgStr[ArgCnt], MModImm | MModIReg16 | MModReg8);
  995.   switch (AdrMode)
  996.   {
  997.     case ModReg8:
  998.       BAsmCode[CodeLen++] = 0x80 | (Code << 3) | AdrVals[0];
  999.       break;
  1000.     case ModIReg16:
  1001.       if (AdrVals[0] != HLReg) WrError(ErrNum_InvAddrMode);
  1002.       else
  1003.         BAsmCode[CodeLen++] = 0x86 | (Code << 3);
  1004.       break;
  1005.     case ModImm:
  1006.       BAsmCode[CodeLen++] = 0xc6 | (Code << 3);
  1007.       BAsmCode[CodeLen++] = AdrVals[0];
  1008.       break;
  1009.     default:
  1010.       break;
  1011.   }
  1012. }
  1013.  
  1014. static void DecodeINCDEC(Word Code)
  1015. {
  1016.   if (ChkZ80Syntax(eSyntaxZ80)
  1017.    && ChkArgCnt(1, 1))
  1018.   {
  1019.     DecodeAdr_Z80(&ArgStr[1], MModReg8 | MModReg16 | MModIReg16);
  1020.     switch (AdrMode)
  1021.     {
  1022.       case ModReg8:
  1023.         BAsmCode[CodeLen++] = 0x04 | Code | (AdrVals[0] << 3);
  1024.         break;
  1025.       case ModReg16:
  1026.         BAsmCode[CodeLen++] = 0x03 | (Code << 3) | (AdrVals[0] << 4);
  1027.         break;
  1028.       case ModIReg16:
  1029.         if (AdrVals[0] != HLReg) WrError(ErrNum_InvAddrMode);
  1030.         else
  1031.           BAsmCode[CodeLen++] = 0x34 | Code;
  1032.       default:
  1033.         break;
  1034.     }
  1035.   }
  1036. }
  1037.  
  1038. static void DecodeCP(Word Code)
  1039. {
  1040.   UNUSED(Code);
  1041.  
  1042.   if (!ChkArgCnt(1, (CurrZ80Syntax & eSyntaxZ80) ? 2 : 1))
  1043.     return;
  1044.  
  1045.   /* 2 arguments -> check for A as dest, and compare is meant
  1046.      (syntax is either Z80 or Z80+808x implicitly due to previous check) */
  1047.  
  1048.   if (ArgCnt == 2) /* A as dest */
  1049.   {
  1050.     DecodeAdr_Z80(&ArgStr[1], MModReg8);
  1051.  
  1052.     switch (AdrMode)
  1053.     {
  1054.       case ModNone:
  1055.         return;
  1056.       case ModReg8:
  1057.         if (AdrVals[0] == AccReg)
  1058.           break;
  1059.         /* else fall-through */
  1060.       default:
  1061.         WrError(ErrNum_InvAddrMode);
  1062.         return;
  1063.     }
  1064.     OpSize = 0;
  1065.   }
  1066.  
  1067.   /* 1 argument -> must be compare anyway in pure Z80 syntax mode, otherwise assume 808x call-on-positive */
  1068.  
  1069.   else
  1070.     OpSize = (CurrZ80Syntax == eSyntaxZ80) ? 0 : 1;
  1071.  
  1072.   DecodeAdr_Z80(&ArgStr[ArgCnt], MModImm | ((CurrZ80Syntax & eSyntaxZ80) ? (MModIReg16 | MModReg8) : 0));
  1073.   switch (AdrMode)
  1074.   {
  1075.     case ModReg8:
  1076.       BAsmCode[CodeLen++] = 0xb8 | AdrVals[0];
  1077.       break;
  1078.     case ModIReg16:
  1079.       if (AdrVals[0] != HLReg) WrError(ErrNum_InvAddrMode);
  1080.       else
  1081.         BAsmCode[CodeLen++] = 0xbe;
  1082.       break;
  1083.     case ModImm:
  1084.       if (1 == OpSize) /* see comment above */
  1085.       {
  1086.         BAsmCode[CodeLen++] = 0xf4;
  1087.         BAsmCode[CodeLen++] = AdrVals[0];
  1088.         BAsmCode[CodeLen++] = AdrVals[1];
  1089.       }
  1090.       else
  1091.       {
  1092.         BAsmCode[CodeLen++] = 0xfe;
  1093.         BAsmCode[CodeLen++] = AdrVals[0];
  1094.       }
  1095.       break;
  1096.     default:
  1097.       break;
  1098.   }
  1099. }
  1100.  
  1101. static void DecodeJP(Word Code)
  1102. {
  1103.   Byte Condition;
  1104.   UNUSED(Code);
  1105.  
  1106.   if (!ChkArgCnt(1, (CurrZ80Syntax & eSyntaxZ80) ? 2 : 1))
  1107.     return;
  1108.  
  1109.   /* if two arguments, first one is (Z80) condition */
  1110.  
  1111.   if (ArgCnt == 2)
  1112.   {
  1113.     if (!DecodeCondition(ArgStr[1].str.p_str, &Condition, True))
  1114.     {
  1115.       WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1116.       return;
  1117.     }
  1118.   }
  1119.  
  1120.   /* if one argument, it's unconditional JP in Z80 mode, or jump-if positive */
  1121.  
  1122.   else
  1123.     Condition = (CurrZ80Syntax == eSyntaxZ80) ? 0xff : 6 << 3;
  1124.  
  1125.   OpSize = 1;
  1126.   DecodeAdr_Z80(&ArgStr[ArgCnt], MModImm | (((ArgCnt == 1) && (CurrZ80Syntax & eSyntaxZ80)) ? MModIReg16 : 0));
  1127.   switch (AdrMode)
  1128.   {
  1129.     case ModIReg16:
  1130.       if (AdrVals[0] != HLReg) WrError(ErrNum_InvAddrMode);
  1131.       else
  1132.         BAsmCode[CodeLen++] = 0xe9;
  1133.       break;
  1134.     case ModImm:
  1135.       BAsmCode[CodeLen++] = (0xff == Condition) ? 0xc3 : 0xc2 + Condition;
  1136.       BAsmCode[CodeLen++] = AdrVals[0];
  1137.       BAsmCode[CodeLen++] = AdrVals[1];
  1138.     default:
  1139.       break;
  1140.   }
  1141. }
  1142.  
  1143. static void DecodeCALL(Word Code)
  1144. {
  1145.   Byte Condition;
  1146.   UNUSED(Code);
  1147.  
  1148.   if (!ChkArgCnt(1, (CurrZ80Syntax & eSyntaxZ80) ? 2 : 1))
  1149.     return;
  1150.  
  1151.   if (ArgCnt == 2) /* Z80-style with condition */
  1152.   {
  1153.     if (!DecodeCondition(ArgStr[1].str.p_str, &Condition, False))
  1154.     {
  1155.       WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1156.       return;
  1157.     }
  1158.   }
  1159.   else
  1160.     Condition = 0xff;
  1161.  
  1162.   OpSize = 1;
  1163.   DecodeAdr_Z80(&ArgStr[ArgCnt], MModImm);
  1164.   switch (AdrMode)
  1165.   {
  1166.     case ModImm:
  1167.       BAsmCode[CodeLen++] = (1 == ArgCnt) ? 0xcd : 0xc4 | Condition;
  1168.       BAsmCode[CodeLen++] = AdrVals[0];
  1169.       BAsmCode[CodeLen++] = AdrVals[1];
  1170.     default:
  1171.       break;
  1172.   }
  1173. }
  1174.  
  1175. static void DecodeRET(Word Code)
  1176. {
  1177.   Byte Condition;
  1178.   UNUSED(Code);
  1179.  
  1180.   if (!ChkArgCnt(0, (CurrZ80Syntax & eSyntaxZ80) ? 1 : 0))
  1181.     return;
  1182.  
  1183.   if (ArgCnt == 1) /* Z80-style with condition */
  1184.   {
  1185.     if (!DecodeCondition(ArgStr[1].str.p_str, &Condition, False)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1186.     else
  1187.       BAsmCode[CodeLen++] = 0xc0 | Condition;
  1188.   }
  1189.   else
  1190.    BAsmCode[CodeLen++] = 0xc9;
  1191. }
  1192.  
  1193. static void DecodeINOUT(Word Code)
  1194. {
  1195.   tEvalResult EvalResult;
  1196.  
  1197.   if (!ChkArgCnt((CurrZ80Syntax & eSyntax808x) ? 1 : 2, (CurrZ80Syntax & eSyntaxZ80) ? 2 : 1))
  1198.     return;
  1199.  
  1200.   if (ArgCnt == 2) /* Z80-style with A */
  1201.   {
  1202.     DecodeAdr_Z80(&ArgStr[Code == 0xdb ? 1 : 2], MModReg8);
  1203.     if ((AdrMode != ModNone) && (AdrVals[0] != AccReg))
  1204.     {
  1205.       WrError(ErrNum_InvAddrMode);
  1206.       AdrMode = ModNone;
  1207.     }
  1208.     if (AdrMode == ModNone)
  1209.       return;
  1210.   }
  1211.   BAsmCode[1] = EvalStrIntExpressionWithResult(&ArgStr[((Code == 0xdb) && (ArgCnt == 2)) ? 2 : 1], UInt8, &EvalResult);
  1212.   if (EvalResult.OK)
  1213.   {
  1214.     ChkSpace(SegIO, EvalResult.AddrSpaceMask);
  1215.     BAsmCode[0] = Lo(Code);
  1216.     CodeLen = 2;
  1217.   }
  1218. }
  1219.  
  1220. static void DecodeSRA(Word Code)
  1221. {
  1222.   Byte Reg;
  1223.  
  1224.   if (!ChkArgCnt(1, 1));
  1225.   else if (!ChkMinCPU(CPU8085U));
  1226.   else if (!ChkZ80Syntax(eSyntaxZ80));
  1227.   else if (!DecodeReg16(ArgStr[1].str.p_str, CurrZ80Syntax, &Reg) || (Reg != HLReg)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  1228.   else
  1229.    BAsmCode[CodeLen++] = Lo(Code);
  1230. }
  1231.  
  1232. static void DecodeRLC(Word Code)
  1233. {
  1234.   if (!ChkArgCnt((CurrZ80Syntax & eSyntax808x) ? 0 : 1, (CurrZ80Syntax & eSyntaxZ80) ? 1 : 0))
  1235.     return;
  1236.  
  1237.   switch (ArgCnt)
  1238.   {
  1239.     case 0:
  1240.       BAsmCode[CodeLen++] = Code;
  1241.       break;
  1242.     case 1:
  1243.     {
  1244.       Byte Reg;
  1245.  
  1246.       if (!DecodeReg16(ArgStr[1].str.p_str, CurrZ80Syntax, &Reg) || (Reg != DEReg)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  1247.       else
  1248.         BAsmCode[CodeLen++] = 0x18;
  1249.       break;
  1250.     }
  1251.   }
  1252. }
  1253.  
  1254. /*!------------------------------------------------------------------------
  1255.  * \fn     DecodeCALLN(Word code)
  1256.  * \brief  handle CALLN instruction
  1257.  * \param  code machine code
  1258.  * ------------------------------------------------------------------------ */
  1259.  
  1260. static void DecodeCALLN(Word code)
  1261. {
  1262.   if (ChkArgCnt(1, 1) && ChkExactCPU(CPUV30EMU))
  1263.   {
  1264.     Boolean ok;
  1265.  
  1266.     BAsmCode[2] = EvalStrIntExpression(&ArgStr[1], UInt8, &ok);
  1267.     if (ok)
  1268.     {
  1269.       BAsmCode[0] = Hi(code);
  1270.       BAsmCode[1] = Lo(code);
  1271.       CodeLen = 3;
  1272.     }
  1273.   }
  1274. }
  1275.  
  1276. /*!------------------------------------------------------------------------
  1277.  * \fn     DecodeRETEM(Word code)
  1278.  * \brief  handle RETEM instruction
  1279.  * \param  code machine code
  1280.  * ------------------------------------------------------------------------ */
  1281.  
  1282. static void DecodeRETEM(Word code)
  1283. {
  1284.   if (ChkArgCnt(0, 0) && ChkExactCPU(CPUV30EMU))
  1285.   {
  1286.     BAsmCode[0] = Hi(code);
  1287.     BAsmCode[1] = Lo(code);
  1288.     CodeLen = 2;
  1289.   }
  1290. }
  1291.  
  1292. static void DecodePORT(Word Index)
  1293. {
  1294.   UNUSED(Index);
  1295.  
  1296.   CodeEquate(SegIO, 0, 0xff);
  1297. }
  1298.  
  1299. /*--------------------------------------------------------------------------------------------------------*/
  1300.  
  1301. static void AddFixed(const char *NName, CPUVar NMinCPU, Byte NCode, Word SyntaxMask)
  1302. {
  1303.   if (MomCPU >= NMinCPU)
  1304.     AddInstTable(InstTable, NName, (SyntaxMask << 8) | NCode, DecodeFixed);
  1305. }
  1306.  
  1307. static void AddOp16(const char *NName, CPUVar NMinCPU, Byte NCode, Word SyntaxMask)
  1308. {
  1309.   if (MomCPU >= NMinCPU)
  1310.     AddInstTable(InstTable, NName, (SyntaxMask << 8) | NCode, DecodeOp16);
  1311. }
  1312.  
  1313. static void AddOp8(const char *NName, CPUVar NMinCPU, Word NCode, Word SyntaxMask)
  1314. {
  1315.   if (MomCPU >= NMinCPU)
  1316.     AddInstTable(InstTable, NName, (SyntaxMask << 8) | NCode, DecodeOp8);
  1317. }
  1318.  
  1319. static void AddALU(const char *NName, Byte NCode, Word SyntaxMask)
  1320. {
  1321.   AddInstTable(InstTable, NName, (SyntaxMask << 8) | NCode, DecodeALU);
  1322. }
  1323.  
  1324. static void InitFields(void)
  1325. {
  1326.   InstTable = CreateInstTable(201);
  1327.  
  1328.   AddInstTable(InstTable, "MOV" , 0, DecodeMOV);
  1329.   AddInstTable(InstTable, "MVI" , 0, DecodeMVI);
  1330.   AddInstTable(InstTable, "LXI" , 0, DecodeLXI);
  1331.   AddInstTable(InstTable, "STAX", 0, DecodeLDAX_STAX);
  1332.   AddInstTable(InstTable, "LDAX", 1, DecodeLDAX_STAX);
  1333.   AddInstTable(InstTable, "SHLX", 0, DecodeLHLX_SHLX);
  1334.   AddInstTable(InstTable, "LHLX", 1, DecodeLHLX_SHLX);
  1335.   AddInstTable(InstTable, "PUSH", 4, DecodePUSH_POP);
  1336.   AddInstTable(InstTable, "POP" , 0, DecodePUSH_POP);
  1337.   AddInstTable(InstTable, "RST" , 0, DecodeRST);
  1338.   AddInstTable(InstTable, "INR" , 0, DecodeINR_DCR);
  1339.   AddInstTable(InstTable, "DCR" , 1, DecodeINR_DCR);
  1340.   AddInstTable(InstTable, "INX" , 0, DecodeINX_DCX);
  1341.   AddInstTable(InstTable, "DCX" , 8, DecodeINX_DCX);
  1342.   AddInstTable(InstTable, "DAD" , 0, DecodeDAD);
  1343.   AddInstTable(InstTable, "DSUB", 0, DecodeDSUB);
  1344.   AddInstTable(InstTable, "PORT", 0, DecodePORT);
  1345.  
  1346.   AddFixed("XCHG", CPU8080 , 0xeb, eSyntax808x);
  1347.   AddFixed("XTHL", CPU8080 , 0xe3, eSyntax808x);
  1348.   AddFixed("SPHL", CPU8080 , 0xf9, eSyntax808x);
  1349.   AddFixed("PCHL", CPU8080 , 0xe9, eSyntax808x);
  1350.   AddFixed("RC"  , CPU8080 , 0xd8, eSyntax808x);
  1351.   AddFixed("RNC" , CPU8080 , 0xd0, eSyntax808x);
  1352.   AddFixed("RZ"  , CPU8080 , 0xc8, eSyntax808x);
  1353.   AddFixed("RNZ" , CPU8080 , 0xc0, eSyntax808x);
  1354.   AddFixed("RP"  , CPU8080 , 0xf0, eSyntax808x);
  1355.   AddFixed("RM"  , CPU8080 , 0xf8, eSyntax808x);
  1356.   AddFixed("RPE" , CPU8080 , 0xe8, eSyntax808x);
  1357.   AddFixed("RPO" , CPU8080 , 0xe0, eSyntax808x);
  1358.   /* RLC needs special handling */
  1359.   AddFixed("RLCA", CPU8080 , 0x07, eSyntaxZ80);
  1360.   AddFixed("RRC" , CPU8080 , 0x0f, eSyntax808x);
  1361.   AddFixed("RRCA", CPU8080 , 0x0f, eSyntaxZ80);
  1362.   AddFixed("RAL" , CPU8080 , 0x17, eSyntax808x);
  1363.   AddFixed("RLA" , CPU8080 , 0x17, eSyntaxZ80);
  1364.   AddFixed("RAR" , CPU8080 , 0x1f, eSyntax808x);
  1365.   AddFixed("RRA" , CPU8080 , 0x1f, eSyntaxZ80);
  1366.   AddFixed("CMA" , CPU8080 , 0x2f, eSyntax808x);
  1367.   AddFixed("CPL" , CPU8080 , 0x2f, eSyntaxZ80);
  1368.   AddFixed("STC" , CPU8080 , 0x37, eSyntax808x);
  1369.   AddFixed("SCF" , CPU8080 , 0x37, eSyntaxZ80);
  1370.   AddFixed("CMC" , CPU8080 , 0x3f, eSyntax808x);
  1371.   AddFixed("CCF" , CPU8080 , 0x3f, eSyntaxZ80);
  1372.   AddFixed("DAA" , CPU8080 , 0x27, eSyntax808x | eSyntaxZ80);
  1373.   AddFixed("EI"  , CPU8080 , 0xfb, eSyntax808x | eSyntaxZ80);
  1374.   AddFixed("DI"  , CPU8080 , 0xf3, eSyntax808x | eSyntaxZ80);
  1375.   AddFixed("NOP" , CPU8080 , 0x00, eSyntax808x | eSyntaxZ80);
  1376.   AddFixed("HLT" , CPU8080 , 0x76, eSyntax808x);
  1377.   AddFixed("HALT", CPU8080 , 0x76, eSyntaxZ80);
  1378.   AddFixed("RIM" , CPU8085 , 0x20, eSyntax808x);
  1379.   AddFixed("SIM" , CPU8085 , 0x30, eSyntax808x);
  1380.   AddFixed("ARHL", CPU8085U, 0x10, eSyntax808x);
  1381.   AddFixed("RDEL", CPU8085U, 0x18, eSyntax808x | eSyntaxZ80); /* TODO: find LD equivalent */
  1382.   AddFixed("RSTV", CPU8085U, 0xcb, eSyntax808x);
  1383.  
  1384.  
  1385.   AddOp16("STA" , CPU8080 , 0x32, eSyntax808x);
  1386.   AddOp16("LDA" , CPU8080 , 0x3a, eSyntax808x);
  1387.   AddOp16("SHLD", CPU8080 , 0x22, eSyntax808x);
  1388.   AddOp16("LHLD", CPU8080 , 0x2a, eSyntax808x);
  1389.   AddOp16("JMP" , CPU8080 , 0xc3, eSyntax808x);
  1390.   AddOp16("JC"  , CPU8080 , 0xda, eSyntax808x);
  1391.   AddOp16("JNC" , CPU8080 , 0xd2, eSyntax808x);
  1392.   AddOp16("JZ"  , CPU8080 , 0xca, eSyntax808x);
  1393.   AddOp16("JNZ" , CPU8080 , 0xc2, eSyntax808x);
  1394.   /* JP needs special handling */
  1395.   AddOp16("JM"  , CPU8080 , 0xfa, eSyntax808x);
  1396.   AddOp16("JPE" , CPU8080 , 0xea, eSyntax808x);
  1397.   AddOp16("JPO" , CPU8080 , 0xe2, eSyntax808x);
  1398.   /* CALL needs special handling */
  1399.   AddOp16("CC"  , CPU8080 , 0xdc, eSyntax808x);
  1400.   AddOp16("CNC" , CPU8080 , 0xd4, eSyntax808x);
  1401.   AddOp16("CZ"  , CPU8080 , 0xcc, eSyntax808x);
  1402.   AddOp16("CNZ" , CPU8080 , 0xc4, eSyntax808x);
  1403.   /* CP needs special handling */
  1404.   AddOp16("CM"  , CPU8080 , 0xfc, eSyntax808x);
  1405.   AddOp16("CPE" , CPU8080 , 0xec, eSyntax808x);
  1406.   AddOp16("CPO" , CPU8080 , 0xe4, eSyntax808x);
  1407.   AddOp16("JNX5", CPU8085U, 0xdd, eSyntax808x);
  1408.   AddOp16("JX5" , CPU8085U, 0xfd, eSyntax808x);
  1409.  
  1410.   AddOp8("ADI" , CPU8080 , 0xc6, eSyntax808x);
  1411.   AddOp8("ACI" , CPU8080 , 0xce, eSyntax808x);
  1412.   AddOp8("SUI" , CPU8080 , 0xd6, eSyntax808x);
  1413.   AddOp8("SBI" , CPU8080 , 0xde, eSyntax808x);
  1414.   AddOp8("ANI" , CPU8080 , 0xe6, eSyntax808x);
  1415.   AddOp8("XRI" , CPU8080 , 0xee, eSyntax808x);
  1416.   AddOp8("ORI" , CPU8080 , 0xf6, eSyntax808x);
  1417.   AddOp8("CPI" , CPU8080 , 0xfe, eSyntax808x);
  1418.   AddOp8("LDHI", CPU8085U, 0x28, eSyntax808x | eSyntaxZ80); /* TODO: find LD equivalent */
  1419.   AddOp8("LDSI", CPU8085U, 0x38, eSyntax808x | eSyntaxZ80);
  1420.  
  1421.   AddALU("SBB" , 0x98, eSyntax808x);
  1422.   AddALU("ANA" , 0xa0, eSyntax808x);
  1423.   AddALU("XRA" , 0xa8, eSyntax808x);
  1424.   AddALU("ORA" , 0xb0, eSyntax808x);
  1425.   AddALU("CMP" , 0xb8, eSyntax808x);
  1426.  
  1427.   AddInstTable(InstTable, "LD", 0, DecodeLD);
  1428.   AddInstTable(InstTable, "EX", 0, DecodeEX);
  1429.   AddInstTable(InstTable, "ADD", 0, DecodeADD);
  1430.   AddInstTable(InstTable, "ADC", 0, DecodeADC);
  1431.   AddInstTable(InstTable, "SUB", 0, DecodeSUB);
  1432.   AddInstTable(InstTable, "SBC", 3, DecodeALU8_Z80);
  1433.   AddInstTable(InstTable, "INC", 0, DecodeINCDEC);
  1434.   AddInstTable(InstTable, "DEC", 1, DecodeINCDEC);
  1435.   AddInstTable(InstTable, "AND", 4, DecodeALU8_Z80);
  1436.   AddInstTable(InstTable, "XOR", 5, DecodeALU8_Z80);
  1437.   AddInstTable(InstTable, "OR" , 6, DecodeALU8_Z80);
  1438.   AddInstTable(InstTable, "CP" , 0, DecodeCP);
  1439.   AddInstTable(InstTable, "JP" , 0, DecodeJP);
  1440.   AddInstTable(InstTable, "CALL", 0, DecodeCALL);
  1441.   AddInstTable(InstTable, "RET", 0, DecodeRET);
  1442.   AddInstTable(InstTable, "IN", 0xdb, DecodeINOUT);
  1443.   AddInstTable(InstTable, "OUT", 0xd3, DecodeINOUT);
  1444.   AddInstTable(InstTable, "SRA", 0x10, DecodeSRA);
  1445.   AddInstTable(InstTable, "RLC", 0x07, DecodeRLC);
  1446.  
  1447.   AddInstTable(InstTable, "CALLN", 0xeded, DecodeCALLN);
  1448.   AddInstTable(InstTable, "RETEM", 0xedfd, DecodeRETEM);
  1449.  
  1450.   AddZ80Syntax(InstTable);
  1451. }
  1452.  
  1453. static void DeinitFields(void)
  1454. {
  1455.   DestroyInstTable(InstTable);
  1456. }
  1457.  
  1458. /*--------------------------------------------------------------------------------------------------------*/
  1459.  
  1460. static void MakeCode_85(void)
  1461. {
  1462.   CodeLen = 0;
  1463.   DontPrint = False;
  1464.   OpSize = 0;
  1465.  
  1466.   /* zu ignorierendes */
  1467.  
  1468.   if (Memo("")) return;
  1469.  
  1470.   /* Pseudoanweisungen */
  1471.  
  1472.   if (DecodeIntelPseudo(False)) return;
  1473.  
  1474.   /* suchen */
  1475.  
  1476.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1477.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1478. }
  1479.  
  1480. static Boolean IsDef_85(void)
  1481. {
  1482.   return Memo("PORT");
  1483. }
  1484.  
  1485. static void SwitchFrom_85(void)
  1486. {
  1487.   DeinitFields();
  1488. }
  1489.  
  1490. static void SwitchTo_85(void)
  1491. {
  1492.   TurnWords = False;
  1493.   SetIntConstMode(eIntConstModeIntel);
  1494.  
  1495.   PCSymbol = "$";
  1496.   HeaderID = 0x41;
  1497.   NOPCode = 0x00;
  1498.   DivideChars = ",";
  1499.   HasAttrs = False;
  1500.  
  1501.   ValidSegs = (1 << SegCode) | (1 << SegIO);
  1502.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  1503.   SegLimits[SegCode] = 0xffff;
  1504.   Grans[SegIO  ] = 1; ListGrans[SegIO  ] = 1; SegInits[SegIO  ] = 0;
  1505.   SegLimits[SegIO  ] = 0xff;
  1506.  
  1507.   MakeCode = MakeCode_85;
  1508.   IsDef = IsDef_85;
  1509.   SwitchFrom = SwitchFrom_85;
  1510.   InitFields();
  1511. }
  1512.  
  1513. void code85_init(void)
  1514. {
  1515.   CPU8080 = AddCPU("8080", SwitchTo_85);
  1516.   CPUV30EMU = AddCPU("V30EMU", SwitchTo_85);
  1517.   CPU8085 = AddCPU("8085", SwitchTo_85);
  1518.   CPU8085U = AddCPU("8085UNDOC", SwitchTo_85);
  1519. }
  1520.