Subversion Repositories pentevo

Rev

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

  1. /* codeace.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegeneratormodul ACE-Familie                                            */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <string.h>
  14.  
  15. #include "bpemu.h"
  16. #include "strutil.h"
  17. #include "chunks.h"
  18. #include "headids.h"
  19. #include "asmdef.h"
  20. #include "asmsub.h"
  21. #include "asmpars.h"
  22. #include "asmitree.h"
  23. #include "codepseudo.h"
  24. #include "intpseudo.h"
  25. #include "codevars.h"
  26. #include "onoff_common.h"
  27. #include "errmsg.h"
  28.  
  29. #include "codeace.h"
  30.  
  31. enum
  32. {
  33.   ModNone = -1,
  34.   ModAcc = 0,
  35.   ModX = 1,
  36.   ModXInd = 2,
  37.   ModXDisp = 3,
  38.   ModDir = 4,
  39.   ModImm = 5
  40. };
  41.  
  42. #define MModAcc (1 << ModAcc)
  43. #define MModX (1 << ModX)
  44. #define MModXInd (1 << ModXInd)
  45. #define MModXDisp (1 << ModXDisp)
  46. #define MModDir (1 << ModDir)
  47. #define MModImm (1 << ModImm)
  48.  
  49. typedef struct
  50. {
  51.   Byte ImmCode, DirCode, IndCode, DispCode;
  52. } AriOrder;
  53.  
  54. typedef struct
  55. {
  56.   Byte AccCode, XCode, DirCode;
  57. } SingOrder;
  58.  
  59. typedef struct
  60. {
  61.   Byte AccCode, XIndCode, DirCode;
  62. } BitOrder;
  63.  
  64. enum { D_CPUACE1101, D_CPUACE1202 };
  65.  
  66. static CPUVar CPUACE1101, CPUACE1202;
  67.  
  68. static AriOrder *AriOrders;
  69. static SingOrder *SingOrders;
  70. static BitOrder *BitOrders;
  71.  
  72. static ShortInt AdrMode;
  73. static Byte AdrVal;
  74. static Word WAdrVal;
  75. static Boolean OpSize;
  76.  
  77. /*---------------------------------------------------------------------------*/
  78.  
  79. static void ChkAdr(Word Mask)
  80. {
  81.   if ((AdrMode == ModXDisp) && !ChkMinCPUExt(CPUACE1202, ErrNum_AddrModeNotSupported))
  82.     AdrMode = ModNone;
  83.   else if ((AdrMode != ModNone) && ((Mask & (1 << AdrMode)) == 0))
  84.   {
  85.     AdrMode = ModNone; WrError(ErrNum_InvAddrMode);
  86.   }
  87. }
  88.  
  89. static void DecodeAdr(const tStrComp *pArg, Word Mask)
  90. {
  91.   Boolean OK, DispOcc, XOcc;
  92.   int ArgLen;
  93.   char *p;
  94.  
  95.   AdrMode = ModNone;
  96.  
  97.   /* Register ? */
  98.  
  99.   if (!as_strcasecmp(pArg->str.p_str, "A"))
  100.    AdrMode = ModAcc;
  101.  
  102.   else if (!as_strcasecmp(pArg->str.p_str, "X"))
  103.    AdrMode = ModX;
  104.  
  105.   /* immediate ? */
  106.  
  107.   else if (*pArg->str.p_str== '#')
  108.   {
  109.     if (OpSize)
  110.       WAdrVal = EvalStrIntExpressionOffs(pArg, 1, Int12, &OK);
  111.     else
  112.       AdrVal = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
  113.     if (OK) AdrMode = ModImm;
  114.   }
  115.  
  116.   /* indirekt ? */
  117.  
  118.   else if (*pArg->str.p_str == '[')
  119.   {
  120.     ArgLen = strlen(pArg->str.p_str);
  121.     if (pArg->str.p_str[ArgLen - 1] != ']') WrError(ErrNum_InvAddrMode);
  122.     else
  123.     {
  124.       tStrComp Arg, Remainder;
  125.  
  126.       StrCompRefRight(&Arg, pArg, 1);
  127.       StrCompShorten(&Arg, 1);
  128.       DispOcc = XOcc = False;
  129.       do
  130.       {
  131.         p = QuotPos(Arg.str.p_str, ',');
  132.         if (p)
  133.           StrCompSplitRef(&Arg, &Remainder, &Arg, p);
  134.         KillPrefBlanksStrComp(&Arg);
  135.         KillPostBlanksStrComp(&Arg);
  136.         if (!as_strcasecmp(Arg.str.p_str, "X"))
  137.           if (XOcc)
  138.           {
  139.             WrError(ErrNum_InvAddrMode); break;
  140.           }
  141.           else
  142.             XOcc = True;
  143.         else if (DispOcc)
  144.         {
  145.           WrError(ErrNum_InvAddrMode); break;
  146.         }
  147.         else
  148.         {
  149.           AdrVal = EvalStrIntExpressionOffs(&Arg, !!(*Arg.str.p_str == '#'), UInt8, &OK);
  150.           if (!OK) break;
  151.           DispOcc = True;
  152.         }
  153.         if (p)
  154.           Arg = Remainder;
  155.       }
  156.       while (p);
  157.       if (!p)
  158.         AdrMode = (DispOcc && (AdrVal != 0)) ? ModXDisp : ModXInd;
  159.     }
  160.   }
  161.  
  162.   /* direkt */
  163.  
  164.   else
  165.   {
  166.     if (OpSize)
  167.       WAdrVal = EvalStrIntExpression(pArg, UInt12, &OK);
  168.     else
  169.       AdrVal = EvalStrIntExpression(pArg, UInt8, &OK);
  170.     if (OK) AdrMode = ModDir;
  171.   }
  172.  
  173.   ChkAdr(Mask);
  174. }
  175.  
  176. /*---------------------------------------------------------------------------*/
  177.  
  178. static void DecodeFixed(Word Code)
  179. {
  180.   if (ChkArgCnt(0, 0))
  181.   {
  182.     BAsmCode[0] = Code;
  183.     CodeLen = 1;
  184.   }
  185. }
  186.  
  187. static void DecodeAri(Word Index)
  188. {
  189.   AriOrder *porder = AriOrders + Index;
  190.  
  191.   if (ChkArgCnt(2, 2))
  192.   {
  193.     DecodeAdr(&ArgStr[1], MModAcc);
  194.     if (AdrMode != ModNone)
  195.     {
  196.       DecodeAdr(&ArgStr[2], MModImm | MModDir | MModXInd | MModXDisp);
  197.       switch (AdrMode)
  198.       {
  199.         case ModImm:
  200.           BAsmCode[0] = porder->ImmCode;
  201.           BAsmCode[1] = AdrVal;
  202.           CodeLen = 2;
  203.           break;
  204.         case ModDir:
  205.           BAsmCode[0] = porder->DirCode;
  206.           BAsmCode[1] = AdrVal;
  207.           CodeLen = 2;
  208.           break;
  209.         case ModXInd:
  210.           BAsmCode[0] = porder->IndCode;
  211.           CodeLen = 1;
  212.           break;
  213.         case ModXDisp:
  214.           BAsmCode[0] = porder->DispCode;
  215.           BAsmCode[1] = AdrVal;
  216.           CodeLen = 2;
  217.           break;
  218.       }
  219.     }
  220.   }
  221. }
  222.  
  223. static void DecodeSing(Word Index)
  224. {
  225.   SingOrder *porder = SingOrders + Index;
  226.  
  227.   if (ChkArgCnt(1, 1))
  228.   {
  229.     DecodeAdr(&ArgStr[1], MModDir | MModX | MModAcc);
  230.     switch (AdrMode)
  231.     {
  232.       case ModDir:
  233.         BAsmCode[0] = porder->DirCode;
  234.         BAsmCode[1] = AdrVal;
  235.         CodeLen = 2;
  236.         break;
  237.       case ModAcc:
  238.         BAsmCode[0] = porder->AccCode;
  239.         CodeLen = 1;
  240.         break;
  241.       case ModX:
  242.         BAsmCode[0] = porder->XCode;
  243.         CodeLen = 1;
  244.         break;
  245.     }
  246.   }
  247. }
  248.  
  249. static void DecodeBit(Word Index)
  250. {
  251.   Byte Bit, Mask;
  252.   BitOrder *porder = BitOrders + Index;
  253.   Boolean OK;
  254.  
  255.   if (ChkArgCnt(2, 2))
  256.   {
  257.     Bit = EvalStrIntExpression(&ArgStr[1], UInt8, &OK);
  258.     if (OK)
  259.     {
  260.       Mask = 0;
  261.       if (porder->AccCode != 0xff) Mask |= MModAcc;
  262.       if (porder->XIndCode != 0xff) Mask |= MModXInd;
  263.       if (porder->DirCode != 0xff) Mask |= MModDir;
  264.       DecodeAdr(&ArgStr[2], Mask);
  265.       switch (AdrMode)
  266.       {
  267.         case ModAcc:
  268.           BAsmCode[0] = porder->AccCode;
  269.           if (porder->AccCode & 7)
  270.           {
  271.             BAsmCode[1] = 1 << Bit;
  272.             if (porder->AccCode & 1)
  273.               BAsmCode[1] = 255 - BAsmCode[1];
  274.             CodeLen = 2;
  275.           }
  276.           else
  277.           {
  278.             BAsmCode[0] |= Bit;
  279.             CodeLen = 1;
  280.           }
  281.           break;
  282.         case ModXInd:
  283.           BAsmCode[0] = porder->XIndCode + Bit;
  284.           CodeLen = 1;
  285.           break;
  286.         case ModDir:
  287.           BAsmCode[0] = porder->DirCode + Bit;
  288.           BAsmCode[1] = AdrVal;
  289.           CodeLen = 2;
  290.           break;
  291.       }
  292.     }
  293.   }
  294. }
  295.  
  296. static void DecodeIFEQ(Word Index)
  297. {
  298.   UNUSED(Index);
  299.  
  300.   if (ChkArgCnt(2, 2))
  301.   {
  302.     DecodeAdr(&ArgStr[1], MModAcc | MModX | MModDir);
  303.     switch (AdrMode)
  304.     {
  305.       case ModAcc:
  306.         DecodeAdr(&ArgStr[2], MModImm | MModDir | MModXInd | MModXDisp);
  307.         switch (AdrMode)
  308.         {
  309.           case ModImm:
  310.             BAsmCode[0] = 0x65;
  311.             BAsmCode[1] = AdrVal;
  312.             CodeLen = 2;
  313.             break;
  314.           case ModDir:
  315.             BAsmCode[0] = 0x56;
  316.             BAsmCode[1] = AdrVal;
  317.             CodeLen = 2;
  318.             break;
  319.           case ModXInd:
  320.             BAsmCode[0] = 0x09;
  321.             CodeLen = 1;
  322.             break;
  323.           case ModXDisp:
  324.             BAsmCode[0] = 0x76;
  325.             BAsmCode[1] = AdrVal;
  326.             CodeLen = 2;
  327.             break;
  328.         }
  329.         break;
  330.       case ModX:
  331.         OpSize = True;
  332.         DecodeAdr(&ArgStr[2], MModImm);
  333.         switch (AdrMode)
  334.         {
  335.           case ModImm:
  336.             BAsmCode[0] = 0x26;
  337.             BAsmCode[1] = Lo(WAdrVal);
  338.             BAsmCode[2] = Hi(WAdrVal);
  339.             CodeLen = 3;
  340.             break;
  341.         }
  342.         break;
  343.       case ModDir:
  344.         BAsmCode[1] = AdrVal;
  345.         DecodeAdr(&ArgStr[2], MModImm);
  346.         switch (AdrMode)
  347.         {
  348.           case ModImm:
  349.             BAsmCode[0] = 0x20;
  350.             BAsmCode[2] = AdrVal;
  351.             CodeLen = 3;
  352.             break;
  353.         }
  354.         break;
  355.     }
  356.   }
  357. }
  358.  
  359. static void DecodeIFGT(Word Index)
  360. {
  361.   UNUSED(Index);
  362.  
  363.   if (ChkArgCnt(2, 2))
  364.   {
  365.     DecodeAdr(&ArgStr[1], MModAcc | MModX);
  366.     switch (AdrMode)
  367.     {
  368.       case ModAcc:
  369.         DecodeAdr(&ArgStr[2], MModImm | MModDir | MModXInd | MModXDisp);
  370.         switch (AdrMode)
  371.         {
  372.           case ModImm:
  373.             BAsmCode[0] = 0x67;
  374.             BAsmCode[1] = AdrVal;
  375.             CodeLen = 2;
  376.             break;
  377.           case ModDir:
  378.             BAsmCode[0] = 0x55;
  379.             BAsmCode[1] = AdrVal;
  380.             CodeLen = 2;
  381.             break;
  382.           case ModXInd:
  383.             BAsmCode[0] = 0x0a;
  384.             CodeLen = 1;
  385.             break;
  386.           case ModXDisp:
  387.             BAsmCode[0] = 0x77;
  388.             BAsmCode[1] = AdrVal;
  389.             CodeLen = 2;
  390.             break;
  391.         }
  392.         break;
  393.       case ModX:
  394.         OpSize = True;
  395.         DecodeAdr(&ArgStr[2], MModImm);
  396.         switch (AdrMode)
  397.         {
  398.           case ModImm:
  399.             BAsmCode[0] = 0x27;
  400.             BAsmCode[1] = Lo(WAdrVal);
  401.             BAsmCode[2] = Hi(WAdrVal);
  402.             CodeLen = 3;
  403.             break;
  404.         }
  405.         break;
  406.     }
  407.   }
  408. }
  409.  
  410. static void DecodeIFLT(Word Index)
  411. {
  412.   UNUSED(Index);
  413.  
  414.   if (ChkArgCnt(2, 2))
  415.   {
  416.     DecodeAdr(&ArgStr[1], MModX);
  417.     switch (AdrMode)
  418.     {
  419.       case ModX:
  420.         OpSize = True;
  421.         DecodeAdr(&ArgStr[2], MModImm);
  422.         switch (AdrMode)
  423.         {
  424.           case ModImm:
  425.             BAsmCode[0] = 0x28;
  426.             BAsmCode[1] = Lo(WAdrVal);
  427.             BAsmCode[2] = Hi(WAdrVal);
  428.             CodeLen = 3;
  429.             break;
  430.         }
  431.         break;
  432.     }
  433.   }
  434. }
  435.  
  436. static void DecodeJMPJSR(Word Index)
  437. {
  438.   if (ChkArgCnt(1, 1))
  439.   {
  440.     OpSize = True;
  441.     DecodeAdr(&ArgStr[1], MModDir | MModXDisp);
  442.     switch (AdrMode)
  443.     {
  444.       case ModDir:
  445.         BAsmCode[0] = 0x24 - Index;
  446.         BAsmCode[1] = Lo(WAdrVal);
  447.         BAsmCode[2] = Hi(WAdrVal);
  448.         CodeLen = 3;
  449.         break;
  450.       case ModXDisp:
  451.         BAsmCode[0] = 0x7e + Index;
  452.         BAsmCode[1] = AdrVal;
  453.         CodeLen = 2;
  454.         break;
  455.     }
  456.   }
  457. }
  458.  
  459. static void DecodeJP(Word Index)
  460. {
  461.   LongInt Dist;
  462.   Boolean OK;
  463.   tSymbolFlags Flags;
  464.  
  465.   UNUSED(Index);
  466.  
  467.   if (ChkArgCnt(1, 1))
  468.   {
  469.     Dist = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt12, &OK, &Flags) - (EProgCounter() + 1);
  470.     if (OK)
  471.     {
  472.       if (!mSymbolQuestionable(Flags) && ((Dist > 31) || (Dist < -31))) WrError(ErrNum_JmpDistTooBig);
  473.       else
  474.       {
  475.         BAsmCode[0] = (Dist >= 0) ? 0xe0 + Dist : 0xc0 - Dist;
  476.         CodeLen = 1;
  477.       }
  478.     }
  479.   }
  480. }
  481.  
  482. static void DecodeLD(Word Index)
  483. {
  484.   UNUSED(Index);
  485.  
  486.   if (ChkArgCnt(2, 2))
  487.   {
  488.     DecodeAdr(&ArgStr[1], MModAcc | MModX | MModDir);
  489.     switch (AdrMode)
  490.     {
  491.       case ModAcc:
  492.         DecodeAdr(&ArgStr[2], MModImm | MModDir | MModXInd | MModXDisp);
  493.         switch (AdrMode)
  494.         {
  495.           case ModImm:
  496.             BAsmCode[0] = 0x51;
  497.             BAsmCode[1] = AdrVal;
  498.             CodeLen = 2;
  499.             break;
  500.           case ModDir:
  501.             BAsmCode[0] = 0x46;
  502.             BAsmCode[1] = AdrVal;
  503.             CodeLen = 2;
  504.             break;
  505.           case ModXInd:
  506.             BAsmCode[0] = 0x0e;
  507.             CodeLen = 1;
  508.             break;
  509.           case ModXDisp:
  510.             BAsmCode[0] = 0x52;
  511.             BAsmCode[1] = AdrVal;
  512.             CodeLen = 2;
  513.             break;
  514.         }
  515.         break;
  516.       case ModX:
  517.         OpSize = True;
  518.         DecodeAdr(&ArgStr[2], MModImm);
  519.         switch (AdrMode)
  520.         {
  521.           case ModImm:
  522.             BAsmCode[0] = 0x25;
  523.             BAsmCode[1] = Lo(WAdrVal);
  524.             BAsmCode[2] = Hi(WAdrVal);
  525.             CodeLen = 3;
  526.             break;
  527.         }
  528.         break;
  529.       case ModDir:
  530.         BAsmCode[1] = AdrVal;
  531.         DecodeAdr(&ArgStr[2], MModImm | MModDir);
  532.         switch (AdrMode)
  533.         {
  534.           case ModImm:
  535.             BAsmCode[0] = 0x21;
  536.             BAsmCode[2] = AdrVal;
  537.             CodeLen = 3;
  538.             break;
  539.           case ModDir:
  540.             BAsmCode[0] = 0x22;
  541.             BAsmCode[2] = BAsmCode[1];
  542.             BAsmCode[1] = AdrVal;
  543.             CodeLen = 3;
  544.             break;
  545.         }
  546.         break;
  547.     }
  548.   }
  549. }
  550.  
  551. static void DecodeRotate(Word Index)
  552. {
  553.   if (ChkArgCnt(1, 1))
  554.   {
  555.     DecodeAdr(&ArgStr[1], MModAcc | MModDir);
  556.     switch (AdrMode)
  557.     {
  558.       case ModAcc:
  559.         BAsmCode[0] = 0x15 - Index - Index;
  560.         CodeLen = 1;
  561.         break;
  562.       case ModDir:
  563.         BAsmCode[0] = 0x79 + Index;
  564.         BAsmCode[1] = AdrVal;
  565.         CodeLen = 2;
  566.         break;
  567.     }
  568.   }
  569. }
  570.  
  571. static void DecodeST(Word Index)
  572. {
  573.   UNUSED(Index);
  574.  
  575.   if (ChkArgCnt(2, 2))
  576.   {
  577.     DecodeAdr(&ArgStr[1], MModAcc);
  578.     switch (AdrMode)
  579.     {
  580.       case ModAcc:
  581.         DecodeAdr(&ArgStr[2], MModDir | MModXInd | MModXDisp);
  582.         switch (AdrMode)
  583.         {
  584.           case ModDir:
  585.             BAsmCode[0] = 0x47;
  586.             BAsmCode[1] = AdrVal;
  587.             CodeLen = 2;
  588.             break;
  589.           case ModXInd:
  590.             BAsmCode[0] = 0x11;
  591.             CodeLen = 1;
  592.             break;
  593.           case ModXDisp:
  594.             BAsmCode[0] = 0x40;
  595.             BAsmCode[1] = AdrVal;
  596.             CodeLen = 2;
  597.             break;
  598.         }
  599.         break;
  600.     }
  601.   }
  602. }
  603.  
  604. static void DecodeSFR(Word Code)
  605. {
  606.   UNUSED(Code);
  607.  
  608.   CodeEquate(SegCode, 0, 0xff);
  609. }
  610.  
  611. /*---------------------------------------------------------------------------*/
  612.  
  613. static void AddFixed(const char *NName, Byte NCode)
  614. {
  615.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  616. }
  617.  
  618. static void AddAri(const char *NName, Byte NImm, Byte NDir, Byte NInd, Byte NDisp)
  619. {
  620.   order_array_rsv_end(AriOrders, AriOrder);
  621.   AriOrders[InstrZ].ImmCode = NImm;
  622.   AriOrders[InstrZ].DirCode = NDir;
  623.   AriOrders[InstrZ].IndCode = NInd;
  624.   AriOrders[InstrZ].DispCode = NDisp;
  625.   AddInstTable(InstTable, NName, InstrZ++, DecodeAri);
  626. }
  627.  
  628. static void AddSing(const char *NName, Byte NAcc, Byte NX, Byte NDir)
  629. {
  630.   order_array_rsv_end(SingOrders, SingOrder);
  631.   SingOrders[InstrZ].AccCode = NAcc;
  632.   SingOrders[InstrZ].XCode = NX;
  633.   SingOrders[InstrZ].DirCode = NDir;
  634.   AddInstTable(InstTable, NName, InstrZ++, DecodeSing);
  635. }
  636.  
  637. static void AddBit(const char *NName, Byte NAcc, Byte NIndX, Byte NDir)
  638. {
  639.   order_array_rsv_end(BitOrders, BitOrder);
  640.   BitOrders[InstrZ].AccCode = NAcc;
  641.   BitOrders[InstrZ].XIndCode = NIndX;
  642.   BitOrders[InstrZ].DirCode = NDir;
  643.   AddInstTable(InstTable, NName, InstrZ++, DecodeBit);
  644. }
  645.  
  646. static void InitFields(void)
  647. {
  648.   InstTable = CreateInstTable(101);
  649.  
  650.   add_null_pseudo(InstTable);
  651.  
  652.   InstrZ = 0;
  653.   AddFixed("IFC"  ,0x19);  AddFixed("IFNC" ,0x1f);  AddFixed("INTR" ,0x00);
  654.   AddFixed("INVC" ,0x12);  AddFixed("NOP"  ,0x1c);  AddFixed("RC"   ,0x1e);
  655.   AddFixed("RET"  ,0x17);  AddFixed("RETI" ,0x18);  AddFixed("SC"   ,0x1d);
  656.  
  657.   InstrZ = 0;
  658.   AddAri("ADC" , 0x60, 0x42, 0x02, 0x70);
  659.   AddAri("ADD" , 0x66, 0x43, 0x03, 0x71);
  660.   AddAri("AND" , 0x61, 0x50, 0x04, 0x72);
  661.   AddAri("IFNE", 0x57, 0x54, 0x0b, 0x78);
  662.   AddAri("OR"  , 0x62, 0x44, 0x05, 0x73);
  663.   AddAri("SUBC", 0x63, 0x53, 0x06, 0x74);
  664.   AddAri("XOR" , 0x64, 0x45, 0x07, 0x75);
  665.  
  666.   InstrZ = 0;
  667.   AddSing("CLR" , 0x16, 0x0f, 0x7d);
  668.   AddSing("DEC" , 0x1a, 0x0c, 0x7b);
  669.   AddSing("INC" , 0x1b, 0x0d, 0x7c);
  670.  
  671.   InstrZ = 0;
  672.   AddBit("IFBIT", 0xa0, 0xa8, 0x58);
  673.   AddBit("LDC"  , 0xff, 0xff, 0x80);
  674.   AddBit("RBIT" , 0x61, 0xb8, 0x68);
  675.   AddBit("SBIT" , 0x62, 0xb0, 0x48);
  676.   AddBit("STC"  , 0xff, 0xff, 0x88);
  677.  
  678.   AddInstTable(InstTable, "IFEQ", 0, DecodeIFEQ);
  679.   AddInstTable(InstTable, "IFGT", 0, DecodeIFGT);
  680.   AddInstTable(InstTable, "IFLT", 0, DecodeIFLT);
  681.   AddInstTable(InstTable, "JMP" , 0, DecodeJMPJSR);
  682.   AddInstTable(InstTable, "JSR" , 1, DecodeJMPJSR);
  683.   AddInstTable(InstTable, "JP"  , 0, DecodeJP);
  684.   AddInstTable(InstTable, "LD"  , 0, DecodeLD);
  685.   AddInstTable(InstTable, "RLC" , 0, DecodeRotate);
  686.   AddInstTable(InstTable, "RRC" , 1, DecodeRotate);
  687.   AddInstTable(InstTable, "ST"  , 0, DecodeST);
  688.   AddInstTable(InstTable, "SFR" , 0, DecodeSFR);
  689.  
  690.   AddIntelPseudo(InstTable, eIntPseudoFlag_DynEndian);
  691. }
  692.  
  693. static void DeinitFields(void)
  694. {
  695.   DestroyInstTable(InstTable);
  696.   order_array_free(AriOrders);
  697.   order_array_free(SingOrders);
  698.   order_array_free(BitOrders);
  699. }
  700.  
  701. /*---------------------------------------------------------------------------*/
  702.  
  703. static void MakeCode_ACE(void)
  704. {
  705.   OpSize = False;
  706.  
  707.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  708.    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  709. }
  710.  
  711. static Boolean IsDef_ACE(void)
  712. {
  713.   return (Memo("SFR"));
  714. }
  715.  
  716. static void SwitchFrom_ACE(void)
  717. {
  718.   DeinitFields();
  719. }
  720.  
  721. static void SwitchTo_ACE(void)
  722. {
  723.   const TFamilyDescr *Descr;
  724.  
  725.   TurnWords = False;
  726.   SetIntConstMode(eIntConstModeIntel);
  727.  
  728.   Descr = FindFamilyByName("ACE");
  729.   PCSymbol = "$";
  730.   HeaderID = Descr->Id;
  731.   NOPCode = 0x1c;
  732.   DivideChars = ",";
  733.   HasAttrs = False;
  734.  
  735.   ValidSegs = (1 << SegCode);
  736.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegLimits[SegCode] = 0xfff;
  737.  
  738.   switch (MomCPU - CPUACE1101)
  739.   {
  740.     case D_CPUACE1101:
  741.       SegInits[SegCode] = 0xc00;
  742.       break;
  743.     case D_CPUACE1202:
  744.       SegInits[SegCode] = 0x800;
  745.       break;
  746.   }
  747.  
  748.   MakeCode = MakeCode_ACE;
  749.   IsDef = IsDef_ACE;
  750.   SwitchFrom = SwitchFrom_ACE;
  751.   onoff_bigendian_add();
  752.   InitFields();
  753. }
  754.  
  755. void codeace_init(void)
  756. {
  757.   CPUACE1101 = AddCPU("ACE1101", SwitchTo_ACE);
  758.   CPUACE1202 = AddCPU("ACE1202", SwitchTo_ACE);
  759. }
  760.