1 /* codexa.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS-Portierung                                                             */
6 /*                                                                           */
7 /* AS-Codegenerator Philips XA                                               */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14 
15 #include "nls.h"
16 #include "strutil.h"
17 #include "bpemu.h"
18 #include "asmdef.h"
19 #include "asmsub.h"
20 #include "asmpars.h"
21 #include "asmallg.h"
22 #include "asmitree.h"
23 #include "codepseudo.h"
24 #include "intpseudo.h"
25 #include "motpseudo.h"
26 #include "codevars.h"
27 #include "errmsg.h"
28 
29 #include "codexa.h"
30 
31 /*-------------------------------------------------------------------------*/
32 /* Definitionen */
33 
34 #define ModNone (-1)
35 #define ModReg 0
36 #define MModReg (1 << ModReg)
37 #define ModMem 1
38 #define MModMem (1 << ModMem)
39 #define ModImm 2
40 #define MModImm (1 << ModImm)
41 #define ModAbs 3
42 #define MModAbs (1 << ModAbs)
43 
44 #define REG_SP 7
45 #define REG_MARK 16
46 
47 #define JBitOrderCnt 3
48 #define RegOrderCnt 4
49 #define RelOrderCount 17
50 
51 #define RETICode 0xd690
52 
53 #define eSymbolSize5Bit ((tSymbolSize)-4)
54 #define eSymbolSizeSigned4Bit ((tSymbolSize)-3)
55 #define eSymbolSize4Bit ((tSymbolSize)-2)
56 
57 typedef struct
58 {
59   Byte SizeMask;
60   Byte Code;
61 } RegOrder;
62 
63 typedef struct
64 {
65   const char *Name;
66   Byte SizeMask;
67   Byte Code;
68   Byte Inversion;
69 } InvOrder;
70 
71 static CPUVar CPUXAG1,CPUXAG2,CPUXAG3;
72 
73 static InvOrder *JBitOrders;
74 static RegOrder *RegOrders;
75 static InvOrder *RelOrders;
76 
77 static LongInt Reg_DS;
78 
79 static ShortInt AdrMode;
80 static Byte AdrPart,MemPart;
81 static Byte AdrVals[4];
82 static tSymbolSize OpSize;
83 
84 #define ASSUMEXACount 1
85 static ASSUMERec ASSUMEXAs[ASSUMEXACount] =
86 {
87   {"DS", &Reg_DS, 0, 0xff, 0x100, NULL}
88 };
89 
90 /*-------------------------------------------------------------------------*/
91 /* Hilfsroutinen */
92 
SetOpSize(tSymbolSize NSize)93 static void SetOpSize(tSymbolSize NSize)
94 {
95   if (OpSize == eSymbolSizeUnknown) OpSize = NSize;
96   else if (OpSize != NSize)
97   {
98     AdrMode = ModNone; AdrCnt = 0; WrError(ErrNum_ConfOpSizes);
99   }
100 }
101 
102 /*!------------------------------------------------------------------------
103  * \fn     DecodeRegCore(const char *pArg, tSymbolSize *pSize, Byte *pResult)
104  * \brief  check whether argument is a CPU register
105  * \param  pArg source argument
106  * \param  pSize register size if yes
107  * \param  pResult register number if yes
108  * \return Reg eval result
109  * ------------------------------------------------------------------------ */
110 
DecodeRegCore(const char * pArg,tSymbolSize * pSize,Byte * pResult)111 static tRegEvalResult DecodeRegCore(const char *pArg, tSymbolSize *pSize, Byte *pResult)
112 {
113   int len;
114 
115   if (!as_strcasecmp(pArg, "SP"))
116   {
117     *pResult = REG_SP | REG_MARK;
118     *pSize = eSymbolSize16Bit;
119     return eIsReg;
120   }
121 
122   len = strlen(pArg);
123   if ((len >= 2) && (as_toupper(*pArg) == 'R') && (pArg[1] >= '0') && (pArg[1] <= '7'))
124   {
125     *pResult = pArg[1] - '0';
126     if (len == 2)
127     {
128       if (OpSize == eSymbolSize32Bit)
129       {
130         *pSize = eSymbolSize32Bit;
131         if (*pResult & 1)
132         {
133           WrError(ErrNum_InvRegPair);
134           (*pResult)--;
135           return eRegAbort;
136         }
137         else
138           return eIsReg;
139       }
140       else
141       {
142         *pSize = eSymbolSize16Bit;
143         return eIsReg;
144       }
145     }
146     else if ((len == 3) && (as_toupper(pArg[2]) == 'L'))
147     {
148       *pResult <<= 1;
149       *pSize = eSymbolSize8Bit;
150       return eIsReg;
151     }
152     else if ((len == 3) && (as_toupper(pArg[2]) == 'H'))
153     {
154       *pResult = (*pResult << 1) + 1;
155       *pSize = eSymbolSize8Bit;
156       return eIsReg;
157     }
158     else
159       return eIsNoReg;
160   }
161   return eIsNoReg;
162 }
163 
164 /*!------------------------------------------------------------------------
165  * \fn     DissectReg_XA(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
166  * \brief  dissect register symbols - XA variant
167  * \param  pDest destination buffer
168  * \param  DestSize destination buffer size
169  * \param  Value numeric register value
170  * \param  InpSize register size
171  * ------------------------------------------------------------------------ */
172 
DissectReg_XA(char * pDest,size_t DestSize,tRegInt Value,tSymbolSize InpSize)173 static void DissectReg_XA(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
174 {
175   switch (InpSize)
176   {
177     case eSymbolSize8Bit:
178       as_snprintf(pDest, DestSize, "R%u%c", (unsigned)(Value >> 1), "LH"[Value & 1]);
179       break;
180     case eSymbolSize16Bit:
181       as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
182       break;
183     case eSymbolSize32Bit:
184       as_snprintf(pDest, DestSize, "R%u.D", (unsigned)Value);
185       break;
186     default:
187       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
188   }
189 }
190 
191 
192 /*!------------------------------------------------------------------------
193  * \fn     DecodeReg(const tStrComp *pArg, tSymbolSize *pSize, Byte *pResult, Boolean MustBeReg)
194  * \brief  check whether argument is a CPU register or register alias
195  * \param  pArg source argument
196  * \param  pSize register size if yes
197  * \param  pResult register number if yes
198  * \param  MustBeReg expecting register?
199  * \return Reg eval result
200  * ------------------------------------------------------------------------ */
201 
DecodeReg(const tStrComp * pArg,tSymbolSize * pSize,Byte * pResult,Boolean MustBeReg)202 static tRegEvalResult DecodeReg(const tStrComp *pArg, tSymbolSize *pSize, Byte *pResult, Boolean MustBeReg)
203 {
204   tRegDescr RegDescr;
205   tEvalResult EvalResult;
206   tRegEvalResult RegEvalResult;
207 
208   RegEvalResult = DecodeRegCore(pArg->Str, pSize, pResult);
209   if (RegEvalResult != eIsNoReg)
210   {
211     *pResult &= ~REG_MARK;
212     return RegEvalResult;
213   }
214 
215   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
216   if (RegEvalResult == eIsReg)
217   {
218     *pResult = RegDescr.Reg & ~REG_MARK;
219     *pSize = EvalResult.DataSize;
220   }
221   return RegEvalResult;
222 }
223 
ChkAdr(Word Mask,const tStrComp * pComp)224 static Boolean ChkAdr(Word Mask, const tStrComp *pComp)
225 {
226   if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
227   {
228     WrStrErrorPos(ErrNum_InvAddrMode, pComp);
229     AdrMode = ModNone;
230     AdrCnt = 0;
231     return False;
232   }
233   return True;
234 }
235 
DecodeAdrIndirect(tStrComp * pArg,Word Mask)236 static Boolean DecodeAdrIndirect(tStrComp *pArg, Word Mask)
237 {
238   unsigned ArgLen;
239   Byte Reg;
240   tSymbolSize NSize;
241 
242   ArgLen = strlen(pArg->Str);
243   if (pArg->Str[ArgLen - 1] == '+')
244   {
245     StrCompShorten(pArg, 1); ArgLen--;
246     if (!DecodeReg(pArg, &NSize, &AdrPart, True));
247     else if (NSize != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvAddrMode, pArg);
248     else
249     {
250       AdrMode = ModMem; MemPart = 3;
251     }
252   }
253   else
254   {
255     char *pSplit;
256     Boolean FirstFlag = False, NegFlag = False, NextNegFlag, ErrFlag = False;
257     tStrComp ThisComp = *pArg, RemComp;
258     LongInt DispAcc = 0;
259 
260     AdrPart = 0xff;
261     do
262     {
263       pSplit = QuotMultPos(ThisComp.Str, "+-");
264       NextNegFlag = (pSplit && (*pSplit == '-'));
265       if (pSplit)
266       {
267         StrCompRefRight(&RemComp, &ThisComp, pSplit - ThisComp.Str + 1);
268         *pSplit = '\0';
269       }
270       KillPrefBlanksStrComp(&ThisComp);
271       KillPostBlanksStrComp(&ThisComp);
272 
273       switch (DecodeReg(&ThisComp, &NSize, &Reg, False))
274       {
275         case eIsReg:
276           if ((NSize != eSymbolSize16Bit) || (AdrPart != 0xff) || NegFlag)
277           {
278             WrStrErrorPos(ErrNum_InvAddrMode, &ThisComp); ErrFlag = True;
279           }
280           else
281             AdrPart = Reg;
282           break;
283         case eRegAbort:
284           return False;
285         default:
286         {
287           LongInt DispPart;
288           tSymbolFlags Flags;
289 
290           DispPart = EvalStrIntExpressionWithFlags(&ThisComp, Int32, &ErrFlag, &Flags);
291           ErrFlag = !ErrFlag;
292           if (!ErrFlag)
293           {
294             FirstFlag = FirstFlag || mFirstPassUnknown(Flags);
295             DispAcc += NegFlag ? -DispPart : DispPart;
296           }
297         }
298       }
299 
300       NegFlag = NextNegFlag;
301       if (pSplit)
302         ThisComp = RemComp;
303     }
304     while (pSplit && !ErrFlag);
305 
306     if (FirstFlag) DispAcc &= 0x7fff;
307     if (AdrPart == 0xff) WrStrErrorPos(ErrNum_InvAddrMode, pArg);
308     else if (DispAcc == 0)
309     {
310       AdrMode = ModMem; MemPart = 2;
311     }
312     else if ((DispAcc >= -128) && (DispAcc < 127))
313     {
314       AdrMode = ModMem; MemPart = 4;
315       AdrVals[0] = DispAcc & 0xff; AdrCnt = 1;
316     }
317     else if (ChkRange(DispAcc, -0x8000l, 0x7fffl))
318     {
319       AdrMode = ModMem; MemPart = 5;
320       AdrVals[0] = (DispAcc >> 8) & 0xff;
321       AdrVals[1] = DispAcc & 0xff;
322       AdrCnt = 2;
323     }
324   }
325   return ChkAdr(Mask, pArg);
326 }
327 
DecodeAdr(tStrComp * pArg,Word Mask)328 static Boolean DecodeAdr(tStrComp *pArg, Word Mask)
329 {
330   tSymbolSize NSize;
331   LongInt AdrLong;
332   tEvalResult EvalResult;
333   Word AdrInt;
334   int ArgLen;
335 
336   AdrMode = ModNone; AdrCnt = 0;
337   KillPrefBlanksStrComp(pArg);
338   KillPostBlanksStrComp(pArg);
339 
340   switch (DecodeReg(pArg, &NSize, &AdrPart, False))
341   {
342     case eIsReg:
343       if (Mask & MModReg)
344       {
345         AdrMode = ModReg;
346         SetOpSize(NSize);
347       }
348       else
349       {
350         AdrMode = ModMem;
351         MemPart = 1;
352         SetOpSize(NSize);
353       }
354       return ChkAdr(Mask, pArg);
355     case eRegAbort:
356       return False;
357     default:
358       break;
359   }
360 
361   if (*pArg->Str == '#')
362   {
363     tStrComp ImmComp;
364     Boolean OK;
365 
366     StrCompRefRight(&ImmComp, pArg, 1);
367     switch ((int)OpSize)
368     {
369       case eSymbolSize5Bit:
370         AdrVals[0] = EvalStrIntExpression(&ImmComp, UInt5, &OK);
371         if (OK)
372         {
373           AdrCnt = 1; AdrMode = ModImm;
374         }
375         break;
376       case eSymbolSizeSigned4Bit:
377         AdrVals[0] = EvalStrIntExpression(&ImmComp, SInt4, &OK);
378         if (OK)
379         {
380           AdrCnt = 1; AdrMode = ModImm;
381         }
382         break;
383       case eSymbolSize4Bit:
384         AdrVals[0] = EvalStrIntExpression(&ImmComp, UInt4, &OK);
385         if (OK)
386         {
387           AdrCnt = 1; AdrMode = ModImm;
388         }
389         break;
390       case eSymbolSizeUnknown:
391         WrError(ErrNum_UndefOpSizes);
392         break;
393       case eSymbolSize8Bit:
394         AdrVals[0] = EvalStrIntExpression(&ImmComp, Int8, &OK);
395         if (OK)
396         {
397           AdrCnt = 1; AdrMode = ModImm;
398         }
399         break;
400       case eSymbolSize16Bit:
401         AdrInt = EvalStrIntExpression(&ImmComp, Int16, &OK);
402         if (OK)
403         {
404           AdrVals[0] = Hi(AdrInt);
405           AdrVals[1] = Lo(AdrInt);
406           AdrCnt = 2;
407           AdrMode = ModImm;
408         }
409         break;
410       case eSymbolSize32Bit:
411         AdrLong = EvalStrIntExpression(&ImmComp, Int32, &OK);
412         if (OK)
413         {
414           AdrVals[0] = (AdrLong >> 24) & 0xff;
415           AdrVals[1] = (AdrLong >> 16) & 0xff;
416           AdrVals[2] = (AdrLong >> 8) & 0xff;
417           AdrVals[3] = AdrLong & 0xff;
418           AdrCnt = 4;
419           AdrMode = ModImm;
420         }
421         break;
422       default:
423         break;
424     }
425     return ChkAdr(Mask, pArg);
426   }
427 
428   ArgLen = strlen(pArg->Str);
429   if ((*pArg->Str == '[') && (pArg->Str[ArgLen - 1] == ']'))
430   {
431     tStrComp IndirComp;
432 
433     pArg->Str[--ArgLen] = '\0'; pArg->Pos.Len--;
434     StrCompRefRight(&IndirComp, pArg, 1);
435     KillPrefBlanksStrComp(&IndirComp);
436     KillPostBlanksStrComp(&IndirComp);
437 
438     return DecodeAdrIndirect(&IndirComp, Mask);
439   }
440 
441   AdrLong = EvalStrIntExpressionWithResult(pArg, UInt24, &EvalResult);
442   if (EvalResult.OK)
443   {
444     if (mFirstPassUnknown(EvalResult.Flags))
445     {
446       if (!(Mask & MModAbs)) AdrLong &= 0x3ff;
447     }
448     if ((AdrLong & 0xffff) > 0x7ff) WrError(ErrNum_AdrOverflow);
449     else if ((AdrLong & 0xffff) <= 0x3ff)
450     {
451       if ((AdrLong >> 16) != Reg_DS) WrError(ErrNum_InAccPage);
452       ChkSpace(SegData, EvalResult.AddrSpaceMask);
453       AdrMode = ModMem; MemPart = 6;
454       AdrPart = Hi(AdrLong);
455       AdrVals[0] = Lo(AdrLong);
456       AdrCnt = 1;
457     }
458     else if (AdrLong > 0x7ff) WrError(ErrNum_AdrOverflow);
459     else
460     {
461       ChkSpace(SegIO, EvalResult.AddrSpaceMask);
462       AdrMode = ModMem; MemPart = 6;
463       AdrPart = Hi(AdrLong);
464       AdrVals[0] = Lo(AdrLong);
465       AdrCnt = 1;
466     }
467   }
468 
469   return ChkAdr(Mask, pArg);
470 }
471 
DecodeBitAddr(tStrComp * pArg,LongInt * Erg)472 static Boolean DecodeBitAddr(tStrComp *pArg, LongInt *Erg)
473 {
474   char *p;
475   Byte BPos, Reg;
476   ShortInt Res;
477   tSymbolSize Size;
478   LongInt AdrLong;
479   tEvalResult EvalResult;
480 
481   p = RQuotPos(pArg->Str, '.'); Res = 0;
482   if (!p)
483   {
484     AdrLong = EvalStrIntExpressionWithResult(pArg, UInt24, &EvalResult);
485     if (mFirstPassUnknown(EvalResult.Flags)) AdrLong &= 0x3ff;
486     *Erg = AdrLong; Res = 1;
487   }
488   else
489   {
490     int l = p - pArg->Str;
491 
492     BPos = EvalStrIntExpressionOffsWithResult(pArg, l + 1, UInt4, &EvalResult);
493     if (mFirstPassUnknown(EvalResult.Flags)) BPos &= 7;
494 
495     *p = '\0'; pArg->Pos.Len -= l + 1;
496     if (EvalResult.OK)
497     {
498       switch (DecodeReg(pArg, &Size, &Reg, False))
499       {
500         case eRegAbort:
501           return False;
502         case eIsReg:
503           if ((Size == eSymbolSize8Bit) && (BPos > 7)) WrError(ErrNum_OverRange);
504           else
505           {
506             if (Size == eSymbolSize8Bit) *Erg = (Reg << 3) + BPos;
507             else *Erg = (Reg << 4) + BPos;
508             Res = 1;
509           }
510           break;
511         default:
512           if (BPos > 7) WrError(ErrNum_OverRange);
513           else
514           {
515             AdrLong = EvalStrIntExpressionWithResult(pArg, UInt24, &EvalResult);
516             if (EvalResult.AddrSpaceMask & (1 << SegIO))
517             {
518               ChkSpace(SegIO, EvalResult.AddrSpaceMask);
519               if (mFirstPassUnknown(EvalResult.Flags)) AdrLong = (AdrLong & 0x3f) | 0x400;
520               if (ChkRange(AdrLong, 0x400, 0x43f))
521               {
522                 *Erg = 0x200 + ((AdrLong & 0x3f) << 3) + BPos;
523                 Res = 1;
524               }
525               else
526                 Res = -1;
527             }
528             else
529             {
530               ChkSpace(SegData, EvalResult.AddrSpaceMask);
531               if (mFirstPassUnknown(EvalResult.Flags)) AdrLong = (AdrLong & 0x00ff003f) | 0x20;
532               if (ChkRange(AdrLong & 0xff, 0x20, 0x3f))
533               {
534                 *Erg = 0x100 + ((AdrLong & 0x1f) << 3) + BPos + (AdrLong & 0xff0000);
535                 Res = 1;
536               }
537               else
538                 Res = -1;
539             }
540           }
541         break;
542       }
543     }
544     *p = '.';
545   }
546   if (Res == 0) WrError(ErrNum_InvAddrMode);
547   return (Res == 1);
548 }
549 
ChkBitPage(LongInt Adr)550 static void ChkBitPage(LongInt Adr)
551 {
552   if ((Adr >> 16) != Reg_DS) WrError(ErrNum_InAccPage);
553 }
554 
MkEven24(LongWord Inp)555 static LongWord MkEven24(LongWord Inp)
556 {
557   return Inp & 0xfffffeul;
558 }
559 
GetBranchDest(const tStrComp * pComp,tEvalResult * pEvalResult)560 static LongWord GetBranchDest(const tStrComp *pComp, tEvalResult *pEvalResult)
561 {
562   LongWord Result;
563 
564   Result = EvalStrIntExpressionWithResult(pComp, UInt24, pEvalResult);
565   if (pEvalResult->OK)
566   {
567     if (mFirstPassUnknown(pEvalResult->Flags)) Result = MkEven24(Result);
568     ChkSpace(SegCode, pEvalResult->AddrSpaceMask);
569     if (Result & 1)
570     {
571       WrStrErrorPos(ErrNum_NotAligned, pComp);
572       pEvalResult->OK = False;
573     }
574   }
575   return Result;
576 }
577 
ChkShortEvenDist(LongInt * pDist,tSymbolFlags Flags)578 static Boolean ChkShortEvenDist(LongInt *pDist, tSymbolFlags Flags)
579 {
580   if (!mSymbolQuestionable(Flags) && ((*pDist > 254) || (*pDist < -256)))
581     return False;
582   else
583   {
584     *pDist >>= 1;
585     return True;
586   }
587 }
588 
ChkLongEvenDist(LongInt * pDist,const tStrComp * pComp,tSymbolFlags Flags)589 static Boolean ChkLongEvenDist(LongInt *pDist, const tStrComp *pComp, tSymbolFlags Flags)
590 {
591   if (!mSymbolQuestionable(Flags) && ((*pDist > 65534) || (*pDist < -65536)))
592   {
593     WrStrErrorPos(ErrNum_JmpDistTooBig, pComp);
594     return False;
595   }
596   else
597   {
598     *pDist >>= 1;
599     return True;
600   }
601 }
602 
603 /*-------------------------------------------------------------------------*/
604 /* Befehlsdekoder */
605 
DecodePORT(Word Index)606 static void DecodePORT(Word Index)
607 {
608   UNUSED(Index);
609 
610   CodeEquate(SegIO, 0x400, 0x7ff);
611 }
612 
DecodeBIT(Word Index)613 static void DecodeBIT(Word Index)
614 {
615   LongInt BAdr;
616 
617   UNUSED(Index);
618 
619   if (!ChkArgCnt(1, 1));
620   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
621   else if (DecodeBitAddr(&ArgStr[1], &BAdr))
622   {
623     EnterIntSymbol(&LabPart, BAdr, SegNone, False);
624     switch ((BAdr & 0x3ff) >> 8)
625     {
626       case 0:
627         as_snprintf(ListLine, STRINGSIZE, "=R%d.%d",
628                     (unsigned)((BAdr >> 4) & 15),
629                     (unsigned) (BAdr & 15));
630         break;
631       case 1:
632         as_snprintf(ListLine, STRINGSIZE, "=%x:%x.%d",
633                     (unsigned)((BAdr >> 16) & 255),
634                     (unsigned)((BAdr & 0x1f8) >> 3), (unsigned)(BAdr & 7));
635         break;
636       default:
637         as_snprintf(ListLine, STRINGSIZE, "=S:%x.%d",
638                     (unsigned)(((BAdr >> 3) & 0x3f) + 0x400),
639                     (unsigned)(BAdr & 7));
640         break;
641     }
642   }
643 }
644 
DecodeFixed(Word Code)645 static void DecodeFixed(Word Code)
646 {
647   if (ChkArgCnt(0, 0))
648   {
649     if (Hi(Code) != 0) BAsmCode[CodeLen++] = Hi(Code);
650     BAsmCode[CodeLen++] = Lo(Code);
651     if ((Code == RETICode) && (!SupAllowed)) WrError(ErrNum_PrivOrder);
652   }
653 }
654 
DecodeStack(Word Code)655 static void DecodeStack(Word Code)
656 {
657   Byte HReg;
658   Boolean OK;
659   Word Mask;
660   int i;
661 
662   if (ChkArgCnt(1, ArgCntMax))
663   {
664     HReg = 0xff; OK = True; Mask = 0;
665     for (i = 1; i <= ArgCnt; i++)
666       if (OK)
667       {
668         DecodeAdr(&ArgStr[i], MModMem);
669         if (AdrMode == ModNone) OK = False;
670         else switch (MemPart)
671         {
672           case 1:
673             if (HReg == 0)
674             {
675               WrError(ErrNum_InvAddrMode); OK = False;
676             }
677             else
678             {
679               HReg = 1; Mask |= (1 << AdrPart);
680             }
681             break;
682           case 6:
683             if (HReg != 0xff)
684             {
685               WrError(ErrNum_InvAddrMode); OK = False;
686             }
687             else
688               HReg = 0;
689             break;
690           default:
691             WrError(ErrNum_InvAddrMode); OK = False;
692         }
693       }
694     if (OK)
695     {
696       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
697       else if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
698       else if (HReg == 0)
699       {
700         BAsmCode[CodeLen++] = 0x87 + (OpSize << 3);
701         BAsmCode[CodeLen++] = Hi(Code) + AdrPart;
702         BAsmCode[CodeLen++] = AdrVals[0];
703       }
704       else if (Code < 0x2000)  /* POP(U): obere Register zuerst */
705       {
706         if (Hi(Mask) != 0)
707         {
708           BAsmCode[CodeLen++] = Lo(Code) + (OpSize << 3) + 0x40;
709           BAsmCode[CodeLen++]=Hi(Mask);
710         }
711         if (Lo(Mask) != 0)
712         {
713           BAsmCode[CodeLen++] = Lo(Code) + (OpSize << 3);
714           BAsmCode[CodeLen++] = Lo(Mask);
715         }
716         if ((OpSize == eSymbolSize16Bit) && (Code == 0x1027) && (Mask & 0x80)) WrError(ErrNum_Unpredictable);
717       }
718       else              /* PUSH(U): untere Register zuerst */
719       {
720         if (Lo(Mask) != 0)
721         {
722           BAsmCode[CodeLen++] = Lo(Code) + (OpSize << 3);
723           BAsmCode[CodeLen++] = Lo(Mask);
724         }
725         if (Hi(Mask) != 0)
726         {
727           BAsmCode[CodeLen++] = Lo(Code) + (OpSize << 3) + 0x40;
728           BAsmCode[CodeLen++] = Hi(Mask);
729         }
730       }
731     }
732   }
733 }
734 
DecodeALU(Word Index)735 static void DecodeALU(Word Index)
736 {
737   Byte HReg, HCnt, HVals[3], HMem;
738 
739   if (ChkArgCnt(2, 2))
740   {
741     DecodeAdr(&ArgStr[1], MModReg | MModMem);
742     switch (AdrMode)
743     {
744       case ModReg:
745         if (OpSize >= eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
746         else if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
747         else
748         {
749           HReg = AdrPart;
750           DecodeAdr(&ArgStr[2], MModMem | MModImm);
751           switch (AdrMode)
752           {
753             case ModMem:
754               BAsmCode[CodeLen++] = (Index << 4) + (OpSize << 3) + MemPart;
755               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
756               memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
757               CodeLen += AdrCnt;
758               if ((MemPart == 3) && ((HReg >> (1 - OpSize)) == AdrPart)) WrError(ErrNum_Unpredictable);
759               break;
760             case ModImm:
761               BAsmCode[CodeLen++] = 0x91 + (OpSize << 3);
762               BAsmCode[CodeLen++] = (HReg << 4) + Index;
763               memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
764               CodeLen += AdrCnt;
765               break;
766           }
767         }
768         break;
769       case ModMem:
770         HReg = AdrPart; HMem = MemPart; HCnt = AdrCnt;
771         memcpy(HVals, AdrVals, AdrCnt);
772         DecodeAdr(&ArgStr[2], MModReg | MModImm);
773         switch (AdrMode)
774         {
775           case ModReg:
776             if (OpSize == eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
777             else if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
778             else
779             {
780               BAsmCode[CodeLen++] = (Index << 4) + (OpSize << 3) + HMem;
781               BAsmCode[CodeLen++] = (AdrPart << 4) + 8 + HReg;
782               memcpy(BAsmCode + CodeLen, HVals, HCnt);
783               CodeLen += HCnt;
784               if ((HMem == 3) && ((AdrPart >> (1 - OpSize)) == HReg)) WrError(ErrNum_Unpredictable);
785             }
786             break;
787           case ModImm:
788             if (OpSize == eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
789             else if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
790             else
791             {
792               BAsmCode[CodeLen++] = 0x90 + HMem + (OpSize << 3);
793               BAsmCode[CodeLen++] = (HReg << 4) + Index;
794               memcpy(BAsmCode + CodeLen, HVals, HCnt);
795               memcpy(BAsmCode + CodeLen + HCnt, AdrVals, AdrCnt);
796               CodeLen += AdrCnt + HCnt;
797             }
798             break;
799         }
800         break;
801     }
802   }
803 }
804 
DecodeRegO(Word Index)805 static void DecodeRegO(Word Index)
806 {
807   RegOrder *Op = RegOrders + Index;
808 
809   if (ChkArgCnt(1, 1))
810   {
811     DecodeAdr(&ArgStr[1], MModReg);
812     switch (AdrMode)
813     {
814       case ModReg:
815         if ((Op->SizeMask & (1 << OpSize)) == 0) WrError(ErrNum_InvOpSize);
816         else
817         {
818           BAsmCode[CodeLen++] = 0x90 + (OpSize << 3);
819           BAsmCode[CodeLen++] = (AdrPart << 4) + Op->Code;
820         }
821         break;
822     }
823   }
824 }
825 
DecodeShift(Word Index)826 static void DecodeShift(Word Index)
827 {
828   Byte HReg, HMem;
829 
830   if (!ChkArgCnt(2, 2));
831   else if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
832   else
833   {
834     DecodeAdr(&ArgStr[1], MModReg);
835     switch (AdrMode)
836     {
837       case ModReg:
838         HReg = AdrPart; HMem = OpSize;
839         if (*ArgStr[2].Str == '#')
840           OpSize = (HMem == 2) ? eSymbolSize5Bit : eSymbolSize4Bit;
841         else
842           OpSize = eSymbolSize8Bit;
843         DecodeAdr(&ArgStr[2], MModReg | ((Index == 3) ? 0 : MModImm));
844         switch (AdrMode)
845         {
846           case ModReg:
847             BAsmCode[CodeLen++] = 0xc0 + ((HMem & 1) << 3) + Index;
848             if (HMem == 2) BAsmCode[CodeLen - 1] += 12;
849             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
850             if (Index == 3)
851             {
852               if (HMem == 2)
853               {
854                 if ((AdrPart >> 2) == (HReg >> 1)) WrError(ErrNum_Unpredictable);
855               }
856               else if ((AdrPart >> HMem) == HReg) WrError(ErrNum_Unpredictable);
857             }
858             break;
859           case ModImm:
860             BAsmCode[CodeLen++] = 0xd0 + ((HMem & 1) << 3) + Index;
861             if (HMem == 2)
862             {
863               BAsmCode[CodeLen - 1] += 12;
864               BAsmCode[CodeLen++] = ((HReg & 14) << 4) + AdrVals[0];
865             }
866             else
867               BAsmCode[CodeLen++] = (HReg << 4) + AdrVals[0];
868             break;
869         }
870         break;
871     }
872   }
873 }
874 
DecodeRotate(Word Code)875 static void DecodeRotate(Word Code)
876 {
877   Byte HReg, HMem;
878 
879   if (ChkArgCnt(2, 2))
880   {
881     DecodeAdr(&ArgStr[1], MModReg);
882     switch (AdrMode)
883     {
884       case ModReg:
885         if (OpSize == eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
886         else
887         {
888           HReg = AdrPart; HMem = OpSize; OpSize = eSymbolSize4Bit;
889           DecodeAdr(&ArgStr[2], MModImm);
890           switch (AdrMode)
891           {
892             case ModImm:
893               BAsmCode[CodeLen++] = Code + (HMem << 3);
894               BAsmCode[CodeLen++] = (HReg << 4) + AdrVals[0];
895               break;
896           }
897         }
898         break;
899     }
900   }
901 }
902 
DecodeRel(Word Index)903 static void DecodeRel(Word Index)
904 {
905   InvOrder *Op = RelOrders + Index;
906   LongWord Dest;
907   LongInt Dist;
908   tEvalResult EvalResult;
909 
910   if (!ChkArgCnt(1, 1));
911   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
912   else
913   {
914     Dest = GetBranchDest(&ArgStr[1], &EvalResult);
915     if (EvalResult.OK)
916     {
917       Dist = Dest - MkEven24(EProgCounter() + CodeLen + 2);
918       if (ChkShortEvenDist(&Dist, EvalResult.Flags))
919       {
920         BAsmCode[CodeLen++] = Op->Code;
921         BAsmCode[CodeLen++] = Dist & 0xff;
922       }
923       else if (!DoBranchExt) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
924       else if (Op->Inversion == 255)  /* BR */
925       {
926         Dist = Dest - MkEven24(EProgCounter() + CodeLen + 3);
927         if (ChkLongEvenDist(&Dist, &ArgStr[1], EvalResult.Flags))
928         {
929           Dist >>= 1;
930           BAsmCode[CodeLen++] = 0xd5;
931           BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
932           BAsmCode[CodeLen++] = Dist        & 0xff;
933         }
934       }
935       else
936       {
937         Dist = Dest - MkEven24(EProgCounter() + CodeLen + 5);
938         if (ChkLongEvenDist(&Dist, &ArgStr[1], EvalResult.Flags))
939         {
940           BAsmCode[CodeLen++] = RelOrders[Op->Inversion].Code;
941           BAsmCode[CodeLen++] = 2;
942           BAsmCode[CodeLen++] = 0xd5;
943           BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
944           BAsmCode[CodeLen++] = Dist        & 0xff;
945           if (Odd(EProgCounter() + CodeLen)) BAsmCode[CodeLen++] = 0;
946         }
947       }
948     }
949   }
950 }
951 
DecodeJBit(Word Index)952 static void DecodeJBit(Word Index)
953 {
954   LongInt BitAdr, Dist, odd;
955   LongWord Dest;
956   tEvalResult EvalResult;
957   InvOrder *Op = JBitOrders + Index;
958 
959   if (!ChkArgCnt(2, 2));
960   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
961   else if (DecodeBitAddr(&ArgStr[1], &BitAdr))
962   {
963     Dest = GetBranchDest(&ArgStr[2], &EvalResult);
964     if (EvalResult.OK)
965     {
966       Dist = Dest - MkEven24(EProgCounter() + CodeLen + 4);
967       if (ChkShortEvenDist(&Dist, EvalResult.Flags))
968       {
969         BAsmCode[CodeLen++] = 0x97;
970         BAsmCode[CodeLen++] = Op->Code + Hi(BitAdr);
971         BAsmCode[CodeLen++] = Lo(BitAdr);
972         BAsmCode[CodeLen++] = Dist & 0xff;
973       }
974       else if (!DoBranchExt) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[2]);
975       else if (Op->Inversion == 255)
976       {
977         odd = EProgCounter() & 1;
978         Dist = Dest - MkEven24(EProgCounter() + CodeLen + 9 + odd);
979         if (ChkLongEvenDist(&Dist, &ArgStr[2], EvalResult.Flags))
980         {
981           BAsmCode[CodeLen++] = 0x97;
982           BAsmCode[CodeLen++] = Op->Code + Hi(BitAdr);
983           BAsmCode[CodeLen++] = Lo(BitAdr);
984           BAsmCode[CodeLen++] = 1 + odd;
985           BAsmCode[CodeLen++] = 0xfe;
986           BAsmCode[CodeLen++] = 2 + odd;
987           if (odd) BAsmCode[CodeLen++] = 0;
988           BAsmCode[CodeLen++] = 0xd5;
989           BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
990           BAsmCode[CodeLen++] = Dist        & 0xff;
991           BAsmCode[CodeLen++] = 0;
992         }
993       }
994       else
995       {
996         Dist = Dest - MkEven24(EProgCounter() + CodeLen + 7);
997         if (ChkLongEvenDist(&Dist, &ArgStr[2], EvalResult.Flags))
998         {
999           BAsmCode[CodeLen++] = 0x97;
1000           BAsmCode[CodeLen++] = JBitOrders[Op->Inversion].Code + Hi(BitAdr);
1001           BAsmCode[CodeLen++] = Lo(BitAdr);
1002           BAsmCode[CodeLen++] = 2;
1003           BAsmCode[CodeLen++] = 0xd5;
1004           BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
1005           BAsmCode[CodeLen++] = Dist        & 0xff;
1006           if (Odd(EProgCounter() + CodeLen)) BAsmCode[CodeLen++] = 0;
1007         }
1008       }
1009     }
1010   }
1011 }
1012 
1013 
DecodeMOV(Word Index)1014 static void DecodeMOV(Word Index)
1015 {
1016   LongInt AdrLong;
1017   Byte HVals[3], HReg, HPart, HCnt;
1018   UNUSED(Index);
1019 
1020   if (!ChkArgCnt(2, 2));
1021   else if (!as_strcasecmp(ArgStr[1].Str, "C"))
1022   {
1023     if (DecodeBitAddr(&ArgStr[2], &AdrLong))
1024     {
1025       if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1026       else
1027       {
1028         ChkBitPage(AdrLong);
1029         BAsmCode[CodeLen++] = 0x08;
1030         BAsmCode[CodeLen++] = 0x20 + Hi(AdrLong);
1031         BAsmCode[CodeLen++] = Lo(AdrLong);
1032       }
1033     }
1034   }
1035   else if (!as_strcasecmp(ArgStr[2].Str, "C"))
1036   {
1037     if (DecodeBitAddr(&ArgStr[1], &AdrLong))
1038     {
1039       if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1040       else
1041       {
1042         ChkBitPage(AdrLong);
1043         BAsmCode[CodeLen++] = 0x08;
1044         BAsmCode[CodeLen++] = 0x30 + Hi(AdrLong);
1045         BAsmCode[CodeLen++] = Lo(AdrLong);
1046       }
1047     }
1048   }
1049   else if (!as_strcasecmp(ArgStr[1].Str, "USP"))
1050   {
1051     SetOpSize(eSymbolSize16Bit);
1052     DecodeAdr(&ArgStr[2], MModReg);
1053     if (AdrMode == ModReg)
1054     {
1055       BAsmCode[CodeLen++] = 0x98;
1056       BAsmCode[CodeLen++] = (AdrPart << 4) + 0x0f;
1057     }
1058   }
1059   else if (!as_strcasecmp(ArgStr[2].Str, "USP"))
1060   {
1061     SetOpSize(eSymbolSize16Bit);
1062     DecodeAdr(&ArgStr[1], MModReg);
1063     if (AdrMode == ModReg)
1064     {
1065       BAsmCode[CodeLen++] = 0x90;
1066       BAsmCode[CodeLen++] = (AdrPart << 4)+0x0f;
1067     }
1068   }
1069   else
1070   {
1071     DecodeAdr(&ArgStr[1], MModReg | MModMem);
1072     switch (AdrMode)
1073     {
1074       case ModReg:
1075         if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1076         else
1077         {
1078           HReg = AdrPart;
1079           DecodeAdr(&ArgStr[2], MModMem | MModImm);
1080           switch (AdrMode)
1081           {
1082             case ModMem:
1083               BAsmCode[CodeLen++] = 0x80 + (OpSize << 3) + MemPart;
1084               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1085               memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1086               CodeLen += AdrCnt;
1087               if ((MemPart == 3) && ((HReg >> (1 - OpSize)) == AdrPart)) WrError(ErrNum_Unpredictable);
1088               break;
1089             case ModImm:
1090               BAsmCode[CodeLen++] = 0x91 + (OpSize << 3);
1091               BAsmCode[CodeLen++] = 0x08 + (HReg << 4);
1092               memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1093               CodeLen += AdrCnt;
1094               break;
1095           }
1096         }
1097         break;
1098       case ModMem:
1099         memcpy(HVals, AdrVals, AdrCnt); HCnt = AdrCnt; HPart = MemPart; HReg = AdrPart;
1100         DecodeAdr(&ArgStr[2], MModReg | MModMem | MModImm);
1101         switch (AdrMode)
1102         {
1103           case ModReg:
1104             if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1105             else
1106             {
1107               BAsmCode[CodeLen++] = 0x80 + (OpSize << 3) + HPart;
1108               BAsmCode[CodeLen++] = (AdrPart << 4) + 0x08 + HReg;
1109               memcpy(BAsmCode + CodeLen, HVals, HCnt);
1110               CodeLen += HCnt;
1111               if ((HPart == 3) && ((AdrPart >> (1 - OpSize)) == HReg)) WrError(ErrNum_Unpredictable);
1112             }
1113             break;
1114           case ModMem:
1115             if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
1116             else if ((OpSize != eSymbolSize8Bit) & (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1117             else if ((HPart == 6) && (MemPart == 6))
1118             {
1119               BAsmCode[CodeLen++] = 0x97 + (OpSize << 3);
1120               BAsmCode[CodeLen++] = (HReg << 4)+AdrPart;
1121               BAsmCode[CodeLen++] = HVals[0];
1122               BAsmCode[CodeLen++] = AdrVals[0];
1123             }
1124             else if ((HPart == 6) && (MemPart == 2))
1125             {
1126               BAsmCode[CodeLen++] = 0xa0 + (OpSize << 3);
1127               BAsmCode[CodeLen++] = 0x80 + (AdrPart << 4) + HReg;
1128               BAsmCode[CodeLen++] = HVals[0];
1129             }
1130             else if ((HPart == 2) && (MemPart == 6))
1131             {
1132               BAsmCode[CodeLen++] = 0xa0 + (OpSize << 3);
1133               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1134               BAsmCode[CodeLen++] = AdrVals[0];
1135             }
1136             else if ((HPart == 3) && (MemPart == 3))
1137             {
1138               BAsmCode[CodeLen++] = 0x90 + (OpSize << 3);
1139               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1140               if (HReg == AdrPart) WrError(ErrNum_Unpredictable);
1141             }
1142             else
1143               WrError(ErrNum_InvAddrMode);
1144             break;
1145           case ModImm:
1146             if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
1147             else if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1148             else
1149             {
1150               BAsmCode[CodeLen++] = 0x90 + (OpSize << 3) + HPart;
1151               BAsmCode[CodeLen++] = 0x08 + (HReg << 4);
1152               memcpy(BAsmCode + CodeLen, HVals, HCnt);
1153               memcpy(BAsmCode + CodeLen + HCnt, AdrVals, AdrCnt);
1154               CodeLen += HCnt + AdrCnt;
1155             }
1156             break;
1157         }
1158         break;
1159     }
1160   }
1161 }
1162 
DecodeMOVC(Word Index)1163 static void DecodeMOVC(Word Index)
1164 {
1165   Byte HReg;
1166   UNUSED(Index);
1167 
1168   if (!ChkArgCnt(2, 2));
1169   else
1170   {
1171     if (!*AttrPart.Str && !as_strcasecmp(ArgStr[1].Str, "A")) OpSize = eSymbolSize8Bit;
1172     if (!as_strcasecmp(ArgStr[2].Str, "[A+DPTR]"))
1173     {
1174       if (as_strcasecmp(ArgStr[1].Str, "A")) WrError(ErrNum_InvAddrMode);
1175       else if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
1176       else
1177       {
1178         BAsmCode[CodeLen++] = 0x90;
1179         BAsmCode[CodeLen++] = 0x4e;
1180       }
1181     }
1182     else if (!as_strcasecmp(ArgStr[2].Str, "[A+PC]"))
1183     {
1184       if (as_strcasecmp(ArgStr[1].Str, "A")) WrError(ErrNum_InvAddrMode);
1185       else if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
1186       else
1187       {
1188         BAsmCode[CodeLen++] = 0x90;
1189         BAsmCode[CodeLen++] = 0x4c;
1190       }
1191     }
1192     else
1193     {
1194       DecodeAdr(&ArgStr[1], MModReg);
1195       if (AdrMode != ModNone)
1196       {
1197         if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1198         else
1199         {
1200           HReg = AdrPart;
1201           DecodeAdr(&ArgStr[2], MModMem);
1202           if (AdrMode != ModNone)
1203           {
1204             if (MemPart != 3) WrError(ErrNum_InvAddrMode);
1205             else
1206             {
1207               BAsmCode[CodeLen++] = 0x80 + (OpSize << 3);
1208               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1209               if ((MemPart == 3) && ((HReg >> (1 - OpSize)) == AdrPart)) WrError(ErrNum_Unpredictable);
1210             }
1211           }
1212         }
1213       }
1214     }
1215   }
1216 }
1217 
DecodeMOVX(Word Index)1218 static void DecodeMOVX(Word Index)
1219 {
1220   Byte HReg;
1221   UNUSED(Index);
1222 
1223   if (!ChkArgCnt(2, 2));
1224   else
1225   {
1226     DecodeAdr(&ArgStr[1], MModMem);
1227     if (AdrMode == ModMem)
1228     {
1229       switch (MemPart)
1230       {
1231         case 1:
1232           if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1233           else
1234           {
1235             HReg = AdrPart; DecodeAdr(&ArgStr[2], MModMem);
1236             if (AdrMode == ModMem)
1237             {
1238               if (MemPart != 2) WrError(ErrNum_InvAddrMode);
1239               else
1240               {
1241                 BAsmCode[CodeLen++] = 0xa7 + (OpSize << 3);
1242                 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1243               }
1244             }
1245           }
1246           break;
1247         case 2:
1248           HReg = AdrPart; DecodeAdr(&ArgStr[2], MModReg);
1249           if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1250           else
1251           {
1252             BAsmCode[CodeLen++] = 0xa7 + (OpSize << 3);
1253             BAsmCode[CodeLen++] = 0x08 + (AdrPart << 4) + HReg;
1254           }
1255           break;
1256         default:
1257           WrError(ErrNum_InvAddrMode);
1258       }
1259     }
1260   }
1261 }
1262 
DecodeXCH(Word Index)1263 static void DecodeXCH(Word Index)
1264 {
1265   Byte HReg, HPart, HVals[3];
1266   UNUSED(Index);
1267 
1268   if (ChkArgCnt(2, 2))
1269   {
1270     DecodeAdr(&ArgStr[1], MModMem);
1271     if (AdrMode == ModMem)
1272     {
1273       switch (MemPart)
1274       {
1275         case 1:
1276           HReg = AdrPart; DecodeAdr(&ArgStr[2], MModMem);
1277           if (AdrMode == ModMem)
1278           {
1279             if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize8Bit)) WrError(ErrNum_InvOpSize);
1280             else switch (MemPart)
1281             {
1282               case 1:
1283                 BAsmCode[CodeLen++] = 0x60 + (OpSize << 3);
1284                 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1285                 if (HReg == AdrPart) WrError(ErrNum_Unpredictable);
1286                 break;
1287               case 2:
1288                 BAsmCode[CodeLen++] = 0x50 + (OpSize << 3);
1289                 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1290                 break;
1291               case 6:
1292                 BAsmCode[CodeLen++] = 0xa0 + (OpSize << 3);
1293                 BAsmCode[CodeLen++] = 0x08 + (HReg << 4) + AdrPart;
1294                 BAsmCode[CodeLen++] = AdrVals[0];
1295                 break;
1296               default:
1297                 WrError(ErrNum_InvAddrMode);
1298             }
1299           }
1300           break;
1301         case 2:
1302           HReg = AdrPart;
1303           DecodeAdr(&ArgStr[2], MModReg);
1304           if (AdrMode == ModReg)
1305           {
1306             if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1307             else
1308             {
1309               BAsmCode[CodeLen++] = 0x50 + (OpSize << 3);
1310               BAsmCode[CodeLen++] = (AdrPart << 4) + HReg;
1311             }
1312           }
1313           break;
1314         case 6:
1315           HPart = AdrPart; HVals[0] = AdrVals[0];
1316           DecodeAdr(&ArgStr[2], MModReg);
1317           if (AdrMode == ModReg)
1318           {
1319             if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1320             else
1321             {
1322               BAsmCode[CodeLen++] = 0xa0 + (OpSize << 3);
1323               BAsmCode[CodeLen++] = 0x08 + (AdrPart << 4) + HPart;
1324               BAsmCode[CodeLen++] = HVals[0];
1325             }
1326           }
1327           break;
1328         default:
1329           WrError(ErrNum_InvAddrMode);
1330       }
1331     }
1332   }
1333 }
1334 
DecodeADDSMOVS(Word Index)1335 static void DecodeADDSMOVS(Word Index)
1336 {
1337   Byte HReg;
1338   tSymbolSize HSize;
1339 
1340   if (ChkArgCnt(2, 2))
1341   {
1342     HSize = OpSize;
1343     OpSize = eSymbolSizeSigned4Bit;
1344     DecodeAdr(&ArgStr[2], MModImm);
1345     switch (AdrMode)
1346     {
1347       case ModImm:
1348         HReg = AdrVals[0]; OpSize = HSize;
1349         DecodeAdr(&ArgStr[1], MModMem);
1350         switch (AdrMode)
1351         {
1352           case ModMem:
1353             if (OpSize == eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
1354             else if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
1355             else
1356             {
1357                BAsmCode[CodeLen++] = 0xa0 + (Index << 4) + (OpSize << 3) + MemPart;
1358                BAsmCode[CodeLen++] = (AdrPart << 4) + (HReg & 0x0f);
1359                memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1360                CodeLen += AdrCnt;
1361             }
1362             break;
1363         }
1364         break;
1365     }
1366   }
1367 }
1368 
DecodeDIV(Word Index)1369 static void DecodeDIV(Word Index)
1370 {
1371   Byte HReg;
1372   UNUSED(Index);
1373 
1374   if (ChkArgCnt(2, 2))
1375   {
1376     DecodeAdr(&ArgStr[1], MModReg);
1377     if (AdrMode == ModReg)
1378     {
1379       if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
1380       else
1381       {
1382         HReg = AdrPart; OpSize--; DecodeAdr(&ArgStr[2], MModReg | MModImm);
1383         switch (AdrMode)
1384         {
1385           case ModReg:
1386             BAsmCode[CodeLen++] = 0xe7 + (OpSize << 3);
1387             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1388             break;
1389           case ModImm:
1390             BAsmCode[CodeLen++] = 0xe8 + OpSize;
1391             BAsmCode[CodeLen++] = (HReg << 4) + 0x0b - (OpSize << 1);
1392             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1393             CodeLen += AdrCnt;
1394             break;
1395         }
1396       }
1397     }
1398   }
1399 }
1400 
DecodeDIVU(Word Index)1401 static void DecodeDIVU(Word Index)
1402 {
1403   Byte HReg;
1404   int z;
1405   UNUSED(Index);
1406 
1407   if (ChkArgCnt(2, 2))
1408   {
1409     DecodeAdr(&ArgStr[1], MModReg);
1410     if (AdrMode == ModReg)
1411     {
1412       if ((OpSize == eSymbolSize8Bit) && (AdrPart & 1)) WrError(ErrNum_InvReg);
1413       else
1414       {
1415         HReg = AdrPart; z = OpSize; if (OpSize != eSymbolSize8Bit) OpSize--;
1416         DecodeAdr(&ArgStr[2], MModReg | MModImm);
1417         switch (AdrMode)
1418         {
1419           case ModReg:
1420             BAsmCode[CodeLen++] = 0xe1 + (z << 2);
1421             if (z == 2) BAsmCode[CodeLen - 1] += 4;
1422             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1423             break;
1424           case ModImm:
1425             BAsmCode[CodeLen++] = 0xe8 + Ord(z == 2);
1426             BAsmCode[CodeLen++] = (HReg << 4) + 0x01 + (Ord(z == 1) << 1);
1427             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1428             CodeLen += AdrCnt;
1429             break;
1430         }
1431       }
1432     }
1433   }
1434 }
1435 
DecodeMUL(Word Index)1436 static void DecodeMUL(Word Index)
1437 {
1438   Byte HReg;
1439   UNUSED(Index);
1440 
1441   if (ChkArgCnt(2, 2))
1442   {
1443     DecodeAdr(&ArgStr[1], MModReg);
1444     if (AdrMode == ModReg)
1445     {
1446       if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
1447       else if (AdrPart & 1) WrError(ErrNum_InvReg);
1448       else
1449       {
1450         HReg = AdrPart; DecodeAdr(&ArgStr[2], MModReg | MModImm);
1451         switch (AdrMode)
1452         {
1453           case ModReg:
1454             BAsmCode[CodeLen++] = 0xe6;
1455             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1456             break;
1457           case ModImm:
1458             BAsmCode[CodeLen++] = 0xe9;
1459             BAsmCode[CodeLen++] = (HReg << 4) + 0x08;
1460             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1461             CodeLen += AdrCnt;
1462             break;
1463         }
1464       }
1465     }
1466   }
1467 }
1468 
DecodeMULU(Word Index)1469 static void DecodeMULU(Word Index)
1470 {
1471   Byte HReg;
1472   UNUSED(Index);
1473 
1474   if (ChkArgCnt(2, 2))
1475   {
1476     DecodeAdr(&ArgStr[1], MModReg);
1477     if (AdrMode == ModReg)
1478     {
1479       if (AdrPart & 1) WrError(ErrNum_InvReg);
1480       else
1481       {
1482         HReg = AdrPart;
1483         DecodeAdr(&ArgStr[2], MModReg | MModImm);
1484         switch (AdrMode)
1485         {
1486           case ModReg:
1487             BAsmCode[CodeLen++] = 0xe0 + (OpSize << 2);
1488             BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1489             break;
1490           case ModImm:
1491             BAsmCode[CodeLen++] = 0xe8 + OpSize;
1492             BAsmCode[CodeLen++] = (HReg << 4);
1493             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1494             CodeLen += AdrCnt;
1495             break;
1496         }
1497       }
1498     }
1499   }
1500 }
1501 
DecodeLEA(Word Index)1502 static void DecodeLEA(Word Index)
1503 {
1504   Byte HReg;
1505   UNUSED(Index);
1506 
1507   if (ChkArgCnt(2, 2))
1508   {
1509     DecodeAdr(&ArgStr[1], MModReg);
1510     if (AdrMode == ModReg)
1511     {
1512       if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
1513       else
1514       {
1515         HReg = AdrPart;
1516         DecodeAdrIndirect(&ArgStr[2], MModMem);
1517         if (AdrMode == ModMem)
1518           switch (MemPart)
1519           {
1520             case 4:
1521             case 5:
1522               BAsmCode[CodeLen++] = 0x20 + (MemPart << 3);
1523               BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1524               memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1525               CodeLen += AdrCnt;
1526               break;
1527             default:
1528               WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
1529           }
1530       }
1531     }
1532   }
1533 }
1534 
DecodeANLORL(Word Index)1535 static void DecodeANLORL(Word Index)
1536 {
1537   if (!ChkArgCnt(2, 2));
1538   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1539   else if (as_strcasecmp(ArgStr[1].Str, "C")) WrError(ErrNum_InvAddrMode);
1540   else
1541   {
1542     Byte Invert = 0;
1543     LongInt AdrLong;
1544     Boolean Result;
1545 
1546     if (*ArgStr[2].Str == '/')
1547     {
1548       tStrComp Comp;
1549 
1550       StrCompRefRight(&Comp, &ArgStr[2], 1);
1551       Result = DecodeBitAddr(&Comp, &AdrLong);
1552       Invert = 1;
1553     }
1554     else
1555       Result = DecodeBitAddr(&ArgStr[2], &AdrLong);
1556     if (Result)
1557     {
1558       ChkBitPage(AdrLong);
1559       BAsmCode[CodeLen++] = 0x08;
1560       BAsmCode[CodeLen++] = 0x40 | (Index << 5) | (Ord(Invert) << 4) | (Hi(AdrLong) & 3);
1561       BAsmCode[CodeLen++] = Lo(AdrLong);
1562     }
1563   }
1564 }
1565 
DecodeCLRSETB(Word Index)1566 static void DecodeCLRSETB(Word Index)
1567 {
1568   LongInt AdrLong;
1569 
1570   if (!ChkArgCnt(1, 1));
1571   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1572   else if (DecodeBitAddr(&ArgStr[1], &AdrLong))
1573   {
1574     ChkBitPage(AdrLong);
1575     BAsmCode[CodeLen++] = 0x08;
1576     BAsmCode[CodeLen++] = (Index << 4) + (Hi(AdrLong) & 3);
1577     BAsmCode[CodeLen++] = Lo(AdrLong);
1578   }
1579 }
1580 
DecodeTRAP(Word Index)1581 static void DecodeTRAP(Word Index)
1582 {
1583   UNUSED(Index);
1584 
1585   if (!ChkArgCnt(1, 1));
1586   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1587   else
1588   {
1589     OpSize = eSymbolSize4Bit;
1590     DecodeAdr(&ArgStr[1], MModImm);
1591     switch (AdrMode)
1592     {
1593       case ModImm:
1594         BAsmCode[CodeLen++] = 0xd6;
1595         BAsmCode[CodeLen++] = 0x30 + AdrVals[0];
1596         break;
1597     }
1598   }
1599 }
1600 
DecodeCALL(Word Index)1601 static void DecodeCALL(Word Index)
1602 {
1603   UNUSED(Index);
1604 
1605   if (!ChkArgCnt(1, 1));
1606   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1607   else if (*ArgStr[1].Str == '[')
1608   {
1609     DecodeAdr(&ArgStr[1], MModMem);
1610     if (AdrMode != ModNone)
1611     {
1612       if (MemPart != 2) WrError(ErrNum_InvAddrMode);
1613       else
1614       {
1615         BAsmCode[CodeLen++] = 0xc6;
1616         BAsmCode[CodeLen++] = AdrPart;
1617       }
1618     }
1619   }
1620   else
1621   {
1622     tEvalResult EvalResult;
1623     LongWord Dest = GetBranchDest(&ArgStr[1], &EvalResult);
1624 
1625     if (EvalResult.OK)
1626     {
1627       LongInt Dist = Dest - MkEven24(EProgCounter() + CodeLen + 3);
1628 
1629       if (ChkLongEvenDist(&Dist, &ArgStr[1], EvalResult.Flags))
1630       {
1631         BAsmCode[CodeLen++] = 0xc5;
1632         BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
1633         BAsmCode[CodeLen++] = Dist & 0xff;
1634       }
1635     }
1636   }
1637 }
1638 
DecodeJMP(Word Index)1639 static void DecodeJMP(Word Index)
1640 {
1641   UNUSED(Index);
1642 
1643   if (!ChkArgCnt(1, 1));
1644   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1645   else if (!as_strcasecmp(ArgStr[1].Str, "[A+DPTR]"))
1646   {
1647     BAsmCode[CodeLen++] = 0xd6;
1648     BAsmCode[CodeLen++] = 0x46;
1649   }
1650   else if (!strncmp(ArgStr[1].Str, "[[", 2))
1651   {
1652     tStrComp Comp;
1653 
1654     ArgStr[1].Str[strlen(ArgStr[1].Str) - 1] = '\0';
1655     ArgStr[1].Pos.Len--;
1656     StrCompRefRight(&Comp, &ArgStr[1], 1);
1657     DecodeAdr(&Comp, MModMem);
1658     if (AdrMode == ModMem)
1659      switch (MemPart)
1660      {
1661        case 3:
1662          BAsmCode[CodeLen++] = 0xd6;
1663          BAsmCode[CodeLen++] = 0x60 + AdrPart;
1664          break;
1665        default:
1666          WrError(ErrNum_InvAddrMode);
1667      }
1668   }
1669   else if (*ArgStr[1].Str == '[')
1670   {
1671     DecodeAdr(&ArgStr[1], MModMem);
1672     if (AdrMode == ModMem)
1673       switch (MemPart)
1674       {
1675         case 2:
1676           BAsmCode[CodeLen++] = 0xd6;
1677           BAsmCode[CodeLen++] = 0x70 + AdrPart;
1678           break;
1679         default:
1680           WrError(ErrNum_InvAddrMode);
1681       }
1682   }
1683   else
1684   {
1685     tEvalResult EvalResult;
1686     LongWord Dest = GetBranchDest(&ArgStr[1], &EvalResult);
1687 
1688     if (EvalResult.OK)
1689     {
1690       LongInt Dist = Dest - MkEven24(EProgCounter() + CodeLen + 3);
1691 
1692       if (ChkLongEvenDist(&Dist, &ArgStr[1], EvalResult.Flags))
1693       {
1694         BAsmCode[CodeLen++] = 0xd5;
1695         BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
1696         BAsmCode[CodeLen++] = Dist & 0xff;
1697       }
1698     }
1699   }
1700 }
1701 
DecodeCJNE(Word Index)1702 static void DecodeCJNE(Word Index)
1703 {
1704   Byte HReg;
1705   UNUSED(Index);
1706 
1707   if (ChkArgCnt(3, 3))
1708   {
1709     tEvalResult EvalResult;
1710     LongWord Dest = GetBranchDest(&ArgStr[3], &EvalResult);
1711 
1712     if (EvalResult.OK)
1713     {
1714       EvalResult.OK = False; HReg = 0;
1715       DecodeAdr(&ArgStr[1], MModMem);
1716       if (AdrMode == ModMem)
1717       {
1718         switch (MemPart)
1719         {
1720           case 1:
1721             if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1722             else
1723             {
1724               HReg = AdrPart; DecodeAdr(&ArgStr[2], MModMem | MModImm);
1725               switch (AdrMode)
1726               {
1727                 case ModMem:
1728                   if (MemPart != 6) WrError(ErrNum_InvAddrMode);
1729                   else
1730                   {
1731                     BAsmCode[CodeLen] = 0xe2 + (OpSize << 3);
1732                     BAsmCode[CodeLen + 1] = (HReg << 4) + AdrPart;
1733                     BAsmCode[CodeLen + 2] = AdrVals[0];
1734                     HReg=CodeLen + 3;
1735                     CodeLen += 4; EvalResult.OK = True;
1736                   }
1737                   break;
1738                 case ModImm:
1739                   BAsmCode[CodeLen] = 0xe3 + (OpSize << 3);
1740                   BAsmCode[CodeLen + 1] = HReg << 4;
1741                   HReg=CodeLen + 2;
1742                   memcpy(BAsmCode + CodeLen + 3, AdrVals, AdrCnt);
1743                   CodeLen += 3 + AdrCnt; EvalResult.OK = True;
1744                   break;
1745               }
1746             }
1747             break;
1748           case 2:
1749             if ((OpSize != eSymbolSizeUnknown) && (OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1750             else
1751             {
1752               HReg = AdrPart; DecodeAdr(&ArgStr[2], MModImm);
1753               if (AdrMode == ModImm)
1754               {
1755                 BAsmCode[CodeLen] = 0xe3 + (OpSize << 3);
1756                 BAsmCode[CodeLen + 1] = (HReg << 4)+8;
1757                 HReg = CodeLen + 2;
1758                 memcpy(BAsmCode + CodeLen + 3, AdrVals, AdrCnt);
1759                 CodeLen += 3 + AdrCnt; EvalResult.OK = True;
1760               }
1761             }
1762             break;
1763           default:
1764             WrError(ErrNum_InvAddrMode);
1765         }
1766       }
1767       if (EvalResult.OK)
1768       {
1769         LongInt Dist = Dest - MkEven24(EProgCounter() + CodeLen);
1770 
1771         EvalResult.OK = False;
1772         if (ChkShortEvenDist(&Dist, EvalResult.Flags))
1773         {
1774           BAsmCode[HReg] = Dist & 0xff;
1775           EvalResult.OK = True;
1776         }
1777         else if (!DoBranchExt) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[3]);
1778         else
1779         {
1780           LongWord odd = (EProgCounter() + CodeLen) & 1;
1781 
1782           Dist = Dest - MkEven24(EProgCounter() + CodeLen + 5 + odd);
1783           if (ChkLongEvenDist(&Dist, &ArgStr[3], EvalResult.Flags))
1784           {
1785             BAsmCode[HReg] = 1 + odd;
1786             BAsmCode[CodeLen++] = 0xfe;
1787             BAsmCode[CodeLen++] = 2 + odd;
1788             if (odd) BAsmCode[CodeLen++] = 0;
1789             BAsmCode[CodeLen++] = 0xd5;
1790             BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
1791             BAsmCode[CodeLen++] = Dist        & 0xff;
1792             BAsmCode[CodeLen++] = 0;
1793             EvalResult.OK = True;
1794           }
1795         }
1796       }
1797       if (!EvalResult.OK)
1798         CodeLen = 0;
1799     }
1800   }
1801 }
1802 
DecodeDJNZ(Word Index)1803 static void DecodeDJNZ(Word Index)
1804 {
1805   Byte HReg;
1806   UNUSED(Index);
1807 
1808   if (ChkArgCnt(2, 2))
1809   {
1810     tEvalResult EvalResult;
1811     LongInt Dest = GetBranchDest(&ArgStr[2], &EvalResult);
1812 
1813     if (EvalResult.OK)
1814     {
1815       HReg = 0;
1816       DecodeAdr(&ArgStr[1], MModMem);
1817       EvalResult.OK = False; DecodeAdr(&ArgStr[1], MModMem);
1818       if (AdrMode == ModMem)
1819         switch (MemPart)
1820         {
1821           case 1:
1822             if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1823             else
1824             {
1825               BAsmCode[CodeLen] = 0x87 + (OpSize << 3);
1826               BAsmCode[CodeLen + 1] = (AdrPart << 4) + 0x08;
1827               HReg=CodeLen + 2;
1828               CodeLen += 3; EvalResult.OK = True;
1829             }
1830             break;
1831           case 6:
1832             if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
1833             else if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1834             else
1835             {
1836               BAsmCode[CodeLen] = 0xe2 + (OpSize << 3);
1837               BAsmCode[CodeLen+1] = 0x08 + AdrPart;
1838               BAsmCode[CodeLen+2] = AdrVals[0];
1839               HReg=CodeLen + 3;
1840               CodeLen += 4; EvalResult.OK = True;
1841             }
1842             break;
1843           default:
1844             WrError(ErrNum_InvAddrMode);
1845         }
1846       if (EvalResult.OK)
1847       {
1848         LongInt Dist = Dest - MkEven24(EProgCounter() + CodeLen);
1849 
1850         EvalResult.OK = False;
1851         if (ChkShortEvenDist(&Dist, EvalResult.Flags))
1852         {
1853           BAsmCode[HReg] = Dist & 0xff;
1854           EvalResult.OK = True;
1855         }
1856         else if (!DoBranchExt) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[2]);
1857         else
1858         {
1859           LongWord odd = (EProgCounter() + CodeLen) & 1;
1860 
1861           Dist = Dest - MkEven24(EProgCounter() + CodeLen + 5 + odd);
1862           if (ChkLongEvenDist(&Dist, &ArgStr[2], EvalResult.Flags))
1863           {
1864             BAsmCode[HReg] = 1 + odd;
1865             BAsmCode[CodeLen++] = 0xfe;
1866             BAsmCode[CodeLen++] = 2 + odd;
1867             if (odd) BAsmCode[CodeLen++] = 0;
1868             BAsmCode[CodeLen++] = 0xd5;
1869             BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
1870             BAsmCode[CodeLen++] = Dist        & 0xff;
1871             BAsmCode[CodeLen++] = 0;
1872             EvalResult.OK = True;
1873           }
1874         }
1875       }
1876       if (!EvalResult.OK)
1877         CodeLen = 0;
1878     }
1879   }
1880 }
1881 
DecodeFCALLJMP(Word Index)1882 static void DecodeFCALLJMP(Word Index)
1883 {
1884   if (!ChkArgCnt(1, 1));
1885   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1886   else
1887   {
1888     tEvalResult EvalResult;
1889     LongInt AdrLong = GetBranchDest(&ArgStr[1], &EvalResult);
1890     if (EvalResult.OK)
1891     {
1892       BAsmCode[CodeLen++] = 0xc4 | (Index << 4);
1893       BAsmCode[CodeLen++] = (AdrLong >> 8) & 0xff;
1894       BAsmCode[CodeLen++] = AdrLong & 0xff;
1895       BAsmCode[CodeLen++] = (AdrLong >> 16) & 0xff;
1896     }
1897   }
1898 }
1899 
IsRealDef(void)1900 static Boolean IsRealDef(void)
1901 {
1902   switch (*OpPart.Str)
1903   {
1904     case 'P':
1905       return Memo("PORT");
1906     case 'B':
1907       return Memo("BIT");
1908     case 'R':
1909       return Memo("REG");
1910     default:
1911       return FALSE;
1912   }
1913 }
1914 
ForceAlign(void)1915 static void ForceAlign(void)
1916 {
1917   if (EProgCounter() & 1)
1918   {
1919     BAsmCode[0] = NOPCode; CodeLen = 1;
1920   }
1921 }
1922 
DecodeAttrPart_XA(void)1923 static Boolean DecodeAttrPart_XA(void)
1924 {
1925   if (*AttrPart.Str)
1926     switch (as_toupper(*AttrPart.Str))
1927     {
1928       case 'B': AttrPartOpSize = eSymbolSize8Bit; break;
1929       case 'W': AttrPartOpSize = eSymbolSize16Bit; break;
1930       case 'D': AttrPartOpSize = eSymbolSize32Bit; break;
1931       default : WrStrErrorPos(ErrNum_UndefAttr, &AttrPart); return False;
1932     }
1933   return True;
1934 }
1935 
MakeCode_XA(void)1936 static void MakeCode_XA(void)
1937 {
1938   CodeLen = 0; DontPrint = False; OpSize = eSymbolSizeUnknown;
1939 
1940    /* Operandengroesse */
1941 
1942   if (*AttrPart.Str)
1943     SetOpSize(AttrPartOpSize);
1944 
1945   /* Labels muessen auf geraden Adressen liegen */
1946 
1947   if ( (ActPC == SegCode) && (!IsRealDef()) &&
1948        ((*LabPart.Str != '\0') ||((ArgCnt == 1) && (!strcmp(ArgStr[1].Str, "$")))) )
1949   {
1950     ForceAlign();
1951     if (*LabPart.Str != '\0')
1952       EnterIntSymbol(&LabPart, EProgCounter() + CodeLen, ActPC, False);
1953   }
1954 
1955   if (DecodeMoto16Pseudo(OpSize, False)) return;
1956   if (DecodeIntelPseudo(False)) return;
1957 
1958   /* zu ignorierendes */
1959 
1960   if (Memo("")) return;
1961 
1962   /* via Tabelle suchen */
1963 
1964   if (!LookupInstTable(InstTable, OpPart.Str))
1965     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
1966 }
1967 
1968 /*-------------------------------------------------------------------------*/
1969 /* Codetabellenverwaltung */
1970 
AddFixed(const char * NName,Word NCode)1971 static void AddFixed(const char *NName, Word NCode)
1972 {
1973   AddInstTable(InstTable, NName, NCode, DecodeFixed);
1974 }
1975 
AddJBit(const char * NName,Word NCode)1976 static void AddJBit(const char *NName, Word NCode)
1977 {
1978   if (InstrZ >= JBitOrderCnt) exit(255);
1979   JBitOrders[InstrZ].Name = NName;
1980   JBitOrders[InstrZ].Inversion = 255;
1981   JBitOrders[InstrZ].Code = NCode;
1982   AddInstTable(InstTable, NName, InstrZ++, DecodeJBit);
1983 }
1984 
AddStack(const char * NName,Word NCode)1985 static void AddStack(const char *NName, Word NCode)
1986 {
1987   AddInstTable(InstTable, NName, NCode, DecodeStack);
1988 }
1989 
AddReg(const char * NName,Byte NMask,Byte NCode)1990 static void AddReg(const char *NName, Byte NMask, Byte NCode)
1991 {
1992   if (InstrZ >= RegOrderCnt) exit(255);
1993   RegOrders[InstrZ].Code = NCode;
1994   RegOrders[InstrZ].SizeMask = NMask;
1995   AddInstTable(InstTable, NName, InstrZ++, DecodeRegO);
1996 }
1997 
AddRotate(const char * NName,Word NCode)1998 static void AddRotate(const char *NName, Word NCode)
1999 {
2000   AddInstTable(InstTable, NName, NCode, DecodeRotate);
2001 }
2002 
AddRel(const char * NName,Word NCode)2003 static void AddRel(const char *NName, Word NCode)
2004 {
2005   if (InstrZ >= RelOrderCount) exit(255);
2006   RelOrders[InstrZ].Name = NName;
2007   RelOrders[InstrZ].Inversion = 255;
2008   RelOrders[InstrZ].Code = NCode;
2009   AddInstTable(InstTable, NName, InstrZ++, DecodeRel);
2010 }
2011 
SetInv(const char * Name1,const char * Name2,InvOrder * Orders)2012 static void SetInv(const char *Name1, const char *Name2, InvOrder *Orders)
2013 {
2014   InvOrder *Order1, *Order2;
2015 
2016   for (Order1 = Orders; strcmp(Order1->Name, Name1); Order1++);
2017   for (Order2 = Orders; strcmp(Order2->Name, Name2); Order2++);
2018   Order1->Inversion = Order2 - Orders;
2019   Order2->Inversion = Order1 - Orders;
2020 }
2021 
InitFields(void)2022 static void InitFields(void)
2023 {
2024   InstTable = CreateInstTable(201);
2025   AddInstTable(InstTable, "MOV"  , 0, DecodeMOV);
2026   AddInstTable(InstTable, "MOVC" , 0, DecodeMOVC);
2027   AddInstTable(InstTable, "MOVX" , 0, DecodeMOVX);
2028   AddInstTable(InstTable, "XCH"  , 0, DecodeXCH);
2029   AddInstTable(InstTable, "ADDS" , 0, DecodeADDSMOVS);
2030   AddInstTable(InstTable, "MOVS" , 1, DecodeADDSMOVS);
2031   AddInstTable(InstTable, "DIV"  , 0, DecodeDIV);
2032   AddInstTable(InstTable, "DIVU" , 0, DecodeDIVU);
2033   AddInstTable(InstTable, "MUL"  , 0, DecodeMUL);
2034   AddInstTable(InstTable, "MULU" , 0, DecodeMULU);
2035   AddInstTable(InstTable, "LEA"  , 0, DecodeLEA);
2036   AddInstTable(InstTable, "ANL"  , 0, DecodeANLORL);
2037   AddInstTable(InstTable, "ORL"  , 1, DecodeANLORL);
2038   AddInstTable(InstTable, "CLR"  , 0, DecodeCLRSETB);
2039   AddInstTable(InstTable, "SETB" , 1, DecodeCLRSETB);
2040   AddInstTable(InstTable, "TRAP" , 0, DecodeTRAP);
2041   AddInstTable(InstTable, "CALL" , 0, DecodeCALL);
2042   AddInstTable(InstTable, "JMP"  , 0, DecodeJMP);
2043   AddInstTable(InstTable, "CJNE" , 0, DecodeCJNE);
2044   AddInstTable(InstTable, "DJNZ" , 0, DecodeDJNZ);
2045   AddInstTable(InstTable, "FCALL", 0, DecodeFCALLJMP);
2046   AddInstTable(InstTable, "FJMP" , 1, DecodeFCALLJMP);
2047   AddInstTable(InstTable, "PORT" , 0, DecodePORT);
2048   AddInstTable(InstTable, "BIT"  , 0, DecodeBIT);
2049   AddInstTable(InstTable, "REG"  , 0, CodeREG);
2050 
2051   AddFixed("NOP"  , 0x0000);
2052   AddFixed("RET"  , 0xd680);
2053   AddFixed("RETI" , RETICode);
2054   AddFixed("BKPT" , 0x00ff);
2055   AddFixed("RESET", 0xd610);
2056 
2057   JBitOrders = (InvOrder *) malloc(sizeof(InvOrder) * JBitOrderCnt); InstrZ = 0;
2058   AddJBit("JB"  , 0x80);
2059   AddJBit("JBC" , 0xc0);
2060   AddJBit("JNB" , 0xa0);
2061   SetInv("JB", "JNB", JBitOrders);
2062 
2063   AddStack("POP"  , 0x1027);
2064   AddStack("POPU" , 0x0037);
2065   AddStack("PUSH" , 0x3007);
2066   AddStack("PUSHU", 0x2017);
2067 
2068   InstrZ = 0;
2069   AddInstTable(InstTable, "ADD" , InstrZ++, DecodeALU);
2070   AddInstTable(InstTable, "ADDC", InstrZ++, DecodeALU);
2071   AddInstTable(InstTable, "SUB" , InstrZ++, DecodeALU);
2072   AddInstTable(InstTable, "SUBB", InstrZ++, DecodeALU);
2073   AddInstTable(InstTable, "CMP" , InstrZ++, DecodeALU);
2074   AddInstTable(InstTable, "AND" , InstrZ++, DecodeALU);
2075   AddInstTable(InstTable, "OR"  , InstrZ++, DecodeALU);
2076   AddInstTable(InstTable, "XOR" , InstrZ++, DecodeALU);
2077 
2078   RegOrders = (RegOrder *) malloc(sizeof(RegOrder) * RegOrderCnt); InstrZ = 0;
2079   AddReg("NEG" , 3, 0x0b);
2080   AddReg("CPL" , 3, 0x0a);
2081   AddReg("SEXT", 3, 0x09);
2082   AddReg("DA"  , 1, 0x08);
2083 
2084   AddInstTable(InstTable, "LSR" , 0, DecodeShift);
2085   AddInstTable(InstTable, "ASL" , 1, DecodeShift);
2086   AddInstTable(InstTable, "ASR" , 2, DecodeShift);
2087   AddInstTable(InstTable, "NORM", 3, DecodeShift);
2088 
2089   AddRotate("RR" , 0xb0); AddRotate("RL" , 0xd3);
2090   AddRotate("RRC", 0xb7); AddRotate("RLC", 0xd7);
2091 
2092   RelOrders = (InvOrder *) malloc(sizeof(InvOrder) * RelOrderCount); InstrZ = 0;
2093   AddRel("BCC", 0xf0); AddRel("BCS", 0xf1); AddRel("BNE", 0xf2);
2094   AddRel("BEQ", 0xf3); AddRel("BNV", 0xf4); AddRel("BOV", 0xf5);
2095   AddRel("BPL", 0xf6); AddRel("BMI", 0xf7); AddRel("BG" , 0xf8);
2096   AddRel("BL" , 0xf9); AddRel("BGE", 0xfa); AddRel("BLT", 0xfb);
2097   AddRel("BGT", 0xfc); AddRel("BLE", 0xfd); AddRel("BR" , 0xfe);
2098   AddRel("JZ" , 0xec); AddRel("JNZ", 0xee);
2099   SetInv("BCC", "BCS", RelOrders);
2100   SetInv("BNE", "BEQ", RelOrders);
2101   SetInv("BNV", "BOV", RelOrders);
2102   SetInv("BPL", "BMI", RelOrders);
2103   SetInv("BG" , "BL" , RelOrders);
2104   SetInv("BGE", "BLT", RelOrders);
2105   SetInv("BGT", "BLE", RelOrders);
2106   SetInv("JZ" , "JNZ", RelOrders);
2107 }
2108 
DeinitFields(void)2109 static void DeinitFields(void)
2110 {
2111   free(JBitOrders);
2112   free(RegOrders);
2113   free(RelOrders);
2114 
2115   DestroyInstTable(InstTable);
2116 }
2117 
2118 /*-------------------------------------------------------------------------*/
2119 /* Callbacks */
2120 
2121 /*!------------------------------------------------------------------------
2122  * \fn     InternSymbol_XA(char *pArg, TempResult *pResult)
2123  * \brief  handle built-in symbols on XA
2124  * \param  pArg source argument
2125  * \param  pResult result buffer
2126  * ------------------------------------------------------------------------ */
2127 
InternSymbol_XA(char * pArg,TempResult * pResult)2128 static void InternSymbol_XA(char *pArg, TempResult *pResult)
2129 {
2130   Byte Reg;
2131   tSymbolSize Size;
2132 
2133   if (*AttrPart.Str)
2134     OpSize = AttrPartOpSize;
2135 
2136   if (DecodeRegCore(pArg, &Size, &Reg))
2137   {
2138     pResult->Typ = TempReg;
2139     pResult->DataSize = Size;
2140     pResult->Contents.RegDescr.Reg = Reg;
2141     pResult->Contents.RegDescr.Dissect = DissectReg_XA;
2142   }
2143 }
2144 
InitCode_XA(void)2145 static void InitCode_XA(void)
2146 {
2147   Reg_DS = 0;
2148 }
2149 
ChkPC_XA(LargeWord Addr)2150 static Boolean ChkPC_XA(LargeWord Addr)
2151 {
2152   switch (ActPC)
2153   {
2154     case SegCode:
2155     case SegData:
2156       return (Addr<0x1000000);
2157     case SegIO:
2158       return ((Addr > 0x3ff) && (Addr < 0x800));
2159     default:
2160       return False;
2161   }
2162 }
2163 
IsDef_XA(void)2164 static Boolean IsDef_XA(void)
2165 {
2166   return (ActPC == SegCode) || IsRealDef();
2167 }
2168 
SwitchFrom_XA(void)2169 static void SwitchFrom_XA(void)
2170 {
2171   DeinitFields(); ClearONOFF();
2172 }
2173 
SwitchTo_XA(void)2174 static void SwitchTo_XA(void)
2175 {
2176   TurnWords = False; ConstMode = ConstModeIntel;
2177 
2178   PCSymbol = "$"; HeaderID = 0x3c; NOPCode = 0x00;
2179   DivideChars = ","; HasAttrs = True; AttrChars = ".";
2180 
2181   ValidSegs =(1 << SegCode) | (1 << SegData) | (1 << SegIO);
2182   Grans[SegCode ] = 1; ListGrans[SegCode ] = 1; SegInits[SegCode ] = 0;
2183   Grans[SegData ] = 1; ListGrans[SegData ] = 1; SegInits[SegData ] = 0;
2184   Grans[SegIO   ] = 1; ListGrans[SegIO   ] = 1; SegInits[SegIO   ] = 0x400;
2185 
2186   DecodeAttrPart = DecodeAttrPart_XA;
2187   MakeCode = MakeCode_XA;
2188   ChkPC = ChkPC_XA;
2189   IsDef = IsDef_XA;
2190   InternSymbol = InternSymbol_XA;
2191   DissectReg = DissectReg_XA;
2192   SwitchFrom = SwitchFrom_XA; InitFields();
2193   AddONOFF("SUPMODE",   &SupAllowed,  SupAllowedName, False);
2194   AddONOFF("BRANCHEXT", &DoBranchExt, BranchExtName , False);
2195   AddMoto16PseudoONOFF();
2196 
2197   pASSUMERecs = ASSUMEXAs;
2198   ASSUMERecCnt = ASSUMEXACount;
2199 
2200   SetFlag(&DoPadding, DoPaddingName, False);
2201 }
2202 
codexa_init(void)2203 void codexa_init(void)
2204 {
2205   CPUXAG1 = AddCPU("XAG1", SwitchTo_XA);
2206   CPUXAG2 = AddCPU("XAG2", SwitchTo_XA);
2207   CPUXAG3 = AddCPU("XAG3", SwitchTo_XA);
2208 
2209   AddInitPassProc(InitCode_XA);
2210 }
2211