Subversion Repositories pentevo

Rev

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

  1. /* codefmc8.c */
  2. /****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS, C-Version                                                            */
  6. /*                                                                          */
  7. /* Codegenerator fuer Fujitsu-F2MC8L-Prozessoren                            */
  8. /*                                                                          */
  9. /****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "bpemu.h"
  16. #include "strutil.h"
  17. #include "asmdef.h"
  18. #include "asmpars.h"
  19. #include "asmsub.h"
  20. #include "codepseudo.h"
  21. #include "intpseudo.h"
  22. #include "asmitree.h"
  23. #include "codevars.h"
  24. #include "headids.h"
  25. #include "errmsg.h"
  26.  
  27. #include "codefmc8.h"
  28.  
  29. /*--------------------------------------------------------------------------*/
  30. /* Definitionen */
  31.  
  32. #define ModNone (-1)
  33. enum
  34. {
  35.   ModAcc,
  36.   ModDir,
  37.   ModExt,
  38.   ModIIX,
  39.   ModIEP,
  40.   ModIA,
  41.   ModReg,
  42.   ModReg16,
  43.   ModT,
  44.   ModPC,
  45.   ModPS,
  46.   ModImm
  47. };
  48. #define MModAcc   (1 << ModAcc)
  49. #define MModDir   (1 << ModDir)
  50. #define MModExt   (1 << ModExt)
  51. #define MModIIX   (1 << ModIIX)
  52. #define MModIEP   (1 << ModIEP)
  53. #define MModIA    (1 << ModIA)
  54. #define MModReg   (1 << ModReg)
  55. #define MModReg16 (1 << ModReg16)
  56. #define MModT     (1 << ModT)
  57. #define MModPC    (1 << ModPC)
  58. #define MModPS    (1 << ModPS)
  59. #define MModImm   (1 << ModImm)
  60.  
  61. static CPUVar CPU89190;
  62.  
  63. static int AdrMode;
  64. static Byte AdrPart, AdrVals[2];
  65. static int OpSize;
  66.  
  67. /*--------------------------------------------------------------------------*/
  68. /* Adressdekoder */
  69.  
  70. static void DecodeAdr(const tStrComp *pArg, unsigned Mask)
  71. {
  72.   Boolean OK;
  73.   Word Address;
  74.  
  75.   AdrMode = ModNone;
  76.   AdrCnt = 0;
  77.  
  78.   /* Register ? */
  79.  
  80.   if (!as_strcasecmp(pArg->str.p_str, "A"))
  81.    AdrMode = ModAcc;
  82.  
  83.   else if (!as_strcasecmp(pArg->str.p_str, "SP"))
  84.   {
  85.     AdrMode = ModReg16;
  86.     AdrPart = 1;
  87.   }
  88.  
  89.   else if (!as_strcasecmp(pArg->str.p_str, "IX"))
  90.   {
  91.     AdrMode = ModReg16;
  92.     AdrPart = 2;
  93.   }
  94.  
  95.   else if (!as_strcasecmp(pArg->str.p_str, "EP"))
  96.   {
  97.     AdrMode = ModReg16;
  98.     AdrPart = 3;
  99.   }
  100.  
  101.   else if (!as_strcasecmp(pArg->str.p_str, "T"))
  102.     AdrMode = ModT;
  103.  
  104.   else if (!as_strcasecmp(pArg->str.p_str, "PC"))
  105.     AdrMode = ModPC;
  106.  
  107.   else if (!as_strcasecmp(pArg->str.p_str, "PS"))
  108.     AdrMode = ModPS;
  109.  
  110.   else if ((strlen(pArg->str.p_str) == 2) && (as_toupper(*pArg->str.p_str) == 'R') && (pArg->str.p_str[1]>= '0') && (pArg->str.p_str[1] <= '7'))
  111.   {
  112.     AdrMode = ModReg;
  113.     AdrPart = pArg->str.p_str[1] - '0' + 8;
  114.   }
  115.  
  116.   /* immediate ? */
  117.  
  118.   else if (*pArg->str.p_str == '#')
  119.   {
  120.     if (OpSize)
  121.     {
  122.       Address = EvalStrIntExpressionOffs(pArg, 1, Int16, &OK);
  123.       if (OK)
  124.       {
  125.         /***Problem: Byte order? */
  126.         AdrVals[0] = Lo(Address);
  127.         AdrVals[1] = Hi(Address);
  128.         AdrMode = ModImm;
  129.         AdrCnt = 2;
  130.         AdrPart = 4;
  131.       }
  132.     }
  133.     else
  134.     {
  135.       AdrVals[0] = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
  136.       if (OK)
  137.       {
  138.         AdrMode = ModImm;
  139.         AdrCnt = 1;
  140.         AdrPart = 4;
  141.       }
  142.     }
  143.   }
  144.  
  145.   /* indirekt ? */
  146.  
  147.   else if (!as_strcasecmp(pArg->str.p_str, "@EP"))
  148.   {
  149.     AdrMode = ModIEP;
  150.     AdrPart = 7;
  151.   }
  152.  
  153.   else if (!as_strcasecmp(pArg->str.p_str, "@A"))
  154.   {
  155.     AdrMode = ModIA;
  156.     AdrPart = 7;
  157.   }
  158.  
  159.   else if (!as_strncasecmp(pArg->str.p_str, "@IX", 3))
  160.   {
  161.     /***Problem: Offset signed oder unsigned? */
  162.     AdrVals[0] = EvalStrIntExpressionOffs(pArg, 3, SInt8, &OK);
  163.     if (OK)
  164.     {
  165.       AdrMode = ModIIX;
  166.       AdrCnt = 1;
  167.       AdrPart = 6;
  168.     }
  169.   }
  170.  
  171.   /* direkt ? */
  172.  
  173.   else
  174.   {
  175.     Address = EvalStrIntExpression(pArg, (Mask & MModExt) ? UInt16 : UInt8, &OK);
  176.     if (OK)
  177.     {
  178.       if ((Mask & MModDir) && (Hi(Address) == 0))
  179.       {
  180.         AdrVals[0] = Lo(Address);
  181.         AdrMode = ModDir;
  182.         AdrCnt = 1;
  183.         AdrPart = 5;
  184.       }
  185.       else
  186.       {
  187.         AdrMode = ModExt;
  188.         AdrCnt = 2;
  189.         /***Problem: Byte order? */
  190.         AdrVals[0] = Lo(Address);
  191.         AdrVals[1] = Hi(Address);
  192.       }
  193.     }
  194.   }
  195.  
  196.   /* erlaubt ? */
  197.  
  198.   if ((AdrMode != ModNone) && ((Mask & (1 << AdrMode)) == 0))
  199.   {
  200.     WrError(ErrNum_InvAddrMode);
  201.     AdrMode = ModNone;
  202.     AdrCnt = 0;
  203.   }
  204. }
  205.  
  206. static Boolean DecodeBitAdr(const tStrComp *pArg, Byte *Adr, Byte *Bit)
  207. {
  208.   char *sep;
  209.   tStrComp AddrArg, BitArg;
  210.   Boolean OK;
  211.  
  212.   sep = strchr(pArg->str.p_str, ':');
  213.   if (!sep)
  214.     return FALSE;
  215.   StrCompSplitRef(&AddrArg, &BitArg, pArg, sep);
  216.  
  217.   *Adr = EvalStrIntExpression(&AddrArg, UInt8, &OK);
  218.   if (!OK) return FALSE;
  219.  
  220.   *Bit = EvalStrIntExpression(&BitArg, UInt3, &OK);
  221.   if (!OK) return FALSE;
  222.  
  223.   return TRUE;
  224. }
  225.  
  226. /*--------------------------------------------------------------------------*/
  227. /* ind. Decoder */
  228.  
  229. static void DecodeFixed(Word Code)
  230. {
  231.   if (ChkArgCnt(0, 0))
  232.   {
  233.     BAsmCode[0] = Code;
  234.     CodeLen = 1;
  235.   }
  236. }
  237.  
  238. static void DecodeAcc(Word Code)
  239. {
  240.   if (ChkArgCnt(1, 1))
  241.   {
  242.     DecodeAdr(&ArgStr[1], MModAcc);
  243.     if (AdrMode != ModNone)
  244.     {
  245.       BAsmCode[0] = Code;
  246.       CodeLen = 1;
  247.     }
  248.   }
  249. }
  250.  
  251. static void DecodeALU(Word Code)
  252. {
  253.   if (ChkArgCnt(1, 2))
  254.   {
  255.     DecodeAdr(&ArgStr[1], MModAcc);
  256.     if (AdrMode != ModNone)
  257.     {
  258.       if (ArgCnt == 1)
  259.       {
  260.         BAsmCode[0] = Code + 2;
  261.         CodeLen = 1;
  262.       }
  263.       else
  264.       {
  265.         OpSize = 0;
  266.         DecodeAdr(&ArgStr[2], MModDir | MModIIX | MModIEP | MModReg | MModImm);
  267.         if (AdrMode != ModNone)
  268.         {
  269.           BAsmCode[0] = Code + AdrPart;
  270.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  271.           CodeLen = 1 + AdrCnt;
  272.         }
  273.       }
  274.     }
  275.   }
  276. }
  277.  
  278. static void DecodeRel(Word Code)
  279. {
  280.   Integer Adr;
  281.   Boolean OK;
  282.   tSymbolFlags Flags;
  283.  
  284.   if (ChkArgCnt(1, 1))
  285.   {
  286.     Adr = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &OK, &Flags) - (EProgCounter() + 2);
  287.     if (OK)
  288.     {
  289.       if (((Adr < -128) || (Adr > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  290.       else
  291.       {
  292.         BAsmCode[0] = Code;
  293.         BAsmCode[1] = Adr & 0xff;
  294.         CodeLen = 2;
  295.       }
  296.     }
  297.   }
  298. }
  299.  
  300. static void DecodeMOV(Word Index)
  301. {
  302.   Byte HReg;
  303.   UNUSED(Index);
  304.  
  305.   if (ChkArgCnt(2, 2))
  306.   {
  307.     OpSize = 0;
  308.     DecodeAdr(&ArgStr[1], MModAcc | MModDir | MModIIX | MModIEP | MModExt | MModReg | MModIA);
  309.     switch (AdrMode)
  310.     {
  311.       case ModAcc:
  312.         DecodeAdr(&ArgStr[2], MModDir | MModIIX | MModIEP | MModIA | MModReg | MModImm| MModExt);
  313.         switch (AdrMode)
  314.         {
  315.           case ModDir:
  316.           case ModIIX:
  317.           case ModIEP:
  318.           case ModReg:
  319.           case ModImm:
  320.             BAsmCode[0] = 0x00 + AdrPart;
  321.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  322.             CodeLen = 1 + AdrCnt;
  323.             break;
  324.           case ModExt:
  325.             BAsmCode[0] = 0x60;
  326.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  327.             CodeLen = 1 + AdrCnt;
  328.             break;
  329.           case ModIA:
  330.             BAsmCode[0] = 0x92;
  331.             CodeLen = 1 + AdrCnt;
  332.             break;
  333.         }
  334.         break;
  335.  
  336.       case ModDir:
  337.         BAsmCode[1] = AdrVals[0];
  338.         DecodeAdr(&ArgStr[2], MModAcc | MModImm);
  339.         switch (AdrMode)
  340.         {
  341.           case ModAcc:
  342.             BAsmCode[0] = 0x45;
  343.             CodeLen = 2;
  344.             break;
  345.           case ModImm:
  346.             BAsmCode[0] = 0x85;       /***turn Byte 1+2 for F2MC ? */
  347.             BAsmCode[2] = AdrVals[0];
  348.            CodeLen = 3;
  349.            break;
  350.        }
  351.        break;
  352.  
  353.       case ModIIX:
  354.         BAsmCode[1] = AdrVals[0];
  355.         DecodeAdr(&ArgStr[2], MModAcc | MModImm);
  356.         switch (AdrMode)
  357.         {
  358.          case ModAcc:
  359.            BAsmCode[0] = 0x46;
  360.            CodeLen = 2;
  361.            break;
  362.          case ModImm:
  363.            BAsmCode[0] = 0x86;       /***turn Byte 1+2 for F2MC ? */
  364.            BAsmCode[2] = AdrVals[0];
  365.            CodeLen = 3;
  366.            break;
  367.         }
  368.         break;
  369.  
  370.       case ModIEP:
  371.         DecodeAdr(&ArgStr[2], MModAcc | MModImm);
  372.         switch (AdrMode)
  373.         {
  374.           case ModAcc:
  375.             BAsmCode[0] = 0x47;
  376.             CodeLen = 1;
  377.             break;
  378.           case ModImm:
  379.             BAsmCode[0] = 0x87;
  380.             BAsmCode[1] = AdrVals[0];
  381.             CodeLen = 2;
  382.             break;
  383.         }
  384.        break;
  385.  
  386.       case ModExt:
  387.         BAsmCode[1] = AdrVals[0];
  388.         BAsmCode[2] = AdrVals[1];
  389.         DecodeAdr(&ArgStr[2], MModAcc);
  390.         switch (AdrMode)
  391.         {
  392.           case ModAcc:
  393.             BAsmCode[0] = 0x61;
  394.             CodeLen = 3;
  395.             break;
  396.         }
  397.         break;
  398.  
  399.       case ModReg:
  400.         HReg = AdrPart;
  401.         DecodeAdr(&ArgStr[2], MModAcc | MModImm);
  402.         switch (AdrMode)
  403.         {
  404.           case ModAcc:
  405.             BAsmCode[0] = 0x40 + HReg;
  406.             CodeLen = 1;
  407.             break;
  408.           case ModImm:
  409.             BAsmCode[0] = 0x80 + HReg;
  410.             BAsmCode[1] = AdrVals[0];
  411.             CodeLen = 2;
  412.             break;
  413.         }
  414.         break;
  415.  
  416.       case ModIA:
  417.         DecodeAdr(&ArgStr[2], MModT);
  418.         switch (AdrMode)
  419.         {
  420.          case ModT:
  421.            BAsmCode[0] = 0x82;
  422.            CodeLen = 1;
  423.            break;
  424.         }
  425.         break;
  426.     }
  427.   }
  428. }
  429.  
  430. static void DecodeMOVW(Word Index)
  431. {
  432.   Byte HReg;
  433.   UNUSED(Index);
  434.  
  435.   OpSize = 1;
  436.   if (ChkArgCnt(2, 2))
  437.   {
  438.     DecodeAdr(&ArgStr[1], MModAcc | MModDir | MModIIX | MModExt | MModIEP | MModReg16 | MModIA | MModPS);
  439.     switch(AdrMode)
  440.     {
  441.       case ModAcc:
  442.         DecodeAdr(&ArgStr[2], MModImm | MModDir | MModIEP | MModIIX | MModExt | MModIA | MModReg16 | MModPS | MModPC);
  443.         switch (AdrMode)
  444.         {
  445.           case ModImm:
  446.             BAsmCode[0] = 0xe4;
  447.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  448.             CodeLen = 1 + AdrCnt;
  449.             break;
  450.           case ModExt:
  451.             BAsmCode[0] = 0xc4;
  452.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  453.             CodeLen = 1 + AdrCnt;
  454.             break;
  455.           case ModDir:
  456.           case ModIEP:
  457.           case ModIIX:
  458.             BAsmCode[0] = 0xc0 | AdrPart;
  459.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  460.             CodeLen = 1 + AdrCnt;
  461.             break;
  462.           case ModIA:
  463.             BAsmCode[0] = 0x93;
  464.             CodeLen = 1;
  465.             break;
  466.           case ModReg16:
  467.             BAsmCode[0] = 0xf0 + AdrPart;
  468.             CodeLen = 1;
  469.             break;
  470.           case ModPS:
  471.             BAsmCode[0] = 0x70;
  472.             CodeLen = 1;
  473.             break;
  474.           case ModPC:
  475.             BAsmCode[0] = 0xf0;
  476.             CodeLen = 1;
  477.             break;
  478.         }
  479.         break;
  480.  
  481.       case ModDir:
  482.         BAsmCode[1] = AdrVals[0];
  483.         DecodeAdr(&ArgStr[2], MModAcc);
  484.         switch (AdrMode)
  485.         {
  486.           case ModAcc:
  487.             BAsmCode[0] = 0xd5;
  488.             CodeLen = 2;
  489.             break;
  490.         }
  491.         break;
  492.  
  493.       case ModIIX:
  494.         BAsmCode[1] = AdrVals[0];
  495.         DecodeAdr(&ArgStr[2], MModAcc);
  496.         switch (AdrMode)
  497.         {
  498.           case ModAcc:
  499.             BAsmCode[0] = 0xd6;
  500.             CodeLen = 2;
  501.             break;
  502.         }
  503.         break;
  504.  
  505.       case ModExt:
  506.         BAsmCode[1] = AdrVals[0];
  507.         BAsmCode[2] = AdrVals[1];
  508.         DecodeAdr(&ArgStr[2], MModAcc);
  509.         switch (AdrMode)
  510.         {
  511.           case ModAcc:
  512.             BAsmCode[0] = 0xd4;
  513.             CodeLen = 3;
  514.             break;
  515.         }
  516.         break;
  517.  
  518.       case ModIEP:
  519.         DecodeAdr(&ArgStr[2], MModAcc);
  520.         switch (AdrMode)
  521.         {
  522.           case ModAcc:
  523.             BAsmCode[0] = 0xd7;
  524.             CodeLen = 1;
  525.             break;
  526.         }
  527.         break;
  528.  
  529.       case ModReg16:
  530.         HReg = AdrPart;
  531.         DecodeAdr(&ArgStr[2], MModAcc | MModImm);
  532.         switch (AdrMode)
  533.         {
  534.           case ModAcc:
  535.             BAsmCode[0] = 0xe0 + HReg;
  536.             CodeLen = 1;
  537.             break;
  538.           case ModImm:
  539.             BAsmCode[0] = 0xe4 + HReg;
  540.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  541.             CodeLen = 1 + AdrCnt;
  542.             break;
  543.         }
  544.         break;
  545.  
  546.       case ModIA:
  547.         DecodeAdr(&ArgStr[2], MModT);
  548.         switch (AdrMode)
  549.         {
  550.           case ModT:
  551.             BAsmCode[0] = 0x83;
  552.             CodeLen = 1;
  553.             break;
  554.         }
  555.         break;
  556.  
  557.       case ModPS:
  558.         DecodeAdr(&ArgStr[2], MModAcc);
  559.         switch (AdrMode)
  560.         {
  561.           case ModAcc:
  562.             BAsmCode[0] = 0x71;
  563.             CodeLen = 1;
  564.             break;
  565.         }
  566.         break;
  567.     }
  568.   }
  569. }
  570.  
  571. static void DecodeBit(Word Index)
  572. {
  573.   Byte Adr, Bit;
  574.  
  575.   if (!ChkArgCnt(1, 1));
  576.   else if (!DecodeBitAdr(&ArgStr[1], &Adr, &Bit)) WrError(ErrNum_InvAddrMode);
  577.   else
  578.   {
  579.     BAsmCode[0] = 0xa0 + (Index << 3) + Bit;
  580.     BAsmCode[1] = Adr;
  581.     CodeLen = 2;
  582.   }
  583. }
  584.  
  585. static void DecodeXCH(Word Index)
  586. {
  587.   UNUSED(Index);
  588.  
  589.   if (ChkArgCnt(2, 2))
  590.   {
  591.     DecodeAdr(&ArgStr[1], MModAcc | MModT);
  592.     switch (AdrMode)
  593.     {
  594.       case ModAcc:
  595.        DecodeAdr(&ArgStr[2], MModT);
  596.        if (AdrMode != ModNone)
  597.        {
  598.          BAsmCode[0] = 0x42;
  599.          CodeLen = 1;
  600.        }
  601.        break;
  602.       case ModT:
  603.        DecodeAdr(&ArgStr[2], MModAcc);
  604.        if (AdrMode != ModNone)
  605.        {
  606.          BAsmCode[0] = 0x42;
  607.          CodeLen = 1;
  608.        }
  609.        break;
  610.     }
  611.   }
  612. }
  613.  
  614. static void DecodeXCHW(Word Index)
  615. {
  616.   Byte HReg;
  617.   UNUSED(Index);
  618.  
  619.   if (ChkArgCnt(2, 2))
  620.   {
  621.     DecodeAdr(&ArgStr[1], MModAcc | MModT | MModReg16 | MModPC);
  622.     switch (AdrMode)
  623.     {
  624.       case ModAcc:
  625.         DecodeAdr(&ArgStr[2], MModT | MModReg16 | MModPC);
  626.         switch (AdrMode)
  627.         {
  628.           case ModT:
  629.             BAsmCode[0] = 0x43;
  630.             CodeLen = 1;
  631.             break;
  632.           case ModReg16:
  633.             BAsmCode[0] = 0xf4 + AdrPart;
  634.             CodeLen = 1;
  635.             break;
  636.           case ModPC:
  637.             BAsmCode[0] = 0xf4;
  638.             CodeLen = 1;
  639.             break;
  640.         }
  641.         break;
  642.       case ModT:
  643.         DecodeAdr(&ArgStr[2], MModAcc);
  644.         if (AdrMode != ModNone)
  645.         {
  646.           BAsmCode[0] = 0x43;
  647.           CodeLen = 1;
  648.         }
  649.         break;
  650.       case ModReg16:
  651.         HReg = AdrPart;
  652.         DecodeAdr(&ArgStr[2], MModAcc);
  653.         if (AdrMode != ModNone)
  654.         {
  655.           BAsmCode[0] = 0xf4 | HReg;
  656.           CodeLen = 1;
  657.         }
  658.         break;
  659.       case ModPC:
  660.         DecodeAdr(&ArgStr[2], MModAcc);
  661.         if (AdrMode != ModNone)
  662.         {
  663.           BAsmCode[0] = 0xf4;
  664.           CodeLen = 1;
  665.         }
  666.     }
  667.   }
  668. }
  669.  
  670. static void DecodeINCDEC(Word Index)
  671. {
  672.   if (ChkArgCnt(1, 1))
  673.   {
  674.     DecodeAdr(&ArgStr[1], MModReg);
  675.     if (AdrMode != ModNone)
  676.     {
  677.       BAsmCode[0] = 0xc0 + (Index << 4) + AdrPart;
  678.       CodeLen = 1;
  679.     }
  680.   }
  681. }
  682.  
  683. static void DecodeINCDECW(Word Index)
  684. {
  685.   if (ChkArgCnt(1, 1))
  686.   {
  687.     DecodeAdr(&ArgStr[1], MModAcc | MModReg16);
  688.     switch (AdrMode)
  689.     {
  690.       case ModAcc:
  691.         BAsmCode[0] = 0xc0 + (Index << 4);
  692.         CodeLen = 1;
  693.         break;
  694.       case ModReg16:
  695.         BAsmCode[0] = 0xc0 + (Index << 4) + AdrPart;
  696.         CodeLen = 1;
  697.         break;
  698.     }
  699.   }
  700. }
  701.  
  702. static void DecodeCMP(Word Index)
  703. {
  704.   Byte HReg;
  705.   UNUSED(Index);
  706.  
  707.   if (ChkArgCnt(1, 2))
  708.   {
  709.     DecodeAdr(&ArgStr[1], MModAcc | MModDir | MModIIX | MModIEP | MModReg);
  710.     switch (AdrMode)
  711.     {
  712.       case ModAcc:
  713.         if (ArgCnt == 1)
  714.         {
  715.           BAsmCode[0] = 0x12;
  716.           CodeLen = 1;
  717.         }
  718.         else
  719.         {
  720.           DecodeAdr(&ArgStr[2], MModDir | MModIEP | MModIIX | MModReg | MModImm);
  721.           if (AdrMode != ModNone)
  722.           {
  723.             BAsmCode[0] = 0x10 + AdrPart;
  724.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  725.             CodeLen = 1 + AdrCnt;
  726.           }
  727.         }
  728.         break;
  729.       case ModDir:
  730.         if (ChkArgCnt(2, 2))
  731.         {
  732.           BAsmCode[1] = AdrVals[0];
  733.           DecodeAdr(&ArgStr[2], MModImm);
  734.           if (AdrMode != ModNone)
  735.           {
  736.             BAsmCode[0] = 0x95;
  737.             BAsmCode[2] = AdrVals[0]; /* reverse for F2MC8 */
  738.             CodeLen = 3;
  739.           }
  740.         }
  741.         break;
  742.       case ModIIX:
  743.         if (ChkArgCnt(2, 2))
  744.         {
  745.           BAsmCode[1] = AdrVals[0];
  746.           DecodeAdr(&ArgStr[2], MModImm);
  747.           if (AdrMode != ModNone)
  748.           {
  749.             BAsmCode[0] = 0x96;
  750.             BAsmCode[2] = AdrVals[0]; /* reverse for F2MC8 */
  751.             CodeLen = 3;
  752.           }
  753.         }
  754.         break;
  755.       case ModIEP:
  756.         if (ChkArgCnt(2, 2))
  757.         {
  758.           DecodeAdr(&ArgStr[2], MModImm);
  759.           if (AdrMode != ModNone)
  760.           {
  761.             BAsmCode[0] = 0x97;
  762.             BAsmCode[1] = AdrVals[0];
  763.             CodeLen = 2;
  764.           }
  765.         }
  766.         break;
  767.       case ModReg:
  768.         if (ChkArgCnt(2, 2))
  769.         {
  770.           HReg = AdrPart;
  771.           DecodeAdr(&ArgStr[2], MModImm);
  772.           if (AdrMode != ModNone)
  773.           {
  774.             BAsmCode[0] = 0x90 + HReg;
  775.             BAsmCode[1] = AdrVals[0];
  776.             CodeLen = 2;
  777.           }
  778.         }
  779.         break;
  780.     }
  781.   }
  782. }
  783.  
  784. static void DecodeBitBr(Word Index)
  785. {
  786.   Byte Bit, BAdr;
  787.   Boolean OK;
  788.   Integer Adr;
  789.   tSymbolFlags Flags;
  790.  
  791.   if (!ChkArgCnt(2, 2));
  792.   else if (!DecodeBitAdr(&ArgStr[1], &BAdr, &Bit)) WrError(ErrNum_InvAddrMode);
  793.   else
  794.   {
  795.     Adr = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt16, &OK, &Flags) - (EProgCounter() + 3);
  796.     if (OK)
  797.     {
  798.       if (((Adr < -128) || (Adr > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  799.       else
  800.       {
  801.         BAsmCode[0] = 0xb0 + (Index << 3) + Bit;
  802.         BAsmCode[1] = BAdr; /* reverse for F2MC8? */
  803.         BAsmCode[2] = Adr & 0xff;
  804.         CodeLen = 3;
  805.       }
  806.     }
  807.   }
  808. }
  809.  
  810. static void DecodeJmp(Word Index)
  811. {
  812.   if (ChkArgCnt(1, 1))
  813.   {
  814.     DecodeAdr(&ArgStr[1], MModExt | ((Index) ? 0 : MModIA));
  815.     switch (AdrMode)
  816.     {
  817.       case ModIA:
  818.         BAsmCode[0] = 0xe0;
  819.         CodeLen = 1;
  820.         break;
  821.       case ModExt:
  822.         BAsmCode[0] = 0x21 | (Index << 4);
  823.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  824.         CodeLen = 1 + AdrCnt;
  825.         break;
  826.     }
  827.   }
  828. }
  829.  
  830. static void DecodeCALLV(Word Index)
  831. {
  832.   Boolean OK;
  833.   UNUSED(Index);
  834.  
  835.   if (!ChkArgCnt(1, 1));
  836.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
  837.   else
  838.   {
  839.     BAsmCode[0] = 0xb8 + EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt3, &OK);
  840.     if (OK)
  841.       CodeLen = 1;
  842.   }
  843. }
  844.  
  845. static void DecodeStack(Word Index)
  846. {
  847.   if (ChkArgCnt(1, 1))
  848.   {
  849.     DecodeAdr(&ArgStr[1], MModAcc | MModReg16);
  850.     switch (AdrMode)
  851.     {
  852.       case ModAcc:
  853.         BAsmCode[0] = 0x40 + (Index << 4);
  854.         CodeLen = 1;
  855.         break;
  856.       case ModReg16:
  857.         if (AdrPart != 2) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  858.         else
  859.         {
  860.           BAsmCode[0] = 0x41 + (Index << 4);
  861.           CodeLen = 1;
  862.         }
  863.         break;
  864.     }
  865.   }
  866. }
  867.  
  868. /*--------------------------------------------------------------------------*/
  869. /* Codetabellen */
  870.  
  871. static void AddFixed(const char *NName, Byte NCode)
  872. {
  873.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  874. }
  875.  
  876. static void AddALU(const char *NName, Byte NCode)
  877. {
  878.   AddInstTable(InstTable, NName, NCode, DecodeALU);
  879. }
  880.  
  881. static void AddAcc(const char *NName, Byte NCode)
  882. {
  883.   AddInstTable(InstTable, NName, NCode, DecodeAcc);
  884. }
  885.  
  886. static void AddRel(const char *NName, Byte NCode)
  887. {
  888.   AddInstTable(InstTable, NName, NCode, DecodeRel);
  889. }
  890.  
  891. static void InitFields(void)
  892. {
  893.   InstTable = CreateInstTable(201);
  894.  
  895.   add_null_pseudo(InstTable);
  896.  
  897.   AddFixed("SWAP"  , 0x10); AddFixed("DAA"   , 0x84);
  898.   AddFixed("DAS"   , 0x94); AddFixed("RET"   , 0x20);
  899.   AddFixed("RETI"  , 0x30); AddFixed("NOP"   , 0x00);
  900.   AddFixed("CLRC"  , 0x81); AddFixed("SETC"  , 0x91);
  901.   AddFixed("CLRI"  , 0x80); AddFixed("SETI"  , 0x90);
  902.  
  903.   AddALU("ADDC"  , 0x20); AddALU("SUBC"  , 0x30);
  904.   AddALU("XOR"   , 0x50); AddALU("AND"   , 0x60);
  905.   AddALU("OR"    , 0x70);
  906.  
  907.   AddAcc("ADDCW" , 0x23); AddAcc("SUBCW" , 0x33);
  908.   AddAcc("MULU"  , 0x01); AddAcc("DIVU"  , 0x11);
  909.   AddAcc("ANDW"  , 0x63); AddAcc("ORW"   , 0x73);
  910.   AddAcc("XORW"  , 0x53); AddAcc("CMPW"  , 0x13);
  911.   AddAcc("RORC"  , 0x03); AddAcc("ROLC"  , 0x02);
  912.  
  913.   AddRel("BEQ", 0xfd); AddRel("BZ" , 0xfd);
  914.   AddRel("BNZ", 0xfc); AddRel("BNE", 0xfc);
  915.   AddRel("BC" , 0xf9); AddRel("BLO", 0xf9);
  916.   AddRel("BNC", 0xf8); AddRel("BHS", 0xf8);
  917.   AddRel("BN" , 0xfb); AddRel("BP" , 0xfa);
  918.   AddRel("BLT", 0xff); AddRel("BGE", 0xfe);
  919.  
  920.   AddInstTable(InstTable, "MOV"  , 0, DecodeMOV);
  921.   AddInstTable(InstTable, "MOVW" , 0, DecodeMOVW);
  922.   AddInstTable(InstTable, "XCH"  , 0, DecodeXCH);
  923.   AddInstTable(InstTable, "XCHW" , 0, DecodeXCHW);
  924.   AddInstTable(InstTable, "SETB" , 1, DecodeBit);
  925.   AddInstTable(InstTable, "CLRB" , 0, DecodeBit);
  926.   AddInstTable(InstTable, "INC"  , 0, DecodeINCDEC);
  927.   AddInstTable(InstTable, "DEC"  , 1, DecodeINCDEC);
  928.   AddInstTable(InstTable, "INCW" , 0, DecodeINCDECW);
  929.   AddInstTable(InstTable, "DECW" , 1, DecodeINCDECW);
  930.   AddInstTable(InstTable, "CMP"  , 0, DecodeCMP);
  931.   AddInstTable(InstTable, "BBC"  , 0, DecodeBitBr);
  932.   AddInstTable(InstTable, "BBS"  , 1, DecodeBitBr);
  933.   AddInstTable(InstTable, "JMP"  , 0, DecodeJmp);
  934.   AddInstTable(InstTable, "CALL" , 1, DecodeJmp);
  935.   AddInstTable(InstTable, "CALLV", 0, DecodeCALLV);
  936.   AddInstTable(InstTable, "PUSHW", 0, DecodeStack);
  937.   AddInstTable(InstTable, "POPW" , 1, DecodeStack);
  938.   AddIntelPseudo(InstTable, eIntPseudoFlag_LittleEndian);
  939. }
  940.  
  941. static void DeinitFields(void)
  942. {
  943.   DestroyInstTable(InstTable);
  944. }
  945.  
  946. /*--------------------------------------------------------------------------*/
  947. /* Interface zu AS */
  948.  
  949. static void MakeCode_F2MC8(void)
  950. {
  951.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  952.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  953. }
  954.  
  955. static Boolean IsDef_F2MC8(void)
  956. {
  957.   return FALSE;
  958. }
  959.  
  960. static void SwitchFrom_F2MC8(void)
  961. {
  962.   DeinitFields();
  963. }
  964.  
  965. static void SwitchTo_F2MC8(void)
  966. {
  967.   const TFamilyDescr *FoundDescr;
  968.  
  969.   FoundDescr = FindFamilyByName("F2MC8");
  970.  
  971.   TurnWords = False;
  972.   SetIntConstMode(eIntConstModeIntel);
  973.  
  974.   PCSymbol = "$";
  975.   HeaderID = FoundDescr->Id;
  976.   NOPCode = 0x00;
  977.   DivideChars = ",";
  978.   HasAttrs = False;
  979.  
  980.   ValidSegs = 1 << SegCode;
  981.   Grans[SegCode] = 1;
  982.   ListGrans[SegCode] = 1;
  983.   SegInits[SegCode] = 0;
  984.   SegLimits[SegCode] = 0xffff;
  985.  
  986.   MakeCode = MakeCode_F2MC8;
  987.   IsDef = IsDef_F2MC8;
  988.   SwitchFrom = SwitchFrom_F2MC8;
  989.   InitFields();
  990. }
  991.  
  992. /*--------------------------------------------------------------------------*/
  993. /* Initialisierung */
  994.  
  995. void codef2mc8_init(void)
  996. {
  997.   CPU89190 = AddCPU("MB89190", SwitchTo_F2MC8);
  998. }
  999.