Subversion Repositories pentevo

Rev

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

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