Subversion Repositories pentevo

Rev

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

  1. /* codehmcs400.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator Hitachi HMCS400-Familie                                     */
  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 "asmsub.h"
  19. #include "asmpars.h"
  20. #include "asmitree.h"
  21. #include "codepseudo.h"
  22. #include "fourpseudo.h"
  23. #include "codevars.h"
  24. #include "headids.h"
  25. #include "errmsg.h"
  26.  
  27. #include "codehmcs400.h"
  28.  
  29. static CPUVar CPU614023, CPU614043, CPU614081;
  30. static IntType CodeIntType, DataIntType, OpSizeType;
  31. static ShortInt AdrMode;
  32. static Word AdrVal;
  33.  
  34. enum
  35. {
  36.   ModA = 0,
  37.   ModB = 1,
  38.   ModX = 2,
  39.   ModY = 3,
  40.   ModW = 4,
  41.   ModM = 5,
  42.   ModMInc = 6,
  43.   ModMDec = 7,
  44.   ModSPX = 8,
  45.   ModSPY = 9,
  46.   ModImm = 10,
  47.   ModDir = 11,
  48.   ModMR = 12,
  49.   ModNone = 0x7f
  50. };
  51.  
  52. #define MModA (1 << ModA)
  53. #define MModB (1 << ModB)
  54. #define MModX (1 << ModX)
  55. #define MModY (1 << ModY)
  56. #define MModW (1 << ModW)
  57. #define MModM (1 << ModM)
  58. #define MModMInc (1 << ModMInc)
  59. #define MModMDec (1 << ModMDec)
  60. #define MModSPX (1 << ModSPX)
  61. #define MModSPY (1 << ModSPY)
  62. #define MModImm (1 << ModImm)
  63. #define MModDir (1 << ModDir)
  64. #define MModMR (1 << ModMR)
  65.  
  66. /*-------------------------------------------------------------------------*/
  67.  
  68. static void DecodeAdr(const tStrComp *pArg, Word Mask)
  69. {
  70.   tEvalResult EvalResult;
  71.   int l;
  72.  
  73.   if (!as_strcasecmp(pArg->str.p_str, "A"))
  74.   {
  75.     AdrMode = ModA;
  76.     goto AdrFound;
  77.   }
  78.  
  79.   if (!as_strcasecmp(pArg->str.p_str, "B"))
  80.   {
  81.     AdrMode = ModB;
  82.     goto AdrFound;
  83.   }
  84.  
  85.   if (!as_strcasecmp(pArg->str.p_str, "X"))
  86.   {
  87.     AdrMode = ModX;
  88.     goto AdrFound;
  89.   }
  90.  
  91.   if (!as_strcasecmp(pArg->str.p_str, "Y"))
  92.   {
  93.     AdrMode = ModY;
  94.     goto AdrFound;
  95.   }
  96.  
  97.   if (!as_strcasecmp(pArg->str.p_str, "W"))
  98.   {
  99.     AdrMode = ModW;
  100.     OpSizeType = UInt2;
  101.     goto AdrFound;
  102.   }
  103.  
  104.   if (!as_strcasecmp(pArg->str.p_str, "M"))
  105.   {
  106.     AdrMode = ModM;
  107.     goto AdrFound;
  108.   }
  109.  
  110.   if (!as_strcasecmp(pArg->str.p_str, "M+"))
  111.   {
  112.     AdrMode = ModMInc;
  113.     goto AdrFound;
  114.   }
  115.  
  116.   if (!as_strcasecmp(pArg->str.p_str, "M-"))
  117.   {
  118.     AdrMode = ModMDec;
  119.     goto AdrFound;
  120.   }
  121.  
  122.   if (!as_strcasecmp(pArg->str.p_str, "SPX"))
  123.   {
  124.     AdrMode = ModSPX;
  125.     goto AdrFound;
  126.   }
  127.  
  128.   if (!as_strcasecmp(pArg->str.p_str, "SPY"))
  129.   {
  130.     AdrMode = ModSPY;
  131.     goto AdrFound;
  132.   }
  133.  
  134.   l = strlen(pArg->str.p_str);
  135.   if ((l >= 3) && (l <= 4)
  136.    && (as_toupper(pArg->str.p_str[0]) == 'M')
  137.    && (as_toupper(pArg->str.p_str[1]) == 'R')
  138.    && (isdigit(pArg->str.p_str[2]))
  139.    && (isdigit(pArg->str.p_str[l - 1])))
  140.   {
  141.     AdrVal = pArg->str.p_str[2] - '0';
  142.     if (l == 4)
  143.       AdrVal = (AdrVal * 10) + (pArg->str.p_str[3] - '0');
  144.     if (AdrVal < 16)
  145.     {
  146.       AdrMode = ModMR;
  147.       goto AdrFound;
  148.     }
  149.   }
  150.  
  151.   if (0[pArg->str.p_str] == '#')
  152.   {
  153.     AdrVal = EvalStrIntExpressionOffsWithResult(pArg, 1, OpSizeType, &EvalResult);
  154.     if (EvalResult.OK)
  155.     {
  156.       AdrMode = ModImm;
  157.       AdrVal &= IntTypeDefs[OpSizeType].Mask;
  158.     }
  159.     goto AdrFound;
  160.   }
  161.  
  162.   AdrVal = EvalStrIntExpressionWithResult(pArg, DataIntType, &EvalResult);
  163.   if (EvalResult.OK)
  164.   {
  165.     if (!mFirstPassUnknown(EvalResult.Flags) && (AdrVal > SegLimits[SegData])) WrError(ErrNum_OverRange);
  166.     else
  167.     {
  168.       AdrMode = ModDir;
  169.       AdrVal &= IntTypeDefs[DataIntType].Mask;
  170.       ChkSpace(SegData, EvalResult.AddrSpaceMask);
  171.     }
  172.     goto AdrFound;
  173.   }
  174.  
  175.  
  176. AdrFound:
  177.  
  178.   if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
  179.   {
  180.     WrError(ErrNum_InvAddrMode);
  181.     AdrMode = ModNone; AdrCnt = 0;
  182.   }
  183. }
  184.  
  185. /*-------------------------------------------------------------------------*/
  186.  
  187. static void DecodeLD(Word Code)
  188. {
  189.   UNUSED(Code);
  190.  
  191.   if (ChkArgCnt(2, 2))
  192.   {
  193.     DecodeAdr(&ArgStr[2], MModA | MModB | MModX | MModY | MModW | MModM | MModMInc | MModMDec | MModDir);
  194.     switch (AdrMode)
  195.     {
  196.       case ModA:
  197.         DecodeAdr(&ArgStr[1], MModB | MModY | MModM | MModSPX | MModSPY | MModImm | MModDir | MModMR);
  198.         switch (AdrMode)
  199.         {
  200.           case ModB:
  201.             WAsmCode[CodeLen++] = 0x048;
  202.             break;
  203.           case ModY:
  204.             WAsmCode[CodeLen++] = 0x0af;
  205.             break;
  206.           case ModM:
  207.             WAsmCode[CodeLen++] = 0x090;
  208.             break;
  209.           case ModSPX:
  210.             WAsmCode[CodeLen++] = 0x068;
  211.             break;
  212.           case ModSPY:
  213.             WAsmCode[CodeLen++] = 0x058;
  214.             break;
  215.           case ModDir:
  216.             WAsmCode[CodeLen++] = 0x190;
  217.             WAsmCode[CodeLen++] = AdrVal;
  218.             break;
  219.           case ModImm:
  220.             WAsmCode[CodeLen++] = 0x230 | AdrVal;
  221.             break;
  222.           case ModMR:
  223.             WAsmCode[CodeLen++] = 0x270 | AdrVal;
  224.             break;
  225.         }
  226.         break;
  227.       case ModB:
  228.         DecodeAdr(&ArgStr[1], MModA | MModImm | MModM);
  229.         switch (AdrMode)
  230.         {
  231.           case ModA:
  232.             WAsmCode[CodeLen++] = 0x0c8;
  233.             break;
  234.           case ModImm:
  235.             WAsmCode[CodeLen++] = 0x200 | AdrVal;
  236.             break;
  237.           case ModM:
  238.             WAsmCode[CodeLen++] = 0x400;
  239.             break;
  240.         }
  241.         break;
  242.       case ModX:
  243.         DecodeAdr(&ArgStr[1], MModA | MModImm);
  244.         switch (AdrMode)
  245.         {
  246.           case ModA:
  247.             WAsmCode[CodeLen++] = 0x0e8;
  248.             break;
  249.           case ModImm:
  250.             WAsmCode[CodeLen++] = 0x220 | AdrVal;
  251.             break;
  252.         }
  253.         break;
  254.       case ModY:
  255.         DecodeAdr(&ArgStr[1], MModA | MModImm);
  256.         switch (AdrMode)
  257.         {
  258.           case ModA:
  259.             WAsmCode[CodeLen++] = 0x0d8;
  260.             break;
  261.           case ModImm:
  262.             WAsmCode[CodeLen++] = 0x210 | AdrVal;
  263.             break;
  264.         }
  265.         break;
  266.       case ModW:
  267.         DecodeAdr(&ArgStr[1], MModImm);
  268.         switch (AdrMode)
  269.         {
  270.           case ModImm:
  271.             WAsmCode[CodeLen++] = 0x0f0 | AdrVal;
  272.             break;
  273.         }
  274.         break;
  275.       case ModM:
  276.         DecodeAdr(&ArgStr[1], MModA);
  277.         switch (AdrMode)
  278.         {
  279.           case ModA:
  280.             WAsmCode[CodeLen++] = 0x094;
  281.             break;
  282.         }
  283.         break;
  284.       case ModMInc:
  285.         DecodeAdr(&ArgStr[1], MModA | MModImm);
  286.         switch (AdrMode)
  287.         {
  288.           case ModA:
  289.             WAsmCode[CodeLen++] = 0x050;
  290.             break;
  291.           case ModImm:
  292.             WAsmCode[CodeLen++] = 0x290 | AdrVal;
  293.             break;
  294.         }
  295.         break;
  296.       case ModMDec:
  297.         DecodeAdr(&ArgStr[1], MModA);
  298.         switch (AdrMode)
  299.         {
  300.           case ModA:
  301.             WAsmCode[CodeLen++] = 0x0d0;
  302.             break;
  303.         }
  304.         break;
  305.       case ModDir:
  306.       {
  307.         Word HVal = AdrVal;
  308.  
  309.         DecodeAdr(&ArgStr[1], MModA | MModImm);
  310.         switch (AdrMode)
  311.         {
  312.           case ModA:
  313.             WAsmCode[CodeLen++] = 0x194;
  314.             WAsmCode[CodeLen++] = HVal;
  315.             break;
  316.           case ModImm:
  317.             WAsmCode[CodeLen++] = 0x1a0 | AdrVal;
  318.             WAsmCode[CodeLen++] = HVal;
  319.             break;
  320.         }
  321.         break;
  322.       }
  323.     }
  324.   }
  325. }
  326.  
  327. static void DecodeXCH(Word Code)
  328. {
  329.   Word HVal;
  330.  
  331.   UNUSED(Code);
  332.  
  333.   if (ChkArgCnt(2, 2))
  334.   {
  335.     DecodeAdr(&ArgStr[2], MModA | MModB | MModX | MModY | MModSPX | MModSPY | MModM | MModDir | MModMR);
  336.     switch (AdrMode)
  337.     {
  338.       case ModA:
  339.         DecodeAdr(&ArgStr[1], MModMR | MModM | MModDir);
  340.         switch (AdrMode)
  341.         {
  342.           case ModMR:
  343.             WAsmCode[CodeLen++] = 0x2f0 | AdrVal;
  344.             break;
  345.           case ModM:
  346.             WAsmCode[CodeLen++] = 0x080;
  347.             break;
  348.           case ModDir:
  349.             WAsmCode[CodeLen++] = 0x180;
  350.             WAsmCode[CodeLen++] = AdrVal;
  351.             break;
  352.         }
  353.         break;
  354.       case ModB:
  355.         DecodeAdr(&ArgStr[1], MModM);
  356.         switch (AdrMode)
  357.         {
  358.           case ModM:
  359.             WAsmCode[CodeLen++] = 0x0c0;
  360.             break;
  361.         }
  362.         break;
  363.       case ModX:
  364.         DecodeAdr(&ArgStr[1], MModSPX);
  365.         switch (AdrMode)
  366.         {
  367.           case ModSPX:
  368.             WAsmCode[CodeLen++] = 0x001;
  369.             break;
  370.         }
  371.         break;
  372.       case ModY:
  373.         DecodeAdr(&ArgStr[1], MModSPY);
  374.         switch (AdrMode)
  375.         {
  376.           case ModSPY:
  377.             WAsmCode[CodeLen++] = 0x002;
  378.             break;
  379.         }
  380.         break;
  381.       case ModSPX:
  382.         DecodeAdr(&ArgStr[1], MModX);
  383.         switch (AdrMode)
  384.         {
  385.           case ModX:
  386.             WAsmCode[CodeLen++] = 0x001;
  387.             break;
  388.         }
  389.         break;
  390.       case ModSPY:
  391.         DecodeAdr(&ArgStr[1], MModY);
  392.         switch (AdrMode)
  393.         {
  394.           case ModY:
  395.             WAsmCode[CodeLen++] = 0x002;
  396.             break;
  397.         }
  398.         break;
  399.       case ModMR:
  400.         HVal = AdrVal;
  401.         DecodeAdr(&ArgStr[1], MModA);
  402.         switch (AdrMode)
  403.         {
  404.           case ModA:
  405.             WAsmCode[CodeLen++] = 0x2f0 | HVal;
  406.             break;
  407.         }
  408.         break;
  409.       case ModM:
  410.         DecodeAdr(&ArgStr[1], MModA | MModB);
  411.         switch (AdrMode)
  412.         {
  413.           case ModA:
  414.             WAsmCode[CodeLen++] = 0x080;
  415.             break;
  416.           case ModB:
  417.             WAsmCode[CodeLen++] = 0x0c0;
  418.             break;
  419.         }
  420.         break;
  421.       case ModDir:
  422.         HVal = AdrVal;
  423.         DecodeAdr(&ArgStr[1], MModA);
  424.         switch (AdrMode)
  425.         {
  426.           case ModA:
  427.             WAsmCode[CodeLen++] = 0x180;
  428.             WAsmCode[CodeLen++] = HVal;
  429.             break;
  430.         }
  431.         break;
  432.     }
  433.   }
  434. }
  435.  
  436. static void DecodeINCDEC(Word Code)
  437. {
  438.   if (ChkArgCnt(1, 1))
  439.   {
  440.     DecodeAdr(&ArgStr[1], MModY | MModB);
  441.     switch (AdrMode)
  442.     {
  443.       case ModY:
  444.         WAsmCode[CodeLen++] = Code | 0x10;
  445.         break;
  446.       case ModB:
  447.         WAsmCode[CodeLen++] = Code;
  448.         break;
  449.     }
  450.   }
  451. }
  452.  
  453. static void DecodeADD(Word Code)
  454. {
  455.   UNUSED(Code);
  456.  
  457.   if (ChkArgCnt(2, 2))
  458.   {
  459.     DecodeAdr(&ArgStr[2], MModA | MModY);
  460.     switch (AdrMode)
  461.     {
  462.       case ModA:
  463.         DecodeAdr(&ArgStr[1], MModImm | MModM | MModDir);
  464.         switch (AdrMode)
  465.         {
  466.           case ModImm:
  467.             WAsmCode[CodeLen++] = 0x280 | AdrVal;
  468.             break;
  469.           case ModM:
  470.             WAsmCode[CodeLen++] = 0x008;
  471.             break;
  472.           case ModDir:
  473.             WAsmCode[CodeLen++] = 0x108;
  474.             WAsmCode[CodeLen++] = AdrVal;
  475.             break;
  476.         }
  477.         break;
  478.       case ModY:
  479.         DecodeAdr(&ArgStr[1], MModA);
  480.         switch (AdrMode)
  481.         {
  482.           case ModA:
  483.             WAsmCode[CodeLen++] = 0x054;
  484.             break;
  485.         }
  486.         break;
  487.     }
  488.   }
  489. }
  490.  
  491. static void DecodeADC(Word Code)
  492. {
  493.   UNUSED(Code);
  494.  
  495.   if (ChkArgCnt(2, 2))
  496.   {
  497.     DecodeAdr(&ArgStr[2], MModA);
  498.     switch (AdrMode)
  499.     {
  500.       case ModA:
  501.         DecodeAdr(&ArgStr[1], MModM | MModDir);
  502.         switch (AdrMode)
  503.         {
  504.           case ModM:
  505.             WAsmCode[CodeLen++] = 0x018;
  506.             break;
  507.           case ModDir:
  508.             WAsmCode[CodeLen++] = 0x118;
  509.             WAsmCode[CodeLen++] = AdrVal;
  510.             break;
  511.         }
  512.         break;
  513.     }
  514.   }
  515. }
  516.  
  517. static void DecodeSUB(Word Code)
  518. {
  519.   UNUSED(Code);
  520.  
  521.   if (ChkArgCnt(2, 2))
  522.   {
  523.     DecodeAdr(&ArgStr[2], MModY);
  524.     switch (AdrMode)
  525.     {
  526.       case ModY:
  527.         DecodeAdr(&ArgStr[1], MModA);
  528.         switch (AdrMode)
  529.         {
  530.           case ModA:
  531.             WAsmCode[CodeLen++] = 0x0d4;
  532.             break;
  533.         }
  534.         break;
  535.     }
  536.   }
  537. }
  538.  
  539. static void DecodeSBC(Word Code)
  540. {
  541.   UNUSED(Code);
  542.  
  543.   if (ChkArgCnt(2, 2))
  544.   {
  545.     DecodeAdr(&ArgStr[2], MModA);
  546.     switch (AdrMode)
  547.     {
  548.       case ModA:
  549.         DecodeAdr(&ArgStr[1], MModM | MModDir);
  550.         switch (AdrMode)
  551.         {
  552.           case ModM:
  553.             WAsmCode[CodeLen++] = 0x098;
  554.             break;
  555.           case ModDir:
  556.             WAsmCode[CodeLen++] = 0x198;
  557.             WAsmCode[CodeLen++] = AdrVal;
  558.             break;
  559.         }
  560.         break;
  561.     }
  562.   }
  563. }
  564.  
  565. static void DecodeOR(Word Code)
  566. {
  567.   UNUSED(Code);
  568.  
  569.   if (ArgCnt == 0)
  570.     WAsmCode[CodeLen++] = 0x144;
  571.   else if (ChkArgCnt(2, 2))
  572.   {
  573.     DecodeAdr(&ArgStr[2], MModA);
  574.     switch (AdrMode)
  575.     {
  576.       case ModA:
  577.         DecodeAdr(&ArgStr[1], MModB | MModM | MModDir);
  578.         switch (AdrMode)
  579.         {
  580.           case ModB:
  581.             WAsmCode[CodeLen++] = 0x144;
  582.             break;
  583.           case ModM:
  584.             WAsmCode[CodeLen++] = 0x00c;
  585.             break;
  586.           case ModDir:
  587.             WAsmCode[CodeLen++] = 0x10c;
  588.             WAsmCode[CodeLen++] = AdrVal;
  589.             break;
  590.         }
  591.         break;
  592.     }
  593.   }
  594. }
  595.  
  596. static void DecodeAND(Word Code)
  597. {
  598.   UNUSED(Code);
  599.  
  600.   if (ChkArgCnt(2, 2))
  601.   {
  602.     DecodeAdr(&ArgStr[2], MModA);
  603.     switch (AdrMode)
  604.     {
  605.       case ModA:
  606.         DecodeAdr(&ArgStr[1], MModM | MModDir);
  607.         switch (AdrMode)
  608.         {
  609.           case ModM:
  610.             WAsmCode[CodeLen++] = 0x09c;
  611.             break;
  612.           case ModDir:
  613.             WAsmCode[CodeLen++] = 0x19c;
  614.             WAsmCode[CodeLen++] = AdrVal;
  615.             break;
  616.         }
  617.         break;
  618.     }
  619.   }
  620. }
  621.  
  622. static void DecodeEOR(Word Code)
  623. {
  624.   UNUSED(Code);
  625.  
  626.   if (ChkArgCnt(2, 2))
  627.   {
  628.     DecodeAdr(&ArgStr[2], MModA);
  629.     switch (AdrMode)
  630.     {
  631.       case ModA:
  632.         DecodeAdr(&ArgStr[1], MModM | MModDir);
  633.         switch (AdrMode)
  634.         {
  635.           case ModM:
  636.             WAsmCode[CodeLen++] = 0x01c;
  637.             break;
  638.           case ModDir:
  639.             WAsmCode[CodeLen++] = 0x11c;
  640.             WAsmCode[CodeLen++] = AdrVal;
  641.             break;
  642.         }
  643.         break;
  644.     }
  645.   }
  646. }
  647.  
  648. static void DecodeCP(Word Code)
  649. {
  650.   Boolean IsLE;
  651.   Word HVal;
  652.  
  653.   UNUSED(Code);
  654.  
  655.   if (!ChkArgCnt(3, 3))
  656.     return;
  657.  
  658.   if (!as_strcasecmp(ArgStr[1].str.p_str, "NE"))
  659.     IsLE = False;
  660.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "LE"))
  661.     IsLE = True;
  662.   else
  663.   {
  664.     WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  665.     return;
  666.   }
  667.   DecodeAdr(&ArgStr[3], MModA | MModB | (IsLE ? 0 : MModM | MModDir | MModY) | MModImm);
  668.   switch (AdrMode)
  669.   {
  670.     case ModA:
  671.       DecodeAdr(&ArgStr[2], MModM | MModDir | (IsLE ? MModImm : 0));
  672.       switch (AdrMode)
  673.       {
  674.         case ModM:
  675.           WAsmCode[CodeLen++] = IsLE ? 0x014 : 0x004;
  676.           break;
  677.         case ModDir:
  678.           WAsmCode[CodeLen++] = IsLE ? 0x114 : 0x104;
  679.           WAsmCode[CodeLen++] = AdrVal;
  680.           break;
  681.         case ModImm:
  682.           WAsmCode[CodeLen++] = 0x2b0 | AdrVal;
  683.           break;
  684.       }
  685.       break;
  686.     case ModB:
  687.       DecodeAdr(&ArgStr[2], MModM);
  688.       switch (AdrMode)
  689.       {
  690.         case ModM:
  691.           WAsmCode[CodeLen++] = IsLE ? 0x0c4 : 0x044;
  692.           break;
  693.       }
  694.       break;
  695.     case ModY:
  696.       DecodeAdr(&ArgStr[2], MModImm);
  697.       switch (AdrMode)
  698.       {
  699.         case ModImm:
  700.           WAsmCode[CodeLen++] = 0x070 | AdrVal;
  701.           break;
  702.       }
  703.       break;
  704.     case ModM:
  705.       DecodeAdr(&ArgStr[2], MModImm | MModA | MModB);
  706.       switch (AdrMode)
  707.       {
  708.         case ModImm:
  709.           WAsmCode[CodeLen++] = 0x020 | AdrVal;
  710.           break;
  711.         case ModA:
  712.           WAsmCode[CodeLen++] = 0x004;
  713.           break;
  714.         case ModB:
  715.           WAsmCode[CodeLen++] = 0x044;
  716.           break;
  717.       }
  718.       break;
  719.     case ModDir:
  720.       HVal = AdrVal;
  721.       DecodeAdr(&ArgStr[2], MModImm | MModA);
  722.       switch (AdrMode)
  723.       {
  724.         case ModImm:
  725.           WAsmCode[CodeLen++] = 0x120 | AdrVal;
  726.           WAsmCode[CodeLen++] = HVal;
  727.           break;
  728.         case ModA:
  729.           WAsmCode[CodeLen++] = 0x104;
  730.           WAsmCode[CodeLen++] = HVal;
  731.           break;
  732.       }
  733.       break;
  734.     case ModImm:
  735.       HVal = AdrVal;
  736.       DecodeAdr(&ArgStr[2], MModM | MModDir | (IsLE ? 0 : MModY));
  737.       switch (AdrMode)
  738.       {
  739.         case ModM:
  740.           WAsmCode[CodeLen++] = (IsLE ? 0x030 : 0x020) | HVal;
  741.           break;
  742.         case ModDir:
  743.           WAsmCode[CodeLen++] = (IsLE ? 0x130 : 0x120) | HVal;
  744.           WAsmCode[CodeLen++] = AdrVal;
  745.           break;
  746.         case ModY:
  747.           WAsmCode[CodeLen++] = 0x070 | HVal;
  748.           break;
  749.       }
  750.       break;
  751.   }
  752. }
  753.  
  754. static void DecodeBit(Word Code)
  755. {
  756.   if (ArgCnt == 1)
  757.   {
  758.     if (!as_strcasecmp(ArgStr[1].str.p_str, "CA"))
  759.       WAsmCode[CodeLen++] = Hi(Code);
  760.     else
  761.       WrError(ErrNum_InvAddrMode);
  762.   }
  763.   else if (ChkArgCnt(2, 2))
  764.   {
  765.     Boolean OK;
  766.     unsigned BitNo = EvalStrIntExpression(&ArgStr[1], UInt2, &OK);
  767.  
  768.     if (OK)
  769.     {
  770.       DecodeAdr(&ArgStr[2], MModDir | MModM);
  771.       switch (AdrMode)
  772.       {
  773.         case ModDir:
  774.           WAsmCode[CodeLen++] = Lo(Code) | 0x100 | BitNo;
  775.           WAsmCode[CodeLen++] = AdrVal;
  776.           break;
  777.         case ModM:
  778.           WAsmCode[CodeLen++] = Lo(Code) | BitNo;
  779.           break;
  780.       }
  781.     }
  782.   }
  783. }
  784.  
  785. static void CodeFixed(Word Code)
  786. {
  787.   if (ChkArgCnt(0, 0))
  788.     WAsmCode[CodeLen++] = Code;
  789. }
  790.  
  791. static void CodeImm(Word Code)
  792. {
  793.   if (ChkArgCnt(1, 1))
  794.   {
  795.     Boolean OK;
  796.     Word ImmVal = EvalStrIntExpression(&ArgStr[1], (Code & 0x8000) ? UInt2 : Int4, &OK);
  797.  
  798.     if (OK)
  799.       WAsmCode[CodeLen++] = (Code & 0x3ff) | (ImmVal & 15);
  800.   }
  801. }
  802.  
  803. static void CodeDir(Word Code)
  804. {
  805.   if (ChkArgCnt(1, 1))
  806.   {
  807.     DecodeAdr(&ArgStr[1], MModDir);
  808.     if (AdrMode == ModDir)
  809.     {
  810.       WAsmCode[CodeLen++] = Code;
  811.       WAsmCode[CodeLen++] = AdrVal;
  812.     }
  813.   }
  814. }
  815.  
  816. static void CodeImmDir(Word Code)
  817. {
  818.   if (ChkArgCnt(2, 2))
  819.   {
  820.     Boolean OK;
  821.     Word ImmVal = EvalStrIntExpression(&ArgStr[1], (Code & 0x8000) ? UInt2 : Int4, &OK);
  822.  
  823.     if (OK)
  824.     {
  825.       DecodeAdr(&ArgStr[2], MModDir);
  826.       if (AdrMode == ModDir)
  827.       {
  828.         WAsmCode[CodeLen++] = (Code & 0x3ff) | (ImmVal & 15);
  829.         WAsmCode[CodeLen++] = AdrVal;
  830.       }
  831.     }
  832.   }
  833. }
  834.  
  835. static void CodeIO(Word Code)
  836. {
  837.   if (ChkArgCnt(1, 1))
  838.   {
  839.     tEvalResult EvalResult;
  840.     Word DirVal;
  841.  
  842.     DirVal = EvalStrIntExpressionWithResult(&ArgStr[1], UInt4, &EvalResult);
  843.     if (EvalResult.OK)
  844.     {
  845.       ChkSpace(SegIO, EvalResult.AddrSpaceMask);
  846.       WAsmCode[CodeLen++] = Code | (DirVal & 15);
  847.     }
  848.   }
  849. }
  850.  
  851. static void CodeLong(Word Code)
  852. {
  853.   if (ChkArgCnt(1, 1))
  854.   {
  855.     tEvalResult EvalResult;
  856.     Word DirVal;
  857.  
  858.     DirVal = EvalStrIntExpressionWithResult(&ArgStr[1], CodeIntType, &EvalResult);
  859.     if (EvalResult.OK)
  860.     {
  861.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  862.       WAsmCode[CodeLen++] = Code | ((DirVal >> 10) & 15);
  863.       WAsmCode[CodeLen++] = DirVal & 0x3ff;
  864.     }
  865.   }
  866. }
  867.  
  868. static void CodeBR(Word Code)
  869. {
  870.   if (ChkArgCnt(1, 1))
  871.   {
  872.     tEvalResult EvalResult;
  873.     Word DirVal;
  874.  
  875.     DirVal = EvalStrIntExpressionWithResult(&ArgStr[1], CodeIntType, &EvalResult);
  876.     if (EvalResult.OK && ChkSamePage(EProgCounter() + 1, DirVal, 8, EvalResult.Flags))
  877.     {
  878.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  879.       WAsmCode[CodeLen++] = Code | (DirVal & 0xff);
  880.     }
  881.   }
  882. }
  883.  
  884. static void CodeCAL(Word Code)
  885. {
  886.   if (ChkArgCnt(1, 1))
  887.   {
  888.     tEvalResult EvalResult;
  889.     Word DirVal;
  890.  
  891.     DirVal = EvalStrIntExpressionWithResult(&ArgStr[1], UInt6, &EvalResult);
  892.     if (EvalResult.OK)
  893.     {
  894.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  895.       WAsmCode[CodeLen++] = Code | (DirVal & 0x3f);
  896.     }
  897.   }
  898. }
  899.  
  900. static void DecodeDATA_HMCS400(Word Code)
  901. {
  902.   UNUSED(Code);
  903.  
  904.   DecodeDATA(Int10, Int4);
  905. }
  906.  
  907. static void DecodeSFR(Word Code)
  908. {
  909.   UNUSED(Code);
  910.  
  911.   CodeEquate(SegData, 0, SegLimits[SegData]);
  912. }
  913.  
  914. /*-------------------------------------------------------------------------*/
  915.  
  916. static void AddX(const char *pOpPart, Word Code, InstProc Proc)
  917. {
  918.   char OpPart[30];
  919.  
  920.   AddInstTable(InstTable, pOpPart, Code, Proc);
  921.   as_snprintf(OpPart, sizeof(OpPart), "%sX", pOpPart);
  922.   AddInstTable(InstTable, OpPart, Code | 1, Proc);
  923. }
  924.  
  925. static void AddXY(const char *pOpPart, Word Code, InstProc Proc)
  926. {
  927.   char OpPart[30];
  928.  
  929.   AddInstTable(InstTable, pOpPart, Code, Proc);
  930.   as_snprintf(OpPart, sizeof(OpPart), "%sX", pOpPart);
  931.   AddInstTable(InstTable, OpPart, Code | 1, Proc);
  932.   as_snprintf(OpPart, sizeof(OpPart), "%sY", pOpPart);
  933.   AddInstTable(InstTable, OpPart, Code | 2, Proc);
  934.   as_snprintf(OpPart, sizeof(OpPart), "%sXY", pOpPart);
  935.   AddInstTable(InstTable, OpPart, Code | 3, Proc);
  936. }
  937.  
  938. static void InitFields(void)
  939. {
  940.   InstTable = CreateInstTable(201);
  941.   SetDynamicInstTable(InstTable);
  942.  
  943.   AddInstTable(InstTable, "LD", 0, DecodeLD);
  944.   AddInstTable(InstTable, "XCH", 0, DecodeXCH);
  945.   AddInstTable(InstTable, "INC", 0x04c, DecodeINCDEC);
  946.   AddInstTable(InstTable, "DEC", 0x0cf, DecodeINCDEC);
  947.   AddInstTable(InstTable, "ADD", 0, DecodeADD);
  948.   AddInstTable(InstTable, "ADC", 0, DecodeADC);
  949.   AddInstTable(InstTable, "SUB", 0, DecodeSUB);
  950.   AddInstTable(InstTable, "SBC", 0, DecodeSBC);
  951.   AddInstTable(InstTable, "OR", 0, DecodeOR);
  952.   AddInstTable(InstTable, "AND", 0, DecodeAND);
  953.   AddInstTable(InstTable, "EOR", 0, DecodeEOR);
  954.   AddInstTable(InstTable, "CP", 0, DecodeCP);
  955.   AddInstTable(InstTable, "BSET", 0xef84, DecodeBit);
  956.   AddInstTable(InstTable, "BCLR", 0xec88, DecodeBit);
  957.   AddInstTable(InstTable, "BTST", 0x6f8c, DecodeBit);
  958.  
  959.   AddInstTable(InstTable, "LAB",    0x048, CodeFixed);
  960.   AddInstTable(InstTable, "LBA",    0x0c8, CodeFixed);
  961.   AddInstTable(InstTable, "LAY",    0x0af, CodeFixed);
  962.   AddInstTable(InstTable, "LASPX",  0x068, CodeFixed);
  963.   AddInstTable(InstTable, "LASPY",  0x058, CodeFixed);
  964.   AddInstTable(InstTable, "LXA",    0x0e8, CodeFixed);
  965.   AddInstTable(InstTable, "LYA",    0x0d8, CodeFixed);
  966.   AddInstTable(InstTable, "IY",     0x05c, CodeFixed);
  967.   AddInstTable(InstTable, "DY",     0x0df, CodeFixed);
  968.   AddInstTable(InstTable, "AYY",    0x054, CodeFixed);
  969.   AddInstTable(InstTable, "SYY",    0x0d4, CodeFixed);
  970.   AddInstTable(InstTable, "XSPX",   0x001, CodeFixed);
  971.   AddInstTable(InstTable, "XSPY",   0x002, CodeFixed);
  972.   AddInstTable(InstTable, "XSPXY",  0x003, CodeFixed);
  973.   AddXY("LAM", 0x090, CodeFixed);
  974.   AddXY("LBM", 0x040, CodeFixed);
  975.   AddXY("LMA", 0x094, CodeFixed);
  976.   AddX("LMAIY", 0x050, CodeFixed);
  977.   AddX("LMADY", 0x0d0, CodeFixed);
  978.   AddXY("XMA", 0x080, CodeFixed);
  979.   AddXY("XMB", 0x0c0, CodeFixed);
  980.   AddInstTable(InstTable, "IB",     0x04c, CodeFixed);
  981.   AddInstTable(InstTable, "DB",     0x0cf, CodeFixed);
  982.   AddInstTable(InstTable, "DAA",    0x0a6, CodeFixed);
  983.   AddInstTable(InstTable, "DAS",    0x0aa, CodeFixed);
  984.   AddInstTable(InstTable, "NEGA",   0x060, CodeFixed);
  985.   AddInstTable(InstTable, "COMB",   0x140, CodeFixed);
  986.   AddInstTable(InstTable, "ROTR",   0x0a0, CodeFixed);
  987.   AddInstTable(InstTable, "ROTL",   0x0a1, CodeFixed);
  988.   AddInstTable(InstTable, "SEC",    0x0ef, CodeFixed);
  989.   AddInstTable(InstTable, "REC",    0x0ec, CodeFixed);
  990.   AddInstTable(InstTable, "TC",     0x06f, CodeFixed);
  991.   AddInstTable(InstTable, "AM",     0x008, CodeFixed);
  992.   AddInstTable(InstTable, "AMC",    0x018, CodeFixed);
  993.   AddInstTable(InstTable, "SMC",    0x098, CodeFixed);
  994.   AddInstTable(InstTable, "ANM",    0x09c, CodeFixed);
  995.   AddInstTable(InstTable, "ORM",    0x00c, CodeFixed);
  996.   AddInstTable(InstTable, "EORM",   0x01c, CodeFixed);
  997.   AddInstTable(InstTable, "ANEM",   0x004, CodeFixed);
  998.   AddInstTable(InstTable, "BNEM",   0x044, CodeFixed);
  999.   AddInstTable(InstTable, "ALEM",   0x014, CodeFixed);
  1000.   AddInstTable(InstTable, "BLEM",   0x0c4, CodeFixed);
  1001.   AddInstTable(InstTable, "RTN",    0x010, CodeFixed);
  1002.   AddInstTable(InstTable, "RTNI",   0x011, CodeFixed);
  1003.   AddInstTable(InstTable, "SED",    0x0e4, CodeFixed);
  1004.   AddInstTable(InstTable, "RED",    0x064, CodeFixed);
  1005.   AddInstTable(InstTable, "TD",     0x0e0, CodeFixed);
  1006.   AddInstTable(InstTable, "NOP",    0x000, CodeFixed);
  1007.   AddInstTable(InstTable, "SBY",    0x14c, CodeFixed);
  1008.   AddInstTable(InstTable, "STOP",   0x14d, CodeFixed);
  1009.  
  1010.   AddInstTable(InstTable, "LAI",    0x230, CodeImm);
  1011.   AddInstTable(InstTable, "LBI",    0x200, CodeImm);
  1012.   AddInstTable(InstTable, "LMIIY",  0x290, CodeImm);
  1013.   AddInstTable(InstTable, "LWI",   0x80f0, CodeImm);
  1014.   AddInstTable(InstTable, "LXI",    0x220, CodeImm);
  1015.   AddInstTable(InstTable, "LYI",    0x210, CodeImm);
  1016.   AddInstTable(InstTable, "AI",     0x280, CodeImm);
  1017.   AddInstTable(InstTable, "INEM",   0x020, CodeImm);
  1018.   AddInstTable(InstTable, "YNEI",   0x070, CodeImm);
  1019.   AddInstTable(InstTable, "ILEM",   0x030, CodeImm);
  1020.   AddInstTable(InstTable, "ALEI",   0x2b0, CodeImm);
  1021.   AddInstTable(InstTable, "SEM",   0x8084, CodeImm);
  1022.   AddInstTable(InstTable, "REM",   0x8088, CodeImm);
  1023.   AddInstTable(InstTable, "TM",    0x808c, CodeImm);
  1024.   AddInstTable(InstTable, "P",      0x1b0, CodeImm);
  1025.   AddInstTable(InstTable, "TBR",    0x0b0, CodeImm);
  1026.  
  1027.   AddInstTable(InstTable, "LAMD",   0x190, CodeDir);
  1028.   AddInstTable(InstTable, "LMAD",   0x194, CodeDir);
  1029.   AddInstTable(InstTable, "XMAD",   0x180, CodeDir);
  1030.   AddInstTable(InstTable, "AMD",    0x108, CodeDir);
  1031.   AddInstTable(InstTable, "AMCD",   0x118, CodeDir);
  1032.   AddInstTable(InstTable, "SMCD",   0x198, CodeDir);
  1033.   AddInstTable(InstTable, "ANMD",   0x19c, CodeDir);
  1034.   AddInstTable(InstTable, "ORMD",   0x10c, CodeDir);
  1035.   AddInstTable(InstTable, "EORMD",  0x11c, CodeDir);
  1036.   AddInstTable(InstTable, "ANEMD",  0x104, CodeDir);
  1037.   AddInstTable(InstTable, "ALEMD",  0x114, CodeDir);
  1038.  
  1039.   AddInstTable(InstTable, "LMID",   0x1a0, CodeImmDir);
  1040.   AddInstTable(InstTable, "INEMD",  0x120, CodeImmDir);
  1041.   AddInstTable(InstTable, "ILEMD",  0x130, CodeImmDir);
  1042.   AddInstTable(InstTable, "SEMD",  0x8184, CodeImmDir);
  1043.   AddInstTable(InstTable, "REMD",  0x8188, CodeImmDir);
  1044.   AddInstTable(InstTable, "TMD",   0x818c, CodeImmDir);
  1045.  
  1046.   AddInstTable(InstTable, "LAMR",   0x270, CodeIO);
  1047.   AddInstTable(InstTable, "XMRA",   0x2f0, CodeIO);
  1048.   AddInstTable(InstTable, "SEDD",   0x2e0, CodeIO);
  1049.   AddInstTable(InstTable, "REDD",   0x260, CodeIO);
  1050.   AddInstTable(InstTable, "TDD",    0x2a0, CodeIO);
  1051.   AddInstTable(InstTable, "LAR",    0x250, CodeIO);
  1052.   AddInstTable(InstTable, "LBR",    0x240, CodeIO);
  1053.   AddInstTable(InstTable, "LRA",    0x2d0, CodeIO);
  1054.   AddInstTable(InstTable, "LRB",    0x2c0, CodeIO);
  1055.  
  1056.   AddInstTable(InstTable, "BRL",    0x270, CodeLong);
  1057.   AddInstTable(InstTable, "JMPL",   0x250, CodeLong);
  1058.   AddInstTable(InstTable, "CALL",   0x260, CodeLong);
  1059.   AddInstTable(InstTable, "BR",     0x300, CodeBR);
  1060.   AddInstTable(InstTable, "CAL",    0x1c0, CodeCAL);
  1061.  
  1062.   AddInstTable(InstTable, "RES", 0, DecodeRES);
  1063.   AddInstTable(InstTable, "DATA", 0, DecodeDATA_HMCS400);
  1064.   AddInstTable(InstTable, "SFR", 0, DecodeSFR);
  1065. }
  1066.  
  1067. static void DeinitFields(void)
  1068. {
  1069.   DestroyInstTable(InstTable);
  1070. }
  1071.  
  1072. /*-------------------------------------------------------------------------*/
  1073.  
  1074. static void  MakeCode_HMCS400(void)
  1075. {
  1076.   CodeLen = 0; DontPrint = False; OpSizeType = Int4;
  1077.  
  1078.   /* zu ignorierendes */
  1079.  
  1080.   if (Memo(""))
  1081.     return;
  1082.  
  1083.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1084.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1085. }
  1086.  
  1087.  
  1088. static Boolean IsDef_HMCS400(void)
  1089. {
  1090.   return False;
  1091. }
  1092.  
  1093. static void SwitchFrom_HMCS400(void)
  1094. {
  1095.   DeinitFields();
  1096. }
  1097.  
  1098. static void SwitchTo_HMCS400(void)
  1099. {
  1100.   const TFamilyDescr *pDescr;
  1101.  
  1102.   pDescr = FindFamilyByName("HMCS400");
  1103.  
  1104.   TurnWords = False;
  1105.   SetIntConstMode(eIntConstModeMoto);
  1106.  
  1107.   PCSymbol = "*";
  1108.   HeaderID = pDescr->Id;
  1109.   NOPCode = 0x0000;
  1110.   DivideChars = ",";
  1111.   HasAttrs = False;
  1112.  
  1113.   ValidSegs = (1 << SegCode) | (1 << SegData) | (1 << SegIO);
  1114.   Grans[SegCode] = 2; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
  1115.   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegCode] = 0;
  1116.   Grans[SegIO]   = 1; ListGrans[SegIO]   = 1; SegInits[SegIO]   = 0;
  1117.   if (MomCPU == CPU614023)
  1118.   {
  1119.     CodeIntType = UInt11;
  1120.     DataIntType = UInt8;
  1121.     SegLimits[SegData] = 159;
  1122.   }
  1123.   else if (MomCPU == CPU614043)
  1124.   {
  1125.     CodeIntType = UInt12;
  1126.     DataIntType = UInt8;
  1127.     SegLimits[SegData] = 255;
  1128.   }
  1129.   else if (MomCPU == CPU614081)
  1130.   {
  1131.     CodeIntType = UInt13;
  1132.     DataIntType = UInt9;
  1133.     SegLimits[SegData] = 511;
  1134.   }
  1135.   SegLimits[SegIO] = 15;
  1136.   SegLimits[SegCode] = IntTypeDefs[CodeIntType].Max;
  1137.  
  1138.   MakeCode = MakeCode_HMCS400;
  1139.   IsDef = IsDef_HMCS400;
  1140.   SwitchFrom = SwitchFrom_HMCS400; InitFields();
  1141.  
  1142. }
  1143.  
  1144. void codehmcs400_init(void)
  1145. {
  1146.   CPU614023 = AddCPU("HD614023", SwitchTo_HMCS400);
  1147.   CPU614043 = AddCPU("HD614043", SwitchTo_HMCS400);
  1148.   CPU614081 = AddCPU("HD614081", SwitchTo_HMCS400);
  1149. }
  1150.