Subversion Repositories pentevo

Rev

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

  1. /* code75k0.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator NEC 75K0                                                    */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "nls.h"
  16. #include "strutil.h"
  17. #include "bpemu.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmitree.h"
  22. #include "codepseudo.h"
  23. #include "intpseudo.h"
  24. #include "codevars.h"
  25. #include "errmsg.h"
  26. #include "intformat.h"
  27.  
  28. #include "code75k0.h"
  29.  
  30. enum
  31. {
  32.   ModNone  = -1,
  33.   ModReg4  = 0,
  34.   ModReg8  = 1,
  35.   ModImm  = 2 ,
  36.   ModInd  = 3,
  37.   ModAbs  = 4
  38. };
  39.  
  40. #define MModReg4 (1 << ModReg4)
  41. #define MModReg8 (1 << ModReg8)
  42. #define MModImm (1 << ModImm)
  43. #define MModInd (1 << ModInd)
  44. #define MModAbs (1 << ModAbs)
  45. #define MModMinOneIs0 (1 << 7)
  46.  
  47. enum
  48. {
  49.   eCore402 = 0,
  50.   eCore004 = 1,
  51.   eCore104 = 2
  52. };
  53.  
  54. typedef struct
  55. {
  56.   char Name[6];
  57.   Byte CoreType;
  58. } tCPUProps;
  59.  
  60. typedef struct
  61. {
  62.   Byte Part;
  63.   ShortInt Mode;
  64.   tSymbolFlags PartSymFlags;
  65. } tAdrResult;
  66.  
  67. static LongInt MBSValue, MBEValue;
  68. static const tCPUProps *pCurrCPUProps;
  69.  
  70. static ShortInt OpSize;
  71.  
  72. /*-------------------------------------------------------------------------*/
  73. /* Untermengen von Befehlssatz abpruefen */
  74.  
  75. static void CheckCore(Byte MinCore)
  76. {
  77.   if (pCurrCPUProps->CoreType < MinCore)
  78.   {
  79.     WrError(ErrNum_InstructionNotSupported);
  80.     CodeLen = 0;
  81.   }
  82. }
  83.  
  84. static Boolean CheckACore(Byte MinCore)
  85. {
  86.   if (pCurrCPUProps->CoreType < MinCore)
  87.   {
  88.     WrError(ErrNum_AddrModeNotSupported);
  89.     return False;
  90.   }
  91.   return True;
  92. }
  93.  
  94. /*-------------------------------------------------------------------------*/
  95. /* Adressausdruck parsen */
  96.  
  97. static Boolean SetOpSize(ShortInt NewSize)
  98. {
  99.   if (OpSize == -1)
  100.     OpSize = NewSize;
  101.   else if (NewSize != OpSize)
  102.   {
  103.     WrError(ErrNum_ConfOpSizes);
  104.     return False;
  105.   }
  106.   return True;
  107. }
  108.  
  109. static void ChkDataPage(Word Adr)
  110. {
  111.   switch (MBEValue)
  112.   {
  113.     case 0:
  114.       if ((Adr > 0x7f) && (Adr < 0xf80))
  115.         WrError(ErrNum_InAccPage);
  116.       break;
  117.     case 1:
  118.       if (Hi(Adr) != MBSValue)
  119.         WrError(ErrNum_InAccPage);
  120.       break;
  121.   }
  122. }
  123.  
  124. static void CheckMBE(void)
  125. {
  126.   if ((pCurrCPUProps->CoreType == eCore402) && (MBEValue != 0))
  127.   {
  128.     MBEValue = 0;
  129.     WrError(ErrNum_InvCtrlReg);
  130.   }
  131. }
  132.  
  133. static Boolean DecodeAdr(const tStrComp *pArg, Byte Mask, tAdrResult *pResult)
  134. {
  135.   static const char RegNames[] = "XAHLDEBC";
  136.  
  137.   const char *p;
  138.   int pos, ArgLen = strlen(pArg->str.p_str);
  139.   Boolean OK;
  140.   tEvalResult EvalResult;
  141.   String s;
  142.  
  143.   pResult->Mode = ModNone;
  144.   pResult->PartSymFlags = eSymbolFlag_None;
  145.  
  146.   /* Register ? */
  147.  
  148.   memcpy(s, pArg->str.p_str, 2);
  149.   s[2] = '\0';
  150.   NLS_UpString(s);
  151.   p = strstr(RegNames, s);
  152.  
  153.   if (p)
  154.   {
  155.     pos = p - RegNames;
  156.  
  157.     /* 8-Bit-Register ? */
  158.  
  159.     if (ArgLen == 1)
  160.     {
  161.       pResult->Part = pos ^ 1;
  162.       if (SetOpSize(0))
  163.       {
  164.         if ((pResult->Part > 4) && !CheckACore(eCore004));
  165.         else
  166.           pResult->Mode = ModReg4;
  167.       }
  168.       goto chk;
  169.     }
  170.  
  171.     /* 16-Bit-Register ? */
  172.  
  173.     if ((ArgLen == 2) && (!Odd(pos)))
  174.     {
  175.       pResult->Part = pos;
  176.       if (SetOpSize(1))
  177.       {
  178.         if ((pResult->Part > 2) && !CheckACore(eCore004));
  179.         else
  180.           pResult->Mode = ModReg8;
  181.       }
  182.       goto chk;
  183.     }
  184.  
  185.     /* 16-Bit-Schattenregister ? */
  186.  
  187.     if ((ArgLen == 3) && ((pArg->str.p_str[2] == '\'') || (pArg->str.p_str[2] == '`')) && (!Odd(pos)))
  188.     {
  189.       pResult->Part = pos + 1;
  190.       if (SetOpSize(1))
  191.       {
  192.         if (CheckACore(eCore104))
  193.           pResult->Mode = ModReg8;
  194.       }
  195.       goto chk;
  196.     }
  197.   }
  198.  
  199.   /* immediate? */
  200.  
  201.   if (*pArg->str.p_str == '#')
  202.   {
  203.     if ((OpSize == -1) && (Mask & MModMinOneIs0))
  204.       OpSize = 0;
  205.     switch (OpSize)
  206.     {
  207.       case -1:
  208.         WrError(ErrNum_UndefOpSizes);
  209.         OK = False;
  210.         break;
  211.       case 0:
  212.         pResult->Part = EvalStrIntExpressionOffs(pArg, 1, Int4, &OK) & 15;
  213.         break;
  214.       case 1:
  215.         pResult->Part = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
  216.         break;
  217.     }
  218.     if (OK)
  219.       pResult->Mode = ModImm;
  220.     goto chk;
  221.   }
  222.  
  223.   /* indirekt ? */
  224.  
  225.   if (*pArg->str.p_str == '@')
  226.   {
  227.     tStrComp Arg;
  228.  
  229.     StrCompRefRight(&Arg, pArg, 1);
  230.     if (!as_strcasecmp(Arg.str.p_str, "HL")) pResult->Part = 1;
  231.     else if (!as_strcasecmp(Arg.str.p_str, "HL+")) pResult->Part = 2;
  232.     else if (!as_strcasecmp(Arg.str.p_str, "HL-")) pResult->Part = 3;
  233.     else if (!as_strcasecmp(Arg.str.p_str, "DE")) pResult->Part = 4;
  234.     else if (!as_strcasecmp(Arg.str.p_str, "DL")) pResult->Part = 5;
  235.     else
  236.       pResult->Part = 0;
  237.     if (pResult->Part != 0)
  238.     {
  239.       if ((pResult->Part != 1) && !CheckACore(eCore004));
  240.       else if (((pResult->Part == 2) || (pResult->Part == 3)) && !CheckACore(eCore104));
  241.       else
  242.         pResult->Mode = ModInd;
  243.       goto chk;
  244.     }
  245.   }
  246.  
  247.   /* absolut */
  248.  
  249.   pos = EvalStrIntExpressionWithResult(pArg, UInt12, &EvalResult);
  250.   if (EvalResult.OK)
  251.   {
  252.     pResult->Part = Lo(pos);
  253.     pResult->Mode = ModAbs;
  254.     ChkSpace(SegData, EvalResult.AddrSpaceMask);
  255.     if (!mFirstPassUnknown(EvalResult.Flags))
  256.       ChkDataPage(pos);
  257.     pResult->PartSymFlags = EvalResult.Flags;
  258.   }
  259.  
  260. chk:
  261.   if ((pResult->Mode != ModNone) && (!(Mask & (1 << pResult->Mode))))
  262.   {
  263.     WrError(ErrNum_InvAddrMode);
  264.     pResult->Mode = ModNone;
  265.   }
  266.   return pResult->Mode != ModNone;
  267. }
  268.  
  269. /* Bit argument coding:
  270.  
  271.    aaaa01bbaaaaaaaa -> aaaaaaaaaaaa.bb
  272.            11bbxxxx -> 0ffxh.bb
  273.            10bbxxxx -> 0fbxh.bb
  274.            00bbxxxx -> @h+x.bb
  275.            0100xxxx -> 0fc0h+(x*4).@l
  276.  */
  277.  
  278. /*!------------------------------------------------------------------------
  279.  * \fn     DissectBit_75K0(char *pDest, size_t DestSize, LargeWord Inp)
  280.  * \brief  dissect compact storage of bit (field) into readable form for listing
  281.  * \param  pDest destination for ASCII representation
  282.  * \param  DestSize destination buffer size
  283.  * \param  Inp compact storage
  284.  * ------------------------------------------------------------------------ */
  285.  
  286. static void DissectBit_75K0(char *pDest, size_t DestSize, LargeWord Inp)
  287. {
  288.   if (Hi(Inp))
  289.     as_snprintf(pDest, DestSize, "%~03.*u%s.%c",
  290.                 ListRadixBase, (unsigned)(((Inp >> 4) & 0xf00) + Lo(Inp)), GetIntConstIntelSuffix(ListRadixBase),
  291.                 '0' + (Hi(Inp) & 3));
  292.   else switch ((Inp >> 6) & 3)
  293.   {
  294.     case 0:
  295.       as_snprintf(pDest, DestSize, "@%c+%0.*u%s.%c",
  296.                   HexStartCharacter + ('H' - 'A'),
  297.                   ListRadixBase, (unsigned)(Inp & 0x0f), GetIntConstIntelSuffix(ListRadixBase),
  298.                   '0' + ((Inp >> 4) & 3));
  299.       break;
  300.     case 1:
  301.       as_snprintf(pDest, DestSize, "%~03.*u%s.@%c",
  302.                   ListRadixBase, (unsigned)(0xfc0 + ((Inp & 0x0f) << 2)), GetIntConstIntelSuffix(ListRadixBase),
  303.                   HexStartCharacter + ('L' - 'A'));
  304.       break;
  305.     case 2:
  306.       as_snprintf(pDest, DestSize, "%~03.*u%s.%c",
  307.                   ListRadixBase, (unsigned)(0xfb0 + (Inp & 15)), GetIntConstIntelSuffix(ListRadixBase),
  308.                   '0' + ((Inp >> 4) & 3));
  309.       break;
  310.     case 3:
  311.       as_snprintf(pDest, DestSize, "%~03.*u%s.%c",
  312.                   ListRadixBase, (unsigned)(0xff0 + (Inp & 15)), GetIntConstIntelSuffix(ListRadixBase),
  313.                   '0' + ((Inp >> 4) & 3));
  314.       break;
  315.   }
  316. }
  317.  
  318. static Boolean DecodeBitAddr(const tStrComp *pArg, Word *Erg, tEvalResult *pEvalResult)
  319. {
  320.   char *p;
  321.   int Num;
  322.   Boolean OK;
  323.   Word Adr;
  324.   tStrComp AddrPart, BitPart;
  325.  
  326.   p = QuotPos(pArg->str.p_str, '.');
  327.   if (!p)
  328.   {
  329.     *Erg = EvalStrIntExpressionWithResult(pArg, Int16, pEvalResult);
  330.     if (Hi(*Erg) != 0)
  331.       ChkDataPage(((*Erg >> 4) & 0xf00) + Lo(*Erg));
  332.     return pEvalResult->OK;
  333.   }
  334.  
  335.   StrCompSplitRef(&AddrPart, &BitPart, pArg, p);
  336.  
  337.   if (!as_strcasecmp(BitPart.str.p_str, "@L"))
  338.   {
  339.     Adr = EvalStrIntExpressionWithResult(&AddrPart, UInt12, pEvalResult);
  340.     if (mFirstPassUnknown(pEvalResult->Flags))
  341.       Adr = (Adr & 0xffc) | 0xfc0;
  342.     if (pEvalResult->OK)
  343.     {
  344.       ChkSpace(SegData, pEvalResult->AddrSpaceMask);
  345.       if ((Adr & 3) != 0) WrError(ErrNum_NotAligned);
  346.       else if (Adr < 0xfc0) WrError(ErrNum_UnderRange);
  347.       else if (CheckACore(eCore004))
  348.       {
  349.         *Erg = 0x40 + ((Adr & 0x3c) >> 2);
  350.         return True;
  351.       }
  352.     }
  353.   }
  354.   else
  355.   {
  356.     Num = EvalStrIntExpression(&BitPart, UInt2, &OK);
  357.     if (OK)
  358.     {
  359.       if (!as_strncasecmp(AddrPart.str.p_str, "@H", 2))
  360.       {
  361.         Adr = EvalStrIntExpressionOffsWithResult(&AddrPart, 2, UInt4, pEvalResult);
  362.         if (pEvalResult->OK)
  363.         {
  364.           if (CheckACore(eCore004))
  365.           {
  366.             *Erg = (Num << 4) + Adr;
  367.             return True;
  368.           }
  369.         }
  370.       }
  371.       else
  372.       {
  373.         Adr = EvalStrIntExpressionWithResult(&AddrPart, UInt12, pEvalResult);
  374.         if (mFirstPassUnknown(pEvalResult->Flags))
  375.           Adr = (Adr | 0xff0);
  376.         if (pEvalResult->OK)
  377.         {
  378.           ChkSpace(SegData, pEvalResult->AddrSpaceMask);
  379.           if ((Adr >= 0xfb0) && (Adr < 0xfc0))
  380.             *Erg = 0x80 + (Num << 4) + (Adr & 15);
  381.           else if (Adr >= 0xff0)
  382.             *Erg = 0xc0 + (Num << 4) + (Adr & 15);
  383.           else
  384.             *Erg = 0x400 + (((Word)Num) << 8) + Lo(Adr) + (Hi(Adr) << 12);
  385.           return True;
  386.         }
  387.       }
  388.     }
  389.   }
  390.   return False;
  391. }
  392.  
  393. static Boolean DecodeIntName(char *Asc, Byte *Erg)
  394. {
  395.   Word HErg;
  396.   Byte LPart;
  397.   String Asc_N;
  398.  
  399.   strmaxcpy(Asc_N, Asc, STRINGSIZE);
  400.   NLS_UpString(Asc_N);
  401.   Asc = Asc_N;
  402.  
  403.   if (pCurrCPUProps->CoreType <= eCore402)
  404.     LPart = 0;
  405.   else if (pCurrCPUProps->CoreType < eCore004)
  406.     LPart = 1;
  407.   else if (pCurrCPUProps->CoreType < eCore104)
  408.     LPart = 2;
  409.   else
  410.     LPart = 3;
  411.        if (!strcmp(Asc, "IEBT"))   HErg = 0x000;
  412.   else if (!strcmp(Asc, "IEW"))    HErg = 0x102;
  413.   else if (!strcmp(Asc, "IETPG"))  HErg = 0x203;
  414.   else if (!strcmp(Asc, "IET0"))   HErg = 0x104;
  415.   else if (!strcmp(Asc, "IECSI"))  HErg = 0x005;
  416.   else if (!strcmp(Asc, "IECSIO")) HErg = 0x205;
  417.   else if (!strcmp(Asc, "IE0"))    HErg = 0x006;
  418.   else if (!strcmp(Asc, "IE2"))    HErg = 0x007;
  419.   else if (!strcmp(Asc, "IE4"))    HErg = 0x120;
  420.   else if (!strcmp(Asc, "IEKS"))   HErg = 0x123;
  421.   else if (!strcmp(Asc, "IET1"))   HErg = 0x224;
  422.   else if (!strcmp(Asc, "IE1"))    HErg = 0x126;
  423.   else if (!strcmp(Asc, "IE3"))    HErg = 0x227;
  424.   else
  425.     HErg = 0xfff;
  426.   if (HErg == 0xfff)
  427.     return False;
  428.   else if (Hi(HErg) > LPart)
  429.     return False;
  430.   else
  431.   {
  432.     *Erg = Lo(HErg);
  433.     return True;
  434.   }
  435. }
  436.  
  437. static void PutCode(Word Code)
  438. {
  439.   BAsmCode[0] = Lo(Code);
  440.   if (Hi(Code) == 0) CodeLen = 1;
  441.   else
  442.   {
  443.     BAsmCode[1] = Hi(Code); CodeLen = 2;
  444.   }
  445. }
  446.  
  447. static Word PageNum(Word Inp)
  448. {
  449.   return ((Inp >> 12) & 15);
  450. }
  451.  
  452. /*-------------------------------------------------------------------------*/
  453. /* Instruction Decoders */
  454.  
  455. static void DecodeFixed(Word Code)
  456. {
  457.   if (ChkArgCnt(0, 0))
  458.     PutCode(Code);
  459. }
  460.  
  461. static void DecodeMOV(Word Code)
  462. {
  463.   UNUSED(Code);
  464.  
  465.   if (ChkArgCnt(2, 2))
  466.   {
  467.     tAdrResult DestResult;
  468.  
  469.     DecodeAdr(&ArgStr[1], MModReg4 | MModReg8 | MModInd | MModAbs, &DestResult);
  470.     switch (DestResult.Mode)
  471.     {
  472.       case ModReg4:
  473.       {
  474.         tAdrResult SrcResult;
  475.  
  476.         DecodeAdr(&ArgStr[2], MModReg4 | MModInd | MModAbs | MModImm, &SrcResult);
  477.         switch (SrcResult.Mode)
  478.         {
  479.           case ModReg4:
  480.             if (DestResult.Part == 0)
  481.             {
  482.               PutCode(0x7899 + (((Word)SrcResult.Part) << 8)); CheckCore(eCore004);
  483.             }
  484.             else if (SrcResult.Part == 0)
  485.             {
  486.               PutCode(0x7099 + (((Word)DestResult.Part) << 8)); CheckCore(eCore004);
  487.             }
  488.             else WrError(ErrNum_InvAddrMode);
  489.             break;
  490.           case ModInd:
  491.             if (DestResult.Part != 0) WrError(ErrNum_InvAddrMode);
  492.             else PutCode(0xe0 + SrcResult.Part);
  493.             break;
  494.           case ModAbs:
  495.             if (DestResult.Part != 0) WrError(ErrNum_InvAddrMode);
  496.             else
  497.             {
  498.               BAsmCode[0] = 0xa3; BAsmCode[1] = SrcResult.Part; CodeLen = 2;
  499.             }
  500.             break;
  501.           case ModImm:
  502.             if (DestResult.Part == 0) PutCode(0x70 + SrcResult.Part);
  503.             else
  504.             {
  505.               PutCode(0x089a + (((Word)SrcResult.Part) << 12) + (((Word)DestResult.Part) << 8));
  506.               CheckCore(eCore004);
  507.             }
  508.             break;
  509.         }
  510.         break;
  511.       }
  512.       case ModReg8:
  513.       {
  514.         tAdrResult SrcResult;
  515.  
  516.         DecodeAdr(&ArgStr[2], MModReg8 | MModAbs | MModInd | MModImm, &SrcResult);
  517.         switch (SrcResult.Mode)
  518.         {
  519.           case ModReg8:
  520.             if (DestResult.Part == 0)
  521.             {
  522.               PutCode(0x58aa + (((Word)SrcResult.Part) << 8)); CheckCore(eCore004);
  523.             }
  524.             else if (SrcResult.Part == 0)
  525.             {
  526.               PutCode(0x50aa + (((Word)DestResult.Part) << 8)); CheckCore(eCore004);
  527.             }
  528.             else WrError(ErrNum_InvAddrMode);
  529.             break;
  530.           case ModAbs:
  531.             if (DestResult.Part != 0) WrError(ErrNum_InvAddrMode);
  532.             else
  533.             {
  534.               BAsmCode[0] = 0xa2; BAsmCode[1] = SrcResult.Part; CodeLen = 2;
  535.               if (!mFirstPassUnknown(SrcResult.PartSymFlags) && Odd(SrcResult.Part)) WrError(ErrNum_AddrNotAligned);
  536.             }
  537.             break;
  538.           case ModInd:
  539.             if ((DestResult.Part != 0) || (SrcResult.Part != 1)) WrError(ErrNum_InvAddrMode);
  540.             else
  541.             {
  542.               PutCode(0x18aa); CheckCore(eCore004);
  543.             }
  544.             break;
  545.           case ModImm:
  546.             if (Odd(DestResult.Part)) WrError(ErrNum_InvAddrMode);
  547.             else
  548.             {
  549.               BAsmCode[0] = 0x89 + DestResult.Part; BAsmCode[1] = SrcResult.Part; CodeLen = 2;
  550.             }
  551.             break;
  552.         }
  553.         break;
  554.       }
  555.       case ModInd:
  556.         if (DestResult.Part != 1) WrError(ErrNum_InvAddrMode);
  557.         else
  558.         {
  559.           tAdrResult SrcResult;
  560.  
  561.           DecodeAdr(&ArgStr[2], MModReg4 | MModReg8, &SrcResult);
  562.           switch (SrcResult.Mode)
  563.           {
  564.             case ModReg4:
  565.               if (SrcResult.Part != 0) WrError(ErrNum_InvAddrMode);
  566.               else
  567.               {
  568.                 PutCode(0xe8); CheckCore(eCore004);
  569.               }
  570.               break;
  571.             case ModReg8:
  572.               if (SrcResult.Part != 0) WrError(ErrNum_InvAddrMode);
  573.               else
  574.               {
  575.                 PutCode(0x10aa); CheckCore(eCore004);
  576.               }
  577.               break;
  578.           }
  579.         }
  580.         break;
  581.       case ModAbs:
  582.       {
  583.         tAdrResult SrcResult;
  584.  
  585.         DecodeAdr(&ArgStr[2], MModReg4 | MModReg8, &SrcResult);
  586.         switch (SrcResult.Mode)
  587.         {
  588.           case ModReg4:
  589.             if (SrcResult.Part != 0) WrError(ErrNum_InvAddrMode);
  590.             else
  591.             {
  592.               BAsmCode[0] = 0x93; BAsmCode[1] = DestResult.Part; CodeLen = 2;
  593.             }
  594.             break;
  595.           case ModReg8:
  596.             if (SrcResult.Part != 0) WrError(ErrNum_InvAddrMode);
  597.             else
  598.             {
  599.               BAsmCode[0] = 0x92; BAsmCode[1] = DestResult.Part; CodeLen = 2;
  600.               if (!mFirstPassUnknown(SrcResult.PartSymFlags) && Odd(DestResult.Part)) WrError(ErrNum_AddrNotAligned);
  601.             }
  602.             break;
  603.         }
  604.         break;
  605.       }
  606.     }
  607.   }
  608. }
  609.  
  610. static void DecodeXCH(Word Code)
  611. {
  612.   UNUSED(Code);
  613.  
  614.   if (ChkArgCnt(2, 2))
  615.   {
  616.     tAdrResult DestResult;
  617.  
  618.     DecodeAdr(&ArgStr[1], MModReg4 | MModReg8 | MModAbs | MModInd, &DestResult);
  619.     switch (DestResult.Mode)
  620.     {
  621.       case ModReg4:
  622.       {
  623.         tAdrResult SrcResult;
  624.  
  625.         DecodeAdr(&ArgStr[2], MModReg4 | MModAbs | MModInd, &SrcResult);
  626.         switch (SrcResult.Mode)
  627.         {
  628.           case ModReg4:
  629.             if (DestResult.Part == 0) PutCode(0xd8 + SrcResult.Part);
  630.             else if (SrcResult.Part == 0) PutCode(0xd8 + DestResult.Part);
  631.             else WrError(ErrNum_InvAddrMode);
  632.             break;
  633.           case ModAbs:
  634.             if (DestResult.Part != 0) WrError(ErrNum_InvAddrMode);
  635.             else
  636.             {
  637.               BAsmCode[0] = 0xb3; BAsmCode[1] = SrcResult.Part; CodeLen = 2;
  638.             }
  639.             break;
  640.           case ModInd:
  641.             if (DestResult.Part != 0) WrError(ErrNum_InvAddrMode);
  642.             else PutCode(0xe8 + SrcResult.Part);
  643.             break;
  644.         }
  645.         break;
  646.       }
  647.       case ModReg8:
  648.       {
  649.         tAdrResult SrcResult;
  650.  
  651.         DecodeAdr(&ArgStr[2], MModReg8 | MModAbs | MModInd, &SrcResult);
  652.         switch (SrcResult.Mode)
  653.         {
  654.           case ModReg8:
  655.             if (DestResult.Part == 0)
  656.             {
  657.               PutCode(0x40aa + (((Word)SrcResult.Part) << 8)); CheckCore(eCore004);
  658.             }
  659.             else if (SrcResult.Part == 0)
  660.             {
  661.               PutCode(0x40aa + (((Word)DestResult.Part) << 8)); CheckCore(eCore004);
  662.             }
  663.             else WrError(ErrNum_InvAddrMode);
  664.             break;
  665.           case ModAbs:
  666.             if (DestResult.Part != 0) WrError(ErrNum_InvAddrMode);
  667.             else
  668.             {
  669.               BAsmCode[0] = 0xb2; BAsmCode[1] = SrcResult.Part; CodeLen = 2;
  670.               if (mFirstPassUnknown(SrcResult.PartSymFlags) && Odd(SrcResult.Part)) WrError(ErrNum_AddrNotAligned);
  671.             }
  672.             break;
  673.           case ModInd:
  674.             if ((SrcResult.Part != 1) || (DestResult.Part != 0)) WrError(ErrNum_InvAddrMode);
  675.             else
  676.             {
  677.               PutCode(0x11aa); CheckCore(eCore004);
  678.             }
  679.             break;
  680.         }
  681.         break;
  682.       }
  683.       case ModAbs:
  684.       {
  685.         tAdrResult SrcResult;
  686.  
  687.         DecodeAdr(&ArgStr[2], MModReg4 | MModReg8, &SrcResult);
  688.         switch (SrcResult.Mode)
  689.         {
  690.           case ModReg4:
  691.             if (SrcResult.Part != 0) WrError(ErrNum_InvAddrMode);
  692.             else
  693.             {
  694.               BAsmCode[0] = 0xb3; BAsmCode[1] = DestResult.Part; CodeLen = 2;
  695.             }
  696.             break;
  697.           case ModReg8:
  698.             if (SrcResult.Part != 0) WrError(ErrNum_InvAddrMode);
  699.             else
  700.             {
  701.               BAsmCode[0] = 0xb2; BAsmCode[1] = DestResult.Part; CodeLen = 2;
  702.               if (mFirstPassUnknown(SrcResult.PartSymFlags) && Odd(DestResult.Part)) WrError(ErrNum_AddrNotAligned);
  703.             }
  704.             break;
  705.         }
  706.         break;
  707.       }
  708.       case ModInd:
  709.       {
  710.         tAdrResult SrcResult;
  711.  
  712.         DecodeAdr(&ArgStr[2], MModReg4 | MModReg8, &SrcResult);
  713.         switch (SrcResult.Mode)
  714.         {
  715.           case ModReg4:
  716.             if (SrcResult.Part != 0) WrError(ErrNum_InvAddrMode);
  717.             else PutCode(0xe8 + DestResult.Part);
  718.             break;
  719.           case ModReg8:
  720.             if ((SrcResult.Part != 0) || (DestResult.Part != 1)) WrError(ErrNum_InvAddrMode);
  721.             else
  722.             {
  723.               PutCode(0x11aa);
  724.               CheckCore(eCore004);
  725.             }
  726.             break;
  727.         }
  728.         break;
  729.       }
  730.     }
  731.   }
  732. }
  733.  
  734. static void DecodeMOVT(Word Code)
  735. {
  736.   UNUSED(Code);
  737.  
  738.   if (!ChkArgCnt(2, 2));
  739.   else if (as_strcasecmp(ArgStr[1].str.p_str, "XA")) WrError(ErrNum_InvAddrMode);
  740.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "@PCDE"))
  741.   {
  742.     PutCode(0xd4);
  743.     CheckCore(eCore004);
  744.   }
  745.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "@PCXA"))
  746.     PutCode(0xd0);
  747.   else
  748.     WrError(ErrNum_InvAddrMode);
  749. }
  750.  
  751. static void DecodePUSH_POP(Word Code)
  752. {
  753.   if (!ChkArgCnt(1, 1));
  754.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "BS"))
  755.   {
  756.     PutCode(0x0699 + (Code << 8)); CheckCore(eCore004);
  757.   }
  758.   else
  759.   {
  760.     tAdrResult Result;
  761.  
  762.     DecodeAdr(&ArgStr[1], MModReg8, &Result);
  763.     switch (Result.Mode)
  764.     {
  765.       case ModReg8:
  766.         if (Odd(Result.Part)) WrError(ErrNum_InvAddrMode);
  767.         else PutCode(0x48 + Code + Result.Part);
  768.         break;
  769.     }
  770.   }
  771. }
  772.  
  773. static void DecodeIN_OUT(Word IsIN)
  774. {
  775.   if (ChkArgCnt(2, 2))
  776.   {
  777.     const tStrComp *pPortArg = IsIN ? &ArgStr[2] : &ArgStr[1],
  778.                    *pRegArg = IsIN ? &ArgStr[1] : &ArgStr[2];
  779.  
  780.     if (as_strncasecmp(pPortArg->str.p_str, "PORT", 4)) WrError(ErrNum_InvAddrMode);
  781.     else
  782.     {
  783.       Boolean OK;
  784.  
  785.       BAsmCode[1] = 0xf0 + EvalStrIntExpressionOffs(pPortArg, 4, UInt4, &OK);
  786.       if (OK)
  787.       {
  788.         tAdrResult Result;
  789.  
  790.         DecodeAdr(pRegArg, MModReg8 | MModReg4, &Result);
  791.         switch (Result.Mode)
  792.         {
  793.           case ModReg4:
  794.             if (Result.Part != 0) WrError(ErrNum_InvAddrMode);
  795.             else
  796.             {
  797.               BAsmCode[0] = 0x93 + (IsIN << 4); CodeLen = 2;
  798.             }
  799.             break;
  800.           case ModReg8:
  801.             if (Result.Part != 0) WrError(ErrNum_InvAddrMode);
  802.             else
  803.             {
  804.               BAsmCode[0] = 0x92 + (IsIN << 4); CodeLen = 2;
  805.               CheckCore(eCore004);
  806.             }
  807.             break;
  808.         }
  809.       }
  810.     }
  811.   }
  812. }
  813.  
  814. static void DecodeADDS(Word Code)
  815. {
  816.   UNUSED(Code);
  817.  
  818.   if (ChkArgCnt(2, 2))
  819.   {
  820.     tAdrResult Result;
  821.  
  822.     DecodeAdr(&ArgStr[1], MModReg4 | MModReg8, &Result);
  823.     switch (Result.Mode)
  824.     {
  825.       case ModReg4:
  826.         if (Result.Part != 0) WrError(ErrNum_InvAddrMode);
  827.         else
  828.         {
  829.           DecodeAdr(&ArgStr[2], MModImm | MModInd, &Result);
  830.           switch (Result.Mode)
  831.           {
  832.             case ModImm:
  833.               PutCode(0x60 + Result.Part); break;
  834.             case ModInd:
  835.               if (Result.Part == 1) PutCode(0xd2); else WrError(ErrNum_InvAddrMode);
  836.               break;
  837.           }
  838.         }
  839.         break;
  840.       case ModReg8:
  841.         if (Result.Part == 0)
  842.         {
  843.           DecodeAdr(&ArgStr[2], MModReg8 | MModImm, &Result);
  844.           switch (Result.Mode)
  845.           {
  846.             case ModReg8:
  847.               PutCode(0xc8aa + (((Word)Result.Part) << 8));
  848.               CheckCore(eCore104);
  849.               break;
  850.             case ModImm:
  851.               BAsmCode[0] = 0xb9; BAsmCode[1] = Result.Part;
  852.               CodeLen = 2;
  853.               CheckCore(eCore104);
  854.               break;
  855.           }
  856.         }
  857.         else if (as_strcasecmp(ArgStr[2].str.p_str, "XA")) WrError(ErrNum_InvAddrMode);
  858.         else
  859.         {
  860.           PutCode(0xc0aa + (((Word)Result.Part) << 8));
  861.           CheckCore(eCore104);
  862.         }
  863.         break;
  864.     }
  865.   }
  866. }
  867.  
  868. static void DecodeAri(Word Code)
  869. {
  870.   if (ChkArgCnt(2, 2))
  871.   {
  872.     tAdrResult Result;
  873.  
  874.     DecodeAdr(&ArgStr[1], MModReg4 | MModReg8, &Result);
  875.     switch (Result.Mode)
  876.     {
  877.       case ModReg4:
  878.         if (Result.Part != 0) WrError(ErrNum_InvAddrMode);
  879.         else
  880.         {
  881.           DecodeAdr(&ArgStr[2], MModInd, &Result);
  882.           switch (Result.Mode)
  883.           {
  884.             case ModInd:
  885.               if (Result.Part == 1)
  886.               {
  887.                 BAsmCode[0] = 0xa8;
  888.                 if (Code == 0) BAsmCode[0]++;
  889.                 if (Code == 2) BAsmCode[0] += 0x10;
  890.                 CodeLen = 1;
  891.                 if (Code != 0)
  892.                   CheckCore(eCore004);
  893.               }
  894.               else
  895.                 WrError(ErrNum_InvAddrMode);
  896.              break;
  897.           }
  898.         }
  899.         break;
  900.       case ModReg8:
  901.         if (Result.Part == 0)
  902.         {
  903.           DecodeAdr(&ArgStr[2], MModReg8, &Result);
  904.           switch (Result.Mode)
  905.           {
  906.             case ModReg8:
  907.               PutCode(0xc8aa + ((Code + 1) << 12) + (((Word)Result.Part) << 8));
  908.               CheckCore(eCore104);
  909.               break;
  910.           }
  911.         }
  912.         else if (as_strcasecmp(ArgStr[2].str.p_str, "XA")) WrError(ErrNum_InvAddrMode);
  913.         else
  914.         {
  915.           PutCode(0xc0aa + ((Code + 1) << 12) + (((Word)Result.Part) << 8));
  916.           CheckCore(eCore104);
  917.         }
  918.         break;
  919.     }
  920.   }
  921. }
  922.  
  923. static void DecodeLog(Word Code)
  924. {
  925.   if (ChkArgCnt(2, 2))
  926.   {
  927.     tAdrResult Result;
  928.  
  929.     DecodeAdr(&ArgStr[1], MModReg4 | MModReg8, &Result);
  930.     switch (Result.Mode)
  931.     {
  932.       case ModReg4:
  933.         if (Result.Part != 0) WrError(ErrNum_InvAddrMode);
  934.         else
  935.         {
  936.           DecodeAdr(&ArgStr[2], MModImm | MModInd, &Result);
  937.           switch (Result.Mode)
  938.           {
  939.             case ModImm:
  940.               PutCode(0x2099 + (((Word)Result.Part & 15) << 8) + ((Code + 1) << 12));
  941.               CheckCore(eCore004);
  942.               break;
  943.             case ModInd:
  944.               if (Result.Part == 1)
  945.                 PutCode(0x80 + ((Code + 1) << 4));
  946.               else
  947.                 WrError(ErrNum_InvAddrMode);
  948.               break;
  949.           }
  950.         }
  951.         break;
  952.       case ModReg8:
  953.         if (Result.Part == 0)
  954.         {
  955.           DecodeAdr(&ArgStr[2], MModReg8, &Result);
  956.           switch (Result.Mode)
  957.           {
  958.             case ModReg8:
  959.               PutCode(0x88aa + (((Word)Result.Part) << 8) + ((Code + 1) << 12));
  960.               CheckCore(eCore104);
  961.               break;
  962.           }
  963.         }
  964.         else if (as_strcasecmp(ArgStr[2].str.p_str, "XA")) WrError(ErrNum_InvAddrMode);
  965.         else
  966.         {
  967.           PutCode(0x80aa + (((Word)Result.Part) << 8) + ((Code + 1) << 12));
  968.           CheckCore(eCore104);
  969.         }
  970.         break;
  971.     }
  972.   }
  973. }
  974.  
  975. static void DecodeLog1(Word Code)
  976. {
  977.   Word BVal;
  978.   tEvalResult EvalResult;
  979.  
  980.   if (!ChkArgCnt(2, 2));
  981.   else if (as_strcasecmp(ArgStr[1].str.p_str, "CY")) WrError(ErrNum_InvAddrMode);
  982.   else if (DecodeBitAddr(&ArgStr[2], &BVal, &EvalResult))
  983.   {
  984.     if (Hi(BVal) != 0) WrError(ErrNum_InvAddrMode);
  985.     else
  986.     {
  987.       BAsmCode[0] = 0xac + ((Code & 1) << 1) + ((Code & 2) << 3);
  988.       BAsmCode[1] = BVal;
  989.       CodeLen = 2;
  990.     }
  991.   }
  992. }
  993.  
  994. static void DecodeINCS(Word Code)
  995. {
  996.   UNUSED(Code);
  997.  
  998.   if (ChkArgCnt(1, 1))
  999.   {
  1000.     tAdrResult Result;
  1001.  
  1002.     DecodeAdr(&ArgStr[1], MModReg4 | MModReg8 | MModInd | MModAbs, &Result);
  1003.     switch (Result.Mode)
  1004.     {
  1005.       case ModReg4:
  1006.         PutCode(0xc0 + Result.Part);
  1007.         break;
  1008.       case ModReg8:
  1009.         if ((Result.Part < 1) || (Odd(Result.Part))) WrError(ErrNum_InvAddrMode);
  1010.         else
  1011.         {
  1012.           PutCode(0x88 + Result.Part);
  1013.           CheckCore(eCore104);
  1014.         }
  1015.         break;
  1016.       case ModInd:
  1017.         if (Result.Part == 1)
  1018.         {
  1019.           PutCode(0x0299);
  1020.           CheckCore(eCore004);
  1021.         }
  1022.         else
  1023.           WrError(ErrNum_InvAddrMode);
  1024.         break;
  1025.       case ModAbs:
  1026.         BAsmCode[0] = 0x82;
  1027.         BAsmCode[1] = Result.Part;
  1028.         CodeLen = 2;
  1029.         break;
  1030.     }
  1031.   }
  1032. }
  1033.  
  1034. static void DecodeDECS(Word Code)
  1035. {
  1036.   UNUSED(Code);
  1037.  
  1038.   if (ChkArgCnt(1, 1))
  1039.   {
  1040.     tAdrResult Result;
  1041.  
  1042.     DecodeAdr(&ArgStr[1], MModReg4 | MModReg8, &Result);
  1043.     switch (Result.Mode)
  1044.     {
  1045.       case ModReg4:
  1046.         PutCode(0xc8 + Result.Part);
  1047.         break;
  1048.       case ModReg8:
  1049.         PutCode(0x68aa + (((Word)Result.Part) << 8));
  1050.         CheckCore(eCore104);
  1051.         break;
  1052.     }
  1053.   }
  1054. }
  1055.  
  1056. static void DecodeSKE(Word Code)
  1057. {
  1058.   UNUSED(Code);
  1059.  
  1060.   if (ChkArgCnt(2, 2))
  1061.   {
  1062.     tAdrResult DestResult;
  1063.  
  1064.     DecodeAdr(&ArgStr[1], MModReg4 | MModReg8 | MModInd, &DestResult);
  1065.     switch (DestResult.Mode)
  1066.     {
  1067.       case ModReg4:
  1068.       {
  1069.         tAdrResult SrcResult;
  1070.  
  1071.         DecodeAdr(&ArgStr[2], MModImm | MModInd | MModReg4, &SrcResult);
  1072.         switch (SrcResult.Mode)
  1073.         {
  1074.           case ModReg4:
  1075.             if (DestResult.Part == 0)
  1076.             {
  1077.               PutCode(0x0899 + (((Word)SrcResult.Part) << 8));
  1078.               CheckCore(eCore004);
  1079.             }
  1080.             else if (SrcResult.Part == 0)
  1081.             {
  1082.               PutCode(0x0899 + (((Word)DestResult.Part) << 8));
  1083.               CheckCore(eCore004);
  1084.             }
  1085.             else WrError(ErrNum_InvAddrMode);
  1086.             break;
  1087.           case ModImm:
  1088.             BAsmCode[0] = 0x9a;
  1089.             BAsmCode[1] = (SrcResult.Part << 4) + DestResult.Part;
  1090.             CodeLen = 2;
  1091.             break;
  1092.           case ModInd:
  1093.             if ((SrcResult.Part == 1) && (DestResult.Part == 0))
  1094.               PutCode(0x80);
  1095.             else
  1096.               WrError(ErrNum_InvAddrMode);
  1097.             break;
  1098.         }
  1099.         break;
  1100.       }
  1101.       case ModReg8:
  1102.       {
  1103.         tAdrResult SrcResult;
  1104.  
  1105.         DecodeAdr(&ArgStr[2], MModInd | MModReg8, &SrcResult);
  1106.         switch (SrcResult.Mode)
  1107.         {
  1108.           case ModReg8:
  1109.             if (DestResult.Part == 0)
  1110.             {
  1111.               PutCode(0x48aa + (((Word)SrcResult.Part) << 8));
  1112.               CheckCore(eCore104);
  1113.             }
  1114.             else if (SrcResult.Part == 0)
  1115.             {
  1116.               PutCode(0x48aa + (((Word)DestResult.Part) << 8));
  1117.               CheckCore(eCore104);
  1118.             }
  1119.             else WrError(ErrNum_InvAddrMode);
  1120.             break;
  1121.           case ModInd:
  1122.             if (SrcResult.Part == 1)
  1123.             {
  1124.               PutCode(0x19aa);
  1125.               CheckCore(eCore104);
  1126.             }
  1127.             else
  1128.               WrError(ErrNum_InvAddrMode);
  1129.             break;
  1130.         }
  1131.         break;
  1132.       }
  1133.       case ModInd:
  1134.         if (DestResult.Part != 1) WrError(ErrNum_InvAddrMode);
  1135.         else
  1136.         {
  1137.           tAdrResult SrcResult;
  1138.  
  1139.           DecodeAdr(&ArgStr[2], MModImm | MModReg4 | MModReg8 | MModMinOneIs0, &SrcResult);
  1140.           switch (SrcResult.Mode)
  1141.           {
  1142.             case ModImm:
  1143.               PutCode(0x6099 + (((Word)SrcResult.Part) << 8));
  1144.               CheckCore(eCore004);
  1145.               break;
  1146.             case ModReg4:
  1147.               if (SrcResult.Part == 0)
  1148.                 PutCode(0x80);
  1149.               else
  1150.                 WrError(ErrNum_InvAddrMode);
  1151.               break;
  1152.             case ModReg8:
  1153.               if (SrcResult.Part == 0)
  1154.               {
  1155.                 PutCode(0x19aa);
  1156.                 CheckCore(eCore004);
  1157.               }
  1158.               else
  1159.                 WrError(ErrNum_InvAddrMode);
  1160.               break;
  1161.           }
  1162.         }
  1163.         break;
  1164.     }
  1165.   }
  1166. }
  1167.  
  1168. static void DecodeAcc(Word Code)
  1169. {
  1170.   if (!ChkArgCnt(1, 1));
  1171.   else if (as_strcasecmp(ArgStr[1].str.p_str, "A")) WrError(ErrNum_InvAddrMode);
  1172.   else
  1173.     PutCode(Code);
  1174. }
  1175.  
  1176. static void DecodeMOV1(Word Code)
  1177. {
  1178.   UNUSED(Code);
  1179.  
  1180.   if (ChkArgCnt(2, 2))
  1181.   {
  1182.     Boolean OK = True;
  1183.     Word BVal;
  1184.     tEvalResult EvalResult;
  1185.  
  1186.     if (!as_strcasecmp(ArgStr[1].str.p_str, "CY"))
  1187.       Code = 0xbd;
  1188.     else if (!as_strcasecmp(ArgStr[2].str.p_str, "CY"))
  1189.       Code = 0x9b;
  1190.     else OK = False;
  1191.     if (!OK) WrError(ErrNum_InvAddrMode);
  1192.     else if (DecodeBitAddr(&ArgStr[((Code >> 2) & 3) - 1], &BVal, &EvalResult))
  1193.     {
  1194.       if (Hi(BVal) != 0) WrError(ErrNum_InvAddrMode);
  1195.       else
  1196.       {
  1197.         BAsmCode[0] = Code;
  1198.         BAsmCode[1] = BVal;
  1199.         CodeLen = 2;
  1200.         CheckCore(eCore104);
  1201.       }
  1202.     }
  1203.   }
  1204. }
  1205.  
  1206. static void DecodeSET1_CLR1(Word Code)
  1207. {
  1208.   Word BVal;
  1209.   tEvalResult EvalResult;
  1210.  
  1211.   if (!ChkArgCnt(1, 1));
  1212.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "CY"))
  1213.     PutCode(0xe6 + Code);
  1214.   else if (DecodeBitAddr(&ArgStr[1], &BVal, &EvalResult))
  1215.   {
  1216.     if (Hi(BVal) != 0)
  1217.     {
  1218.       BAsmCode[0] = 0x84 + Code + (Hi(BVal & 0x300) << 4);
  1219.       BAsmCode[1] = Lo(BVal);
  1220.       CodeLen = 2;
  1221.     }
  1222.     else
  1223.     {
  1224.       BAsmCode[0] = 0x9c + Code;
  1225.       BAsmCode[1] = BVal;
  1226.       CodeLen = 2;
  1227.     }
  1228.   }
  1229. }
  1230.  
  1231. static void DecodeSKT_SKF(Word Code)
  1232. {
  1233.   Word BVal;
  1234.   tEvalResult EvalResult;
  1235.  
  1236.   if (!ChkArgCnt(1, 1));
  1237.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "CY"))
  1238.   {
  1239.     if (Code)
  1240.       PutCode(0xd7);
  1241.     else
  1242.       WrError(ErrNum_InvAddrMode);
  1243.   }
  1244.   else if (DecodeBitAddr(&ArgStr[1], &BVal, &EvalResult))
  1245.   {
  1246.     if (Hi(BVal) != 0)
  1247.     {
  1248.       BAsmCode[0] = 0x86 + Code + (Hi(BVal & 0x300) << 4);
  1249.       BAsmCode[1] = Lo(BVal);
  1250.       CodeLen = 2;
  1251.     }
  1252.     else
  1253.     {
  1254.       BAsmCode[0] = 0xbe + Code;
  1255.       BAsmCode[1] = BVal;
  1256.       CodeLen = 2;
  1257.     }
  1258.   }
  1259. }
  1260.  
  1261. static void DecodeNOT1(Word Code)
  1262. {
  1263.   UNUSED(Code);
  1264.  
  1265.   if (!ChkArgCnt(1, 1));
  1266.   else if (as_strcasecmp(ArgStr[1].str.p_str, "CY")) WrError(ErrNum_InvAddrMode);
  1267.   else
  1268.     PutCode(0xd6);
  1269. }
  1270.  
  1271. static void DecodeSKTCLR(Word Code)
  1272. {
  1273.   Word BVal;
  1274.   tEvalResult EvalResult;
  1275.  
  1276.   UNUSED(Code);
  1277.  
  1278.   if (!ChkArgCnt(1, 1));
  1279.   else if (DecodeBitAddr(&ArgStr[1], &BVal, &EvalResult))
  1280.   {
  1281.     if (Hi(BVal) != 0) WrError(ErrNum_InvAddrMode);
  1282.     else
  1283.     {
  1284.       BAsmCode[0] = 0x9f;
  1285.       BAsmCode[1] = BVal;
  1286.       CodeLen = 2;
  1287.     }
  1288.   }
  1289. }
  1290.  
  1291. static void DecodeBR(Word Code)
  1292. {
  1293.   UNUSED(Code);
  1294.  
  1295.   if (!ChkArgCnt(1, 1));
  1296.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "PCDE"))
  1297.   {
  1298.     PutCode(0x0499);
  1299.     CheckCore(eCore004);
  1300.   }
  1301.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "PCXA"))
  1302.   {
  1303.     BAsmCode[0] = 0x99;
  1304.     BAsmCode[1] = 0x00;
  1305.     CodeLen = 2;
  1306.     CheckCore(eCore104);
  1307.   }
  1308.   else
  1309.   {
  1310.     Integer AdrInt, Dist;
  1311.     Boolean BrRel, BrLong;
  1312.     unsigned Offset = 0;
  1313.     tEvalResult EvalResult;
  1314.  
  1315.     BrRel = False;
  1316.     BrLong = False;
  1317.     if (ArgStr[1].str.p_str[Offset] == '$')
  1318.     {
  1319.       BrRel = True;
  1320.       Offset++;
  1321.     }
  1322.     else if (ArgStr[1].str.p_str[Offset] == '!')
  1323.     {
  1324.       BrLong = True;
  1325.       Offset++;
  1326.     }
  1327.     AdrInt = EvalStrIntExpressionOffsWithResult(&ArgStr[1], Offset, UInt16, &EvalResult);
  1328.     if (EvalResult.OK)
  1329.     {
  1330.       Dist = AdrInt - EProgCounter();
  1331.       if ((BrRel) || ((Dist <= 16) && (Dist >= -15) && (Dist != 0)))
  1332.       {
  1333.         if (Dist > 0)
  1334.         {
  1335.           Dist--;
  1336.           if ((Dist > 15) && !mSymbolQuestionable(EvalResult.Flags)) WrError(ErrNum_JmpDistTooBig);
  1337.           else
  1338.             PutCode(0x00 + Dist);
  1339.         }
  1340.         else
  1341.         {
  1342.           if ((Dist < -15) && !mSymbolQuestionable(EvalResult.Flags)) WrError(ErrNum_JmpDistTooBig);
  1343.           else
  1344.             PutCode(0xf0 + 15 + Dist);
  1345.         }
  1346.       }
  1347.       else if ((!BrLong) && (PageNum(AdrInt) == PageNum(EProgCounter())) && ((EProgCounter() & 0xfff) < 0xffe))
  1348.       {
  1349.         BAsmCode[0] = 0x50 + ((AdrInt >> 8) & 15);
  1350.         BAsmCode[1] = Lo(AdrInt);
  1351.         CodeLen = 2;
  1352.       }
  1353.       else
  1354.       {
  1355.         BAsmCode[0] = 0xab;
  1356.         BAsmCode[1] = Hi(AdrInt & 0x3fff);
  1357.         BAsmCode[2] = Lo(AdrInt);
  1358.         CodeLen = 3;
  1359.         CheckCore(eCore004);
  1360.       }
  1361.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1362.     }
  1363.   }
  1364. }
  1365.  
  1366. static void DecodeBRCB(Word Code)
  1367. {
  1368.   UNUSED(Code);
  1369.  
  1370.   if (ChkArgCnt(1, 1))
  1371.   {
  1372.     tEvalResult EvalResult;
  1373.     Integer AdrInt = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
  1374.  
  1375.     if (EvalResult.OK)
  1376.     {
  1377.       if (!ChkSamePage(AdrInt, EProgCounter(), 12, EvalResult.Flags));
  1378.       else if ((EProgCounter() & 0xfff) >= 0xffe) WrError(ErrNum_NotFromThisAddress);
  1379.       else
  1380.       {
  1381.         BAsmCode[0] = 0x50 + ((AdrInt >> 8) & 15);
  1382.         BAsmCode[1] = Lo(AdrInt);
  1383.         CodeLen = 2;
  1384.         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1385.       }
  1386.     }
  1387.   }
  1388. }
  1389.  
  1390. static void DecodeCALL(Word Code)
  1391. {
  1392.   UNUSED(Code);
  1393.  
  1394.   if (ChkArgCnt(1, 1))
  1395.   {
  1396.     unsigned BrLong = !!(*ArgStr[1].str.p_str == '!');
  1397.     tEvalResult EvalResult;
  1398.     Integer AdrInt = EvalStrIntExpressionOffsWithResult(&ArgStr[1], BrLong, UInt16, &EvalResult);
  1399.     if (mFirstPassUnknown(EvalResult.Flags)) AdrInt &= 0x7ff;
  1400.     if (EvalResult.OK)
  1401.     {
  1402.       if ((BrLong) || (AdrInt > 0x7ff))
  1403.       {
  1404.         BAsmCode[0] = 0xab;
  1405.         BAsmCode[1] = 0x40 + Hi(AdrInt & 0x3fff);
  1406.         BAsmCode[2] = Lo(AdrInt);
  1407.         CodeLen = 3;
  1408.         CheckCore(eCore004);
  1409.       }
  1410.       else
  1411.       {
  1412.         BAsmCode[0] = 0x40 + Hi(AdrInt & 0x7ff);
  1413.         BAsmCode[1] = Lo(AdrInt);
  1414.         CodeLen = 2;
  1415.       }
  1416.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1417.     }
  1418.   }
  1419. }
  1420.  
  1421. static void DecodeCALLF(Word Code)
  1422. {
  1423.   UNUSED(Code);
  1424.  
  1425.   if (ChkArgCnt(1, 1))
  1426.   {
  1427.     tEvalResult EvalResult;
  1428.     Integer AdrInt = EvalStrIntExpressionOffsWithResult(&ArgStr[1], !!(*ArgStr[1].str.p_str == '!'), UInt11, &EvalResult);
  1429.     if (EvalResult.OK)
  1430.     {
  1431.       BAsmCode[0] = 0x40 + Hi(AdrInt);
  1432.       BAsmCode[1] = Lo(AdrInt);
  1433.       CodeLen = 2;
  1434.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1435.     }
  1436.   }
  1437. }
  1438.  
  1439. static void DecodeGETI(Word Code)
  1440. {
  1441.   UNUSED(Code);
  1442.  
  1443.   if (ChkArgCnt(1, 1))
  1444.   {
  1445.     Boolean OK;
  1446.  
  1447.     BAsmCode[0] = EvalStrIntExpression(&ArgStr[1], UInt6, &OK);
  1448.     CodeLen = Ord(OK);
  1449.     CheckCore(eCore004);
  1450.   }
  1451. }
  1452.  
  1453. static void DecodeEI_DI(Word Code)
  1454. {
  1455.   Byte HReg;
  1456.  
  1457.   if (ArgCnt == 0)
  1458.     PutCode(0xb29c + Code);
  1459.   else if (!ChkArgCnt(1, 1));
  1460.   else if (DecodeIntName(ArgStr[1].str.p_str, &HReg))
  1461.     PutCode(0x989c + Code + (((Word)HReg) << 8));
  1462.   else
  1463.     WrError(ErrNum_InvCtrlReg);
  1464. }
  1465.  
  1466. static void DecodeSEL(Word Code)
  1467. {
  1468.   Boolean OK;
  1469.  
  1470.   UNUSED(Code);
  1471.  
  1472.   BAsmCode[0] = 0x99;
  1473.   if (!ChkArgCnt(1, 1));
  1474.   else if (!as_strncasecmp(ArgStr[1].str.p_str, "RB", 2))
  1475.   {
  1476.     BAsmCode[1] = 0x20 + EvalStrIntExpressionOffs(&ArgStr[1], 2, UInt2, &OK);
  1477.     if (OK)
  1478.     {
  1479.       CodeLen = 2;
  1480.       CheckCore(eCore104);
  1481.     }
  1482.   }
  1483.   else if (!as_strncasecmp(ArgStr[1].str.p_str, "MB", 2))
  1484.   {
  1485.     BAsmCode[1] = 0x10 + EvalStrIntExpressionOffs(&ArgStr[1], 2, UInt4, &OK);
  1486.     if (OK)
  1487.     {
  1488.       CodeLen = 2;
  1489.       CheckCore(eCore004);
  1490.     }
  1491.   }
  1492.   else
  1493.     WrError(ErrNum_InvAddrMode);
  1494. }
  1495.  
  1496. static void DecodeSFR(Word Code)
  1497. {
  1498.   UNUSED(Code);
  1499.  
  1500.   CodeEquate(SegData, 0, 0xfff);
  1501. }
  1502.  
  1503. static void DecodeBIT(Word Code)
  1504. {
  1505.   Word BErg;
  1506.  
  1507.   UNUSED(Code);
  1508.  
  1509.   if (ChkArgCnt(1, 1))
  1510.   {
  1511.     tEvalResult EvalResult;
  1512.  
  1513.     if (DecodeBitAddr(&ArgStr[1], &BErg, &EvalResult))
  1514.       if (!mFirstPassUnknown(EvalResult.Flags))
  1515.       {
  1516.         PushLocHandle(-1);
  1517.         EnterIntSymbol(&LabPart, BErg, SegBData, False);
  1518.         *ListLine = '=';
  1519.         DissectBit_75K0(ListLine + 1,  STRINGSIZE- 1, BErg);
  1520.         PopLocHandle();
  1521.       }
  1522.   }
  1523. }
  1524.  
  1525. /*-------------------------------------------------------------------------*/
  1526. /* dynamische Codetabellenverwaltung */
  1527.  
  1528. static void AddFixed(const char *NewName, Word NewCode)
  1529. {
  1530.   AddInstTable(InstTable, NewName, NewCode, DecodeFixed);
  1531. }
  1532.  
  1533. static void InitFields(void)
  1534. {
  1535.   InstTable = CreateInstTable(103);
  1536.   AddInstTable(InstTable, "MOV", 0, DecodeMOV);
  1537.   AddInstTable(InstTable, "XCH", 0, DecodeXCH);
  1538.   AddInstTable(InstTable, "MOVT", 0, DecodeMOVT);
  1539.   AddInstTable(InstTable, "PUSH", 1, DecodePUSH_POP);
  1540.   AddInstTable(InstTable, "POP", 0, DecodePUSH_POP);
  1541.   AddInstTable(InstTable, "IN", 1, DecodeIN_OUT);
  1542.   AddInstTable(InstTable, "OUT", 0, DecodeIN_OUT);
  1543.   AddInstTable(InstTable, "ADDS", 0, DecodeADDS);
  1544.   AddInstTable(InstTable, "INCS", 0, DecodeINCS);
  1545.   AddInstTable(InstTable, "DECS", 0, DecodeDECS);
  1546.   AddInstTable(InstTable, "SKE", 0, DecodeSKE);
  1547.   AddInstTable(InstTable, "RORC", 0x98, DecodeAcc);
  1548.   AddInstTable(InstTable, "NOT", 0x5f99, DecodeAcc);
  1549.   AddInstTable(InstTable, "MOV1", 0, DecodeMOV1);
  1550.   AddInstTable(InstTable, "SET1", 1, DecodeSET1_CLR1);
  1551.   AddInstTable(InstTable, "CLR1", 0, DecodeSET1_CLR1);
  1552.   AddInstTable(InstTable, "SKT", 1, DecodeSKT_SKF);
  1553.   AddInstTable(InstTable, "SKF", 0, DecodeSKT_SKF);
  1554.   AddInstTable(InstTable, "NOT1", 0, DecodeNOT1);
  1555.   AddInstTable(InstTable, "SKTCLR", 0, DecodeSKTCLR);
  1556.   AddInstTable(InstTable, "BR", 0, DecodeBR);
  1557.   AddInstTable(InstTable, "BRCB", 0, DecodeBRCB);
  1558.   AddInstTable(InstTable, "CALL", 0, DecodeCALL);
  1559.   AddInstTable(InstTable, "CALLF", 0, DecodeCALLF);
  1560.   AddInstTable(InstTable, "GETI", 0, DecodeGETI);
  1561.   AddInstTable(InstTable, "EI", 1, DecodeEI_DI);
  1562.   AddInstTable(InstTable, "DI", 0, DecodeEI_DI);
  1563.   AddInstTable(InstTable, "SEL", 0, DecodeSEL);
  1564.   AddInstTable(InstTable, "SFR", 0, DecodeSFR);
  1565.   AddInstTable(InstTable, "BIT", 0, DecodeBIT);
  1566.  
  1567.   AddFixed("RET" , 0x00ee);
  1568.   AddFixed("RETS", 0x00e0);
  1569.   AddFixed("RETI", 0x00ef);
  1570.   AddFixed("HALT", 0xa39d);
  1571.   AddFixed("STOP", 0xb39d);
  1572.   AddFixed("NOP" , 0x0060);
  1573.  
  1574.   InstrZ = 0;
  1575.   AddInstTable(InstTable, "ADDC", InstrZ++, DecodeAri);
  1576.   AddInstTable(InstTable, "SUBS", InstrZ++, DecodeAri);
  1577.   AddInstTable(InstTable, "SUBC", InstrZ++, DecodeAri);
  1578.  
  1579.   InstrZ = 0;
  1580.   AddInstTable(InstTable, "AND", InstrZ++, DecodeLog);
  1581.   AddInstTable(InstTable, "OR" , InstrZ++, DecodeLog);
  1582.   AddInstTable(InstTable, "XOR", InstrZ++, DecodeLog);
  1583.  
  1584.   InstrZ = 0;
  1585.   AddInstTable(InstTable, "AND1", InstrZ++, DecodeLog1);
  1586.   AddInstTable(InstTable, "OR1" , InstrZ++, DecodeLog1);
  1587.   AddInstTable(InstTable, "XOR1", InstrZ++, DecodeLog1);
  1588. }
  1589.  
  1590. static void DeinitFields(void)
  1591. {
  1592.   DestroyInstTable(InstTable);
  1593. }
  1594.  
  1595. /*-------------------------------------------------------------------------*/
  1596.  
  1597. static void MakeCode_75K0(void)
  1598. {
  1599.   CodeLen = 0;
  1600.   DontPrint = False;
  1601.   OpSize = -1;
  1602.  
  1603.   /* zu ignorierendes */
  1604.  
  1605.   if (Memo(""))
  1606.     return;
  1607.  
  1608.   /* Pseudoanweisungen */
  1609.  
  1610.   if (DecodeIntelPseudo(True))
  1611.     return;
  1612.  
  1613.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1614.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1615. }
  1616.  
  1617. static void InitCode_75K0(void)
  1618. {
  1619.   MBSValue = 0; MBEValue = 0;
  1620. }
  1621.  
  1622. static Boolean IsDef_75K0(void)
  1623. {
  1624.   return ((Memo("SFR")) || (Memo("BIT")));
  1625. }
  1626.  
  1627. static void SwitchFrom_75K0(void)
  1628. {
  1629.   DeinitFields();
  1630. }
  1631.  
  1632. static ASSUMERec ASSUME75s[] =
  1633. {
  1634.   {"MBS", &MBSValue, 0, 0x0f, 0x10, NULL},
  1635.   {"MBE", &MBEValue, 0, 0x01, 0x01, CheckMBE}
  1636. };
  1637. #define ASSUME75Count (sizeof(ASSUME75s) / sizeof(*ASSUME75s))
  1638.  
  1639. static void SwitchTo_75K0(void *pUser)
  1640. {
  1641.   Boolean Err;
  1642.   Word ROMEnd;
  1643.  
  1644.   pCurrCPUProps = (const tCPUProps*)pUser;
  1645.   TurnWords = False;
  1646.   SetIntConstMode(eIntConstModeIntel);
  1647.  
  1648.   PCSymbol = "PC"; HeaderID = 0x7b; NOPCode = 0x60;
  1649.   DivideChars = ","; HasAttrs = False;
  1650.  
  1651.   ValidSegs = (1 << SegCode)|(1 << SegData);
  1652.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  1653.   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 0;
  1654.   SegLimits[SegData] = 0xfff;
  1655.   ROMEnd = ConstLongInt(&MomCPUName[3], &Err, 10);
  1656.   if (ROMEnd > 2)
  1657.     ROMEnd %= 10;
  1658.   SegLimits[SegCode] = (ROMEnd << 10) - 1;
  1659.  
  1660.   pASSUMERecs = ASSUME75s;
  1661.   ASSUMERecCnt = ASSUME75Count;
  1662.  
  1663.   MakeCode = MakeCode_75K0; IsDef = IsDef_75K0;
  1664.   SwitchFrom = SwitchFrom_75K0; InitFields();
  1665.   DissectBit = DissectBit_75K0;
  1666. }
  1667.  
  1668. static const tCPUProps CPUProps[] =
  1669. {
  1670.   { "75402", eCore402 },
  1671.   { "75004", eCore004 },
  1672.   { "75006", eCore004 },
  1673.   { "75008", eCore004 },
  1674.   { "75268", eCore004 },
  1675.   { "75304", eCore004 },
  1676.   { "75306", eCore004 },
  1677.   { "75308", eCore004 },
  1678.   { "75312", eCore004 },
  1679.   { "75316", eCore004 },
  1680.   { "75328", eCore004 },
  1681.   { "75104", eCore104 },
  1682.   { "75106", eCore104 },
  1683.   { "75108", eCore104 },
  1684.   { "75112", eCore104 },
  1685.   { "75116", eCore104 },
  1686.   { "75206", eCore104 },
  1687.   { "75208", eCore104 },
  1688.   { "75212", eCore104 },
  1689.   { "75216", eCore104 },
  1690.   { "75512", eCore104 },
  1691.   { "75516", eCore104 },
  1692.   { ""     , 0        }
  1693. };
  1694.  
  1695. void code75k0_init(void)
  1696. {
  1697.   const tCPUProps *pProps;
  1698.  
  1699.   for (pProps = CPUProps; pProps->Name[0]; pProps++)
  1700.     (void)AddCPUUser(pProps->Name, SwitchTo_75K0, (void*)pProps, NULL);
  1701.  
  1702.   AddInitPassProc(InitCode_75K0);
  1703. }
  1704.