Subversion Repositories pentevo

Rev

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

  1. /* codeol50.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator OKI OLMS-50-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 "asmallg.h"
  20. #include "asmpars.h"
  21. #include "asmitree.h"
  22. #include "codepseudo.h"
  23. #include "fourpseudo.h"
  24. #include "codevars.h"
  25. #include "headids.h"
  26. #include "errmsg.h"
  27.  
  28. #include "codeol50.h"
  29.  
  30. typedef enum
  31. {
  32.   ModACC = 0,
  33.   ModAP = 1,
  34.   ModAX = 2,
  35.   ModImm = 3,
  36.   ModNone = 0x7f
  37. } tAdrMode;
  38.  
  39. typedef struct
  40. {
  41.   Word ACCCode, ImmCode;
  42.   Word CPUMask;
  43. } tAriOrder;
  44. static tAriOrder *AriOrders;
  45.  
  46. typedef struct
  47. {
  48.   Word Code, CPUMask;
  49. } tAPOrder;
  50. static tAPOrder *APOrders;
  51.  
  52. typedef struct
  53. {
  54.   Word APCode, AXCode, CPUMask;
  55. } tAPAXOrder;
  56. static tAPAXOrder *APAXOrders;
  57.  
  58. typedef struct
  59. {
  60.   Word Code, CPUMask;
  61. } tFixedOrder;
  62. static tFixedOrder *FixedOrders;
  63.  
  64. typedef struct
  65. {
  66.   Word Code, CPUMask;
  67. } tImmOrder;
  68. static tImmOrder *ImmOrders;
  69.  
  70. typedef struct
  71. {
  72.   Word Code, PlusCPUMask, MinusCPUMask;
  73. } tRelOrder;
  74. static tRelOrder *RelOrders;
  75.  
  76. typedef struct
  77. {
  78.   Word Code, CPUMask;
  79. } tDSPOrder;
  80. static tDSPOrder *DSPOrders;
  81.  
  82. typedef struct
  83. {
  84.   Word Code;
  85.   Word Shift;
  86.   Word CPUMask;
  87. } tONOFFOrder;
  88. static tONOFFOrder *ONOFFOrders;
  89.  
  90. typedef struct
  91. {
  92.   Word APCode, ImmCode;
  93.   Boolean AllowAP;
  94.   Word CPUMask;
  95. } tCtrlOrder;
  96. static tCtrlOrder *CtrlOrders;
  97.  
  98. typedef struct
  99. {
  100.   Word Code;
  101.   Word CPUMask;
  102. } tMemOrder;
  103. static tMemOrder *MemOrders;
  104.  
  105. #define MModACC (1 << ModACC)
  106. #define MModAP (1 << ModAP)
  107. #define MModAX (1 << ModAX)
  108. #define MModImm (1 << ModImm)
  109.  
  110. #define M_5054 (1 << 0)
  111. #define M_5055 (1 << 1)
  112. #define M_5056 (1 << 2)
  113. #define M_6051 (1 << 3)
  114. #define M_6052 (1 << 4)
  115.  
  116. static CPUVar CPU5054, CPU5055, CPU5056, CPU6051, CPU6052;
  117. static tAdrMode AdrMode;
  118. static Word AdrVal;
  119. static LongInt PRegAssume;
  120. static IntType CodeIntType, DataIntType;
  121.  
  122. /*-------------------------------------------------------------------------*/
  123.  
  124. static Boolean DecodeAdr(const tStrComp *pArg, Word Mask)
  125. {
  126.   Boolean OK;
  127.   tSymbolFlags Flags;
  128.  
  129.   AdrMode = ModNone;
  130.  
  131.   if (!as_strcasecmp(pArg->str.p_str, "ACC"))
  132.   {
  133.     AdrMode = ModACC;
  134.     goto AdrFound;
  135.   }
  136.  
  137.   if (0[pArg->str.p_str] == '#')
  138.   {
  139.     AdrVal = EvalStrIntExpressionOffs(pArg, 1, Int4, &OK);
  140.     if (OK)
  141.     {
  142.       AdrVal = (AdrVal & 15) << 4;
  143.       AdrMode = ModImm;
  144.     }
  145.     goto AdrFound;
  146.   }
  147.  
  148.   AdrVal = EvalStrIntExpressionWithFlags(pArg, DataIntType, &OK, &Flags);
  149.   if (OK)
  150.   {
  151.     if (mFirstPassUnknown(Flags))
  152.       AdrVal &= 15;
  153.  
  154.     if (AdrVal < 16)
  155.       AdrMode = ModAP;
  156.     else if (((AdrVal >> 4) & 15) == PRegAssume)
  157.     {
  158.       AdrVal = (AdrVal & 15) | 0x100;
  159.       AdrMode = ModAP;
  160.     }
  161.     else if (Mask & MModAX)
  162.       AdrMode = ModAX;
  163.     else
  164.       WrError(ErrNum_AddrOnDifferentPage);
  165.   }
  166.  
  167. AdrFound:
  168.  
  169.   if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
  170.   {
  171.     WrError(ErrNum_InvAddrMode);
  172.     AdrMode = ModNone; AdrCnt = 0;
  173.   }
  174.   return (AdrMode != ModNone);
  175. }
  176.  
  177. static Boolean CheckCPU(Byte Mask)
  178. {
  179.   if (MomCPU == CPU5054)
  180.     Mask &= M_5054;
  181.   else if (MomCPU == CPU5055)
  182.     Mask &= M_5055;
  183.   else if (MomCPU == CPU5056)
  184.     Mask &= M_5056;
  185.   else if (MomCPU == CPU6051)
  186.     Mask &= M_6051;
  187.   else if (MomCPU == CPU6052)
  188.     Mask &= M_6052;
  189.   return !!Mask;
  190. }
  191.  
  192. static int ImmPtr(const char *pArg)
  193. {
  194.   return !!(*pArg == '#');
  195. }
  196.  
  197. /*-------------------------------------------------------------------------*/
  198.  
  199. static void DecodeAri(Word Index)
  200. {
  201.   const tAriOrder *pOrder = AriOrders + Index;
  202.  
  203.   if (ChkArgCnt(2, 2)
  204.    && (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0))
  205.   {
  206.     if (DecodeAdr(&ArgStr[2], MModAP))
  207.     {
  208.       WAsmCode[0] = AdrVal;
  209.       DecodeAdr(&ArgStr[1], MModACC | MModImm);
  210.       switch (AdrMode)
  211.       {
  212.         case ModACC:
  213.           WAsmCode[0] |= pOrder->ACCCode;
  214.           CodeLen = 1;
  215.           break;
  216.         case ModImm:
  217.           WAsmCode[0] |= pOrder->ImmCode | AdrVal;
  218.           CodeLen = 1;
  219.           break;
  220.         default:
  221.           break;
  222.       }
  223.     }
  224.   }
  225. }
  226.  
  227. static void DecodeADJUST(Word Code)
  228. {
  229.   UNUSED(Code);
  230.  
  231.   if (ChkArgCnt(2, 2)
  232.    && (ChkExactCPUMask(M_5054 | M_5055, CPU5054) >= 0))
  233.   {
  234.     if (DecodeAdr(&ArgStr[2], MModAP))
  235.     {
  236.       Boolean OK;
  237.       Word N = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
  238.  
  239.       if (OK)
  240.       {
  241.         N = ((~N) + 1) & 15;
  242.         WAsmCode[0] = 0x3000 | AdrVal | (N << 4);
  243.         CodeLen = 1;
  244.       }
  245.     }
  246.   }
  247. }
  248.  
  249. static void DecodeAP(Word Index)
  250. {
  251.   const tAPOrder *pOrder = APOrders + Index;
  252.  
  253.   if (ChkArgCnt(1, 1)
  254.    && (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0))
  255.   {
  256.     if (DecodeAdr(&ArgStr[1], MModAP))
  257.     {
  258.       WAsmCode[0] = pOrder->Code | AdrVal;
  259.       CodeLen = 1;
  260.     }
  261.   }
  262. }
  263.  
  264. static void DecodeFixed(Word Index)
  265. {
  266.   const tFixedOrder *pOrder = FixedOrders + Index;
  267.  
  268.   if (ChkArgCnt(0, 0)
  269.    && (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0))
  270.   {
  271.     WAsmCode[0] = pOrder->Code;
  272.     CodeLen = 1;
  273.   }
  274. }
  275.  
  276. static void DecodeMOV(Word Code)
  277. {
  278.   UNUSED(Code);
  279.  
  280.   if (ChkArgCnt(2, 2)
  281.    && (ChkExactCPUMask(M_5054 | M_5055 | M_5056 | M_6051 | M_6052, CPU5054) >= 0))
  282.   {
  283.     DecodeAdr(&ArgStr[2], MModACC | MModAP | MModAX);
  284.     switch (AdrMode)
  285.     {
  286.       case ModACC:
  287.         DecodeAdr(&ArgStr[1], MModAP | MModAX);
  288.         switch (AdrMode)
  289.         {
  290.           case ModAP:
  291.           case ModAX:
  292.             WAsmCode[0] = 0x3e00 | AdrVal;
  293.             CodeLen = 1;
  294.             break;
  295.           default:
  296.             break;
  297.         }
  298.         break;
  299.       case ModAP:
  300.         WAsmCode[0] = AdrVal;
  301.         DecodeAdr(&ArgStr[1], MModACC | MModImm);
  302.         switch (AdrMode)
  303.         {
  304.           case ModACC:
  305.             WAsmCode[0] |= 0x3c00;
  306.             CodeLen = 1;
  307.             break;
  308.           case ModImm:
  309.             WAsmCode[0] |= 0x1c00 | AdrVal;
  310.             CodeLen = 1;
  311.             break;
  312.           default:
  313.             break;
  314.         }
  315.         break;
  316.       case ModAX:
  317.         WAsmCode[0] = AdrVal;
  318.         if (DecodeAdr(&ArgStr[1], MModACC))
  319.         {
  320.           WAsmCode[0] |= 0x3c00;
  321.           CodeLen = 1;
  322.         }
  323.         break;
  324.       default:
  325.         break;
  326.     }
  327.   }
  328. }
  329.  
  330. static void DecodeAPAX(Word Index)
  331. {
  332.   const tAPAXOrder *pOrder = APAXOrders + Index;
  333.  
  334.   if (ChkArgCnt(1, 1)
  335.    && (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0))
  336.   {
  337.     DecodeAdr(&ArgStr[1], MModAP | MModAX);
  338.     switch (AdrMode)
  339.     {
  340.       case ModAP:
  341.         WAsmCode[0] = pOrder->APCode | AdrVal;
  342.         CodeLen = 1;
  343.         break;
  344.       case ModAX:
  345.         WAsmCode[0] = pOrder->AXCode | AdrVal;
  346.         CodeLen = 1;
  347.         break;
  348.       default:
  349.         break;
  350.     }
  351.   }
  352. }
  353.  
  354. static void DecodeJMPIO(Word Code)
  355. {
  356.   if (ChkArgCnt(1, 1));
  357.   else if (ChkExactCPUMask(M_5054 | M_5055 | M_5056 | M_6051 | M_6052, CPU5054) < 0);
  358.   else if (*ArgStr[1].str.p_str != '@') WrError(ErrNum_InvAddrMode);
  359.   {
  360.     tStrComp Arg;
  361.  
  362.     StrCompRefRight(&Arg, &ArgStr[1], 1);
  363.     if (DecodeAdr(&Arg, MModAP))
  364.     {
  365.       WAsmCode[0] = Code | AdrVal;
  366.       CodeLen = 1;
  367.     }
  368.   }
  369. }
  370.  
  371. static void DecodeJMP(Word Code)
  372. {
  373.   UNUSED(Code);
  374.  
  375.   if (!ChkArgCnt(1, 1));
  376.   else if (ChkExactCPUMask(M_5054 | M_5055 | M_5056 | M_6051 | M_6052, CPU5054) < 0);
  377.   else if (*ArgStr[1].str.p_str == '@')
  378.     DecodeJMPIO(0x00d0);
  379.   else
  380.   {
  381.     Boolean OK;
  382.     tSymbolFlags Flags;
  383.  
  384.     WAsmCode[0] = EvalStrIntExpressionWithFlags(&ArgStr[1], CodeIntType, &OK, &Flags);
  385.     if (OK)
  386.     {
  387.       if (mFirstPassUnknown(Flags) && (WAsmCode[0] >= SegLimits[SegCode]))
  388.         WAsmCode[0] = SegLimits[SegCode];
  389.       if (ChkRange(WAsmCode[0], 0, SegLimits[SegCode]))
  390.       {
  391.         WAsmCode[0] |= 0x2000;
  392.         CodeLen = 1;
  393.       }
  394.     }
  395.   }
  396. }
  397.  
  398. static void DecodeCALL(Word Code)
  399. {
  400.   UNUSED(Code);
  401.  
  402.   if (ChkArgCnt(1, 1)
  403.    && (ChkExactCPUMask(M_6051 | M_6052, CPU5054) >= 0))
  404.   {
  405.     Boolean OK;
  406.  
  407.     WAsmCode[0] = EvalStrIntExpression(&ArgStr[1], (MomCPU == CPU6052) ? UInt11 : UInt10, &OK);
  408.     if (OK)
  409.     {
  410.       WAsmCode[0] |= (MomCPU == CPU6052) ? 0x2800 : 0x2c00;
  411.       CodeLen = 1;
  412.     }
  413.   }
  414. }
  415.  
  416. static void DecodeMSA(Word Code)
  417. {
  418.   UNUSED(Code);
  419.  
  420.   if (ChkArgCnt(1, 1)
  421.    && (ChkExactCPUMask(M_6051, CPU5054) >= 0))
  422.   {
  423.     Boolean OK;
  424.  
  425.     WAsmCode[0] = EvalStrIntExpression(&ArgStr[1], UInt9, &OK);
  426.     if (OK)
  427.     {
  428.       WAsmCode[0] |= 0x2a00;
  429.       CodeLen = 1;
  430.     }
  431.   }
  432. }
  433.  
  434. static void DecodeRel(Word Index)
  435. {
  436.   const tRelOrder *pOrder = RelOrders + Index;
  437.   Boolean AllowMinus = CheckCPU(pOrder->MinusCPUMask),
  438.        AllowPlus = CheckCPU(pOrder->PlusCPUMask);
  439.  
  440.   if (ChkArgCnt(1, 1)
  441.    && (ChkExactCPUMask(pOrder->MinusCPUMask | pOrder->PlusCPUMask, CPU5054) >= 0))
  442.   {
  443.     Boolean OK;
  444.     tSymbolFlags Flags;
  445.     Integer Distance = EvalStrIntExpressionWithFlags(&ArgStr[1], CodeIntType, &OK, &Flags) - (EProgCounter() + 1);
  446.     Integer MinDist = AllowMinus ? -32 : 0,
  447.             MaxDist = AllowPlus ? 31 : -1;
  448.  
  449.     if (((Distance < MinDist) || (Distance > MaxDist)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  450.     else
  451.     {
  452.       if (Distance >= 0)
  453.         WAsmCode[0] = 0;
  454.       else
  455.       {
  456.         WAsmCode[0] = 0x0100;
  457.         Distance = -1 - Distance;
  458.       }
  459.       WAsmCode[0] |= pOrder->Code | (Distance & 0x1f);
  460.       CodeLen = 1;
  461.     }
  462.   }
  463. }
  464.  
  465. static void DecodeCtrl(Word Index)
  466. {
  467.   const tCtrlOrder *pOrder = CtrlOrders + Index;
  468.  
  469.   if (ChkArgCnt(1, 1)
  470.    && (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0))
  471.   {
  472.     DecodeAdr(&ArgStr[1], MModImm | MModAP);
  473.     switch (AdrMode)
  474.     {
  475.       case ModImm:
  476.         WAsmCode[0] = pOrder->ImmCode | (AdrVal >> 4);
  477.         CodeLen = 1;
  478.         break;
  479.       case ModAP:
  480.         if (!pOrder->AllowAP && (AdrVal & 0x100)) WrError(ErrNum_InvAddrMode);
  481.         else
  482.         {
  483.           WAsmCode[0] = pOrder->APCode | AdrVal;
  484.           CodeLen = 1;
  485.         }
  486.         break;
  487.       default:
  488.         break;
  489.     }
  490.   }
  491. }
  492.  
  493. static void DecodeDSP(Word Index)
  494. {
  495.   const tDSPOrder *pOrder = DSPOrders + Index;
  496.  
  497.   if (ChkArgCnt(2, 2)
  498.    && (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0)
  499.    && DecodeAdr(&ArgStr[2], MModAP))
  500.   {
  501.     Boolean OK;
  502.     Word Digit;
  503.  
  504.     Digit = EvalStrIntExpressionOffs(&ArgStr[1], ImmPtr(ArgStr[1].str.p_str), UInt4, &OK);
  505.     if (OK)
  506.     {
  507.       WAsmCode[0] = pOrder->Code | AdrVal | (Digit << 4);
  508.       CodeLen = 1;
  509.     }
  510.   }
  511. }
  512.  
  513. static void DecodeINTENDSAB(Word Code)
  514. {
  515.   if (ChkArgCnt(0, 0)
  516.    && (ChkExactCPUMask(M_5054 | M_5055 | M_6051, CPU5054) >= 0))
  517.   {
  518.     WAsmCode[0] = 0x04b0 | (Code & 0x0f);
  519.     WAsmCode[1] = 0x0440 | ((Code >> 4) & 0x0f);
  520.     CodeLen = 2;
  521.   }
  522. }
  523.  
  524. static void DecodeONOFF(Word Index)
  525. {
  526.   const tONOFFOrder *pOrder = ONOFFOrders + Index;
  527.   Boolean IsON;
  528.  
  529.   if (!ChkArgCnt(1, 1));
  530.   else if (ChkExactCPUMask(pOrder->CPUMask, CPU5054) < 0);
  531.   else if (CheckONOFFArg(&ArgStr[1], &IsON))
  532.   {
  533.     WAsmCode[0] = pOrder->Code | ((IsON ? 3 : 2) << pOrder->Shift);
  534.     CodeLen = 1;
  535.   }
  536. }
  537.  
  538. static void DecodeImm(Word Index)
  539. {
  540.   const tImmOrder *pOrder = ImmOrders + Index;
  541.  
  542.   if (ChkArgCnt(1, 1)
  543.    && (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0))
  544.   {
  545.     Boolean OK;
  546.     Word Freq = EvalStrIntExpressionOffs(&ArgStr[1], ImmPtr(ArgStr[1].str.p_str), UInt4, &OK);
  547.  
  548.     if (OK)
  549.     {
  550.       WAsmCode[0] = pOrder->Code | Freq;
  551.       CodeLen = 1;
  552.     }
  553.   }
  554. }
  555.  
  556. static void DecodeBUZZER(Word Code)
  557. {
  558.   int ReqArgCnt = (MomCPU == CPU5055) ? 1 : 2;
  559.  
  560.   UNUSED(Code);
  561.  
  562.   if (ChkArgCnt(ReqArgCnt, ReqArgCnt)
  563.    && (ChkExactCPUMask(M_5054 | M_5055, CPU5054) >= 0))
  564.   {
  565.     Boolean OK = True, OK2;
  566.     Word Freq, Sound;
  567.  
  568.     Freq =  (ReqArgCnt >= 2) ? EvalStrIntExpressionOffs(&ArgStr[1], ImmPtr(ArgStr[1].str.p_str), UInt2, &OK) : 2;
  569.     Sound = EvalStrIntExpressionOffs(&ArgStr[ArgCnt], ImmPtr(ArgStr[ArgCnt].str.p_str), UInt2, &OK2);
  570.     if (OK && OK2)
  571.     {
  572.       WAsmCode[0] = 0x04c0 | Freq | (Sound << 2);
  573.       CodeLen = 1;
  574.     }
  575.   }
  576. }
  577.  
  578. static void DecodeINP(Word Code)
  579. {
  580.   UNUSED(Code);
  581.  
  582.   if (ChkArgCnt(2, 2)
  583.    && (ChkExactCPUMask(M_5056, CPU5054) >= 0))
  584.   {
  585.     Boolean OK;
  586.     Word Port = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
  587.  
  588.     if (OK && DecodeAdr(&ArgStr[2], MModAP))
  589.     {
  590.       WAsmCode[0] = 0x3400 | AdrVal | (Port << 4);
  591.       CodeLen = 1;
  592.     }
  593.   }
  594. }
  595.  
  596. static void DecodeIN(Word Code)
  597. {
  598.   UNUSED(Code);
  599.  
  600.   if (ChkArgCnt(2, 2)
  601.    && (ChkExactCPUMask(M_6052, CPU5054) >= 0))
  602.   {
  603.     Boolean OK;
  604.     Word Port = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
  605.  
  606.     if (OK && DecodeAdr(&ArgStr[2], MModAP))
  607.     {
  608.       WAsmCode[0] = 0x0400 | AdrVal | (Port << 4);
  609.       CodeLen = 1;
  610.     }
  611.   }
  612. }
  613.  
  614. static void DecodeOUT(Word Code)
  615. {
  616.   UNUSED(Code);
  617.  
  618.   if (ChkArgCnt(2, 2)
  619.    && (ChkExactCPUMask(M_5056 | M_6052, CPU5054) >= 0))
  620.   {
  621.     Boolean OK;
  622.     Word Port = EvalStrIntExpression(&ArgStr[2], (MomCPU == CPU6052) ? UInt5 : UInt4, &OK);
  623.  
  624.     if (OK)
  625.     {
  626.       if (MomCPU == CPU6052)
  627.         Port = (Port & 15) | ((Port & 16) << 1);
  628.       DecodeAdr(&ArgStr[1], MModAP | MModImm);
  629.       switch (AdrMode)
  630.       {
  631.         case ModAP:
  632.           WAsmCode[0] = ((MomCPU == CPU6052) ? 0x0800 : 0x3600) | AdrVal | (Port << 4);
  633.           CodeLen = 1;
  634.           break;
  635.         case ModImm:
  636.           WAsmCode[0] = ((MomCPU == CPU6052) ? 0x0c00 : 0x0400) | (AdrVal >> 4) | (Port << 4);
  637.           CodeLen = 1;
  638.           break;
  639.         default:
  640.           break;
  641.       }
  642.     }
  643.   }
  644. }
  645.  
  646. static void DecodeMem(Word Index)
  647. {
  648.   const tMemOrder *pOrder = MemOrders + Index;
  649.  
  650.   if (ChkArgCnt(0, 3)
  651.    && (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0))
  652.   {
  653.     WAsmCode[0] = pOrder->Code;
  654.     if (ArgCnt < 1)
  655.       CodeLen = 1;
  656.     else
  657.     {
  658.       if (!strcmp(ArgStr[1].str.p_str, "-"))
  659.         WAsmCode[0] |= 0x0010;
  660.       else if (strcmp(ArgStr[1].str.p_str, "+"))
  661.       {
  662.         WrError(ErrNum_InvAddrMode);
  663.         return;
  664.       }
  665.       if (ArgCnt < 2)
  666.       {
  667.         WAsmCode[0] |= 0x0020;
  668.         CodeLen = 1;
  669.       }
  670.       else
  671.       {
  672.         if (!as_strcasecmp(ArgStr[2].str.p_str, "Z"))
  673.           WAsmCode[0] |= 0x0040;
  674.         else if (!as_strcasecmp(ArgStr[2].str.p_str, "N"))
  675.           WAsmCode[0] |= 0x0080;
  676.         else if (!as_strcasecmp(ArgStr[2].str.p_str, "L"))
  677.           WAsmCode[0] |= 0x0200;
  678.         else
  679.         {
  680.           WrError(ErrNum_InvAddrMode);
  681.           return;
  682.         }
  683.         if (ArgCnt < 3)
  684.           CodeLen = 1;
  685.         else if (as_strcasecmp(ArgStr[3].str.p_str, "L"))
  686.         {
  687.           WrError(ErrNum_InvAddrMode);
  688.           return;
  689.         }
  690.         else
  691.         {
  692.           WAsmCode[0] |= 0x0200;
  693.           CodeLen = 1;
  694.         }
  695.       }
  696.     }
  697.   }
  698. }
  699.  
  700. /*-------------------------------------------------------------------------*/
  701.  
  702. static void DecodeDATA_OLMS50(Word Code)
  703. {
  704.   UNUSED(Code);
  705.  
  706.   DecodeDATA(Int14, Int4);
  707. }
  708.  
  709. static void DecodeSFR(Word Code)
  710. {
  711.   UNUSED(Code);
  712.  
  713.   CodeEquate(SegData, 0, SegLimits[SegData]);
  714. }
  715.  
  716. /*-------------------------------------------------------------------------*/
  717.  
  718. static void AddAri(const char *pName, Word ACCCode, Word ImmCode, Word CPUMask)
  719. {
  720.   order_array_rsv_end(AriOrders, tAriOrder);
  721.   AriOrders[InstrZ].ACCCode = ACCCode;
  722.   AriOrders[InstrZ].ImmCode = ImmCode;
  723.   AriOrders[InstrZ].CPUMask = CPUMask;
  724.   AddInstTable(InstTable, pName, InstrZ++, DecodeAri);
  725. }
  726.  
  727. static void AddAP(const char *pName, Word Code, Word CPUMask)
  728. {
  729.   order_array_rsv_end(APOrders, tAPOrder);
  730.   APOrders[InstrZ].Code = Code;
  731.   APOrders[InstrZ].CPUMask = CPUMask;
  732.   AddInstTable(InstTable, pName, InstrZ++, DecodeAP);
  733. }
  734.  
  735. static void AddImm(const char *pName, Word Code, Word CPUMask)
  736. {
  737.   order_array_rsv_end(ImmOrders, tImmOrder);
  738.   ImmOrders[InstrZ].Code = Code;
  739.   ImmOrders[InstrZ].CPUMask = CPUMask;
  740.   AddInstTable(InstTable, pName, InstrZ++, DecodeImm);
  741. }
  742.  
  743. static void AddAPAX(const char *pName, Word APCode, Word AXCode, Word CPUMask)
  744. {
  745.   order_array_rsv_end(APAXOrders, tAPAXOrder);
  746.   APAXOrders[InstrZ].APCode = APCode;
  747.   APAXOrders[InstrZ].AXCode = AXCode;
  748.   APAXOrders[InstrZ].CPUMask = CPUMask;
  749.   AddInstTable(InstTable, pName, InstrZ++, DecodeAPAX);
  750. }
  751.  
  752. static void AddFixed(const char *pName, Word Code, Word CPUMask)
  753. {
  754.   order_array_rsv_end(FixedOrders, tFixedOrder);
  755.   FixedOrders[InstrZ].Code = Code;
  756.   FixedOrders[InstrZ].CPUMask = CPUMask;
  757.   AddInstTable(InstTable, pName, InstrZ++, DecodeFixed);
  758. }
  759.  
  760. static void AddRel(const char *pName, Word Code, Word PlusCPUMask, Word MinusCPUMask)
  761. {
  762.   order_array_rsv_end(RelOrders, tRelOrder);
  763.   RelOrders[InstrZ].Code = Code;
  764.   RelOrders[InstrZ].PlusCPUMask = PlusCPUMask;
  765.   RelOrders[InstrZ].MinusCPUMask = MinusCPUMask;
  766.   AddInstTable(InstTable, pName, InstrZ++, DecodeRel);
  767. }
  768.  
  769. static void AddCtrl(const char *pName, Word APCode, Word ImmCode, Boolean AllowAP, Word CPUMask)
  770. {
  771.   order_array_rsv_end(CtrlOrders, tCtrlOrder);
  772.   CtrlOrders[InstrZ].APCode = APCode;
  773.   CtrlOrders[InstrZ].ImmCode = ImmCode;
  774.   CtrlOrders[InstrZ].AllowAP = AllowAP;
  775.   CtrlOrders[InstrZ].CPUMask = CPUMask;
  776.   AddInstTable(InstTable, pName, InstrZ++, DecodeCtrl);
  777. }
  778.  
  779. static void AddDSP(const char *pName, Word Code, Word CPUMask)
  780. {
  781.   order_array_rsv_end(DSPOrders, tDSPOrder);
  782.   DSPOrders[InstrZ].Code = Code;
  783.   DSPOrders[InstrZ].CPUMask = CPUMask;
  784.   AddInstTable(InstTable, pName, InstrZ++, DecodeDSP);
  785. }
  786.  
  787. static void AddONOFFInstr(const char *pName, Word Code, Word Shift, Word CPUMask)
  788. {
  789.   order_array_rsv_end(ONOFFOrders, tONOFFOrder);
  790.   ONOFFOrders[InstrZ].Code = Code;
  791.   ONOFFOrders[InstrZ].CPUMask = CPUMask;
  792.   ONOFFOrders[InstrZ].Shift = Shift;
  793.   AddInstTable(InstTable, pName, InstrZ++, DecodeONOFF);
  794. }
  795.  
  796. static void AddMem(const char *pName, Word Code, Word CPUMask)
  797. {
  798.   order_array_rsv_end(MemOrders, tMemOrder);
  799.   MemOrders[InstrZ].Code = Code;
  800.   MemOrders[InstrZ].CPUMask = CPUMask;
  801.   AddInstTable(InstTable, pName, InstrZ++, DecodeMem);
  802. }
  803.  
  804. static void InitFields(void)
  805. {
  806.   int N;
  807.   char Op[20];
  808.  
  809.   InstTable = CreateInstTable(201);
  810.   SetDynamicInstTable(InstTable);
  811.  
  812.   InstrZ = 0;
  813.   AddAri("ADD", 0x0040, 0x1800, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  814.   AddAri("SUB", 0x0240, 0x1a00, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  815.   AddAri("CMP", 0x02e0, 0x1600, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  816.   AddAri("XOR", 0x0070, 0x1e00, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  817.   AddAri("BIT", 0x00e0, 0x1400, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  818.   AddAri("BIS", 0x0060, 0x1000, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  819.   AddAri("BIC", 0x0260, 0x1200, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  820.  
  821.   InstrZ = 0;
  822.   if (CheckCPU(M_6052))
  823.   {
  824.     AddRel("BEQ", 0x3a40, M_6052, M_6052);
  825.     AddRel("BZE", 0x3a40, M_6052, M_6052);
  826.     AddRel("BNE", 0x3ac0, M_6052, M_6052);
  827.     AddRel("BNZ", 0x3ac0, M_6052, M_6052);
  828.     AddRel("BCS", 0x3a00, M_6052, M_6052);
  829.     AddRel("BCC", 0x3a80, M_6052, M_6052);
  830.     AddRel("BGT", 0x3a20, M_6052, M_6052);
  831.     AddRel("BLE", 0x3aa0, M_6052, M_6052);
  832.     AddRel("BGE", 0x3a60, M_6052, M_6052);
  833.     AddRel("BLT", 0x3ae0, M_6052, M_6052);
  834.   }
  835.   else
  836.   {
  837.     AddRel("BEQ", 0x0640, M_5054 | M_5055 | M_5056 | M_6051, M_6051);
  838.     AddRel("BZE", 0x0640, M_5054 | M_5055 | M_5056 | M_6051, M_6051);
  839.     AddRel("BNE", 0x06c0, M_5054 | M_5055 | M_5056 | M_6051, M_6051);
  840.     AddRel("BNZ", 0x06c0, M_5054 | M_5055 | M_5056 | M_6051, M_6051);
  841.     AddRel("BCS", (MomCPU == CPU5056) ? 0x0620 : 0x0600, M_5054 | M_5055 | M_5056 | M_6051, M_6051);
  842.     AddRel("BLT", (MomCPU == CPU6051) ? 0x06e0 : (MomCPU == CPU5056 ? 0x0620 : 0x0600), M_5054 | M_5055 | M_5056 | M_6051, M_6051);
  843.     AddRel("BCC", (MomCPU == CPU5056) ? 0x06a0 : 0x0680, M_5054 | M_5055 | M_5056 | M_6051, M_6051);
  844.     AddRel("BGE", (MomCPU == CPU6051) ? 0x0660 : (MomCPU == CPU5056 ? 0x06a0 : 0x0680), M_5054 | M_5055 | M_5056 | M_6051, M_6051);
  845.     AddRel("BGT", (MomCPU == CPU5056) ? 0x06e0 : 0x0620, M_5056 | M_6051, M_6051);
  846.     AddRel("BLE", (MomCPU == CPU5056) ? 0x0660 : 0x06a0, M_5056 | M_6051, M_6051);
  847.   }
  848.  
  849.   InstrZ = 0;
  850.   AddCtrl("MATRIX", 0x3620, 0x0420, True,  M_5054 | M_5055 | M_6051);
  851.   AddCtrl("FORMAT", 0x3630, 0x0430, True,  M_5054 | M_5055 | M_6051);
  852.   AddCtrl("PAGE",   0x3650, 0x0450, False, M_5054 | M_5055 | M_6051);
  853.   AddCtrl("ADRS",   0x3660, 0x0460, True,  M_5055 | M_6051);
  854.  
  855.   InstrZ = 0;
  856.   AddDSP("DSP",   0x0800,  M_5054 | M_5055 | M_5056 | M_6051);
  857.   AddDSP("DSPH",  0x0a00,  M_5055 | M_6051);
  858.   AddDSP("DSPF",  0x0c00,  M_5054 | M_5055 | M_5056 | M_6051);
  859.   AddDSP("DSPFH", 0x0e00,  M_5055 | M_6051);
  860.  
  861.   InstrZ = 0;
  862.   AddONOFFInstr("LAMP",   0x0410, 0, M_5054 | M_5055 | M_6051);
  863.   AddONOFFInstr("BACKUP", 0x0410, 2, M_5054 | M_5055 | M_6051);
  864.   AddONOFFInstr("XTCP",   0x0480, 0, M_5055 | M_6051);
  865.  
  866.   InstrZ = 0;
  867.   if (CheckCPU(M_5054 | M_5055 | M_5056))
  868.   {
  869.     AddAP("INC"     , 0x1810, M_5054 | M_5055 | M_5056);
  870.     AddAP("DEC"     , 0x1a10, M_5054 | M_5055 | M_5056);
  871.   }
  872.   AddAP("ASR"     , 0x0030, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  873.   AddAP("ASL"     , 0x0230, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  874.   AddAP("ROR"     , 0x0020, M_6051 | M_6052);
  875.   AddAP("ROL"     , 0x0220, M_6051 | M_6052);
  876.   AddAP("SWITCH"  , 0x3410, M_5054 | M_5055 | M_6051);
  877.   AddAP("KSWITCH" , 0x3420, M_5054 | M_5055 | M_6051);
  878.   AddAP("INTMODE" , 0x3440, M_5054 | M_5055 | M_6051);
  879.   AddAP("RATE"    , 0x3490, M_5054 | M_5055 | M_6051);
  880.   AddAP("ADC"     , 0x0050, M_5056 | M_6051 | M_6052);
  881.   AddAP("SBC"     , 0x0250, M_5056 | M_6051 | M_6052);
  882.   AddAP("STATUS"  , 0x34a0, M_6051);
  883.   AddAP("FLAGIN"  , 0x34e0, M_6051);
  884.   AddAP("S1RATE"  , 0x34c0, M_6051);
  885.   AddAP("S2RATE"  , 0x34d0, M_6051);
  886.   for (N = 0; N < 16; N++)
  887.   {
  888.     as_snprintf(Op, sizeof(Op), "ADC%d", N);
  889.     AddAP(Op, 0x3000 | (N << 4), M_6051);
  890.     as_snprintf(Op, sizeof(Op), "SBC%d", N);
  891.     AddAP(Op, 0x3200 | (N << 4), M_6051);
  892.   }
  893.  
  894.   InstrZ = 0;
  895.   AddAPAX("CHG", 0x3800, 0x3800, M_5056 | M_6052);
  896.   if (CheckCPU(M_6051))
  897.   {
  898.     AddAPAX("INC" , 0x3800, 0x3800, M_6051);
  899.     AddAPAX("DEC" , 0x3a00, 0x3a00, M_6051);
  900.   }
  901.  
  902.   InstrZ = 0;
  903.   AddFixed("CLZ"     , 0x00a0, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  904.   AddFixed("CLC"     , 0x0090, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  905.   AddFixed("CLG"     , 0x0080, M_6051 | M_6052);
  906.   AddFixed("CLA"     , 0x00b0, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  907.   AddFixed("SEZ"     , 0x02a0, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  908.   AddFixed("SEC"     , 0x0290, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  909.   AddFixed("SEG"     , 0x0280, M_6051 | M_6052);
  910.   AddFixed("SEA"     , 0x02b0, M_5054 | M_5055 | M_5056 | M_6052);
  911.   AddFixed("BSO"     , 0x04c0, M_5054 | M_5055);
  912.   AddFixed("HALT"    , (MomCPU == CPU6052) ? 0x0e10 : 0x0400, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  913.   AddFixed("RSTRATE" , 0x0488, M_5054 | M_5055 | M_6051);
  914.   AddFixed("NOP"     , 0x0000, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
  915.   AddFixed("RET"     , 0x00c0, M_6051 | M_6052);
  916.   AddFixed("RTI"     , 0x02c0, M_6051 | M_6052);
  917.   AddFixed("MSO"     , 0x04a0, M_6051);
  918.   AddFixed("ACTIVATE", 0x0490, M_6051);
  919.   AddFixed("KENAB"   , 0x04e8, M_6051);
  920.   AddFixed("KDSAB"   , 0x04e4, M_6051);
  921.   AddFixed("STOP"    , 0x0e00, M_6052);
  922.   AddFixed("ACT"     , 0x0e20, M_6052);
  923.   AddFixed("EI"      , 0x0e68, M_6052);
  924.   AddFixed("DI"      , 0x0e64, M_6052);
  925.   AddFixed("ET"      , 0x0e62, M_6052);
  926.   AddFixed("DT"      , 0x0e61, M_6052);
  927.   AddFixed("EC"      , 0x0e78, M_6052);
  928.   AddFixed("DC"      , 0x0e74, M_6052);
  929.   AddFixed("OM"      , 0x0e72, M_6052);
  930.   AddFixed("IM"      , 0x0e71, M_6052);
  931.   AddFixed("RST"     , 0x0e90, M_6052);
  932.  
  933.   InstrZ = 0;
  934.   AddImm("FREQ",  0x04d0, M_5055);
  935.   AddImm("PITCH", 0x04c0, M_6051);
  936.  
  937.   InstrZ = 0;
  938.   AddMem("RDAR",  0x3000, M_6052);
  939.   AddMem("MVAR",  0x3400, M_6052);
  940.  
  941.   AddInstTable(InstTable, "ADJUST", 0, DecodeADJUST);
  942.   AddInstTable(InstTable, "MOV", 0, DecodeMOV);
  943.   AddInstTable(InstTable, "JMP", 0, DecodeJMP);
  944.   AddInstTable(InstTable, "CALL", 0, DecodeCALL);
  945.   AddInstTable(InstTable, "MSA", 0, DecodeMSA);
  946.   AddInstTable(InstTable, "JMPIO", 0x02d0, DecodeJMPIO);
  947.  
  948.   AddInstTable(InstTable, "RES", 0, DecodeRES);
  949.   AddInstTable(InstTable, "DATA", 0, DecodeDATA_OLMS50);
  950.   AddInstTable(InstTable, "SFR", 0, DecodeSFR);
  951.   AddInstTable(InstTable, "INTENAB", 0x0028, DecodeINTENDSAB);
  952.   AddInstTable(InstTable, "INTDSAB", 0x0014, DecodeINTENDSAB);
  953.   AddInstTable(InstTable, "INP", 0, DecodeINP);
  954.   AddInstTable(InstTable, "IN" , 0, DecodeIN);
  955.   AddInstTable(InstTable, "OUT", 0, DecodeOUT);
  956.  
  957.   AddInstTable(InstTable, "BUZZER", 0, DecodeBUZZER);
  958. }
  959.  
  960. static void DeinitFields(void)
  961. {
  962.   DestroyInstTable(InstTable);
  963.   order_array_free(AriOrders);
  964.   order_array_free(APOrders);
  965.   order_array_free(APAXOrders);
  966.   order_array_free(FixedOrders);
  967.   order_array_free(RelOrders);
  968.   order_array_free(CtrlOrders);
  969.   order_array_free(DSPOrders);
  970.   order_array_free(ONOFFOrders);
  971.   order_array_free(ImmOrders);
  972.   order_array_free(MemOrders);
  973. }
  974.  
  975. /*-------------------------------------------------------------------------*/
  976.  
  977. static void  MakeCode_OLMS50(void)
  978. {
  979.   CodeLen = 0;
  980.   DontPrint = False;
  981.  
  982.   /* zu ignorierendes */
  983.  
  984.   if (Memo(""))
  985.     return;
  986.  
  987.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  988.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  989. }
  990.  
  991.  
  992. static Boolean IsDef_OLMS50(void)
  993. {
  994.   return False;
  995. }
  996.  
  997. static void SwitchFrom_OLMS50(void)
  998. {
  999.   DeinitFields();
  1000. }
  1001.  
  1002. static void SwitchTo_OLMS50(void)
  1003. {
  1004.   static ASSUMERec ASSUMEs[] =
  1005. {
  1006.   { "P", &PRegAssume, 0, 0x3, 0x8, NULL }
  1007. };
  1008.  
  1009.   const TFamilyDescr *pDescr;
  1010.  
  1011.   pDescr = FindFamilyByName("OLMS-50");
  1012.  
  1013.   TurnWords = False;
  1014.   SetIntConstMode(eIntConstModeIntel);
  1015.   SwitchIsOccupied = True;
  1016.   PageIsOccupied = True;
  1017.  
  1018.   PCSymbol = "$";
  1019.   HeaderID = pDescr->Id;
  1020.   NOPCode = 0x00;
  1021.   DivideChars = ",";
  1022.   HasAttrs = False;
  1023.  
  1024.   ValidSegs = (1 << SegCode) | (1 << SegData);
  1025.   Grans[SegCode] = 2; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
  1026.   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegCode] = 0;
  1027.   if (MomCPU == CPU5054)
  1028.   {
  1029.     CodeIntType = UInt10;
  1030.     DataIntType = UInt6;
  1031.     SegLimits[SegData] = 61;
  1032.     SegLimits[SegCode] = 1023;
  1033.   }
  1034.   else if (MomCPU == CPU5055)
  1035.   {
  1036.     CodeIntType = UInt11;
  1037.     DataIntType = UInt7;
  1038.     SegLimits[SegData] = 95;
  1039.     SegLimits[SegCode] = 1791;
  1040.   }
  1041.   else if (MomCPU == CPU5056)
  1042.   {
  1043.     CodeIntType = UInt11;
  1044.     DataIntType = UInt7;
  1045.     SegLimits[SegData] = 89;
  1046.     SegLimits[SegCode] = 1791;
  1047.   }
  1048.   else if (MomCPU == CPU6051)
  1049.   {
  1050.     CodeIntType = UInt12;
  1051.     DataIntType = UInt7;
  1052.     SegLimits[SegData] = 119;
  1053.     SegLimits[SegCode] = 2559;
  1054.   }
  1055.   else if (MomCPU == CPU6052)
  1056.   {
  1057.     CodeIntType = UInt11;
  1058.     DataIntType = UInt10;
  1059.     SegLimits[SegData] = 639;
  1060.     SegLimits[SegCode] = 2047;
  1061.   }
  1062.  
  1063.   MakeCode = MakeCode_OLMS50;
  1064.   IsDef = IsDef_OLMS50;
  1065.   SwitchFrom = SwitchFrom_OLMS50; InitFields();
  1066.  
  1067.   pASSUMERecs = ASSUMEs;
  1068.   ASSUMERecCnt = sizeof(ASSUMEs) / sizeof(*ASSUMEs);
  1069. }
  1070.  
  1071. void codeolms50_init(void)
  1072. {
  1073.   CPU5054 = AddCPU("MSM5054" , SwitchTo_OLMS50);
  1074.   CPU5055 = AddCPU("MSM5055" , SwitchTo_OLMS50);
  1075.   CPU5056 = AddCPU("MSM5056" , SwitchTo_OLMS50);
  1076.   CPU6051 = AddCPU("MSM6051" , SwitchTo_OLMS50);
  1077.   CPU6052 = AddCPU("MSM6052" , SwitchTo_OLMS50);
  1078. }
  1079.