Subversion Repositories pentevo

Rev

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

  1. /* codesx20.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Code Generator Parallax SX20                                              */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <string.h>
  14. #include <ctype.h>
  15.  
  16. #include "bpemu.h"
  17. #include "strutil.h"
  18. #include "chunks.h"
  19. #include "headids.h"
  20. #include "asmdef.h"
  21. #include "asmsub.h"
  22. #include "asmpars.h"
  23. #include "asmitree.h"
  24. #include "codepseudo.h"
  25. #include "fourpseudo.h"
  26. #include "codevars.h"
  27. #include "errmsg.h"
  28.  
  29. #include "codef8.h"
  30.  
  31. /*---------------------------------------------------------------------------*/
  32.  
  33. static CPUVar CPUSX20, CPUSX28;
  34.  
  35. static LongInt Reg_FSR, Reg_STATUS;
  36.  
  37. /*---------------------------------------------------------------------------*/
  38.  
  39. static Boolean DecodeRegLinear(const tStrComp *pArg, int Offset, Word *pResult, tEvalResult *pEvalResult)
  40. {
  41.   *pResult = EvalStrIntExpressionOffsWithResult(pArg, Offset, UInt8, pEvalResult);
  42.   if (pEvalResult->OK)
  43.     ChkSpace(SegData, pEvalResult->AddrSpaceMask);
  44.   return pEvalResult->OK;
  45. }
  46.  
  47. static Word Lin2PagedRegAddr(const tStrComp *pArg, Word LinAddr, tSymbolFlags Flags)
  48. {
  49.   if (!mFirstPassUnknown(Flags) && (LinAddr & 0x10))
  50.   {
  51.     if ((Reg_FSR & 0xf0) != (LinAddr & 0xf0))
  52.       WrStrErrorPos(ErrNum_InAccPage, pArg);
  53.   }
  54.   return LinAddr & 0x1f;
  55. }
  56.  
  57. static Boolean DecodeReg(const tStrComp *pArg, int Offset, Word *pResult)
  58. {
  59.   tEvalResult EvalResult;
  60.  
  61.   if (!DecodeRegLinear(pArg, Offset, pResult, &EvalResult))
  62.     return False;
  63.   *pResult = Lin2PagedRegAddr(pArg, *pResult, EvalResult.Flags);
  64.   return True;
  65. }
  66.  
  67. static Boolean DecodeRegAppendix(tStrComp *pArg, const char *pAppendix, Word *pResult)
  68. {
  69.   int ArgLen = strlen(pArg->str.p_str), AppLen = strlen(pAppendix);
  70.   Boolean Result = False;
  71.  
  72.   if ((ArgLen > AppLen) && !as_strcasecmp(pArg->str.p_str + (ArgLen - AppLen), pAppendix))
  73.   {
  74.     char Save = pArg->str.p_str[ArgLen - AppLen];
  75.  
  76.     pArg->str.p_str[ArgLen - AppLen] = '\0';
  77.     pArg->Pos.Len -= AppLen;
  78.     Result = DecodeReg(pArg, 0, pResult);
  79.     pArg->str.p_str[ArgLen - AppLen] = Save;
  80.     pArg->Pos.Len += AppLen;
  81.   }
  82.   return Result;
  83. }
  84.  
  85. /* NOTE: bit symbols have bit position in lower three bits, opposed
  86.    to machine coding.  Done this way because incrementing makes more
  87.    sense this way. */
  88.  
  89. static Word AssembleBitSymbol(Word RegAddr, Word BitPos)
  90. {
  91.   return ((RegAddr & 0xff) << 3) | (BitPos & 7);
  92. }
  93.  
  94. static void SplitBitSymbol(Word BitSymbol, Word *pRegAddr, Word *pBitPos)
  95. {
  96.   *pRegAddr = (BitSymbol >> 3) & 0xff;
  97.   *pBitPos = BitSymbol & 7;
  98. }
  99.  
  100. /*!------------------------------------------------------------------------
  101.  * \fn     DissectBit_SX20(char *pDest, size_t DestSize, LargeWord Inp)
  102.  * \brief  dissect compact storage of bit into readable form for listing
  103.  * \param  pDest destination for ASCII representation
  104.  * \param  DestSize destination buffer size
  105.  * \param  Inp compact storage
  106.  * ------------------------------------------------------------------------ */
  107.  
  108. static void DissectBit_SX20(char *pDest, size_t DestSize, LargeWord Inp)
  109. {
  110.   Word BitPos, Address;
  111.  
  112.   SplitBitSymbol(Inp, &Address, &BitPos);
  113.  
  114.   as_snprintf(pDest, DestSize, "$%x.%u", (unsigned)Address, (unsigned)BitPos);
  115. }
  116.  
  117. /*!------------------------------------------------------------------------
  118.  * \fn     DecodeBitSymbol(const tStrComp *pArg, Word *pBitSymbol)
  119.  * \brief  decode a bit expression and return in internal format
  120.  * \param  pArg bit spec in source code
  121.  * \param  pBitSymbol returns bit in internal format
  122.  * \return True if success
  123.  * ------------------------------------------------------------------------ */
  124.  
  125. static Boolean DecodeBitSymbol(const tStrComp *pArg, Word *pBitSymbol, tEvalResult *pEvalResult)
  126. {
  127.   char *pSplit;
  128.  
  129.   pSplit = strchr(pArg->str.p_str, '.');
  130.   if (!pSplit)
  131.   {
  132.     *pBitSymbol = EvalStrIntExpressionWithResult(pArg, UInt11, pEvalResult);
  133.     if (pEvalResult->OK)
  134.       ChkSpace(SegBData, pEvalResult->AddrSpaceMask);
  135.     return pEvalResult->OK;
  136.   }
  137.   else
  138.   {
  139.     tStrComp RegArg, BitArg;
  140.     Boolean BitOK, RegOK;
  141.     Word BitPos, RegAddr;
  142.  
  143.     StrCompSplitRef(&RegArg, &BitArg, pArg, pSplit);
  144.     BitPos = EvalStrIntExpression(&BitArg, UInt3, &BitOK);
  145.     RegOK = DecodeRegLinear(&RegArg, 0, &RegAddr, pEvalResult);
  146.     *pBitSymbol = AssembleBitSymbol(RegAddr, BitPos);
  147.     return BitOK && RegOK;
  148.   }
  149. }
  150.  
  151. static Boolean DecodeRegBitPacked(const tStrComp *pArg, Word *pPackedResult)
  152. {
  153.   Word BitSymbol, RegAddr, BitPos;
  154.   tEvalResult EvalResult;
  155.  
  156.   if (!DecodeBitSymbol(pArg, &BitSymbol, &EvalResult))
  157.     return False;
  158.   SplitBitSymbol(BitSymbol, &RegAddr, &BitPos);
  159.   *pPackedResult = (BitPos << 5) | Lin2PagedRegAddr(pArg, RegAddr, EvalResult.Flags);
  160.   return True;
  161. }
  162.  
  163. /*---------------------------------------------------------------------------*/
  164.  
  165. static void DecodeFixed(Word Code)
  166. {
  167.   if (ChkArgCnt(0, 0))
  168.     WAsmCode[CodeLen++] = Code;
  169. }
  170.  
  171. static void DecodeOneReg(Word Code)
  172. {
  173.   Word Reg;
  174.  
  175.   if (ChkArgCnt(1, 1)
  176.    && DecodeReg(&ArgStr[1], 0, &Reg))
  177.     WAsmCode[CodeLen++] = Code | Reg;
  178. }
  179.  
  180. static void DecodeNOT(Word Code)
  181. {
  182.   if (!ChkArgCnt(1, 1))
  183.     return;
  184.  
  185.   if (!as_strcasecmp(ArgStr[1].str.p_str, "W"))
  186.     WAsmCode[CodeLen++] = 0xfff;
  187.   else
  188.     DecodeOneReg(Code);
  189. }
  190.  
  191. static void DecodeMOV(Word Code)
  192. {
  193.   Word Reg;
  194.   Boolean OK;
  195.  
  196.   UNUSED(Code);
  197.  
  198.   if (!ChkArgCnt(2, 2))
  199.     return;
  200.  
  201.   if (!as_strcasecmp(ArgStr[1].str.p_str, "W"))
  202.   {
  203.     if (*ArgStr[2].str.p_str == '#')
  204.     {
  205.       Reg = EvalStrIntExpressionOffs(&ArgStr[2], 1, Int8, &OK);
  206.       if (OK)
  207.         WAsmCode[CodeLen++] = 0xc00 | (Reg & 0xff);
  208.     }
  209.     else if (!as_strcasecmp(ArgStr[2].str.p_str, "M"))
  210.       WAsmCode[CodeLen++] = 0x042;
  211.     else if (!strncmp(ArgStr[2].str.p_str, "/", 1) && DecodeReg(&ArgStr[2], 1, &Reg))
  212.       WAsmCode[CodeLen++] = 0x240 | Reg;
  213.     else if (!strncmp(ArgStr[2].str.p_str, "--", 2) && DecodeReg(&ArgStr[2], 2, &Reg))
  214.       WAsmCode[CodeLen++] = 0x0c0 | Reg;
  215.     else if (!strncmp(ArgStr[2].str.p_str, "++", 2) && DecodeReg(&ArgStr[2], 2, &Reg))
  216.       WAsmCode[CodeLen++] = 0x280 | Reg;
  217.     else if (!strncmp(ArgStr[2].str.p_str, "<<", 2) && DecodeReg(&ArgStr[2], 2, &Reg))
  218.       WAsmCode[CodeLen++] = 0x340 | Reg;
  219.     else if (!strncmp(ArgStr[2].str.p_str, ">>", 2) && DecodeReg(&ArgStr[2], 2, &Reg))
  220.       WAsmCode[CodeLen++] = 0x300 | Reg;
  221.     else if (!strncmp(ArgStr[2].str.p_str, "<>", 2) && DecodeReg(&ArgStr[2], 2, &Reg))
  222.       WAsmCode[CodeLen++] = 0x380 | Reg;
  223.     else if (DecodeRegAppendix(&ArgStr[2], "-W", &Reg))
  224.       WAsmCode[CodeLen++] = 0x080 | Reg;
  225.     else if (DecodeReg(&ArgStr[2], 0, &Reg))
  226.       WAsmCode[CodeLen++] = 0x200 | Reg;
  227.   }
  228.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "W"))
  229.   {
  230.     if (!as_strcasecmp(ArgStr[1].str.p_str, "!OPTION"))
  231.       WAsmCode[CodeLen++] = 0x002;
  232.     else if (!as_strcasecmp(ArgStr[1].str.p_str, "M"))
  233.       WAsmCode[CodeLen++] = 0x003;
  234.     else if (!strncmp(ArgStr[1].str.p_str, "!", 1) && DecodeReg(&ArgStr[1], 1, &Reg))
  235.     {
  236.       if (ChkRange(Reg, 0, 7))
  237.         WAsmCode[CodeLen++] = 0x000 | Reg;
  238.     }
  239.     else if (DecodeReg(&ArgStr[1], 0, &Reg))
  240.       WAsmCode[CodeLen++] = 0x020 | Reg;
  241.   }
  242.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "M"))
  243.   {
  244.     if (*ArgStr[2].str.p_str == '#')
  245.     {
  246.       Reg = EvalStrIntExpressionOffs(&ArgStr[2], 1, Int4, &OK);
  247.       if (OK)
  248.         WAsmCode[CodeLen++] = 0x050 | (Reg & 0xf);
  249.     }
  250.     else
  251.       WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  252.   }
  253.   else
  254.     WrError(ErrNum_InvAddrMode);
  255. }
  256.  
  257. static void DecodeMOVSZ(Word Code)
  258. {
  259.   Word Reg;
  260.  
  261.   UNUSED(Code);
  262.  
  263.   if (!ChkArgCnt(2, 2))
  264.     return;
  265.  
  266.   if (!as_strcasecmp(ArgStr[1].str.p_str, "W"))
  267.   {
  268.     if (!strncmp(ArgStr[2].str.p_str, "--", 2) && DecodeReg(&ArgStr[2], 2, &Reg))
  269.       WAsmCode[CodeLen++] = 0x2c0 | Reg;
  270.     else if (!strncmp(ArgStr[2].str.p_str, "++", 2) && DecodeReg(&ArgStr[2], 2, &Reg))
  271.       WAsmCode[CodeLen++] = 0x3c0 | Reg;
  272.     else
  273.       WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  274.   }
  275.   else
  276.     WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  277. }
  278.  
  279. static void DecodeLogic(Word Code)
  280. {
  281.   Word Arg;
  282.  
  283.   if (!ChkArgCnt(2, 2))
  284.     return;
  285.  
  286.   if (!as_strcasecmp(ArgStr[1].str.p_str, "W"))
  287.   {
  288.     if (*ArgStr[2].str.p_str == '#')
  289.     {
  290.       Word ImmCode = Code & 0x0f00;
  291.  
  292.       if (ImmCode)
  293.       {
  294.         Boolean OK;
  295.  
  296.         Arg = EvalStrIntExpressionOffs(&ArgStr[2], 1, Int8, &OK);
  297.         if (OK)
  298.           WAsmCode[CodeLen++] = ImmCode | (Arg & 0xff);
  299.       }
  300.       else
  301.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  302.     }
  303.     else if (DecodeReg(&ArgStr[2], 0, &Arg))
  304.       WAsmCode[CodeLen++] = (Lo(Code) << 4) | Arg;
  305.   }
  306.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "W"))
  307.   {
  308.     if (DecodeReg(&ArgStr[1], 0, &Arg))
  309.       WAsmCode[CodeLen++] = (Lo(Code) << 4) | 0x20 | Arg;
  310.   }
  311.   else
  312.     WrError(ErrNum_InvAddrMode);
  313. }
  314.  
  315. static void DecodeCLR(Word Code)
  316. {
  317.   Word Arg;
  318.  
  319.   UNUSED(Code);
  320.  
  321.   if (!ChkArgCnt(1, 1))
  322.     return;
  323.  
  324.   if (!as_strcasecmp(ArgStr[1].str.p_str, "W"))
  325.     WAsmCode[CodeLen++] = 0x040;
  326.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "!WDT"))
  327.     WAsmCode[CodeLen++] = 0x004;
  328.   else if (DecodeReg(&ArgStr[1], 0, &Arg))
  329.     WAsmCode[CodeLen++] = 0x060 | Arg;
  330. }
  331.  
  332. static void DecodeSUB(Word Code)
  333. {
  334.   Word Arg;
  335.  
  336.   if (!ChkArgCnt(2, 2))
  337.     return;
  338.  
  339.   if (!as_strcasecmp(ArgStr[2].str.p_str, "W"))
  340.   {
  341.     if (DecodeReg(&ArgStr[1], 0, &Arg))
  342.       WAsmCode[CodeLen++] = (Lo(Code) << 4) | 0x20 | Arg;
  343.   }
  344.   else
  345.     WrError(ErrNum_InvAddrMode);
  346. }
  347.  
  348. static void DecodeBit(Word Code)
  349. {
  350.   Word BitArg;
  351.  
  352.   if (!ChkArgCnt(1, 1))
  353.     return;
  354.  
  355.   if (DecodeRegBitPacked(&ArgStr[1], &BitArg))
  356.     WAsmCode[CodeLen++] = Code | BitArg;
  357. }
  358.  
  359. static void DecodeJMP_CALL(Word Code)
  360. {
  361.   Word Addr;
  362.   Boolean IsCall = (Code == 0x900);
  363.   tEvalResult EvalResult;
  364.  
  365.   if (!ChkArgCnt(1, 1))
  366.     return;
  367.  
  368.   if (!IsCall)
  369.   {
  370.     if (!as_strcasecmp(ArgStr[1].str.p_str, "W"))
  371.     {
  372.       WAsmCode[CodeLen++] = 0x022;
  373.       return;
  374.     }
  375.     else if (!as_strcasecmp(ArgStr[1].str.p_str, "PC+W"))
  376.     {
  377.       WAsmCode[CodeLen++] = 0x1e2;
  378.       return;
  379.     }
  380.   }
  381.  
  382.   Addr = EvalStrIntExpressionWithResult(&ArgStr[1], UInt11, &EvalResult);
  383.   if (!EvalResult.OK)
  384.     return;
  385.  
  386.   if (!mFirstPassUnknown(EvalResult.Flags) && IsCall && (Addr & 0x100)) WrStrErrorPos(ErrNum_NotFromThisAddress, &ArgStr[1]);
  387.   else
  388.   {
  389.     if (!mFirstPassUnknown(EvalResult.Flags) && ((Reg_STATUS & 0xe0) != ((Addr >> 4) & 0xe0))) WrStrErrorPos(ErrNum_InAccPage, &ArgStr[1]);
  390.     WAsmCode[CodeLen++] = Code | (Addr & 0x1ff);
  391.     ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  392.   }
  393. }
  394.  
  395. static void DecodeRETW(Word Code)
  396. {
  397.   Boolean OK;
  398.   Word Arg;
  399.  
  400.   if (!ChkArgCnt(1, 1))
  401.     return;
  402.  
  403.   Arg = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
  404.   if (OK)
  405.     WAsmCode[CodeLen++] = Code | Arg;
  406. }
  407.  
  408. static void DecodeBANK(Word Code)
  409. {
  410.   Word Arg;
  411.   tEvalResult EvalResult;
  412.  
  413.   if (!ChkArgCnt(1, 1))
  414.     return;
  415.  
  416.   Arg = EvalStrIntExpressionWithResult(&ArgStr[1], UInt8, &EvalResult);
  417.   if (EvalResult.OK)
  418.   {
  419.     WAsmCode[CodeLen++] = Code | ((Arg >> 5) & 7);
  420.     ChkSpace(SegData, EvalResult.AddrSpaceMask);
  421.   }
  422. }
  423.  
  424. static void DecodePAGE(Word Code)
  425. {
  426.   tEvalResult EvalResult;
  427.   Word Arg;
  428.  
  429.   if (!ChkArgCnt(1, 1))
  430.     return;
  431.  
  432.   Arg = EvalStrIntExpressionWithResult(&ArgStr[1], UInt12, &EvalResult);
  433.   if (EvalResult.OK)
  434.   {
  435.     WAsmCode[CodeLen++] = Code | ((Arg >> 9) & 7);
  436.     ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  437.   }
  438. }
  439.  
  440. static void DecodeMODE(Word Code)
  441. {
  442.   tEvalResult EvalResult;
  443.   Word Arg;
  444.  
  445.   if (!ChkArgCnt(1, 1))
  446.     return;
  447.  
  448.   Arg = EvalStrIntExpressionWithResult(&ArgStr[1], Int4, &EvalResult);
  449.   if (EvalResult.OK)
  450.   {
  451.     WAsmCode[CodeLen++] = Code | Arg;
  452.     ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  453.   }
  454. }
  455.  
  456. static void DecodeSKIP(Word Code)
  457. {
  458.   UNUSED(Code);
  459.  
  460.   if (!ChkArgCnt(0, 0))
  461.     return;
  462.  
  463.   WAsmCode[CodeLen++] = EProgCounter() & 1 ? 0x702 : 0x602;
  464. }
  465.  
  466. static void DecodeSFR(Word Code)
  467. {
  468.   UNUSED(Code);
  469.   CodeEquate(SegData, 0, 0xff);
  470. }
  471.  
  472. static void DecodeBIT(Word Code)
  473. {
  474.   Word BitSymbol;
  475.   tEvalResult EvalResult;
  476.  
  477.   UNUSED(Code);
  478.   if (ChkArgCnt(1, 1)
  479.    && DecodeBitSymbol(&ArgStr[1], &BitSymbol, &EvalResult))
  480.   {
  481.     *ListLine = '=';
  482.     DissectBit_SX20(ListLine + 1, STRINGSIZE - 3, BitSymbol);
  483.     PushLocHandle(-1);
  484.     EnterIntSymbol(&LabPart, BitSymbol, SegBData, False);
  485.     PopLocHandle();
  486.     /* TODO: MakeUseList? */
  487.   }
  488. }
  489.  
  490. static void DecodeDATA_SX20(Word Code)
  491. {
  492.   UNUSED(Code);
  493.  
  494.   DecodeDATA(Int12, Int8);
  495. }
  496.  
  497. static void DecodeZERO(Word Code)
  498. {
  499.   Word Size;
  500.   Boolean ValOK;
  501.   tSymbolFlags Flags;
  502.  
  503.   UNUSED(Code);
  504.  
  505.   if (ChkArgCnt(1, 1))
  506.   {
  507.     Size = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &ValOK, &Flags);
  508.     if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
  509.     if (ValOK && !mFirstPassUnknown(Flags))
  510.     {
  511.       if (SetMaxCodeLen(Size << 1)) WrError(ErrNum_CodeOverflow);
  512.       else
  513.       {
  514.         CodeLen = Size;
  515.         memset(WAsmCode, 0, 2 * Size);
  516.       }
  517.     }
  518.   }
  519. }
  520.  
  521. /*---------------------------------------------------------------------------*/
  522.  
  523. static void InitFields(void)
  524. {
  525.   InstTable = CreateInstTable(103);
  526.  
  527.   AddInstTable(InstTable, "NOP"  , NOPCode, DecodeFixed);
  528.   AddInstTable(InstTable, "RET"  , 0x00c, DecodeFixed);
  529.   AddInstTable(InstTable, "RETP" , 0x00d, DecodeFixed);
  530.   AddInstTable(InstTable, "RETI" , 0x00e, DecodeFixed);
  531.   AddInstTable(InstTable, "RETIW", 0x00f, DecodeFixed);
  532.   AddInstTable(InstTable, "IREAD", 0x041, DecodeFixed);
  533.   AddInstTable(InstTable, "SLEEP", 0x003, DecodeFixed);
  534.   AddInstTable(InstTable, "CLC"  , 0x403, DecodeFixed);
  535.   AddInstTable(InstTable, "CLZ"  , 0x443, DecodeFixed);
  536.   AddInstTable(InstTable, "SEC"  , 0x503, DecodeFixed);
  537.   AddInstTable(InstTable, "SEZ"  , 0x543, DecodeFixed);
  538.   AddInstTable(InstTable, "SC"   , 0x703, DecodeFixed);
  539.   AddInstTable(InstTable, "SZ"   , 0x743, DecodeFixed);
  540.  
  541.   AddInstTable(InstTable, "DEC"  , 0x0e0, DecodeOneReg);
  542.   AddInstTable(InstTable, "INC"  , 0x2a0, DecodeOneReg);
  543.   AddInstTable(InstTable, "DECSZ", 0x2e0, DecodeOneReg);
  544.   AddInstTable(InstTable, "INCSZ", 0x3e0, DecodeOneReg);
  545.   AddInstTable(InstTable, "RL"   , 0x360, DecodeOneReg);
  546.   AddInstTable(InstTable, "RR"   , 0x320, DecodeOneReg);
  547.   AddInstTable(InstTable, "SWAP" , 0x3a0, DecodeOneReg);
  548.   AddInstTable(InstTable, "TEST" , 0x220, DecodeOneReg);
  549.   AddInstTable(InstTable, "NOT"  , 0x260, DecodeNOT);
  550.  
  551.   AddInstTable(InstTable, "MOV"  , 0, DecodeMOV);
  552.   AddInstTable(InstTable, "MOVSZ", 0, DecodeMOVSZ);
  553.  
  554.   AddInstTable(InstTable, "AND"  , 0x0e14, DecodeLogic);
  555.   AddInstTable(InstTable, "OR"   , 0x0d10, DecodeLogic);
  556.   AddInstTable(InstTable, "XOR"  , 0x0f18, DecodeLogic);
  557.   AddInstTable(InstTable, "ADD"  , 0x001c, DecodeLogic);
  558.   AddInstTable(InstTable, "SUB"  , 0x000a, DecodeSUB);
  559.   AddInstTable(InstTable, "CLR"  , 0, DecodeCLR);
  560.  
  561.   AddInstTable(InstTable, "CLRB" , 0x0400, DecodeBit);
  562.   AddInstTable(InstTable, "SB"   , 0x0700, DecodeBit);
  563.   AddInstTable(InstTable, "SETB" , 0x0500, DecodeBit);
  564.   AddInstTable(InstTable, "SNB"  , 0x0600, DecodeBit);
  565.  
  566.   AddInstTable(InstTable, "CALL" , 0x0900, DecodeJMP_CALL);
  567.   AddInstTable(InstTable, "JMP"  , 0x0a00, DecodeJMP_CALL);
  568.   AddInstTable(InstTable, "SKIP" , 0     , DecodeSKIP);
  569.  
  570.   AddInstTable(InstTable, "RETW" , 0x0800, DecodeRETW);
  571.   AddInstTable(InstTable, "BANK" , 0x0800, DecodeBANK);
  572.   AddInstTable(InstTable, "PAGE" , 0x0010, DecodePAGE);
  573.   AddInstTable(InstTable, "MODE" , 0x0050, DecodeMODE);
  574.  
  575.   AddInstTable(InstTable, "SFR"  , 0, DecodeSFR);
  576.   AddInstTable(InstTable, "BIT"  , 0, DecodeBIT);
  577.   AddInstTable(InstTable, "DATA" , 0, DecodeDATA_SX20);
  578.   AddInstTable(InstTable, "ZERO" , 0, DecodeZERO);
  579.   AddInstTable(InstTable, "RES"  , 0, DecodeRES);
  580. }
  581.  
  582. static void DeinitFields(void)
  583. {
  584.   DestroyInstTable(InstTable);
  585. }
  586.  
  587. /*---------------------------------------------------------------------------*/
  588.  
  589. static void MakeCode_SX20(void)
  590. {
  591.   CodeLen = 0; DontPrint = False;
  592.  
  593.   /* zu ignorierendes */
  594.  
  595.   if (Memo("")) return;
  596.  
  597.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  598.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  599. }
  600.  
  601. static void SwitchFrom_SX20(void)
  602. {
  603.   DeinitFields();
  604. }
  605.  
  606. static Boolean IsDef_SX20(void)
  607. {
  608.   return Memo("SFR") || Memo("BIT");
  609. }
  610.  
  611. static void SwitchTo_SX20(void)
  612. {
  613.   const TFamilyDescr *pDescr = FindFamilyByName("SX20");
  614. #define ASSUMESX20Count (sizeof(ASSUMESX20s) / sizeof(*ASSUMESX20s))
  615.   static const ASSUMERec ASSUMESX20s[] =
  616.   {
  617.     { "FSR"   , &Reg_FSR   , 0,  0xff, 0, NULL },
  618.     { "STATUS", &Reg_STATUS, 0,  0xff, 0, NULL },
  619.   };
  620.  
  621.   TurnWords = False;
  622.   SetIntConstMode(eIntConstModeMoto);
  623.  
  624.   PCSymbol = "*";
  625.   HeaderID = pDescr->Id;
  626.   NOPCode = 0x000;
  627.   DivideChars = ",";
  628.   HasAttrs = False;
  629.   PageIsOccupied = True;
  630.  
  631.   ValidSegs = (1 << SegCode) + (1 << SegData);
  632.   Grans[SegCode] = 2; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
  633.   SegLimits[SegCode] = 2047;
  634.   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegCode] = 0;
  635.   SegLimits[SegData] = 0xff;
  636.  
  637.   MakeCode = MakeCode_SX20;
  638.   IsDef = IsDef_SX20;
  639.   SwitchFrom = SwitchFrom_SX20;
  640.   DissectBit = DissectBit_SX20;
  641.   InitFields();
  642.  
  643.   pASSUMERecs = ASSUMESX20s;
  644.   ASSUMERecCnt = ASSUMESX20Count;
  645. }
  646.  
  647. void codesx20_init(void)
  648. {
  649.   CPUSX20 = AddCPU("SX20", SwitchTo_SX20);
  650.   CPUSX28 = AddCPU("SX28", SwitchTo_SX20);
  651. }
  652.