Subversion Repositories pentevo

Rev

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

  1. /* code68.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator fuer 68xx Prozessoren                                       */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "bpemu.h"
  16. #include "strutil.h"
  17. #include "asmdef.h"
  18. #include "asmpars.h"
  19. #include "asmallg.h"
  20. #include "asmsub.h"
  21. #include "errmsg.h"
  22. #include "codepseudo.h"
  23. #include "motpseudo.h"
  24. #include "asmitree.h"
  25. #include "codevars.h"
  26. #include "cpu2phys.h"
  27. #include "function.h"
  28. #include "nlmessages.h"
  29. #include "as.rsc"
  30.  
  31. #include "code68.h"
  32.  
  33. /*---------------------------------------------------------------------------*/
  34.  
  35. typedef struct
  36. {
  37.   CPUVar MinCPU, MaxCPU;
  38.   Word Code;
  39. } FixedOrder;
  40.  
  41. typedef struct
  42. {
  43.   CPUVar MinCPU;
  44.   Word Code;
  45. } RelOrder;
  46.  
  47. typedef struct
  48. {
  49.   Boolean MayImm;
  50.   CPUVar MinCPU;    /* Shift  andere   ,Y   */
  51.   Byte PageShift;   /* 0 :     nix    Pg 2  */
  52.   Byte Code;        /* 1 :     Pg 3   Pg 4  */
  53. } ALU16Order;       /* 2 :     nix    Pg 4  */
  54.                     /* 3 :     Pg 2   Pg 3  */
  55.  
  56. enum
  57. {
  58.   ModNone = -1,
  59.   ModAcc  = 0,
  60.   ModDir  = 1,
  61.   ModExt  = 2,
  62.   ModInd  = 3,
  63.   ModImm  = 4
  64. };
  65.  
  66. #define MModAcc (1 << ModAcc)
  67. #define MModDir (1 << ModDir)
  68. #define MModExt (1 << ModExt)
  69. #define MModInd (1 << ModInd)
  70. #define MModImm (1 << ModImm)
  71.  
  72. #define Page2Prefix 0x18
  73. #define Page3Prefix 0x1a
  74. #define Page4Prefix 0xcd
  75.  
  76.  
  77. static tSymbolSize OpSize;
  78. static Byte PrefCnt;           /* Anzahl Befehlspraefixe */
  79. static ShortInt AdrMode;       /* Ergebnisadressmodus */
  80. static Byte AdrPart;           /* Adressierungsmodusbits im Opcode */
  81. static Byte AdrVals[4];        /* Adressargument */
  82.  
  83. static FixedOrder *FixedOrders;
  84. static RelOrder   *RelOrders;
  85. static ALU16Order *ALU16Orders;
  86.  
  87. static LongInt Reg_MMSIZ, Reg_MMWBR, Reg_MM1CR, Reg_MM2CR, Reg_INIT, Reg_INIT2, Reg_CONFIG;
  88.  
  89. static CPUVar CPU6800, CPU6801, CPU6301, CPU6811, CPU68HC11K4;
  90.  
  91. /*---------------------------------------------------------------------------*/
  92.  
  93. /*!------------------------------------------------------------------------
  94.  * \fn     compute_window(Byte w_size_code, Byte cpu_start_code, LongInt phys_start_code, LongWord phys_offset)
  95.  * \brief  compute single window from MMU registers
  96.  * \param  w_size_code MMSIZ bits (0..3)
  97.  * \param  cpu_start_code Reg_MMWBR bits (0,2,4,6...14)
  98.  * \param  phys_start_code Reg_MMxCR bits
  99.  * \param  phys_offset offset in physical space
  100.  * ------------------------------------------------------------------------ */
  101.  
  102. static void compute_window(Byte w_size_code, Byte cpu_start_code, LongInt phys_start_code, LongWord phys_offset)
  103. {
  104.   if (w_size_code)
  105.   {
  106.     Word size, cpu_start;
  107.     LongWord phys_start;
  108.  
  109.     /* window size */
  110.  
  111.     size = 0x1000 << w_size_code;
  112.  
  113.     /* CPU space start address: assume 8K window, systematically clip out bits for
  114.        larger windows */
  115.  
  116.     cpu_start = (Word)cpu_start_code << 12;
  117.     if (w_size_code > 1)
  118.       cpu_start &= ~0x2000;
  119.     if (w_size_code > 2)
  120.       cpu_start = (cpu_start == 0xc000) ? 0x8000 : cpu_start;
  121.  
  122.     /* physical space start: mask out lower bits according to window size */
  123.  
  124.     phys_start = ((phys_start_code & 0x7f & (~((1 << w_size_code) - 1))) << 12) + phys_offset;
  125.  
  126.     /* set addresses */
  127.  
  128.     cpu_2_phys_area_add(SegCode, cpu_start, phys_start, size);
  129.   }
  130. }
  131.  
  132. static void SetK4Ranges(void)
  133. {
  134.   Word ee_bank, io_bank, ram_bank;
  135.  
  136.   cpu_2_phys_area_clear(SegCode);
  137.  
  138.   /* Add window 1 after window 2, since it has higher priority and may partially overlap window 2 */
  139.  
  140.   compute_window((Reg_MMSIZ >> 4) & 0x3, (Reg_MMWBR >> 4) & 0x0e, Reg_MM2CR, 0x90000);
  141.   compute_window(Reg_MMSIZ & 0x3, Reg_MMWBR & 0x0e, Reg_MM1CR, 0x10000);
  142.  
  143.   /* Internal registers, RAM and EEPROM (if enabled) have priority in CPU address space: */
  144.  
  145.   if (Reg_CONFIG & 1)
  146.   {
  147.     ee_bank = ((Reg_INIT & 15) << 12) + 0x0d80;
  148.     cpu_2_phys_area_add(SegCode, ee_bank, ee_bank, 640);
  149.   }
  150.  
  151.   io_bank = (Reg_INIT & 15) << 12;
  152.   cpu_2_phys_area_add(SegCode, io_bank, io_bank, 128);
  153.  
  154.   /* If RAM position overlaps registers, 128 bytes of RAM get relocated to upper end: */
  155.  
  156.   ram_bank = ((Reg_INIT >> 4) & 15) << 12;
  157.   if (ram_bank == io_bank)
  158.     ram_bank += 128;
  159.   cpu_2_phys_area_add(SegCode, ram_bank, ram_bank, 768);
  160.  
  161.   /* Fill the remainder of CPU address space with 1:1 mappings: */
  162.  
  163.   cpu_2_phys_area_fill(SegCode, 0x0000, 0xffff);
  164. }
  165.  
  166. /*---------------------------------------------------------------------------*/
  167.  
  168. static Boolean DecodeAcc(const char *pArg, Byte *pReg)
  169. {
  170.   static const char Regs[] = "AB";
  171.  
  172.   if (strlen(pArg) == 1)
  173.   {
  174.     const char *pPos = strchr(Regs, as_toupper(*pArg));
  175.  
  176.     if (pPos)
  177.     {
  178.       *pReg = pPos - Regs;
  179.       return True;
  180.     }
  181.   }
  182.   return False;
  183. }
  184.  
  185. static void DecodeAdr(int StartInd, int StopInd, Byte Erl)
  186. {
  187.   tStrComp *pStartArg = &ArgStr[StartInd];
  188.   Boolean OK, ErrOcc;
  189.   tSymbolFlags Flags;
  190.   Word AdrWord;
  191.   Byte Bit8;
  192.  
  193.   AdrMode = ModNone;
  194.   AdrPart = 0;
  195.   ErrOcc = False;
  196.  
  197.   /* eine Komponente ? */
  198.  
  199.   if (StartInd == StopInd)
  200.   {
  201.     /* Akkumulatoren ? */
  202.  
  203.     if (DecodeAcc(pStartArg->str.p_str, &AdrPart))
  204.     {
  205.       if (MModAcc & Erl)
  206.         AdrMode = ModAcc;
  207.     }
  208.  
  209.     /* immediate ? */
  210.  
  211.     else if ((strlen(pStartArg->str.p_str) > 1) && (*pStartArg->str.p_str == '#'))
  212.     {
  213.       if (MModImm & Erl)
  214.       {
  215.         if (OpSize == eSymbolSize16Bit)
  216.         {
  217.           AdrWord = EvalStrIntExpressionOffs(pStartArg, 1, Int16, &OK);
  218.           if (OK)
  219.           {
  220.             AdrMode = ModImm;
  221.             AdrVals[AdrCnt++] = Hi(AdrWord);
  222.             AdrVals[AdrCnt++] = Lo(AdrWord);
  223.           }
  224.           else
  225.             ErrOcc = True;
  226.         }
  227.         else
  228.         {
  229.           AdrVals[AdrCnt] = EvalStrIntExpressionOffs(pStartArg, 1, Int8, &OK);
  230.           if (OK)
  231.           {
  232.             AdrMode = ModImm;
  233.             AdrCnt++;
  234.           }
  235.           else
  236.             ErrOcc = True;
  237.         }
  238.       }
  239.     }
  240.  
  241.     /* absolut ? */
  242.  
  243.     else
  244.     {
  245.       unsigned Offset = 0;
  246.  
  247.       Bit8 = 0;
  248.       if (pStartArg->str.p_str[Offset] == '<')
  249.       {
  250.         Bit8 = 2;
  251.         Offset++;
  252.       }
  253.       else if (pStartArg->str.p_str[Offset] == '>')
  254.       {
  255.         Bit8 = 1;
  256.         Offset++;
  257.       }
  258.       if (MomCPU == CPU68HC11K4)
  259.       {
  260.         LargeWord AdrLWord = EvalStrIntExpressionOffsWithFlags(pStartArg, Offset, UInt21, &OK, &Flags);
  261.         if (OK)
  262.         {
  263.           if (!def_phys_2_cpu(SegCode, &AdrLWord))
  264.           {
  265.             WrError(ErrNum_InAccPage);
  266.             AdrWord = AdrLWord & 0xffffu;
  267.           }
  268.           else
  269.             AdrWord = AdrLWord;
  270.         }
  271.       }
  272.       else
  273.         AdrWord = EvalStrIntExpressionOffsWithFlags(pStartArg, Offset, UInt16, &OK, &Flags);
  274.       if (OK)
  275.       {
  276.         if ((MModDir & Erl) && (Bit8 != 1) && ((Bit8 == 2) || (!(MModExt & Erl)) || (Hi(AdrWord) == 0)))
  277.         {
  278.           if ((Hi(AdrWord) != 0) && !mFirstPassUnknown(Flags))
  279.           {
  280.             WrError(ErrNum_NoShortAddr);
  281.             ErrOcc = True;
  282.           }
  283.           else
  284.           {
  285.             AdrMode = ModDir;
  286.             AdrPart = 1;
  287.             AdrVals[AdrCnt++] = Lo(AdrWord);
  288.           }
  289.         }
  290.         else if ((MModExt & Erl)!=0)
  291.         {
  292.           AdrMode = ModExt;
  293.           AdrPart = 3;
  294.           AdrVals[AdrCnt++] = Hi(AdrWord);
  295.           AdrVals[AdrCnt++] = Lo(AdrWord);
  296.         }
  297.       }
  298.       else
  299.         ErrOcc = True;
  300.     }
  301.   }
  302.  
  303.   /* zwei Komponenten ? */
  304.  
  305.   else if (StartInd + 1 == StopInd)
  306.   {
  307.     Boolean IsX = !as_strcasecmp(ArgStr[StopInd].str.p_str, "X"),
  308.             IsY = !as_strcasecmp(ArgStr[StopInd].str.p_str, "Y");
  309.  
  310.     /* indiziert ? */
  311.  
  312.     if (IsX || IsY)
  313.     {
  314.       if (MModInd & Erl)
  315.       {
  316.         AdrWord = EvalStrIntExpression(pStartArg, UInt8, &OK);
  317.         if (OK)
  318.         {
  319.           if (IsY && !ChkMinCPUExt(CPU6811, ErrNum_AddrModeNotSupported))
  320.             ErrOcc = True;
  321.           else
  322.           {
  323.             AdrVals[AdrCnt++] = Lo(AdrWord);
  324.             AdrMode = ModInd;
  325.             AdrPart = 2;
  326.             if (IsY)
  327.             {
  328.               BAsmCode[PrefCnt++] = 0x18;
  329.             }
  330.           }
  331.         }
  332.         else
  333.           ErrOcc = True;
  334.       }
  335.     }
  336.     else
  337.     {
  338.       WrStrErrorPos(ErrNum_InvReg, &ArgStr[StopInd]);
  339.       ErrOcc = True;
  340.     }
  341.   }
  342.  
  343.   else
  344.   {
  345.     char Str[100];
  346.  
  347.     as_snprintf(Str, sizeof(Str), getmessage(Num_ErrMsgAddrArgCnt), 1, 2, StopInd - StartInd + 1);
  348.     WrXError(ErrNum_WrongArgCnt, Str);
  349.     ErrOcc = True;
  350.   }
  351.  
  352.   if ((!ErrOcc) && (AdrMode == ModNone))
  353.     WrError(ErrNum_InvAddrMode);
  354. }
  355.  
  356. static void AddPrefix(Byte Prefix)
  357. {
  358.   BAsmCode[PrefCnt++] = Prefix;
  359. }
  360.  
  361. static void Try2Split(int Src)
  362. {
  363.   char *p;
  364.   size_t SrcLen;
  365.  
  366.   KillPrefBlanksStrComp(&ArgStr[Src]);
  367.   KillPostBlanksStrComp(&ArgStr[Src]);
  368.   SrcLen = strlen(ArgStr[Src].str.p_str);
  369.   p = ArgStr[Src].str.p_str + SrcLen - 1;
  370.   while ((p > ArgStr[Src].str.p_str) && !as_isspace(*p))
  371.     p--;
  372.   if (p > ArgStr[Src].str.p_str)
  373.   {
  374.     InsertArg(Src + 1, SrcLen);
  375.     StrCompSplitRight(&ArgStr[Src], &ArgStr[Src + 1], p);
  376.     KillPostBlanksStrComp(&ArgStr[Src]);
  377.     KillPrefBlanksStrComp(&ArgStr[Src + 1]);
  378.   }
  379. }
  380.  
  381. /*---------------------------------------------------------------------------*/
  382.  
  383. static void DecodeFixed(Word Index)
  384. {
  385.   const FixedOrder *forder = FixedOrders + Index;
  386.  
  387.   if (!ChkArgCnt(0, 0));
  388.   else if (!ChkRangeCPU(forder->MinCPU, forder->MaxCPU));
  389.   else if (Hi(forder->Code) != 0)
  390.   {
  391.     CodeLen = 2;
  392.     BAsmCode[0] = Hi(forder->Code);
  393.     BAsmCode[1] = Lo(forder->Code);
  394.   }
  395.   else
  396.   {
  397.     CodeLen = 1;
  398.     BAsmCode[0] = Lo(forder->Code);
  399.   }
  400. }
  401.  
  402. static void DecodeRel(Word Index)
  403. {
  404.   const RelOrder *pOrder = &RelOrders[Index];
  405.   Integer AdrInt;
  406.   Boolean OK;
  407.   tSymbolFlags Flags;
  408.  
  409.   if (ChkArgCnt(1, 1)
  410.    && ChkMinCPU(pOrder->MinCPU))
  411.   {
  412.     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
  413.     if (OK)
  414.     {
  415.       AdrInt -= EProgCounter() + 2;
  416.       if (((AdrInt < -128) || (AdrInt > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  417.       else
  418.       {
  419.         CodeLen = 2;
  420.         BAsmCode[0] = pOrder->Code;
  421.         BAsmCode[1] = Lo(AdrInt);
  422.       }
  423.     }
  424.   }
  425. }
  426.  
  427. static void DecodeALU16(Word Index)
  428. {
  429.   const ALU16Order *forder = ALU16Orders + Index;
  430.  
  431.   OpSize = eSymbolSize16Bit;
  432.   if (ChkArgCnt(1, 2)
  433.    && ChkMinCPU(forder->MinCPU))
  434.   {
  435.     DecodeAdr(1, ArgCnt, (forder->MayImm ? MModImm : 0) | MModInd | MModExt | MModDir);
  436.     if (AdrMode != ModNone)
  437.     {
  438.       switch (forder->PageShift)
  439.       {
  440.         case 1:
  441.           if (PrefCnt == 1)
  442.             BAsmCode[PrefCnt - 1] = Page4Prefix;
  443.           else
  444.             AddPrefix(Page3Prefix);
  445.           break;
  446.         case 2:
  447.           if (PrefCnt == 1)
  448.             BAsmCode[PrefCnt - 1] = Page4Prefix;
  449.           break;
  450.         case 3:
  451.           if (PrefCnt == 0)
  452.             AddPrefix((AdrMode == ModInd) ? Page3Prefix : Page2Prefix);
  453.           break;
  454.       }
  455.       BAsmCode[PrefCnt] = forder->Code + (AdrPart << 4);
  456.       CodeLen = PrefCnt + 1 + AdrCnt;
  457.       memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
  458.     }
  459.   }
  460. }
  461.  
  462. static void DecodeBit63(Word Code)
  463. {
  464.   if (ChkArgCnt(2, 3)
  465.    && ChkExactCPU(CPU6301))
  466.   {
  467.     DecodeAdr(1, 1, MModImm);
  468.     if (AdrMode != ModNone)
  469.     {
  470.       DecodeAdr(2, ArgCnt, MModDir | MModInd);
  471.       if (AdrMode != ModNone)
  472.       {
  473.         BAsmCode[PrefCnt] = Code;
  474.         if (AdrMode == ModDir)
  475.           BAsmCode[PrefCnt] |= 0x10;
  476.         CodeLen = PrefCnt + 1 + AdrCnt;
  477.         memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
  478.       }
  479.     }
  480.   }
  481. }
  482.  
  483. static void DecodeJMP(Word Index)
  484. {
  485.   UNUSED(Index);
  486.  
  487.   if (ChkArgCnt(1, 2))
  488.   {
  489.     DecodeAdr(1, ArgCnt, MModExt | MModInd);
  490.     if (AdrMode != ModImm)
  491.     {
  492.       CodeLen = PrefCnt + 1 + AdrCnt;
  493.       BAsmCode[PrefCnt] = 0x4e + (AdrPart << 4);
  494.       memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
  495.     }
  496.   }
  497. }
  498.  
  499. static void DecodeJSR(Word Index)
  500. {
  501.   UNUSED(Index);
  502.  
  503.   if (ChkArgCnt(1, 2))
  504.   {
  505.     DecodeAdr(1, ArgCnt, MModExt | MModInd | ((MomCPU >= CPU6801) ? MModDir : 0));
  506.     if (AdrMode != ModImm)
  507.     {
  508.       CodeLen=PrefCnt + 1 + AdrCnt;
  509.       BAsmCode[PrefCnt] = 0x8d + (AdrPart << 4);
  510.       memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
  511.     }
  512.   }
  513. }
  514.  
  515. static void DecodeBRxx(Word Index)
  516. {
  517.   Boolean OK;
  518.   Byte Mask;
  519.   Integer AdrInt;
  520.  
  521.   if (ArgCnt == 1)
  522.   {
  523.     Try2Split(1);
  524.     Try2Split(1);
  525.   }
  526.   else if (ArgCnt == 2)
  527.   {
  528.     Try2Split(ArgCnt);
  529.     Try2Split(2);
  530.   }
  531.   if (ChkArgCnt(3, 4)
  532.    && ChkMinCPU(CPU6811))
  533.   {
  534.     Mask = EvalStrIntExpressionOffs(&ArgStr[ArgCnt - 1], !!(*ArgStr[ArgCnt - 1].str.p_str == '#'), Int8, &OK);
  535.     if (OK)
  536.     {
  537.       DecodeAdr(1, ArgCnt - 2, MModDir | MModInd);
  538.       if (AdrMode != ModNone)
  539.       {
  540.         AdrInt = EvalStrIntExpression(&ArgStr[ArgCnt], Int16, &OK);
  541.         if (OK)
  542.         {
  543.           AdrInt -= EProgCounter() + 3 + PrefCnt + AdrCnt;
  544.           if ((AdrInt < -128) || (AdrInt > 127)) WrError(ErrNum_JmpDistTooBig);
  545.           else
  546.           {
  547.             CodeLen = PrefCnt + 3 + AdrCnt;
  548.             BAsmCode[PrefCnt] = 0x12 + Index;
  549.             if (AdrMode == ModInd)
  550.               BAsmCode[PrefCnt] += 12;
  551.             memcpy(BAsmCode + PrefCnt + 1, AdrVals, AdrCnt);
  552.             BAsmCode[PrefCnt + 1 + AdrCnt] = Mask;
  553.             BAsmCode[PrefCnt + 2 + AdrCnt] = Lo(AdrInt);
  554.           }
  555.         }
  556.       }
  557.     }
  558.   }
  559. }
  560.  
  561. static void DecodeBxx(Word Index)
  562. {
  563.   Byte Mask;
  564.   Boolean OK;
  565.   int AddrStart, AddrEnd;
  566.   tStrComp *pMaskArg;
  567.  
  568.   if (MomCPU == CPU6301)
  569.   {
  570.     pMaskArg = &ArgStr[1];
  571.     AddrStart = 2;
  572.     AddrEnd = ArgCnt;
  573.   }
  574.   else
  575.   {
  576.     if ((ArgCnt >= 1) && (ArgCnt <= 2)) Try2Split(ArgCnt);
  577.     pMaskArg = &ArgStr[ArgCnt];
  578.     AddrStart = 1;
  579.     AddrEnd = ArgCnt - 1;
  580.   }
  581.   if (ChkArgCnt(2, 3)
  582.    && ChkMinCPU(CPU6301))
  583.   {
  584.     Mask = EvalStrIntExpressionOffs(pMaskArg, !!(*pMaskArg->str.p_str == '#'),
  585.                                     (MomCPU == CPU6301) ? UInt3 : Int8, &OK);
  586.     if (OK && (MomCPU == CPU6301))
  587.     {
  588.       Mask = 1 << Mask;
  589.       if (Index == 1) Mask = 0xff - Mask;
  590.     }
  591.     if (OK)
  592.     {
  593.       DecodeAdr(AddrStart, AddrEnd, MModDir | MModInd);
  594.       if (AdrMode != ModNone)
  595.       {
  596.         CodeLen = PrefCnt + 2 + AdrCnt;
  597.         if (MomCPU == CPU6301)
  598.         {
  599.           BAsmCode[PrefCnt] = 0x62 - Index;
  600.           if (AdrMode == ModDir)
  601.             BAsmCode[PrefCnt] += 0x10;
  602.           BAsmCode[1 + PrefCnt] = Mask;
  603.           memcpy(BAsmCode + 2 + PrefCnt, AdrVals, AdrCnt);
  604.         }
  605.         else
  606.         {
  607.           BAsmCode[PrefCnt] = 0x14 + Index;
  608.           if (AdrMode == ModInd)
  609.             BAsmCode[PrefCnt] += 8;
  610.           memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
  611.           BAsmCode[1 + PrefCnt + AdrCnt] = Mask;
  612.         }
  613.       }
  614.     }
  615.   }
  616. }
  617.  
  618. static void DecodeBTxx(Word Index)
  619. {
  620.   Boolean OK;
  621.   Byte AdrByte;
  622.  
  623.   if (ChkArgCnt(2, 3)
  624.    && ChkExactCPU(CPU6301))
  625.   {
  626.     AdrByte = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), UInt3, &OK);
  627.     if (OK)
  628.     {
  629.       DecodeAdr(2, ArgCnt, MModDir | MModInd);
  630.       if (AdrMode != ModNone)
  631.       {
  632.         CodeLen = PrefCnt + 2 + AdrCnt;
  633.         BAsmCode[1 + PrefCnt] = 1 << AdrByte;
  634.         memcpy(BAsmCode + 2 + PrefCnt, AdrVals, AdrCnt);
  635.         BAsmCode[PrefCnt] = 0x65 + Index;
  636.         if (AdrMode == ModDir)
  637.           BAsmCode[PrefCnt] += 0x10;
  638.       }
  639.     }
  640.   }
  641. }
  642.  
  643. static void DecodeALU8(Word Code)
  644. {
  645.   Byte Reg;
  646.   int MinArgCnt = Hi(Code) & 3;
  647.  
  648.   /* dirty hack: LDA/STA/ORA, and first arg is not A or B, treat like LDAA/STAA/ORAA: */
  649.  
  650.   if ((MinArgCnt == 2)
  651.    && (as_toupper(OpPart.str.p_str[2]) == 'A')
  652.    && (ArgCnt >= 1)
  653.    && !DecodeAcc(ArgStr[1].str.p_str, &Reg))
  654.     MinArgCnt = 1;
  655.  
  656.   if (ChkArgCnt(MinArgCnt, MinArgCnt + 1))
  657.   {
  658.     DecodeAdr(MinArgCnt , ArgCnt, ((Code & 0x8000) ? MModImm : 0) | MModInd | MModExt | MModDir);
  659.     if (AdrMode != ModNone)
  660.     {
  661.       BAsmCode[PrefCnt] = Lo(Code) | (AdrPart << 4);
  662.       if (MinArgCnt == 1)
  663.       {
  664.         AdrMode = ModAcc;
  665.         AdrPart = (Code & 0x4000) >> 14;
  666.       }
  667.       else
  668.         DecodeAdr(1, 1, MModAcc);
  669.       if (AdrMode != ModNone)
  670.       {
  671.         BAsmCode[PrefCnt] |= AdrPart << 6;
  672.         CodeLen = PrefCnt + 1 + AdrCnt;
  673.         memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
  674.       }
  675.     }
  676.   }
  677. }
  678.  
  679. static void DecodeSing8(Word Code)
  680. {
  681.   if (ChkArgCnt(1, 2))
  682.   {
  683.     DecodeAdr(1, ArgCnt, MModAcc | MModExt | MModInd);
  684.     if (AdrMode!=ModNone)
  685.     {
  686.       CodeLen = PrefCnt + 1 + AdrCnt;
  687.       BAsmCode[PrefCnt] = Code | (AdrPart << 4);
  688.       memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
  689.     }
  690.   }
  691. }
  692.  
  693. static void DecodeSing8_Acc(Word Code)
  694. {
  695.   if (ChkArgCnt(0, 0))
  696.   {
  697.     BAsmCode[PrefCnt] = Code;
  698.     CodeLen = PrefCnt + 1;
  699.   }
  700. }
  701.  
  702. static void DecodePSH_PUL(Word Code)
  703. {
  704.   if (ChkArgCnt(1, 1))
  705.   {
  706.     DecodeAdr(1, 1, MModAcc);
  707.     if (AdrMode != ModNone)
  708.     {
  709.       CodeLen = 1;
  710.       BAsmCode[0]=Code | AdrPart;
  711.     }
  712.   }
  713. }
  714.  
  715. static void DecodePRWINS(Word Code)
  716. {
  717.   UNUSED(Code);
  718.  
  719.   if (ChkExactCPU(CPU68HC11K4))
  720.   {
  721.     printf("\nMMSIZ $%02x MMWBR $%02x MM1CR $%02x MM2CR $%02x INIT $%02x INIT2 $%02x CONFIG $%02x\n",
  722.            (unsigned)Reg_MMSIZ, (unsigned)Reg_MMWBR, (unsigned)Reg_MM1CR, (unsigned)Reg_MM2CR,
  723.            (unsigned)Reg_INIT, (unsigned)Reg_INIT2, (unsigned)Reg_CONFIG);
  724.     cpu_2_phys_area_dump(SegCode, stdout);
  725.   }
  726. }
  727.  
  728. /*---------------------------------------------------------------------------*/
  729.  
  730. static void AddFixed(const char *NName, CPUVar NMin, CPUVar NMax, Word NCode)
  731. {
  732.   order_array_rsv_end(FixedOrders, FixedOrder);
  733.   FixedOrders[InstrZ].MinCPU = NMin;
  734.   FixedOrders[InstrZ].MaxCPU = NMax;
  735.   FixedOrders[InstrZ].Code = NCode;
  736.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  737. }
  738.  
  739. static void AddRel(const char *NName, CPUVar NMin, Word NCode)
  740. {
  741.   order_array_rsv_end(RelOrders, RelOrder);
  742.   RelOrders[InstrZ].MinCPU = NMin;
  743.   RelOrders[InstrZ].Code = NCode;
  744.   AddInstTable(InstTable, NName, InstrZ++, DecodeRel);
  745. }
  746.  
  747. static void AddALU8(const char *NamePlain, const char *NameA, const char *NameB, const char *NameB2, Boolean MayImm, Byte NCode)
  748. {
  749.   Word BaseCode = NCode | (MayImm ? 0x8000 : 0);
  750.  
  751.   AddInstTable(InstTable, NamePlain, BaseCode | (2 << 8), DecodeALU8);
  752.   AddInstTable(InstTable, NameA, BaseCode | (1 << 8), DecodeALU8);
  753.   AddInstTable(InstTable, NameB, BaseCode | (1 << 8) | 0x4000, DecodeALU8);
  754.   if (NameB2)
  755.     AddInstTable(InstTable, NameB2, BaseCode | (1 << 8) | 0x4000, DecodeALU8);
  756. }
  757.  
  758. static void AddALU16(const char *NName, Boolean NMay, CPUVar NMin, Byte NShift, Byte NCode)
  759. {
  760.   order_array_rsv_end(ALU16Orders, ALU16Order);
  761.   ALU16Orders[InstrZ].MayImm = NMay;
  762.   ALU16Orders[InstrZ].MinCPU = NMin;
  763.   ALU16Orders[InstrZ].PageShift = NShift;
  764.   ALU16Orders[InstrZ].Code = NCode;
  765.   AddInstTable(InstTable, NName, InstrZ++, DecodeALU16);
  766. }
  767.  
  768. static void AddSing8(const char *NamePlain, const char *NameA, const char *NameB, Byte NCode)
  769. {
  770.   AddInstTable(InstTable, NamePlain, NCode, DecodeSing8);
  771.   AddInstTable(InstTable, NameA, NCode | 0, DecodeSing8_Acc);
  772.   AddInstTable(InstTable, NameB, NCode | 0x10, DecodeSing8_Acc);
  773. }
  774.  
  775. static void InitFields(void)
  776. {
  777.   InstTable = CreateInstTable(317);
  778.   AddInstTable(InstTable, "JMP"  , 0, DecodeJMP);
  779.   AddInstTable(InstTable, "JSR"  , 0, DecodeJSR);
  780.   AddInstTable(InstTable, "BRCLR", 1, DecodeBRxx);
  781.   AddInstTable(InstTable, "BRSET", 0, DecodeBRxx);
  782.   AddInstTable(InstTable, "BCLR" , 1, DecodeBxx);
  783.   AddInstTable(InstTable, "BSET" , 0, DecodeBxx);
  784.   AddInstTable(InstTable, "BTST" , 6, DecodeBTxx);
  785.   AddInstTable(InstTable, "BTGL" , 0, DecodeBTxx);
  786.  
  787.   InstrZ = 0;
  788.   AddFixed("ABA"  ,CPU6800, CPU68HC11K4, 0x001b); AddFixed("ABX"  ,CPU6801, CPU68HC11K4, 0x003a);
  789.   AddFixed("ABY"  ,CPU6811, CPU68HC11K4, 0x183a); AddFixed("ASLD" ,CPU6801, CPU68HC11K4, 0x0005);
  790.   AddFixed("CBA"  ,CPU6800, CPU68HC11K4, 0x0011); AddFixed("CLC"  ,CPU6800, CPU68HC11K4, 0x000c);
  791.   AddFixed("CLI"  ,CPU6800, CPU68HC11K4, 0x000e); AddFixed("CLV"  ,CPU6800, CPU68HC11K4, 0x000a);
  792.   AddFixed("DAA"  ,CPU6800, CPU68HC11K4, 0x0019); AddFixed("DES"  ,CPU6800, CPU68HC11K4, 0x0034);
  793.   AddFixed("DEX"  ,CPU6800, CPU68HC11K4, 0x0009); AddFixed("DEY"  ,CPU6811, CPU68HC11K4, 0x1809);
  794.   AddFixed("FDIV" ,CPU6811, CPU68HC11K4, 0x0003); AddFixed("IDIV" ,CPU6811, CPU68HC11K4, 0x0002);
  795.   AddFixed("INS"  ,CPU6800, CPU68HC11K4, 0x0031); AddFixed("INX"  ,CPU6800, CPU68HC11K4, 0x0008);
  796.   AddFixed("INY"  ,CPU6811, CPU68HC11K4, 0x1808); AddFixed("LSLD" ,CPU6801, CPU68HC11K4, 0x0005);
  797.   AddFixed("LSRD" ,CPU6801, CPU68HC11K4, 0x0004); AddFixed("MUL"  ,CPU6801, CPU68HC11K4, 0x003d);
  798.   AddFixed("NOP"  ,CPU6800, CPU68HC11K4, 0x0001); AddFixed("PSHX" ,CPU6801, CPU68HC11K4, 0x003c);
  799.   AddFixed("PSHY" ,CPU6811, CPU68HC11K4, 0x183c); AddFixed("PULX" ,CPU6801, CPU68HC11K4, 0x0038);
  800.   AddFixed("PULY" ,CPU6811, CPU68HC11K4, 0x1838); AddFixed("RTI"  ,CPU6800, CPU68HC11K4, 0x003b);
  801.   AddFixed("RTS"  ,CPU6800, CPU68HC11K4, 0x0039); AddFixed("SBA"  ,CPU6800, CPU68HC11K4, 0x0010);
  802.   AddFixed("SEC"  ,CPU6800, CPU68HC11K4, 0x000d); AddFixed("SEI"  ,CPU6800, CPU68HC11K4, 0x000f);
  803.   AddFixed("SEV"  ,CPU6800, CPU68HC11K4, 0x000b); AddFixed("SLP"  ,CPU6301, CPU6301    , 0x001a);
  804.   AddFixed("STOP" ,CPU6811, CPU68HC11K4, 0x00cf); AddFixed("SWI"  ,CPU6800, CPU68HC11K4, 0x003f);
  805.   AddFixed("TAB"  ,CPU6800, CPU68HC11K4, 0x0016); AddFixed("TAP"  ,CPU6800, CPU68HC11K4, 0x0006);
  806.   AddFixed("TBA"  ,CPU6800, CPU68HC11K4, 0x0017); AddFixed("TPA"  ,CPU6800, CPU68HC11K4, 0x0007);
  807.   AddFixed("TSX"  ,CPU6800, CPU68HC11K4, 0x0030); AddFixed("TSY"  ,CPU6811, CPU68HC11K4, 0x1830);
  808.   AddFixed("TXS"  ,CPU6800, CPU68HC11K4, 0x0035); AddFixed("TYS"  ,CPU6811, CPU68HC11K4, 0x1835);
  809.   AddFixed("WAI"  ,CPU6800, CPU68HC11K4, 0x003e);
  810.   AddFixed("XGDX" ,CPU6301, CPU68HC11K4, (MomCPU == CPU6301) ? 0x0018 : 0x008f);
  811.   AddFixed("XGDY" ,CPU6811, CPU68HC11K4, 0x188f);
  812.  
  813.   InstrZ = 0;
  814.   AddRel("BCC", CPU6800, 0x24);
  815.   AddRel("BCS", CPU6800, 0x25);
  816.   AddRel("BEQ", CPU6800, 0x27);
  817.   AddRel("BGE", CPU6800, 0x2c);
  818.   AddRel("BGT", CPU6800, 0x2e);
  819.   AddRel("BHI", CPU6800, 0x22);
  820.   AddRel("BHS", CPU6800, 0x24);
  821.   AddRel("BLE", CPU6800, 0x2f);
  822.   AddRel("BLO", CPU6800, 0x25);
  823.   AddRel("BLS", CPU6800, 0x23);
  824.   AddRel("BLT", CPU6800, 0x2d);
  825.   AddRel("BMI", CPU6800, 0x2b);
  826.   AddRel("BNE", CPU6800, 0x26);
  827.   AddRel("BPL", CPU6800, 0x2a);
  828.   AddRel("BRA", CPU6800, 0x20);
  829.   AddRel("BRN", CPU6801, 0x21);
  830.   AddRel("BSR", CPU6800, 0x8d);
  831.   AddRel("BVC", CPU6800, 0x28);
  832.   AddRel("BVS", CPU6800, 0x29);
  833.  
  834.   AddALU8("ADC", "ADCA", "ADCB", NULL , True , 0x89);
  835.   AddALU8("ADD", "ADDA", "ADDB", NULL , True , 0x8b);
  836.   AddALU8("AND", "ANDA", "ANDB", NULL , True , 0x84);
  837.   AddALU8("BIT", "BITA", "BITB", NULL , True , 0x85);
  838.   AddALU8("CMP", "CMPA", "CMPB", NULL , True , 0x81);
  839.   AddALU8("EOR", "EORA", "EORB", NULL , True , 0x88);
  840.   AddALU8("LDA", "LDAA", "LDAB", "LDB", True , 0x86);
  841.   AddALU8("ORA", "ORAA", "ORAB", "ORB", True , 0x8a);
  842.   AddALU8("SBC", "SBCA", "SBCB", NULL , True , 0x82);
  843.   AddALU8("STA", "STAA", "STAB", "STB", False, 0x87);
  844.   AddALU8("SUB", "SUBA", "SUBB", NULL , True , 0x80);
  845.  
  846.   InstrZ = 0;
  847.   AddALU16("ADDD", True , CPU6801, 0, 0xc3);
  848.   AddALU16("CPD" , True , CPU6811, 1, 0x83);
  849.   AddALU16("CMPD", True , CPU6811, 1, 0x83);
  850.   AddALU16("CPX" , True , CPU6800, 2, 0x8c);
  851.   AddALU16("CMPX", True , CPU6800, 2, 0x8c);
  852.   AddALU16("CPY" , True , CPU6811, 3, 0x8c);
  853.   AddALU16("CMPY", True , CPU6811, 3, 0x8c);
  854.   AddALU16("LDD" , True , CPU6801, 0, 0xcc);
  855.   AddALU16("LDS" , True , CPU6800, 0, 0x8e);
  856.   AddALU16("LDX" , True , CPU6800, 2, 0xce);
  857.   AddALU16("LDY" , True , CPU6811, 3, 0xce);
  858.   AddALU16("STD" , False, CPU6801, 0, 0xcd);
  859.   AddALU16("STS" , False, CPU6800, 0, 0x8f);
  860.   AddALU16("STX" , False, CPU6800, 2, 0xcf);
  861.   AddALU16("STY" , False, CPU6811, 3, 0xcf);
  862.   AddALU16("SUBD", True , CPU6801, 0, 0x83);
  863.  
  864.   AddSing8("ASL", "ASLA", "ASLB", 0x48);
  865.   AddSing8("ASR", "ASRA", "ASRB", 0x47);
  866.   AddSing8("CLR", "CLRA", "CLRB", 0x4f);
  867.   AddSing8("COM", "COMA", "COMB", 0x43);
  868.   AddSing8("DEC", "DECA", "DECB", 0x4a);
  869.   AddSing8("INC", "INCA", "INCB", 0x4c);
  870.   AddSing8("LSL", "LSLA", "LSLB", 0x48);
  871.   AddSing8("LSR", "LSRA", "LSRB", 0x44);
  872.   AddSing8("NEG", "NEGA", "NEGB", 0x40);
  873.   AddSing8("ROL", "ROLA", "ROLB", 0x49);
  874.   AddSing8("ROR", "RORA", "RORB", 0x46);
  875.   AddSing8("TST", "TSTA", "TSTB", 0x4d);
  876.  
  877.   AddInstTable(InstTable, "PSH" , 0x36, DecodePSH_PUL);
  878.   AddInstTable(InstTable, "PSHA", 0x36, DecodeSing8_Acc);
  879.   AddInstTable(InstTable, "PSHB", 0x37, DecodeSing8_Acc);
  880.   AddInstTable(InstTable, "PUL" , 0x32, DecodePSH_PUL);
  881.   AddInstTable(InstTable, "PULA", 0x32, DecodeSing8_Acc);
  882.   AddInstTable(InstTable, "PULB", 0x33, DecodeSing8_Acc);
  883.  
  884.   AddInstTable(InstTable, "AIM", 0x61, DecodeBit63);
  885.   AddInstTable(InstTable, "EIM", 0x65, DecodeBit63);
  886.   AddInstTable(InstTable, "OIM", 0x62, DecodeBit63);
  887.   AddInstTable(InstTable, "TIM", 0x6b, DecodeBit63);
  888.  
  889.   AddInstTable(InstTable, "PRWINS", 0, DecodePRWINS);
  890.  
  891.   init_moto8_pseudo(InstTable, e_moto_8_be | e_moto_8_db | e_moto_8_dw);
  892. }
  893.  
  894. static void DeinitFields(void)
  895. {
  896.   DestroyInstTable(InstTable);
  897.   order_array_free(FixedOrders);
  898.   order_array_free(RelOrders);
  899.   order_array_free(ALU16Orders);
  900. }
  901.  
  902. static Boolean DecodeAttrPart_68(void)
  903. {
  904.   if (strlen(AttrPart.str.p_str) > 1)
  905.   {
  906.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  907.     return False;
  908.   }
  909.   return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
  910. }
  911.  
  912. static void MakeCode_68(void)
  913. {
  914.   CodeLen = 0;
  915.   DontPrint = False;
  916.   PrefCnt = 0;
  917.   AdrCnt = 0;
  918.  
  919.   /* Operandengroesse festlegen */
  920.  
  921.   OpSize = (AttrPartOpSize[0] != eSymbolSizeUnknown) ? AttrPartOpSize[0] : eSymbolSize8Bit;
  922.  
  923.   /* zu ignorierendes */
  924.  
  925.   if (*OpPart.str.p_str == '\0')
  926.     return;
  927.  
  928.   /* Pseudoanweisungen */
  929.  
  930.   if (DecodeMoto16Pseudo(OpSize, True))
  931.     return;
  932.  
  933.   /* gehashtes */
  934.  
  935.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  936.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  937. }
  938.  
  939. static void InitCode_68(void)
  940. {
  941.   Reg_MMSIZ = Reg_MMWBR = Reg_MM1CR = Reg_MM2CR = 0;
  942. }
  943.  
  944. static Boolean IsDef_68(void)
  945. {
  946.   return False;
  947. }
  948.  
  949. static void SwitchTo_68(void)
  950. {
  951.   TurnWords = False;
  952.   SetIntConstMode(eIntConstModeMoto);
  953.  
  954.   PCSymbol = "*";
  955.   HeaderID = 0x61;
  956.   NOPCode = 0x01;
  957.   DivideChars = ",";
  958.   HasAttrs = True;
  959.   AttrChars = ".";
  960.  
  961.   ValidSegs = 1 << SegCode;
  962.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  963.   SegLimits[SegCode] = (MomCPU == CPU68HC11K4) ? 0x10ffffl : 0xffff;
  964.  
  965.   DecodeAttrPart = DecodeAttrPart_68;
  966.   MakeCode = MakeCode_68;
  967.   IsDef = IsDef_68;
  968.   SwitchFrom = DeinitFields;
  969.   InitFields();
  970.   AddMoto16PseudoONOFF(False);
  971.  
  972.   if (MomCPU == CPU68HC11K4)
  973.   {
  974.     static const ASSUMERec ASSUMEHC11s[] =
  975.     {
  976.       {"MMSIZ" , &Reg_MMSIZ , 0, 0xff, 0, SetK4Ranges},
  977.       {"MMWBR" , &Reg_MMWBR , 0, 0xff, 0, SetK4Ranges},
  978.       {"MM1CR" , &Reg_MM1CR , 0, 0xff, 0, SetK4Ranges},
  979.       {"MM2CR" , &Reg_MM2CR , 0, 0xff, 0, SetK4Ranges},
  980.       {"INIT"  , &Reg_INIT  , 0, 0xff, 0, SetK4Ranges},
  981.       {"INIT2" , &Reg_INIT2 , 0, 0xff, 0, SetK4Ranges},
  982.       {"CONFIG", &Reg_CONFIG, 0, 0xff, 0, SetK4Ranges},
  983.     };
  984.  
  985.     pASSUMERecs = ASSUMEHC11s;
  986.     ASSUMERecCnt = as_array_size(ASSUMEHC11s);
  987.  
  988.     SetK4Ranges();
  989.   }
  990.   else
  991.     cpu_2_phys_area_clear(SegCode);
  992. }
  993.  
  994. void code68_init(void)
  995. {
  996.   CPU6800 = AddCPU("6800", SwitchTo_68);
  997.   CPU6801 = AddCPU("6801", SwitchTo_68);
  998.   CPU6301 = AddCPU("6301", SwitchTo_68);
  999.   CPU6811 = AddCPU("6811", SwitchTo_68);
  1000.   CPU68HC11K4 = AddCPU("68HC11K4", SwitchTo_68);
  1001.  
  1002.   AddInitPassProc(InitCode_68);
  1003. }
  1004.