1 /* code3254x.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* Macro Assembler AS                                                        */
6 /*                                                                           */
7 /* Code Generator for TI C54x DSP devices                                    */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 /*-------------------------------------------------------------------------*/
12 /* Includes */
13 
14 #include "stdinc.h"
15 #include <string.h>
16 #include <ctype.h>
17 
18 #include "bpemu.h"
19 #include "strutil.h"
20 #include "chunks.h"
21 #include "asmdef.h"
22 #include "asmsub.h"
23 #include "asmpars.h"
24 #include "asmallg.h"
25 #include "asmrelocs.h"
26 #include "asmcode.h"
27 #include "codepseudo.h"
28 #include "tipseudo.h"
29 #include "asmitree.h"
30 #include "codevars.h"
31 #include "fileformat.h"
32 #include "headids.h"
33 #include "errmsg.h"
34 
35 #include "code3254x.h"
36 
37 /*-------------------------------------------------------------------------*/
38 /* Data Structures */
39 
40 #define FixedOrderCnt 12
41 #define AccOrderCnt 16
42 #define Acc2OrderCnt 5
43 #define MemOrderCnt 9
44 #define XYOrderCnt 4
45 #define MemAccOrderCnt 17
46 #define MemConstOrderCnt 5
47 #define MacOrderCnt 3
48 #define ConditionCnt 23
49 
50 typedef struct
51 {
52   Word Code;
53   Boolean IsRepeatable;
54 } FixedOrder;
55 
56 typedef struct
57 {
58   Word Code;
59   Boolean IsRepeatable, Swap;
60   IntType ConstType;
61 } MemConstOrder;
62 
63 typedef struct
64 {
65   const char *Name;
66   Word Class, Code, Mask;
67 } Condition;
68 
69 typedef enum {ModNone = - 1, ModAcc, ModMem, ModImm, ModAReg} ModType;
70 #define MModAcc  (1 << ModAcc)
71 #define MModMem  (1 << ModMem)
72 #define MModImm  (1 << ModImm)
73 #define MModAReg (1 << ModAReg)
74 
75 static LongInt Reg_CPL, Reg_DP, Reg_SP;
76 
77 static Boolean ThisRep, LastRep, ForcePageZero;
78 
79 static FixedOrder *FixedOrders, *AccOrders, *Acc2Orders, *MemOrders, *XYOrders,
80                   *MemAccOrders, *MacOrders;
81 static MemConstOrder *MemConstOrders;
82 static Condition *Conditions;
83 
84 static CPUVar CPU320C541;
85 
86 static IntType OpSize;
87 static ShortInt AdrMode;
88 static Word AdrVals[3];
89 
90 static Boolean ThisPar;
91 static Word LastOpCode;
92 
93 /*-------------------------------------------------------------------------*/
94 /* Address Decoder */
95 
96 static const char ShortConds[4][4] =
97 {
98   "EQ", "LT", "GT", "NEQ"
99 };
100 
IsAcc(char * Asc)101 static Boolean IsAcc(char *Asc)
102 {
103   return ((Asc[1] == '\0') && (as_toupper(*Asc) >= 'A') && (as_toupper(*Asc) <= 'B'));
104 }
105 
DecodeAdr(const tStrComp * pArg,int Mask)106 static Boolean DecodeAdr(const tStrComp *pArg, int Mask)
107 {
108 #define IndirCnt 16
109   static const char Patterns[IndirCnt][9] = /* leading asterisk is omitted since constant */
110   {
111     "ARx",      "ARx-",     "ARx+",      "+ARx",
112     "ARx-0B",   "ARx-0",    "ARx+0",     "ARx+0B",
113     "ARx-%",    "ARx-0%",   "ARx+%",     "ARx+0%",
114     "ARx(n)",   "+ARx(n)",  "+ARx(n)%",  "(n)"
115   };
116   Boolean OK;
117 
118   AdrMode = ModNone;
119   AdrCnt = 0;
120 
121   /* accumulators */
122 
123   if (IsAcc(pArg->Str))
124   {
125     AdrMode = ModAcc;
126     *AdrVals = as_toupper(*pArg->Str) - 'A';
127     goto done;
128   }
129 
130   /* aux registers */
131 
132   if ((strlen(pArg->Str) == 3) && (!as_strncasecmp(pArg->Str, "AR", 2)) && (pArg->Str[2] >= '0') && (pArg->Str[2] <= '7'))
133   {
134     AdrMode = ModAReg;
135     *AdrVals = pArg->Str[2] - '0';
136     goto done;
137   }
138 
139   /* immediate */
140 
141   if (*pArg->Str == '#')
142   {
143     *AdrVals = EvalStrIntExpressionOffs(pArg, 1, OpSize, &OK);
144     if (OK)
145       AdrMode = ModImm;
146     goto done;
147   }
148 
149   /* indirect */
150 
151   if (*pArg->Str == '*')
152   {
153     int z;
154     Word RegNum;
155     char *pConstStart, *pConstEnd;
156 
157     /* check all possible patterns */
158 
159     for (z = 0; z < IndirCnt; z++)
160     {
161       const char *pPattern = Patterns[z];
162       char *pComp = pArg->Str + 1;
163 
164       /* pattern comparison */
165 
166       RegNum = 0;
167       pConstStart = pConstEnd = NULL;
168       OK = TRUE;
169       while ((*pPattern) && (*pComp) && (OK))
170       {
171         switch (*pPattern)
172         {
173           case 'x': /* embedded number */
174             RegNum = *pComp - '0';
175             OK = RegNum < 8;
176             break;
177           case 'n': /* constant */
178             pConstStart = pComp;
179             pConstEnd = QuotPos(pComp, pPattern[1]);
180             if (pConstEnd)
181               pComp = pConstEnd - 1;
182             else
183               OK = False;
184             break;
185           default:  /* compare verbatim */
186             if (as_toupper(*pPattern) != as_toupper(*pComp))
187               OK = False;
188         }
189         if (OK)
190         {
191           pPattern++;
192           pComp++;
193         }
194       }
195 
196       /* for a successful comparison, we must have reached the end of both strings
197          simultaneously. */
198 
199       OK = OK && (!*pPattern) && (!*pComp);
200       if (OK)
201         break;
202     }
203 
204     if (!OK) WrError(ErrNum_InvAddrMode);
205     else
206     {
207       /* decode offset ? pConst... /must/ be set if such a pattern was successfully
208          decoded! */
209 
210       if (strchr(Patterns[z], 'n'))
211       {
212         /* MMR-style instructions do not allow an extension word */
213 
214         if (ForcePageZero)
215         {
216           WrError(ErrNum_InvAddrMode);
217           OK = False;
218         }
219         else
220         {
221           tStrComp Start, Remainder;
222           char Save;
223 
224           StrCompRefRight(&Start, pArg, pConstStart - pArg->Str);
225           Save = StrCompSplitRef(&Start, &Remainder, &Start, pConstEnd);
226           AdrVals[1] = EvalStrIntExpression(&Start, Int16, &OK);
227           *pConstEnd = Save;
228           if (OK)
229             AdrCnt = 1;
230         }
231       }
232 
233       /* all fine until now? Then do the rest... */
234 
235       if (OK)
236       {
237         AdrMode = ModMem;
238         AdrVals[0] = 0x80 | (z << 3) | RegNum;
239       }
240     }
241 
242     goto done;
243   }
244 
245   /* then try absolute resp. immediate if absolute not allowed */
246 
247   if (Mask & MModMem)
248   {
249     tSymbolFlags Flags;
250 
251     *AdrVals = EvalStrIntExpressionWithFlags(pArg, UInt16, &OK, &Flags);
252     if (OK)
253     {
254       if (Reg_CPL) /* short address rel. to SP? */
255       {
256         *AdrVals -= Reg_SP;
257         if (!mFirstPassUnknown(Flags) && (*AdrVals > 127))
258           WrError(ErrNum_InAccPage);
259       }
260       else         /* on DP page ? */
261       {
262         if (!mFirstPassUnknown(Flags) && ((*AdrVals >> 7) != (Reg_DP)))
263           WrError(ErrNum_InAccPage);
264       }
265       AdrVals[0] &= 127;
266       AdrMode = ModMem;
267     }
268   }
269   else
270   {
271     *AdrVals = EvalStrIntExpression(pArg, OpSize, &OK);
272     if (OK)
273       AdrMode = ModImm;
274   }
275 
276 done:
277   if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
278   {
279     AdrMode = ModNone; AdrCnt = 0;
280     WrError(ErrNum_InvAddrMode);
281   }
282   return (AdrMode != ModNone);
283 }
284 
MakeXY(Word * Dest,Boolean Quarrel)285 static Boolean MakeXY(Word *Dest, Boolean Quarrel)
286 {
287   Boolean Result = False;
288 
289   if (AdrMode != ModMem);  /* should never occur, if address mask specified correctly before */
290   else
291   {
292     Word Mode = (*AdrVals >> 3) & 15, Reg = *AdrVals & 7;
293 
294     if ((Reg < 2) || (Reg > 5));
295     else if ((Mode != 0) && (Mode != 1) && (Mode != 2) && (Mode != 11));
296     else
297     {
298       *Dest = (Reg - 2) | ((Mode & 3) << 2);
299       Result = True;
300     }
301   }
302 
303   if ((Quarrel) && (!Result))
304     WrError(ErrNum_InvAddrMode);
305 
306   return Result;
307 }
308 
DecodeCondition(int StartIndex,Word * Result,int * errindex,Boolean * ErrUnknown)309 static Boolean DecodeCondition(int StartIndex, Word *Result, int *errindex, Boolean *ErrUnknown)
310 {
311   int z, z2;
312   Word CurrClass, CurrMask;
313 
314   *Result = CurrMask = 0; CurrClass = 0xffff; *ErrUnknown = False;
315 
316   for (z = StartIndex; z <= ArgCnt; z++)
317   {
318     for (z2 = 0; z2 < ConditionCnt; z2++)
319       if (!as_strcasecmp(ArgStr[z].Str, Conditions[z2].Name))
320         break;
321     if (z2 >= ConditionCnt)
322     {
323       *ErrUnknown = True;
324       break;
325     }
326 
327     if (CurrClass == 0xffff)
328       CurrClass = Conditions[z2].Class;
329     else if (CurrClass != Conditions[z2].Class)
330       break;
331 
332     if (Conditions[z2].Mask & CurrMask)
333       break;
334 
335     CurrMask |= Conditions[z2].Mask;
336     *Result |= Conditions[z2].Code;
337   }
338 
339   *errindex = z;
340   return (CurrClass != 0xffff) && (z > ArgCnt);
341 }
342 
343 /*-------------------------------------------------------------------------*/
344 /* Decoders */
345 
DecodeFixed(Word Index)346 static void DecodeFixed(Word Index)
347 {
348   const FixedOrder *POrder = FixedOrders + Index;
349 
350   if (!ChkArgCnt(0, 0));
351   else if (ThisPar) WrError(ErrNum_ParNotPossible);
352   else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
353   else
354   {
355     WAsmCode[0] = POrder->Code;
356     CodeLen = 1;
357   }
358 }
359 
DecodeAcc(Word Index)360 static void DecodeAcc(Word Index)
361 {
362   const FixedOrder *POrder = AccOrders + Index;
363 
364   if (!ChkArgCnt(1, 1));
365   else if (ThisPar) WrError(ErrNum_ParNotPossible);
366   else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
367   else
368   {
369     if (DecodeAdr(&ArgStr[1], MModAcc))
370     {
371       WAsmCode[0] = POrder->Code | (AdrVals[0] << 8);
372       CodeLen = 1;
373     }
374   }
375 }
376 
DecodeAcc2(Word Index)377 static void DecodeAcc2(Word Index)
378 {
379   const FixedOrder *POrder = Acc2Orders + Index;
380   Boolean OK;
381 
382   if (!ChkArgCnt(1, 2));
383   else if (ThisPar) WrError(ErrNum_ParNotPossible);
384   else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
385   else
386   {
387     OK = DecodeAdr(&ArgStr[1], MModAcc);
388     if (OK)
389     {
390       WAsmCode[0] = POrder->Code | (AdrVals[0] << 9);
391       if (ArgCnt == 2)
392         OK = DecodeAdr(&ArgStr[2], MModAcc);
393       if (OK)
394       {
395         WAsmCode[0] |= (AdrVals[0] << 8);
396         CodeLen = 1;
397       }
398     }
399   }
400 }
401 
DecodeMem(Word Index)402 static void DecodeMem(Word Index)
403 {
404   const FixedOrder *POrder = MemOrders + Index;
405 
406   if (!ChkArgCnt(1, 1));
407   else if (ThisPar) WrError(ErrNum_ParNotPossible);
408   else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
409   else if (DecodeAdr(&ArgStr[1], MModMem))
410   {
411     memcpy(WAsmCode, AdrVals, (AdrCnt + 1) << 1);
412     WAsmCode[0] |= POrder->Code;
413     CodeLen = 1 + AdrCnt;
414   }
415 }
416 
DecodeXY(Word Index)417 static void DecodeXY(Word Index)
418 {
419   const FixedOrder *POrder = XYOrders + Index;
420   Word TmpX, TmpY;
421 
422   if (ArgCnt != 2) WrError(ErrNum_InvAddrMode);
423   else if (ThisPar) WrError(ErrNum_ParNotPossible);
424   else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
425   else
426   {
427     if (DecodeAdr(&ArgStr[1], MModMem))
428       if (MakeXY(&TmpX, True))
429         if (DecodeAdr(&ArgStr[2], MModMem))
430           if (MakeXY(&TmpY, True))
431           {
432             WAsmCode[0] = POrder->Code | (TmpX << 4) | TmpY;
433             CodeLen = 1;
434           }
435   }
436 }
437 
DecodeADDSUB(Word Index)438 static void DecodeADDSUB(Word Index)
439 {
440   Boolean OK;
441   Integer Shift;
442   Word DestAcc;
443 
444   if (ChkArgCnt(2, 4))
445   {
446     OpSize = SInt16;
447     DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModImm);
448     switch (AdrMode)
449     {
450       case ModAcc:  /* ADD src, SHIFT|ASM [,dst] */
451         if (!ChkArgCnt(2, 3));
452         else if (ThisPar) WrError(ErrNum_ParNotPossible);
453         else
454         {
455           Word SrcAcc = *AdrVals;
456 
457           /* SrcAcc remains in AdrVals[0] if no 3rd operand, therefore
458              no extra assignment needed! */
459 
460           if (ArgCnt == 3)
461           {
462             if (!DecodeAdr(&ArgStr[3], MModAcc))
463               break;
464           }
465 
466           /* distinguish variants of shift specification: */
467 
468           if (!as_strcasecmp(ArgStr[2].Str, "ASM"))
469           {
470             WAsmCode[0] = 0xf480 | Index | (SrcAcc << 9) | (*AdrVals << 8);
471             CodeLen = 1;
472           }
473           else
474           {
475             WAsmCode[0] = EvalStrIntExpression(&ArgStr[2], SInt5, &OK);
476             if (OK)
477             {
478               WAsmCode[0] = (WAsmCode[0] & 0x1f) | 0xf400 | (Index << 5) | (SrcAcc << 9) | (*AdrVals << 8);
479               CodeLen = 1;
480             }
481           }
482         }
483         break;
484 
485       case ModMem: /* ADD mem[, TS | SHIFT | Ymem], src[, dst] */
486       {
487         int HCnt;
488 
489         /* rescue decoded address values */
490 
491         memcpy(WAsmCode, AdrVals, (AdrCnt + 1) << 1);
492         HCnt = AdrCnt;
493 
494         /* no shift? this is the case for two operands or three operands and the second is an accumulator */
495 
496         if (ArgCnt == 2)
497           Shift = 0;
498         else if ((ArgCnt == 3) && (IsAcc(ArgStr[2].Str)))
499           Shift = 0;
500 
501         /* special shift value ? */
502 
503         else if (!as_strcasecmp(ArgStr[2].Str, "TS"))
504           Shift = 255;
505 
506         /* shift address operand ? */
507 
508         else if (*ArgStr[2].Str == '*')
509         {
510           Word Tmp;
511 
512           /* break down source operand to reduced variant */
513 
514           if (!MakeXY(WAsmCode, True))
515             break;
516           WAsmCode[0] = WAsmCode[0] << 4;
517 
518           /* merge in second operand */
519 
520           if (!DecodeAdr(&ArgStr[2], MModMem))
521             break;
522           if (!MakeXY(&Tmp, True))
523             break;
524           WAsmCode[0] |= Tmp;
525           Shift = 254;
526         }
527 
528         /* normal immediate shift */
529 
530         else
531         {
532           tSymbolFlags Flags;
533 
534           Shift = EvalStrIntExpressionWithFlags(&ArgStr[2], SInt6, &OK, &Flags);
535           if (!OK)
536             break;
537           if (mFirstPassUnknown(Flags) && (Shift > 16))
538             Shift &= 15;
539           if (!ChkRange(Shift, -16 ,16))
540             break;
541         }
542 
543         /* decode destination accumulator */
544 
545         if (!DecodeAdr(&ArgStr[ArgCnt], MModAcc))
546           break;
547         DestAcc = *AdrVals;
548 
549         /* optionally decode source accumulator.  If no second accumulator, result
550            again remains in AdrVals */
551 
552         if ((ArgCnt == 4) || ((ArgCnt == 3) && (IsAcc(ArgStr[2].Str))))
553         {
554           if (!DecodeAdr(&ArgStr[ArgCnt - 1], MModAcc))
555             break;
556         }
557 
558 	/* now start applying the variants */
559 
560         if (Shift == 255) /* TS case */
561         {
562           if (*AdrVals != DestAcc) WrError(ErrNum_InvAddrMode);
563           else if (ThisPar) WrError(ErrNum_ParNotPossible);
564           else
565           {
566             WAsmCode[0] |= 0x0400 | (Index << 11) | (DestAcc << 8);
567             CodeLen = 1 + HCnt;
568           }
569         }
570 
571         else if (Shift == 254) /* XY case */
572         {
573           if (*AdrVals != DestAcc) WrError(ErrNum_InvAddrMode);
574           else if (ThisPar) WrError(ErrNum_ParNotPossible);
575           else
576           {
577             WAsmCode[0] |= 0xa000 | (Index << 9) | (DestAcc << 8);
578             CodeLen = 1;
579           }
580         }
581 
582         else if (Shift == 16) /* optimization for 16 shifts */
583         {
584           if (ThisPar) WrError(ErrNum_ParNotPossible);
585           else
586           {
587             WAsmCode[0] |= (0x3c00 + (Index << 10)) | (*AdrVals << 9) | (DestAcc << 8);
588             CodeLen = 1 + HCnt;
589           }
590         }
591 
592         else if ((DestAcc == *AdrVals) && (Shift == 0)) /* shortform without shift and with one accu only */
593         {
594           if (ThisPar)
595           {
596             AdrMode = ModMem; AdrVals[0] = WAsmCode[0];
597             if (MakeXY(AdrVals, True))
598             {
599               /* prev. operation must be STH src,0,Xmem */
600               if ((LastOpCode & 0xfe0f) != 0x9a00) WrError(ErrNum_ParNotPossible);
601               else
602               {
603                 RetractWords(1);
604                 WAsmCode[0] = 0xc000 | (Index << 10) | (DestAcc << 8) | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals << 4);
605                 CodeLen = 1;
606               }
607             }
608           }
609           else
610           {
611             WAsmCode[0] |= 0x0000 | (Index << 11) | (DestAcc << 8);
612             CodeLen = 1 + HCnt;
613           }
614         }
615 
616         else if (ThisPar) WrError(ErrNum_ParNotPossible);
617         else
618         {
619           Word SrcAcc = *AdrVals;
620 
621           /* fool MakeXY a bit */
622 
623           AdrMode = ModMem; AdrVals[0] = WAsmCode[0];
624 
625           if ((Shift >= 0) && (DestAcc == SrcAcc) && (MakeXY(WAsmCode, False))) /* X-Addr and positive shift */
626           {
627             WAsmCode[0] = 0x9000 | (Index << 9) | (WAsmCode[0] << 4) | (DestAcc << 8) | Shift;
628             CodeLen = 1;
629           }
630           else /* last resort... */
631           {
632             WAsmCode[0] |= 0x6f00;
633             WAsmCode[2] = WAsmCode[1]; /* shift optional address offset */
634             WAsmCode[1] = 0x0c00 | (Index << 5) | (SrcAcc << 9) | (DestAcc << 8) | (Shift & 0x1f);
635             CodeLen = 2 + HCnt;
636           }
637         }
638 
639         break;
640       }
641 
642       case ModImm:  /* ADD #lk[, SHIFT|16], src[, dst] */
643       {
644         if (ThisPar) WrError(ErrNum_ParNotPossible);
645         {
646           /* store away constant */
647 
648           WAsmCode[1] = *AdrVals;
649 
650           /* no shift? this is the case for two operands or three operands and the second is an accumulator */
651 
652           if (ArgCnt == 2)
653             Shift = 0;
654           else if ((ArgCnt == 3) && (IsAcc(ArgStr[2].Str)))
655             Shift = 0;
656 
657           /* otherwise shift is second argument */
658 
659           else
660           {
661             tSymbolFlags Flags;
662 
663             Shift = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt5, &OK, &Flags);
664             if (!OK)
665               break;
666             if (mFirstPassUnknown(Flags) && (Shift > 16))
667               Shift &= 15;
668             if (!ChkRange(Shift, 0 ,16))
669               break;
670           }
671 
672           /* decode destination accumulator */
673 
674           if (!DecodeAdr(&ArgStr[ArgCnt], MModAcc))
675             break;
676           DestAcc = *AdrVals;
677 
678           /* optionally decode source accumulator.  If no second accumulator, result
679              again remains in AdrVals */
680 
681           if ((ArgCnt == 4) || ((ArgCnt == 3) && (IsAcc(ArgStr[2].Str))))
682           {
683             if (!DecodeAdr(&ArgStr[ArgCnt - 1], MModAcc))
684               break;
685           }
686 
687           /* distinguish according to shift count */
688 
689           if (Shift == 16)
690           {
691             WAsmCode[0] = 0xf060 | Index | (DestAcc << 8) | (*AdrVals << 9);
692             CodeLen = 2;
693           }
694           else
695           {
696             WAsmCode[0] = 0xf000 | (Index << 5) | (DestAcc << 8) | (*AdrVals << 9) | (Shift & 15);
697             CodeLen = 2;
698           }
699         }
700         break;
701       }
702     }
703   }
704 }
705 
DecodeMemAcc(Word Index)706 static void DecodeMemAcc(Word Index)
707 {
708   FixedOrder *POrder = MemAccOrders + Index;
709 
710   if (!ChkArgCnt(2, 2));
711   else if (ThisPar) WrError(ErrNum_ParNotPossible);
712   else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
713   else if (DecodeAdr(&ArgStr[2], MModAcc))
714   {
715     WAsmCode[0] = POrder->Code | (AdrVals[0] << 8);
716     if (DecodeAdr(&ArgStr[1], MModMem))
717     {
718       WAsmCode[0] |= *AdrVals;
719       if (AdrCnt)
720         WAsmCode[1] = AdrVals[1];
721       CodeLen = 1 + AdrCnt;
722     }
723   }
724 }
725 
DecodeMemConst(Word Index)726 static void DecodeMemConst(Word Index)
727 {
728   MemConstOrder *POrder = MemConstOrders + Index;
729   int HCnt;
730 
731   if (!ChkArgCnt(2, 2));
732   else if (ThisPar) WrError(ErrNum_ParNotPossible);
733   else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
734   else if (DecodeAdr(&ArgStr[2 - POrder->Swap], MModMem))
735   {
736     WAsmCode[0] = POrder->Code | 0[AdrVals];
737     HCnt = AdrCnt;
738     if (HCnt)
739       WAsmCode[1] = AdrVals[1];
740     OpSize = POrder->ConstType;
741     if (DecodeAdr(&ArgStr[1 +  POrder->Swap], MModImm))
742     {
743       WAsmCode[1 + HCnt] = *AdrVals;
744       CodeLen = 2 + HCnt;
745     }
746   }
747 }
748 
DecodeMPY(Word Index)749 static void DecodeMPY(Word Index)
750 {
751   Word DestAcc;
752 
753   (void)Index;
754 
755   if (!ChkArgCnt(2, 3));
756   else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
757   {
758     DestAcc = (*AdrVals) << 8;
759     if (ArgCnt == 3)
760     {
761       Word XMode;
762 
763       if (ThisPar) WrError(ErrNum_ParNotPossible);
764       else if (DecodeAdr(&ArgStr[1], MModMem))
765         if (MakeXY(&XMode, True))
766           if (DecodeAdr(&ArgStr[2], MModMem))
767             if (MakeXY(WAsmCode, True))
768             {
769               *WAsmCode |= 0xa400 | DestAcc | (XMode << 4);
770               CodeLen = 1;
771             }
772     }
773     else
774     {
775       OpSize = SInt16;
776       DecodeAdr(&ArgStr[1], MModImm | MModMem);
777       switch (AdrMode)
778       {
779         case ModImm:
780           if (ThisPar) WrError(ErrNum_ParNotPossible);
781           else
782           {
783             WAsmCode[0] = 0xf066 | DestAcc;
784             WAsmCode[1] = *AdrVals;
785             CodeLen = 2;
786           }
787           break;
788         case ModMem:
789           if (ThisPar)
790           {
791             if (MakeXY(AdrVals, True))
792             {
793               /* previous op ST src, Ym */
794               if ((LastOpCode & 0xfe0f) != 0x9a00) WrError(ErrNum_ParNotPossible);
795               else
796               {
797                 RetractWords(1);
798                 *WAsmCode = 0xcc00 | DestAcc | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals);
799                 CodeLen = 1;
800               }
801             }
802           }
803           else
804           {
805             WAsmCode[0] = 0x2000 | DestAcc | 0[AdrVals];
806             if (AdrCnt)
807               WAsmCode[1] = AdrVals[1];
808             CodeLen = 1 + AdrCnt;
809           }
810           break;
811       }
812     }
813   }
814 }
815 
DecodeMPYA(Word Index)816 static void DecodeMPYA(Word Index)
817 {
818   (void) Index;
819 
820   if (!ChkArgCnt(1, 1));
821   else if (ThisPar) WrError(ErrNum_ParNotPossible);
822   else
823   {
824     DecodeAdr(&ArgStr[1], MModAcc | MModMem);
825     switch (AdrMode)
826     {
827       case ModMem:
828         WAsmCode[0] = 0x3100 | AdrVals[0];
829         if (AdrCnt)
830           WAsmCode[1] = AdrVals[1];
831         CodeLen = 1 + AdrCnt;
832         break;
833       case ModAcc:
834         WAsmCode[0] = 0xf48c | (*AdrVals << 8);
835         CodeLen = 1;
836         break;
837     }
838   }
839 }
840 
DecodeSQUR(Word Index)841 static void DecodeSQUR(Word Index)
842 {
843   (void)Index;
844 
845   if (!ChkArgCnt(2, 2));
846   else if (ThisPar) WrError(ErrNum_ParNotPossible);
847   else if (DecodeAdr(&ArgStr[2], MModAcc))
848   {
849     0[WAsmCode] = *AdrVals << 8;
850     DecodeAdr(&ArgStr[1], MModAcc | MModMem);
851     switch (AdrMode)
852     {
853       case ModAcc:
854         if (*AdrVals) WrError(ErrNum_InvAddrMode);
855         else
856         {
857           WAsmCode[0] |= 0xf48d;
858           CodeLen = 1;
859         }
860         break;
861       case ModMem:
862         WAsmCode[0] |= 0x2600 | *AdrVals;
863         if (AdrCnt)
864           WAsmCode[1] = AdrVals[1];
865         CodeLen = 1 + AdrCnt;
866         break;
867     }
868   }
869 }
870 
DecodeMAC(Word Index)871 static void DecodeMAC(Word Index)
872 {
873   (void) Index;
874 
875   if (!ChkArgCnt(2, 4));
876   else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
877   {
878     *WAsmCode = (*AdrVals) << 8;
879     OpSize = SInt16;
880     DecodeAdr(&ArgStr[1], MModImm | MModMem);
881 
882     /* handle syntax 3: immediate op first */
883 
884     if (AdrMode == ModImm)
885     {
886       if (!ChkArgCnt(2, 3));
887       else if (ThisPar) WrError(ErrNum_ParNotPossible);
888       else
889       {
890         *WAsmCode |= 0xf067; WAsmCode[1] = *AdrVals;
891         if (ArgCnt == 2)
892         {
893           *WAsmCode |= ((*WAsmCode & 0x100) << 1);
894           CodeLen = 2;
895         }
896         else if (DecodeAdr(&ArgStr[2], MModAcc))
897         {
898           *WAsmCode |= ((*AdrVals) << 9);
899           CodeLen = 2;
900         }
901       }
902     }
903 
904     /* syntax 1/2/4 have memory operand in front */
905 
906     else if (AdrMode == ModMem)
907     {
908       /* save [first] memory operand */
909 
910       Word HMode = *AdrVals, HCnt = AdrCnt;
911       if (AdrCnt)
912         WAsmCode[1] = AdrVals[1];
913 
914       /* syntax 2+4 have at least 3 operands, handle syntax 1 */
915 
916       if (ArgCnt == 2)
917       {
918         if (ThisPar)
919         {
920           if (MakeXY(AdrVals, True))
921           {
922             if ((LastOpCode & 0xfe0f) == 0x9400) /* previous op LD Xmem, src */
923             {
924               if ((LastOpCode & 0x0100) == (*WAsmCode & 0x0100)) WrError(ErrNum_ParNotPossible);
925               else
926               {
927                 RetractWords(1);
928                 *WAsmCode = 0xa800 | (LastOpCode & 0x01f0) | (*AdrVals);
929                 CodeLen = 1;
930               }
931             }
932             else if ((LastOpCode & 0xfe0f) == 0x9a00) /* previous op ST src, Ymem */
933             {
934               RetractWords(1);
935               *WAsmCode |= 0xd000 | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals << 4);
936               CodeLen = 1;
937             }
938             else WrError(ErrNum_ParNotPossible);
939           }
940         }
941         else
942         {
943           *WAsmCode |= 0x2800 | HMode;
944           CodeLen = 1 + AdrCnt;
945         }
946       }
947       else if (ThisPar) WrError(ErrNum_ParNotPossible);
948       else
949       {
950         /* both syntax 2+4 have optional second accumulator */
951 
952         if (ArgCnt == 3)
953           *WAsmCode |= ((*WAsmCode & 0x100) << 1);
954         else if (DecodeAdr(&ArgStr[3], MModAcc))
955           *WAsmCode |= ((*AdrVals) << 9);
956 
957         /* if no second accu, AdrMode is still set from previous decode */
958 
959         if (AdrMode != ModNone)
960         {
961           /* differentiate & handle syntax 2 & 4. OpSize still set from above! */
962 
963           DecodeAdr(&ArgStr[2], MModMem | MModImm);
964           switch (AdrMode)
965           {
966             case ModMem:
967               if (MakeXY(AdrVals, TRUE))
968               {
969                 WAsmCode[0] |= (*AdrVals);
970                 *AdrVals = HMode;
971                 if (MakeXY(&HMode, TRUE))
972                 {
973                   WAsmCode[0] |= 0xb000 | (HMode << 4);
974                   CodeLen = 1;
975                 }
976               }
977               break;
978             case ModImm:
979               WAsmCode[1 + HCnt] = *AdrVals;
980               WAsmCode[0] |= 0x6400 | HMode;
981               CodeLen = 2 + HCnt;
982               break;
983           }
984         }
985       }
986     }
987   }
988 }
989 
DecodeMACDP(Word Index)990 static void DecodeMACDP(Word Index)
991 {
992   if (!ChkArgCnt(3, 3));
993   else if (ThisPar) WrError(ErrNum_ParNotPossible);
994   else if (DecodeAdr(&ArgStr[3], MModAcc))
995   {
996     *WAsmCode = Index | (0[AdrVals] << 8);
997     if (DecodeAdr(&ArgStr[1], MModMem))
998     {
999       tEvalResult EvalResult;
1000 
1001       *WAsmCode |= *AdrVals;
1002       if (AdrCnt)
1003         WAsmCode[1] = AdrVals[1];
1004       WAsmCode[1 + AdrCnt] = EvalStrIntExpressionWithResult(&ArgStr[2], UInt16, &EvalResult);
1005       if (EvalResult.OK)
1006       {
1007         ChkSpace(Index & 0x200 ? SegData : SegCode, EvalResult.AddrSpaceMask);
1008         CodeLen = 2 + AdrCnt;
1009       }
1010     }
1011   }
1012 }
1013 
DecodeFIRS(Word Index)1014 static void DecodeFIRS(Word Index)
1015 {
1016   (void)Index;
1017 
1018   if (!ChkArgCnt(3, 3));
1019   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1020   else if (DecodeAdr(&ArgStr[1], MModMem))
1021     if (MakeXY(WAsmCode, TRUE))
1022     {
1023       0[WAsmCode] = 0xe000 | ((*WAsmCode) << 4);
1024       if (DecodeAdr(&ArgStr[2], MModMem))
1025         if (MakeXY(AdrVals, TRUE))
1026         {
1027           tEvalResult EvalResult;
1028 
1029           0[WAsmCode] |= *AdrVals;
1030           WAsmCode[1] = EvalStrIntExpressionWithResult(&ArgStr[3], UInt16, &EvalResult);
1031           if (EvalResult.OK)
1032           {
1033             ChkSpace(SegCode, EvalResult.AddrSpaceMask);
1034             CodeLen = 2;
1035           }
1036         }
1037     }
1038 }
1039 
DecodeBIT(Word Index)1040 static void DecodeBIT(Word Index)
1041 {
1042   Boolean OK;
1043 
1044   (void)Index;
1045 
1046   if (!ChkArgCnt(2, 2));
1047   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1048   else if (DecodeAdr(&ArgStr[1], MModMem))
1049     if (MakeXY(AdrVals, TRUE))
1050     {
1051       WAsmCode[0] = EvalStrIntExpression(&ArgStr[2], UInt4, &OK);
1052       if (OK)
1053       {
1054         WAsmCode[0] |= 0x9600 | (AdrVals[0] << 4);
1055         CodeLen = 1;
1056       }
1057     }
1058 }
1059 
DecodeBITF(Word Index)1060 static void DecodeBITF(Word Index)
1061 {
1062   UNUSED(Index);
1063 
1064   if (!ChkArgCnt(2, 2));
1065   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1066   else
1067   {
1068     OpSize = UInt16;
1069     if (DecodeAdr(&ArgStr[2], MModImm))
1070     {
1071       WAsmCode[1] = *AdrVals;
1072       if (DecodeAdr(&ArgStr[1], MModMem))
1073       {
1074         *WAsmCode = 0x6100 | *AdrVals;
1075         if (AdrCnt)
1076         {
1077           WAsmCode[2] = WAsmCode[1];
1078           WAsmCode[1] = AdrVals[1];
1079         }
1080         CodeLen = 2 + AdrCnt;
1081       }
1082     }
1083   }
1084 }
1085 
DecodeMACR(Word Index)1086 static void DecodeMACR(Word Index)
1087 {
1088   (void) Index;
1089 
1090   if (!ChkArgCnt(2, 4));
1091   else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
1092   {
1093     *WAsmCode = *AdrVals << 8;
1094     if (DecodeAdr(&ArgStr[1], MModMem))
1095     {
1096       if (ArgCnt == 2)
1097       {
1098         if (ThisPar)
1099         {
1100           if (MakeXY(AdrVals, True))
1101           {
1102             if ((LastOpCode & 0xfe0f) == 0x9400) /* previous op LD Xmem, src */
1103             {
1104               if ((LastOpCode & 0x0100) == (*WAsmCode & 0x0100)) WrError(ErrNum_ParNotPossible);
1105               else
1106               {
1107                 RetractWords(1);
1108                 *WAsmCode = 0xaa00 | (LastOpCode & 0x01f0) | (*AdrVals);
1109                 CodeLen = 1;
1110               }
1111             }
1112             else if ((LastOpCode & 0xfe0f) == 0x9a00) /* previous op ST src, Ymem */
1113             {
1114               RetractWords(1);
1115               *WAsmCode |= 0xd400 | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals << 4);
1116               CodeLen = 1;
1117             }
1118             else WrError(ErrNum_ParNotPossible);
1119           }
1120         }
1121         else
1122         {
1123           WAsmCode[0] |= 0x2a00 | *AdrVals;
1124           if (AdrCnt)
1125             WAsmCode[1] = AdrVals[1];
1126           CodeLen = 1 + AdrCnt;
1127         }
1128       }
1129       else if (ThisPar) WrError(ErrNum_ParNotPossible);
1130       else
1131       {
1132         if (MakeXY(AdrVals, True))
1133         {
1134           WAsmCode[0] |= 0xb400 | ((*AdrVals) << 4);
1135           if (DecodeAdr(&ArgStr[2], MModMem))
1136             if (MakeXY(AdrVals, True))
1137             {
1138               WAsmCode[0] |= *AdrVals;
1139               if (ArgCnt == 4)
1140               {
1141                 if (DecodeAdr(&ArgStr[3], MModAcc))
1142                   WAsmCode[0] |= (*AdrVals) << 9;
1143               }
1144               else
1145                 *WAsmCode |= ((*WAsmCode & 0x100) << 1);
1146               if (AdrMode != ModNone)
1147                 CodeLen = 1;
1148             }
1149         }
1150       }
1151     }
1152   }
1153 }
1154 
DecodeMac(Word Index)1155 static void DecodeMac(Word Index)
1156 {
1157   FixedOrder *POrder = MacOrders + Index;
1158 
1159   if (!ChkArgCnt(1, ArgCntMax));
1160   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1161   else if (!as_strcasecmp(ArgStr[1].Str, "T"))
1162   {
1163     if (!ChkArgCnt(1, 3));
1164     else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
1165     {
1166       WAsmCode[0] = 0xf480 | (POrder->Code & 0xff) | ((*AdrVals) << 8);
1167       if (ArgCnt == 3)
1168         DecodeAdr(&ArgStr[2], MModAcc);
1169       if (AdrMode != ModNone)
1170       {
1171         WAsmCode[0] |= ((*AdrVals) << 9);
1172         CodeLen = 1;
1173       }
1174     }
1175   }
1176   else if (!ChkArgCnt(1, 2));
1177   else
1178   {
1179     if ((ArgCnt == 2) && (as_strcasecmp(ArgStr[2].Str, "B"))) WrError(ErrNum_InvAddrMode);
1180     else if (DecodeAdr(&ArgStr[1], MModMem))
1181     {
1182       WAsmCode[0] = (POrder->Code & 0xff00) | (*AdrVals);
1183       if (AdrCnt)
1184         WAsmCode[1] = AdrVals[1];
1185       CodeLen = 1 + AdrCnt;
1186     }
1187   }
1188 }
1189 
DecodeMACSU(Word Index)1190 static void DecodeMACSU(Word Index)
1191 {
1192   (void)Index;
1193 
1194   if (!ChkArgCnt(3, 3));
1195   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1196   else if (DecodeAdr(&ArgStr[3], MModAcc))
1197   {
1198     *WAsmCode = 0xa600 | ((*AdrVals) << 8);
1199     if ((DecodeAdr(&ArgStr[1], MModMem))
1200      && (MakeXY(AdrVals, TRUE)))
1201     {
1202       *WAsmCode |= ((*AdrVals) << 4);
1203       if ((DecodeAdr(&ArgStr[2], MModMem))
1204        && (MakeXY(AdrVals, TRUE)))
1205       {
1206         *WAsmCode |= *AdrVals;
1207         CodeLen = 1;
1208       }
1209     }
1210   }
1211 }
1212 
DecodeMAS(Word Index)1213 static void DecodeMAS(Word Index)
1214 {
1215   if (!ChkArgCnt(2, 4));
1216   else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
1217   {
1218     *WAsmCode = ((*AdrVals) << 8);
1219     if (DecodeAdr(&ArgStr[1], MModMem))
1220     {
1221       if (ArgCnt == 2)
1222       {
1223         if (ThisPar)
1224         {
1225           if (MakeXY(AdrVals, True))
1226           {
1227             if ((LastOpCode & 0xfe0f) == 0x9400) /* previous op LD Xmem, src */
1228             {
1229               if ((LastOpCode & 0x0100) == (*WAsmCode & 0x0100)) WrError(ErrNum_ParNotPossible);
1230               else
1231               {
1232                 RetractWords(1);
1233                 *WAsmCode = 0xac00 | Index | (LastOpCode & 0x01f0) | (*AdrVals);
1234                 CodeLen = 1;
1235               }
1236             }
1237             else if ((LastOpCode & 0xfe0f) == 0x9a00) /* previous op ST src, Ymem */
1238             {
1239               RetractWords(1);
1240               *WAsmCode |= 0xd800 | (Index << 1) | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals << 4);
1241               CodeLen = 1;
1242             }
1243             else WrError(ErrNum_ParNotPossible);
1244           }
1245         }
1246         else
1247         {
1248           *WAsmCode |= 0x2c00 | Index | *AdrVals;
1249           if (AdrCnt)
1250             1[WAsmCode] = AdrVals[1];
1251           CodeLen = 1 + AdrCnt;
1252         }
1253       }
1254       else if (ThisPar) WrError(ErrNum_ParNotPossible);
1255       else if (MakeXY(AdrVals, TRUE))
1256       {
1257         *WAsmCode |= 0xb800 | (Index << 1) | ((*AdrVals) << 4);
1258         if (DecodeAdr(&ArgStr[2], MModMem))
1259           if (MakeXY(AdrVals, TRUE))
1260           {
1261             *WAsmCode |= *AdrVals;
1262             if (ArgCnt == 4)
1263             {
1264               if (DecodeAdr(&ArgStr[3], MModAcc))
1265                 *WAsmCode |= ((*AdrVals) << 9);
1266             }
1267             else
1268               *WAsmCode |= ((*WAsmCode & 0x100) << 1);
1269             if (AdrMode != ModNone)
1270               CodeLen = 1;
1271           }
1272       }
1273     }
1274   }
1275 }
1276 
DecodeMASAR(Word Index)1277 static void DecodeMASAR(Word Index)
1278 {
1279   (void)Index;
1280 
1281   if (!ChkArgCnt(2, 3));
1282   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1283   else if (as_strcasecmp(ArgStr[1].Str, "T")) WrError(ErrNum_InvAddrMode);
1284   else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
1285   {
1286     WAsmCode[0] = (*AdrVals << 8);
1287     if (ArgCnt == 3)
1288       DecodeAdr(&ArgStr[2], MModAcc);
1289     if (AdrMode != ModNone)
1290     {
1291       *WAsmCode |= 0xf48b | ((*AdrVals) << 9);
1292       CodeLen = 1;
1293     }
1294   }
1295 }
1296 
DecodeDADD(Word Index)1297 static void DecodeDADD(Word Index)
1298 {
1299   (void)Index;
1300 
1301   if (!ChkArgCnt(2, 3));
1302   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1303   else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
1304   {
1305     WAsmCode[0] = 0x5000 | (AdrVals[0] << 8);
1306     if (ArgCnt == 3)
1307       DecodeAdr(&ArgStr[2], MModAcc);
1308     if (AdrMode != ModNone)
1309     {
1310       WAsmCode[0] |= (AdrVals[0] << 9);
1311       if (DecodeAdr(&ArgStr[1], MModMem))
1312       {
1313         WAsmCode[0] |= AdrVals[0];
1314         if (AdrCnt)
1315           WAsmCode[1] = AdrVals[1];
1316         CodeLen = 1 + AdrCnt;
1317       }
1318     }
1319   }
1320 }
1321 
DecodeLog(Word Index)1322 static void DecodeLog(Word Index)
1323 {
1324   Word Acc, Shift;
1325   Boolean OK;
1326 
1327   if (!ChkArgCnt(1, 4));
1328   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1329   else
1330   {
1331     OpSize = UInt16;
1332     DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModImm);
1333     switch (AdrMode)
1334     {
1335       case ModAcc:  /* Variant 4 */
1336         if (ChkArgCnt(1, 3))
1337         {
1338           Acc = *AdrVals << 9;
1339           *WAsmCode = 0xf080 | Acc | (Index << 5);
1340           Shift = 0; OK = True;
1341           if (((ArgCnt == 2) && IsAcc(ArgStr[2].Str)) || (ArgCnt == 3))
1342           {
1343             OK = DecodeAdr(&ArgStr[ArgCnt], MModAcc);
1344             if (OK)
1345               Acc = *AdrVals << 8;
1346           }
1347           else
1348             Acc = Acc >> 1;
1349           if (OK)
1350             if (((ArgCnt == 2) && (!IsAcc(ArgStr[2].Str))) || (ArgCnt == 3))
1351             {
1352               Shift = EvalStrIntExpression(&ArgStr[2], SInt5, &OK);
1353             }
1354           if (OK)
1355           {
1356             *WAsmCode |= Acc | (Shift & 0x1f);
1357             CodeLen = 1;
1358           }
1359         }
1360         break;
1361 
1362       case ModMem:  /* Variant 1 */
1363         if (ChkArgCnt(2, 2))
1364         {
1365           *WAsmCode = 0x1800 | (*AdrVals) | (Index << 9);
1366           if (AdrCnt)
1367             WAsmCode[1] = AdrVals[1];
1368           CodeLen = AdrCnt + 1;
1369           if (DecodeAdr(&ArgStr[2], MModAcc))
1370             *WAsmCode |= (*AdrVals) << 8;
1371           else
1372             CodeLen = 0;
1373         }
1374         break;
1375 
1376       case ModImm:  /* Variant 2,3 */
1377         if (ChkArgCnt(2, 4))
1378         {
1379           WAsmCode[1] = *AdrVals;
1380           if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
1381           {
1382             *WAsmCode = Acc = *AdrVals << 8;
1383             Shift = 0;
1384             OK = True;
1385             if (((ArgCnt == 3) && IsAcc(ArgStr[2].Str)) || (ArgCnt == 4))
1386             {
1387               OK = DecodeAdr(&ArgStr[ArgCnt - 1], MModAcc);
1388               if (OK)
1389                 Acc = (*AdrVals) << 9;
1390             }
1391             else
1392               Acc = Acc << 1;
1393             if (OK)
1394             {
1395               if (((ArgCnt == 3) && (!IsAcc(ArgStr[2].Str))) || (ArgCnt == 4))
1396               {
1397                 tSymbolFlags Flags;
1398 
1399                 Shift = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt5, &OK, &Flags);
1400                 if (mFirstPassUnknown(Flags))
1401                   Shift &= 15;
1402                 OK = ChkRange(Shift, 0, 16);
1403               }
1404             }
1405             if (OK)
1406             {
1407               *WAsmCode |= Acc;
1408               if (Shift == 16) /* Variant 3 */
1409               {
1410                 *WAsmCode |= 0xf063 + Index;
1411               }
1412               else             /* Variant 2 */
1413               {
1414                 *WAsmCode |= 0xf000 | ((Index + 3) << 4) | Shift;
1415               }
1416               CodeLen = 2;
1417             }
1418           }
1419         }
1420         break;
1421     }
1422   }
1423 }
1424 
DecodeSFT(Word Index)1425 static void DecodeSFT(Word Index)
1426 {
1427   Boolean OK;
1428   int Shift;
1429 
1430   if (!ChkArgCnt(2, 3));
1431   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1432   else if (DecodeAdr(&ArgStr[1], MModAcc))
1433   {
1434     0[WAsmCode] = Index | ((*AdrVals) << 9);
1435     if (ArgCnt == 3)
1436       DecodeAdr(&ArgStr[3], MModAcc);
1437     if (AdrMode != ModNone)
1438     {
1439       0[WAsmCode] |= ((*AdrVals) << 8);
1440       Shift = EvalStrIntExpression(&ArgStr[2], SInt5, &OK);
1441       if (OK)
1442       {
1443         0[WAsmCode] |= (Shift & 0x1f);
1444         CodeLen = 1;
1445       }
1446     }
1447   }
1448 }
1449 
DecodeCMPR(Word Index)1450 static void DecodeCMPR(Word Index)
1451 {
1452   Word z;
1453   Boolean OK;
1454 
1455   (void) Index;
1456 
1457   if (!ChkArgCnt(2, 2));
1458   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1459   else if (DecodeAdr(&ArgStr[2], MModAReg))
1460   {
1461     OK = False;
1462     for (z = 0; z < 4; z++)
1463       if (!as_strcasecmp(ArgStr[1].Str, ShortConds[z]))
1464       {
1465         OK = True;
1466         break;
1467       }
1468     if (!OK)
1469       z = EvalStrIntExpression(&ArgStr[1], UInt2, &OK);
1470     if (OK)
1471     {
1472       0[WAsmCode] = 0xf4a8 | (*AdrVals) | (z << 8);
1473       CodeLen = 1;
1474     }
1475   }
1476 }
1477 
DecodePMAD(Word Index)1478 static void DecodePMAD(Word Index)
1479 {
1480   if (!ChkArgCnt(1, 1));
1481   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1482   else if (LastRep) WrError(ErrNum_NotRepeatable);
1483   else
1484   {
1485     tEvalResult EvalResult;
1486 
1487     WAsmCode[1] = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
1488     if (EvalResult.OK)
1489     {
1490       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
1491       0[WAsmCode] = Index;
1492       CodeLen = 2;
1493     }
1494   }
1495 }
1496 
DecodeBANZ(Word Index)1497 static void DecodeBANZ(Word Index)
1498 {
1499   if (!ChkArgCnt(2, 2));
1500   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1501   else if (LastRep) WrError(ErrNum_NotRepeatable);
1502   else if (DecodeAdr(&ArgStr[2], MModMem))
1503   {
1504     tEvalResult EvalResult;
1505 
1506     if (CodeLen)
1507       WAsmCode[1] = 1[AdrVals];
1508     WAsmCode[1 + CodeLen] = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
1509     if (EvalResult.OK)
1510     {
1511       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
1512       0[WAsmCode] = Index | (*AdrVals);
1513       CodeLen = 2 + AdrCnt;
1514     }
1515   }
1516 }
1517 
DecodePMADCond(Word Index)1518 static void DecodePMADCond(Word Index)
1519 {
1520   int index;
1521   Boolean OK;
1522 
1523   if (!ChkArgCnt(2, ArgCntMax));
1524   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1525   else if (LastRep) WrError(ErrNum_NotRepeatable);
1526   else if (!DecodeCondition(2, WAsmCode, &index, &OK))
1527     WrStrErrorPos(OK ? ErrNum_UndefCond : ErrNum_IncompCond, &ArgStr[index]);
1528   else
1529   {
1530     tEvalResult EvalResult;
1531 
1532     WAsmCode[1] = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
1533     if (EvalResult.OK)
1534     {
1535       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
1536       0[WAsmCode] |= Index;
1537       CodeLen = 2;
1538     }
1539   }
1540 }
1541 
DecodeFPMAD(Word Index)1542 static void DecodeFPMAD(Word Index)
1543 {
1544   if (!ChkArgCnt(1, 1));
1545   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1546   else if (LastRep) WrError(ErrNum_NotRepeatable);
1547   else
1548   {
1549     tEvalResult EvalResult;
1550     LongWord Addr = EvalStrIntExpressionWithResult(&ArgStr[1], UInt23, &EvalResult);
1551     if (EvalResult.OK)
1552     {
1553       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
1554       0[WAsmCode] = Index | (Addr >> 16);
1555       1[WAsmCode] = Addr & 0xffff;
1556       CodeLen = 2;
1557     }
1558   }
1559 }
1560 
DecodeINTR(Word Index)1561 static void DecodeINTR(Word Index)
1562 {
1563   Boolean OK;
1564 
1565   if (!ChkArgCnt(1, 1));
1566   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1567   else if (LastRep) WrError(ErrNum_NotRepeatable);
1568   else
1569   {
1570     *WAsmCode = Index | EvalStrIntExpression(&ArgStr[1], UInt5, &OK);
1571     if (OK)
1572       CodeLen = 1;
1573   }
1574 }
1575 
DecodeRPT(Word Index)1576 static void DecodeRPT(Word Index)
1577 {
1578   UNUSED(Index);
1579 
1580   if (!ChkArgCnt(1, 1));
1581   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1582   else if (LastRep) WrError(ErrNum_NotRepeatable);
1583   else
1584   {
1585     OpSize = UInt16;
1586     DecodeAdr(&ArgStr[1], MModImm | MModMem);
1587     switch (AdrMode)
1588     {
1589       case ModImm:
1590         if (!Hi(*AdrVals))
1591         {
1592           *WAsmCode = 0xec00 | (*AdrVals);
1593           CodeLen = 1;
1594         }
1595         else
1596         {
1597           *WAsmCode = 0xf070;
1598           WAsmCode[1] = *AdrVals;
1599           CodeLen = 2;
1600         }
1601         ThisRep = True;
1602         break;
1603       case ModMem:
1604         WAsmCode[0] = 0x4700 | (*AdrVals);
1605         if (AdrCnt)
1606           WAsmCode[1] = AdrVals[1];
1607         CodeLen = 1 + AdrCnt;
1608         ThisRep = True;
1609         break;
1610     }
1611   }
1612 }
1613 
DecodeRPTZ(Word Index)1614 static void DecodeRPTZ(Word Index)
1615 {
1616   UNUSED(Index);
1617 
1618   if (!ChkArgCnt(2, 2));
1619   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1620   else if (LastRep) WrError(ErrNum_NotRepeatable);
1621   else if (DecodeAdr(&ArgStr[1], MModAcc))
1622   {
1623     *WAsmCode = 0xf071 | (AdrVals[0] << 8);
1624     OpSize = UInt16;
1625     if (DecodeAdr(&ArgStr[2], MModImm))
1626     {
1627       WAsmCode[1] = *AdrVals;
1628       CodeLen = 2;
1629       ThisRep = True;
1630     }
1631   }
1632 }
1633 
DecodeFRAME(Word Index)1634 static void DecodeFRAME(Word Index)
1635 {
1636   Boolean OK;
1637 
1638   UNUSED(Index);
1639 
1640   if (!ChkArgCnt(1, 1));
1641   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1642   else
1643   {
1644     *WAsmCode = 0xee00 | (EvalStrIntExpression(&ArgStr[1], SInt8, &OK) & 0xff);
1645     if (OK)
1646       CodeLen = 1;
1647   }
1648 }
1649 
DecodeIDLE(Word Index)1650 static void DecodeIDLE(Word Index)
1651 {
1652   Boolean OK;
1653 
1654   UNUSED(Index);
1655 
1656   if (!ChkArgCnt(1, 1));
1657   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1658   else if (LastRep) WrError(ErrNum_NotRepeatable);
1659   else
1660   {
1661     tSymbolFlags Flags;
1662 
1663     *WAsmCode = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt2, &OK, &Flags);
1664     if (mFirstPassUnknown(Flags))
1665       *WAsmCode = 1;
1666     if ((OK) && (ChkRange(*WAsmCode, 1, 3)))
1667     {
1668       if (*WAsmCode != 2)
1669         *WAsmCode = (*WAsmCode) >> 1;
1670       *WAsmCode = 0xf4e1 | (*WAsmCode << 8);
1671       CodeLen = 1;
1672     }
1673   }
1674 }
1675 
DecodeSBIT(Word Index)1676 static void DecodeSBIT(Word Index)
1677 {
1678   Boolean OK;
1679   Word Bit;
1680 
1681   if (!ChkArgCnt(1, 2));
1682   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1683   else if (LastRep) WrError(ErrNum_NotRepeatable);
1684   else
1685   {
1686     if (ArgCnt == 1)
1687       Bit = EvalStrIntExpression(&ArgStr[1], UInt5, &OK);
1688     else
1689     {
1690       Bit = EvalStrIntExpression(&ArgStr[1], UInt1, &OK) << 4;
1691       if (OK)
1692         Bit |= EvalStrIntExpression(&ArgStr[2], UInt4, &OK);
1693     }
1694     if (OK)
1695     {
1696       *WAsmCode = Index | ((Bit & 16) << 5) | (Bit & 15);
1697       CodeLen = 1;
1698     }
1699   }
1700 }
1701 
DecodeXC(Word Index)1702 static void DecodeXC(Word Index)
1703 {
1704   Boolean OK;
1705   int errindex;
1706 
1707   UNUSED(Index);
1708 
1709   if (!ChkArgCnt(2, ArgCntMax));
1710   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1711   else if (LastRep) WrError(ErrNum_NotRepeatable);
1712   else if (!DecodeCondition(2, WAsmCode, &errindex, &OK))
1713     WrStrErrorPos(OK ? ErrNum_UndefCond : ErrNum_IncompCond, &ArgStr[errindex]);
1714   else
1715   {
1716     tSymbolFlags Flags;
1717 
1718     errindex = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt2, &OK, &Flags);
1719     if (mFirstPassUnknown(Flags))
1720       errindex = 1;
1721     if ((OK) && (ChkRange(errindex, 1, 2)))
1722     {
1723       errindex--;
1724       0[WAsmCode] |= 0xfd00 | (errindex << 9);
1725       CodeLen = 1;
1726     }
1727   }
1728 }
1729 
DecodeLD(Word Index)1730 static void DecodeLD(Word Index)
1731 {
1732   Integer Shift;
1733   Boolean OK;
1734 
1735   UNUSED(Index);
1736 
1737   if (!ChkArgCnt(2, 3));
1738 
1739   else if (!as_strcasecmp(ArgStr[ArgCnt].Str, "T"))
1740   {
1741     if (!ChkArgCnt(2, 2));
1742     else if (DecodeAdr(&ArgStr[1], MModMem))
1743     {
1744       if (ThisPar)
1745       {
1746         if (MakeXY(AdrVals, TRUE))
1747         {
1748           /* prev. operation must be STH src,0,Xmem */
1749           if ((LastOpCode & 0xfe0f) != 0x9a00) WrError(ErrNum_ParNotPossible);
1750           else
1751           {
1752             RetractWords(1);
1753             *WAsmCode = 0xe400 | ((LastOpCode & 0x0100) << 1)
1754                         | ((LastOpCode & 0x00f0) >> 4) | ((*AdrVals) << 4);
1755             CodeLen = 1;
1756           }
1757         }
1758       }
1759       else
1760       {
1761         WAsmCode[0] = 0x3000 | AdrVals[0];
1762         if (AdrCnt)
1763           WAsmCode[1] = AdrVals[1];
1764         CodeLen = 1 + AdrCnt;
1765       }
1766     }
1767   }
1768 
1769   else if (!as_strcasecmp(ArgStr[ArgCnt].Str, "DP"))
1770   {
1771     if (!ChkArgCnt(2, 2));
1772     else if (ThisPar) WrError(ErrNum_ParNotPossible);
1773     else
1774     {
1775       OpSize = UInt9;
1776       DecodeAdr(&ArgStr[1], MModMem | MModImm);
1777       switch (AdrMode)
1778       {
1779         case ModMem:
1780           WAsmCode[0] = 0x2600 | AdrVals[0];
1781           if (AdrCnt)
1782             WAsmCode[1] = AdrVals[1];
1783           CodeLen = 1 + AdrCnt;
1784           break;
1785         case ModImm:
1786           WAsmCode[0] = 0xea00 | (AdrVals[0] & 0x1ff);
1787           CodeLen = 1;
1788           break;
1789       }
1790     }
1791   }
1792 
1793   else if (!as_strcasecmp(ArgStr[ArgCnt].Str, "ARP"))
1794   {
1795     if (!ChkArgCnt(2, 2));
1796     else if (ThisPar) WrError(ErrNum_ParNotPossible);
1797     else
1798     {
1799       OpSize = UInt3;
1800       if (DecodeAdr(&ArgStr[1], MModImm))
1801       {
1802         WAsmCode[0] = 0xf4a0 | (AdrVals[0] & 7);
1803         CodeLen = 1;
1804       }
1805     }
1806   }
1807 
1808   else if (!as_strcasecmp(ArgStr[2].Str, "ASM"))
1809   {
1810     if (ThisPar) WrError(ErrNum_ParNotPossible);
1811     else
1812     {
1813       OpSize = SInt5;
1814       DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModImm);
1815       switch (AdrMode)
1816       {
1817         case ModAcc:
1818           WAsmCode[0] = *AdrVals << 9;
1819           if (ArgCnt == 3)
1820             DecodeAdr(&ArgStr[3], MModAcc);
1821           if (AdrMode == ModAcc)
1822           {
1823             WAsmCode[0] |= 0xf482 | (AdrVals[0] << 8);
1824             CodeLen = 1;
1825           }
1826           break;
1827         case ModMem:
1828           if (ChkArgCnt(2, 2))
1829           {
1830             WAsmCode[0] = 0x3200 | AdrVals[0];
1831             if (AdrCnt)
1832               WAsmCode[1] = AdrVals[1];
1833             CodeLen = 1 + AdrCnt;
1834           }
1835           break;
1836         case ModImm:
1837           if (ChkArgCnt(2, 2))
1838           {
1839             WAsmCode[0] = 0xed00 | (AdrVals[0] & 0x1f);
1840             CodeLen = 1;
1841           }
1842           break;
1843       }
1844     }
1845   }
1846 
1847   else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
1848   {
1849     *WAsmCode = *AdrVals << 8;
1850     if (ArgCnt == 3)
1851     {
1852       if (!as_strcasecmp(ArgStr[2].Str, "TS"))
1853       {
1854         Shift = 0xff;
1855         OK = True;
1856       }
1857       else
1858       {
1859         tSymbolFlags Flags;
1860 
1861         Shift = EvalStrIntExpressionWithFlags(&ArgStr[2], SInt6, &OK, &Flags);
1862         if (mFirstPassUnknown(Flags))
1863           Shift = 0;
1864         if (OK)
1865           OK = ChkRange(Shift, -16, 16);
1866       }
1867     }
1868     else
1869     {
1870       Shift = 0;
1871       OK = True;
1872     }
1873     if (OK)
1874     {
1875       OpSize = UInt16;
1876       DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModImm);
1877       switch (AdrMode)
1878       {
1879         case ModAcc:
1880           if (ThisPar) WrError(ErrNum_ParNotPossible);
1881           else if (ChkRange(Shift, -16, 15))
1882           {
1883             *WAsmCode |= 0xf440 | (AdrVals[0] << 9) | (Shift & 0x1f);
1884             CodeLen = 1;
1885           }
1886           break;
1887         case ModMem:
1888           if (Shift == 0xff) /* TS ? */
1889           {
1890             if (ThisPar) WrError(ErrNum_ParNotPossible);
1891             else
1892             {
1893               *WAsmCode |= 0x1400 | AdrVals[0];
1894               if (AdrCnt)
1895                 WAsmCode[1] = AdrVals[1];
1896               CodeLen = 1 + AdrCnt;
1897             }
1898           }
1899           else if ((Shift >= 0) && (MakeXY(WAsmCode + 1, False)))
1900           {
1901             if (ThisPar)
1902             {
1903               if (Shift) WrError(ErrNum_ParNotPossible);
1904               /* prev. operation must be STH src,0,Xmem */
1905               else if ((LastOpCode & 0xfe0f) != 0x9a00) WrError(ErrNum_ParNotPossible);
1906               else
1907               {
1908                 RetractWords(1);
1909                 *WAsmCode |= 0xc800 | ((LastOpCode & 0x0100) << 1)
1910                              | ((LastOpCode & 0x00f0) >> 4) | (WAsmCode[1] << 4);
1911                 CodeLen = 1;
1912               }
1913             }
1914             else
1915             {
1916               WAsmCode[0] |= 0x9400 | (WAsmCode[1] << 4) | Shift;
1917               CodeLen = 1;
1918             }
1919           }
1920           else if (Shift == 16)
1921           {
1922             if (ThisPar) WrError(ErrNum_ParNotPossible);
1923             else
1924             {
1925               WAsmCode[0] |= 0x4400 | AdrVals[0];
1926               if (AdrCnt)
1927                 WAsmCode[1] = AdrVals[1];
1928               CodeLen = 1 + AdrCnt;
1929             }
1930           }
1931           else if (!Shift)
1932           {
1933             if (ThisPar) WrError(ErrNum_ParNotPossible);
1934             else
1935             {
1936               WAsmCode[0] |= 0x1000 | AdrVals[0];
1937               if (AdrCnt)
1938                 WAsmCode[1] = AdrVals[1];
1939               CodeLen = 1 + AdrCnt;
1940             }
1941           }
1942           else
1943           {
1944             if (ThisPar) WrError(ErrNum_ParNotPossible);
1945             else
1946             {
1947               WAsmCode[1 + AdrCnt] = 0x0c40 | WAsmCode[0] | (Shift & 0x1f);
1948               WAsmCode[0] = 0x6f00 | AdrVals[0];
1949               if (AdrCnt)
1950                 WAsmCode[1] = AdrVals[1];
1951               CodeLen = 2 + AdrCnt;
1952             }
1953           }
1954           break;
1955         case ModImm:
1956           if (Shift == 0xff) WrError(ErrNum_InvAddrMode);
1957           else if (ThisPar) WrError(ErrNum_ParNotPossible);
1958           else if (ChkRange(Shift, 0, 16))
1959           {
1960             if ((Hi(AdrVals[0]) == 0) && (!Shift))
1961             {
1962               WAsmCode[0] |= 0xe800 | Lo(AdrVals[0]);
1963               CodeLen = 1;
1964             }
1965             else if (Shift == 16)
1966             {
1967               WAsmCode[0] |= 0xf062;
1968               WAsmCode[1] = AdrVals[0];
1969               CodeLen = 2;
1970             }
1971             else
1972             {
1973               WAsmCode[0] |= 0xf020 | (Shift & 15);
1974               WAsmCode[1] = AdrVals[0];
1975               CodeLen = 2;
1976             }
1977           }
1978           break;
1979       }
1980     }
1981   }
1982 }
1983 
DecodePSHM(Word Index)1984 static void DecodePSHM(Word Index)
1985 {
1986   UNUSED(Index);
1987 
1988   if (!ChkArgCnt(1, 1));
1989   else if (ThisPar) WrError(ErrNum_ParNotPossible);
1990   else
1991   {
1992     ForcePageZero = True;
1993     if (DecodeAdr(&ArgStr[1], MModMem))
1994     {
1995       *WAsmCode = 0x4a00 | (*AdrVals);
1996       CodeLen = 1;
1997     }
1998   }
1999 }
2000 
DecodeLDM(Word Index)2001 static void DecodeLDM(Word Index)
2002 {
2003   UNUSED(Index);
2004 
2005   if (!ChkArgCnt(2, 2));
2006   else if (ThisPar) WrError(ErrNum_ParNotPossible);
2007   else if (DecodeAdr(&ArgStr[2], MModAcc))
2008   {
2009     *WAsmCode = 0x4800 | (*AdrVals << 8);
2010     ForcePageZero = True;
2011     if (DecodeAdr(&ArgStr[1], MModMem))
2012     {
2013       *WAsmCode |= *AdrVals;
2014       CodeLen = 1;
2015     }
2016   }
2017 }
2018 
DecodeSTLM(Word Index)2019 static void DecodeSTLM(Word Index)
2020 {
2021   UNUSED(Index);
2022 
2023   if (!ChkArgCnt(2, 2));
2024   else if (ThisPar) WrError(ErrNum_ParNotPossible);
2025   else if (DecodeAdr(&ArgStr[1], MModAcc))
2026   {
2027     *WAsmCode = 0x8800 | (*AdrVals << 8);
2028     ForcePageZero = True;
2029     if (DecodeAdr(&ArgStr[2], MModMem))
2030     {
2031       *WAsmCode |= *AdrVals;
2032       CodeLen = 1;
2033     }
2034   }
2035 }
2036 
DecodeSTM(Word Index)2037 static void DecodeSTM(Word Index)
2038 {
2039   UNUSED(Index);
2040 
2041   if (!ChkArgCnt(2, 2));
2042   else if (ThisPar) WrError(ErrNum_ParNotPossible);
2043   else if (DecodeAdr(&ArgStr[1], MModImm))
2044   {
2045     WAsmCode[1] = *AdrVals;
2046     ForcePageZero = True;
2047     if (DecodeAdr(&ArgStr[2], MModMem))
2048     {
2049       *WAsmCode = 0x7700 | (*AdrVals);
2050       CodeLen = 2;
2051     }
2052   }
2053 }
2054 
DecodeDST(Word Index)2055 static void DecodeDST(Word Index)
2056 {
2057   UNUSED(Index);
2058 
2059   if (!ChkArgCnt(2, 2));
2060   else if (ThisPar) WrError(ErrNum_ParNotPossible);
2061   else if (DecodeAdr(&ArgStr[1], MModAcc))
2062   {
2063     *WAsmCode = 0x4e00 | (*AdrVals << 8);
2064     if (DecodeAdr(&ArgStr[2], MModMem))
2065     {
2066       *WAsmCode |= *AdrVals;
2067       if (AdrCnt)
2068        1[WAsmCode] = 1[AdrVals];
2069       CodeLen = 1 + AdrCnt;
2070     }
2071   }
2072 }
2073 
DecodeST(Word Index)2074 static void DecodeST(Word Index)
2075 {
2076   Word Acc;
2077 
2078   UNUSED(Index);
2079 
2080   /* NOTE: we also allow the form 'ST src,Xmem' as an alias
2081      for 'STH src,Ymem' since the first form is used in parallel
2082      load-store instructions. */
2083 
2084   if (!ChkArgCnt(2, 2));
2085   else if (ThisPar) WrError(ErrNum_ParNotPossible);
2086   else if (DecodeAdr(&ArgStr[2], MModMem))
2087   {
2088     *WAsmCode = *AdrVals;
2089     if (AdrCnt)
2090       1[WAsmCode] = 1[AdrVals];
2091     CodeLen = 1 + AdrCnt;
2092     OpSize = SInt16;
2093     if (!as_strcasecmp(ArgStr[1].Str, "T"))
2094       *WAsmCode |= 0x8c00;
2095     else if (!as_strcasecmp(ArgStr[1].Str, "TRN"))
2096       *WAsmCode |= 0x8d00;
2097     else
2098     {
2099       DecodeAdr(&ArgStr[1], MModImm | MModAcc);
2100       switch (AdrMode)
2101       {
2102         case ModImm:
2103           *WAsmCode |= 0x7600;
2104           (CodeLen++)[WAsmCode] = *AdrVals;
2105           break;
2106         case ModAcc:
2107           Acc = *AdrVals;
2108           *AdrVals = *WAsmCode;
2109           AdrMode = ModMem;
2110           if (MakeXY(AdrVals, True))
2111           {
2112             *WAsmCode = 0x9a00 | (Acc << 8) | (*AdrVals << 4);
2113             CodeLen = 1;
2114           }
2115           else
2116             CodeLen = 0;
2117           break;
2118         default:
2119           CodeLen = 0;
2120       }
2121     }
2122   }
2123 }
2124 
DecodeSTLH(Word Index)2125 static void DecodeSTLH(Word Index)
2126 {
2127   Integer Shift;
2128   Boolean OK;
2129 
2130   if (!ChkArgCnt(2, 3));
2131   else if (ThisPar) WrError(ErrNum_ParNotPossible);
2132   else if (DecodeAdr(&ArgStr[1], MModAcc))
2133   {
2134     *WAsmCode = Index | (*AdrVals << 8);
2135     OK = True;
2136     if (ArgCnt == 2)
2137       Shift = 0;
2138     else if (!as_strcasecmp(ArgStr[2].Str, "ASM"))
2139       Shift = 0xff;
2140     else
2141       Shift = EvalStrIntExpression(&ArgStr[2], SInt5, &OK);
2142     if ((OK) && (DecodeAdr(&ArgStr[ArgCnt], MModMem)))
2143     {
2144       if (AdrCnt)
2145         1[WAsmCode] = 1[AdrVals];
2146       CodeLen = 1 + AdrCnt;
2147       if (!Shift)
2148         *WAsmCode |= 0x8000 | *AdrVals;
2149       else if (Shift == 0xff)
2150         *WAsmCode |= 0x8400 | *AdrVals;
2151       else if ((MakeXY(WAsmCode + 2, False)) && (Shift > 0))
2152         *WAsmCode |= 0x9800 | (2[WAsmCode] << 4) | Shift;
2153       else
2154       {
2155         CodeLen[WAsmCode] = (0x0c80 | ((*WAsmCode) & 0x100) | (Shift & 0x1f)) - (Index >> 4);
2156         *WAsmCode = 0x6f00 | *AdrVals;
2157         CodeLen++;
2158       }
2159     }
2160   }
2161 }
2162 
DecodeCMPS(Word Index)2163 static void DecodeCMPS(Word Index)
2164 {
2165   UNUSED(Index);
2166 
2167   if (!ChkArgCnt(2, 2));
2168   else if (ThisPar) WrError(ErrNum_ParNotPossible);
2169   else if (DecodeAdr(&ArgStr[1], MModAcc))
2170   {
2171     *WAsmCode = 0x8e00 | (*AdrVals << 8);
2172     if (DecodeAdr(&ArgStr[2], MModMem))
2173     {
2174       *WAsmCode |= *AdrVals;
2175       if (AdrCnt)
2176        1[WAsmCode] = 1[AdrVals];
2177       CodeLen = 1 + AdrCnt;
2178     }
2179   }
2180 }
2181 
DecodeSACCD(Word Index)2182 static void DecodeSACCD(Word Index)
2183 {
2184   int index;
2185   Boolean OK;
2186 
2187   UNUSED(Index);
2188 
2189   if (!ChkArgCnt(3, 3));
2190   else if (ThisPar) WrError(ErrNum_ParNotPossible);
2191   else if (DecodeAdr(&ArgStr[1], MModAcc))
2192   {
2193     *WAsmCode = 0x9e00 | ((*AdrVals) << 8);
2194     if ((DecodeAdr(&ArgStr[2], MModMem))
2195      && (MakeXY(AdrVals, True)))
2196     {
2197       *WAsmCode |= ((*AdrVals) << 4);
2198       if (!DecodeCondition(3, WAsmCode + 1, &index, &OK)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[index]);
2199       else if ((WAsmCode[1] & 0xf0) != 0x40) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[index]);
2200       else
2201       {
2202         *WAsmCode |= WAsmCode[1] & 15;
2203         CodeLen = 1;
2204       }
2205     }
2206   }
2207 }
2208 
DecodeStoreCC(Word Index)2209 static void DecodeStoreCC(Word Index)
2210 {
2211   int index;
2212   Boolean OK;
2213 
2214   UNUSED(Index);
2215 
2216   if (!ChkArgCnt(2, 2));
2217   else if (ThisPar) WrError(ErrNum_ParNotPossible);
2218   else if ((DecodeAdr(&ArgStr[1], MModMem)) && (MakeXY(AdrVals, True)))
2219   {
2220     *WAsmCode = Index | ((*AdrVals) << 4);
2221     if (!DecodeCondition(2, WAsmCode + 1, &index, &OK)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[index]);
2222     else if ((WAsmCode[1] & 0xf0) != 0x40) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[index]);
2223     else
2224     {
2225       *WAsmCode |= WAsmCode[1] & 15;
2226       CodeLen = 1;
2227     }
2228   }
2229 }
2230 
DecodeMVDabs(Word Index)2231 static void DecodeMVDabs(Word Index)
2232 {
2233   if (!ChkArgCnt(2, 2));
2234   else if (ThisPar) WrError(ErrNum_ParNotPossible);
2235   else if (DecodeAdr(&ArgStr[1], MModMem))
2236   {
2237     tEvalResult EvalResult;
2238 
2239     *WAsmCode = Index | *AdrVals;
2240     if (AdrCnt)
2241       1[WAsmCode] = 1[AdrVals];
2242     WAsmCode[1 + AdrCnt] = EvalStrIntExpressionWithResult(&ArgStr[2], UInt16, &EvalResult);
2243     if (EvalResult.OK)
2244     {
2245       ChkSpace((Index == 0x7100) ? SegData : SegCode, EvalResult.AddrSpaceMask);
2246       CodeLen = 2 + AdrCnt;
2247     }
2248   }
2249 }
2250 
DecodeMVabsD(Word Index)2251 static void DecodeMVabsD(Word Index)
2252 {
2253   if (!ChkArgCnt(2, 2));
2254   else if (ThisPar) WrError(ErrNum_ParNotPossible);
2255   else if (DecodeAdr(&ArgStr[2], MModMem))
2256   {
2257     tEvalResult EvalResult;
2258 
2259     *WAsmCode = Index | *AdrVals;
2260     if (AdrCnt)
2261       1[WAsmCode] = 1[AdrVals];
2262     WAsmCode[1 + AdrCnt] = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
2263     if (EvalResult.OK)
2264     {
2265       ChkSpace((Index == 0x7000) ? SegData : SegCode, EvalResult.AddrSpaceMask);
2266       CodeLen = 2 + AdrCnt;
2267     }
2268   }
2269 }
2270 
DecodeMVdmadmmr(Word Index)2271 static void DecodeMVdmadmmr(Word Index)
2272 {
2273   if (!ChkArgCnt(2, 2));
2274   else if (ThisPar) WrError(ErrNum_ParNotPossible);
2275   else
2276   {
2277     const tStrComp *pArg1 = (Index & 0x0100) ? &ArgStr[2] : &ArgStr[1],
2278                    *pArg2 = (Index & 0x0100) ? &ArgStr[1] : &ArgStr[2];
2279 
2280     ForcePageZero = True;
2281     if (DecodeAdr(pArg2, MModMem))
2282     {
2283       tEvalResult EvalResult;
2284 
2285       *WAsmCode = Index | *AdrVals;
2286       WAsmCode[1] = EvalStrIntExpressionWithResult(pArg1, UInt16, &EvalResult);
2287       if (EvalResult.OK)
2288       {
2289         ChkSpace(SegData, EvalResult.AddrSpaceMask);
2290         CodeLen = 2;
2291       }
2292     }
2293   }
2294 }
2295 
GetReg(const tStrComp * pArg,Word * Res)2296 static Boolean GetReg(const tStrComp *pArg, Word *Res)
2297 {
2298   tEvalResult EvalResult;
2299 
2300   *Res = EvalStrIntExpressionWithResult(pArg, UInt8, &EvalResult);
2301   if (EvalResult.OK)
2302   {
2303     if (mFirstPassUnknown(EvalResult.Flags))
2304       *Res = 0x10;
2305     ChkSpace(SegData, EvalResult.AddrSpaceMask);
2306     EvalResult.OK = ChkRange(*Res, 0x10, 0x1f);
2307     if (EvalResult.OK)
2308       *Res -= 0x10;
2309   }
2310   return EvalResult.OK;
2311 }
2312 
DecodeMVMM(Word Index)2313 static void DecodeMVMM(Word Index)
2314 {
2315   Word XReg, YReg;
2316   UNUSED(Index);
2317 
2318   if (!ChkArgCnt(2, 2));
2319   else if (ThisPar) WrError(ErrNum_ParNotPossible);
2320   else if ((GetReg(&ArgStr[1], &XReg)) && (GetReg(&ArgStr[2], &YReg)))
2321   {
2322     *WAsmCode = 0xe700 | (XReg << 4) | YReg;
2323     CodeLen = 1;
2324   }
2325 }
2326 
DecodePort(Word Index)2327 static void DecodePort(Word Index)
2328 {
2329   if (!ChkArgCnt(2, 2));
2330   else if (ThisPar) WrError(ErrNum_ParNotPossible);
2331   else
2332   {
2333     const tStrComp *pArg1 = (Index & 0x0100) ? &ArgStr[2] : &ArgStr[1],
2334                    *pArg2 = (Index & 0x0100) ? &ArgStr[1] : &ArgStr[2];
2335 
2336     if (DecodeAdr(pArg2, MModMem))
2337     {
2338       tEvalResult EvalResult;
2339 
2340       *WAsmCode = Index | *AdrVals;
2341       if (AdrCnt)
2342         1[WAsmCode] = 1[AdrVals];
2343       WAsmCode[1 + AdrCnt] = EvalStrIntExpressionWithResult(pArg1, UInt16, &EvalResult);
2344       if (EvalResult.OK)
2345       {
2346         ChkSpace(SegIO, EvalResult.AddrSpaceMask);
2347         CodeLen = 2 + AdrCnt;
2348       }
2349     }
2350   }
2351 }
2352 
2353 /*-------------------------------------------------------------------------*/
2354 /* Pseudo Instructions */
2355 
DecodePseudo(void)2356 static Boolean DecodePseudo(void)
2357 {
2358   if (Memo("PORT"))
2359   {
2360     CodeEquate(SegIO, 0, 65535);
2361     return True;
2362   }
2363 
2364   return False;
2365 }
2366 
2367 /*-------------------------------------------------------------------------*/
2368 /* Code Table Handling */
2369 
AddFixed(const char * Name,Word Code,Boolean IsRepeatable)2370 static void AddFixed(const char *Name, Word Code, Boolean IsRepeatable)
2371 {
2372   if (InstrZ >= FixedOrderCnt)
2373     exit(0);
2374 
2375   FixedOrders[InstrZ].Code         = Code;
2376   FixedOrders[InstrZ].IsRepeatable = IsRepeatable;
2377   AddInstTable(InstTable, Name, InstrZ++, DecodeFixed);
2378 }
2379 
AddAcc(const char * Name,Word Code,Boolean IsRepeatable)2380 static void AddAcc(const char *Name, Word Code, Boolean IsRepeatable)
2381 {
2382   if (InstrZ >= AccOrderCnt)
2383     exit(0);
2384 
2385   AccOrders[InstrZ].Code         = Code;
2386   AccOrders[InstrZ].IsRepeatable = IsRepeatable;
2387   AddInstTable(InstTable, Name, InstrZ++, DecodeAcc);
2388 }
2389 
AddAcc2(const char * Name,Word Code,Boolean IsRepeatable)2390 static void AddAcc2(const char *Name, Word Code, Boolean IsRepeatable)
2391 {
2392   if (InstrZ >= Acc2OrderCnt)
2393     exit(0);
2394 
2395   Acc2Orders[InstrZ].Code         = Code;
2396   Acc2Orders[InstrZ].IsRepeatable = IsRepeatable;
2397   AddInstTable(InstTable, Name, InstrZ++, DecodeAcc2);
2398 }
2399 
AddMem(const char * Name,Word Code,Boolean IsRepeatable)2400 static void AddMem(const char *Name, Word Code, Boolean IsRepeatable)
2401 {
2402   if (InstrZ >= MemOrderCnt)
2403     exit(0);
2404 
2405   MemOrders[InstrZ].Code         = Code;
2406   MemOrders[InstrZ].IsRepeatable = IsRepeatable;
2407   AddInstTable(InstTable, Name, InstrZ++, DecodeMem);
2408 }
2409 
AddXY(const char * Name,Word Code,Boolean IsRepeatable)2410 static void AddXY(const char *Name, Word Code, Boolean IsRepeatable)
2411 {
2412   if (InstrZ >= XYOrderCnt)
2413     exit(0);
2414 
2415   XYOrders[InstrZ].Code         = Code;
2416   XYOrders[InstrZ].IsRepeatable = IsRepeatable;
2417   AddInstTable(InstTable, Name, InstrZ++, DecodeXY);
2418 }
2419 
AddMemAcc(const char * Name,Word Code,Boolean IsRepeatable)2420 static void AddMemAcc(const char *Name, Word Code, Boolean IsRepeatable)
2421 {
2422   if (InstrZ >= MemAccOrderCnt)
2423     exit(0);
2424 
2425   MemAccOrders[InstrZ].Code         = Code;
2426   MemAccOrders[InstrZ].IsRepeatable = IsRepeatable;
2427   AddInstTable(InstTable, Name, InstrZ++, DecodeMemAcc);
2428 }
2429 
AddMemConst(const char * Name,Word Code,Boolean IsRepeatable,Boolean Swap,IntType ConstType)2430 static void AddMemConst(const char *Name, Word Code, Boolean IsRepeatable, Boolean Swap, IntType ConstType)
2431 {
2432   if (InstrZ >= MemConstOrderCnt)
2433     exit(0);
2434 
2435   MemConstOrders[InstrZ].Code         = Code;
2436   MemConstOrders[InstrZ].IsRepeatable = IsRepeatable;
2437   MemConstOrders[InstrZ].Swap         = Swap;
2438   MemConstOrders[InstrZ].ConstType    = ConstType;
2439   AddInstTable(InstTable, Name, InstrZ++, DecodeMemConst);
2440 }
2441 
AddMac(const char * Name,Word Code,Boolean IsRepeatable)2442 static void AddMac(const char *Name, Word Code, Boolean IsRepeatable)
2443 {
2444   if (InstrZ >= MacOrderCnt)
2445     exit(0);
2446 
2447   MacOrders[InstrZ].Code         = Code;
2448   MacOrders[InstrZ].IsRepeatable = IsRepeatable;
2449   AddInstTable(InstTable, Name, InstrZ++, DecodeMac);
2450 }
2451 
AddCondition(const char * NName,Word NClass,Word NCode,Word NMask)2452 static void AddCondition(const char *NName, Word NClass, Word NCode, Word NMask)
2453 {
2454   if (InstrZ >= ConditionCnt)
2455     exit(0);
2456   Conditions[InstrZ  ].Name  = NName;
2457   Conditions[InstrZ  ].Class = NClass;
2458   Conditions[InstrZ  ].Code  = NCode;
2459   Conditions[InstrZ++].Mask  = NMask;
2460 }
2461 
InitFields(void)2462 static void InitFields(void)
2463 {
2464   InstTable = CreateInstTable(203);
2465 
2466   AddInstTable(InstTable, "LD", 0, DecodeLD);
2467   AddInstTable(InstTable, "ST", 0, DecodeST);
2468   AddInstTable(InstTable, "STH", 0x200, DecodeSTLH);
2469   AddInstTable(InstTable, "STL", 0x000, DecodeSTLH);
2470 
2471   FixedOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * FixedOrderCnt); InstrZ = 0;
2472   AddFixed("FRET"  , 0xf4e4, FALSE);
2473   AddFixed("FRETD" , 0xf6e4, FALSE);
2474   AddFixed("FRETE" , 0xf4e5, FALSE);
2475   AddFixed("FRETED", 0xf6e5, FALSE);
2476   AddFixed("NOP"   , NOPCode, TRUE);
2477   AddFixed("RESET" , 0xf7e0, FALSE);
2478   AddFixed("RET"   , 0xfc00, FALSE);
2479   AddFixed("RETD"  , 0xfe00, FALSE);
2480   AddFixed("RETE"  , 0xf4eb, FALSE);
2481   AddFixed("RETED" , 0xf6eb, FALSE);
2482   AddFixed("RETF"  , 0xf49b, FALSE);
2483   AddFixed("RETFD" , 0xf69b, FALSE);
2484 
2485   AccOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * AccOrderCnt); InstrZ = 0;
2486   AddAcc  ("EXP"   , 0xf48e, TRUE );
2487   AddAcc  ("MAX"   , 0xf486, TRUE );
2488   AddAcc  ("MIN"   , 0xf487, TRUE );
2489   AddAcc  ("SAT"   , 0xf483, TRUE );
2490   AddAcc  ("ROL"   , 0xf491, TRUE );
2491   AddAcc  ("ROLTC" , 0xf492, TRUE );
2492   AddAcc  ("ROR"   , 0xf490, TRUE );
2493   AddAcc  ("SFTC"  , 0xf494, TRUE );
2494   AddAcc  ("CALA"  , 0xf4e3, FALSE);
2495   AddAcc  ("CALAD" , 0xf6e3, FALSE);
2496   AddAcc  ("FCALA" , 0xf4e7, FALSE);
2497   AddAcc  ("FCALAD", 0xf6e7, FALSE);
2498   AddAcc  ("BACC"  , 0xf4e2, FALSE);
2499   AddAcc  ("BACCD" , 0xf6e2, FALSE);
2500   AddAcc  ("FBACC" , 0xf4e6, FALSE);
2501   AddAcc  ("FBACCD", 0xf6e6, FALSE);
2502 
2503   Acc2Orders = (FixedOrder*) malloc(sizeof(FixedOrder) * Acc2OrderCnt); InstrZ = 0;
2504   AddAcc2 ("NEG"   , 0xf484, TRUE );
2505   AddAcc2 ("NORM"  , 0xf48f, TRUE );
2506   AddAcc2 ("RND"   , 0xf49f, TRUE );
2507   AddAcc2 ("ABS"   , 0xf485, TRUE );
2508   AddAcc2 ("CMPL"  , 0xf493, TRUE );
2509 
2510   MemOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * MemOrderCnt); InstrZ = 0;
2511   AddMem  ("DELAY" , 0x4d00, TRUE );
2512   AddMem  ("POLY"  , 0x3600, TRUE );
2513   AddMem  ("BITT"  , 0x3400, TRUE );
2514   AddMem  ("POPD"  , 0x8b00, TRUE );
2515   AddMem  ("PSHD"  , 0x4b00, TRUE );
2516   AddMem  ("MAR"   , 0x6d00, TRUE );
2517   AddMem  ("LTD"   , 0x4c00, TRUE );
2518   AddMem  ("READA" , 0x7e00, TRUE );
2519   AddMem  ("WRITA" , 0x7f00, TRUE );
2520 
2521   XYOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * XYOrderCnt); InstrZ = 0;
2522   AddXY   ("ABDST" , 0xe300, TRUE );
2523   AddXY   ("LMS"   , 0xe100, TRUE );
2524   AddXY   ("SQDST" , 0xe200, TRUE );
2525   AddXY   ("MVDD"  , 0xe500, TRUE );
2526 
2527   AddInstTable(InstTable, "ADD", 0, DecodeADDSUB);
2528   AddInstTable(InstTable, "SUB", 1, DecodeADDSUB);
2529 
2530   MemAccOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * MemAccOrderCnt); InstrZ = 0;
2531   AddMemAcc("ADDC" , 0x0600, TRUE );
2532   AddMemAcc("ADDS" , 0x0200, TRUE );
2533   AddMemAcc("SUBB" , 0x0e00, TRUE );
2534   AddMemAcc("SUBC" , 0x1e00, TRUE );
2535   AddMemAcc("SUBS" , 0x0a00, TRUE );
2536   AddMemAcc("MPYR" , 0x2200, TRUE );
2537   AddMemAcc("MPYU" , 0x2400, TRUE );
2538   AddMemAcc("SQURA", 0x3800, TRUE );
2539   AddMemAcc("SQURS", 0x3a00, TRUE );
2540   AddMemAcc("DADST", 0x5a00, TRUE );
2541   AddMemAcc("DRSUB", 0x5800, TRUE );
2542   AddMemAcc("DSADT", 0x5e00, TRUE );
2543   AddMemAcc("DSUB" , 0x5400, TRUE );
2544   AddMemAcc("DSUBT", 0x5c00, TRUE );
2545   AddMemAcc("DLD"  , 0x5600, TRUE );
2546   AddMemAcc("LDR"  , 0x1600, TRUE );
2547   AddMemAcc("LDU"  , 0x1200, TRUE );
2548 
2549   MacOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * MacOrderCnt); InstrZ = 0;
2550   AddMac("MACA"  , 0x3508, TRUE );
2551   AddMac("MACAR" , 0x3709, TRUE );
2552   AddMac("MASA"  , 0x330a, TRUE );
2553 
2554   MemConstOrders = (MemConstOrder*) malloc(sizeof(MemConstOrder) * MemConstOrderCnt); InstrZ = 0;
2555   AddMemConst("ADDM", 0x6b00, FALSE, FALSE, SInt16);
2556   AddMemConst("ANDM", 0x6800, FALSE, FALSE, UInt16);
2557   AddMemConst("CMPM", 0x6000, TRUE , TRUE , SInt16);
2558   AddMemConst("ORM" , 0x6900, FALSE, FALSE, UInt16);
2559   AddMemConst("XORM", 0x6a00, FALSE, FALSE, UInt16);
2560 
2561   AddInstTable(InstTable, "AND"  , 0, DecodeLog);
2562   AddInstTable(InstTable, "OR"   , 1, DecodeLog);
2563   AddInstTable(InstTable, "XOR"  , 2, DecodeLog);
2564   AddInstTable(InstTable, "MPY"  , 0, DecodeMPY);
2565   AddInstTable(InstTable, "MPYA" , 0, DecodeMPYA);
2566   AddInstTable(InstTable, "SQUR" , 0, DecodeSQUR);
2567   AddInstTable(InstTable, "MAC"  , 0, DecodeMAC);
2568   AddInstTable(InstTable, "MACR" , 0, DecodeMACR);
2569   AddInstTable(InstTable, "MACD" , 0x7a00, DecodeMACDP);
2570   AddInstTable(InstTable, "MACP" , 0x7800, DecodeMACDP);
2571   AddInstTable(InstTable, "MACSU", 0, DecodeMACSU);
2572   AddInstTable(InstTable, "MAS"  , 0x000, DecodeMAS);
2573   AddInstTable(InstTable, "MASR" , 0x200, DecodeMAS);
2574   AddInstTable(InstTable, "MASAR", 0, DecodeMASAR);
2575   AddInstTable(InstTable, "DADD" , 0, DecodeDADD);
2576   AddInstTable(InstTable, "FIRS" , 0, DecodeFIRS);
2577   AddInstTable(InstTable, "SFTA" , 0xf460, DecodeSFT);
2578   AddInstTable(InstTable, "SFTL" , 0xf0e0, DecodeSFT);
2579   AddInstTable(InstTable, "BIT"  , 0, DecodeBIT);
2580   AddInstTable(InstTable, "BITF" , 0, DecodeBITF);
2581   AddInstTable(InstTable, "CMPR" , 0, DecodeCMPR);
2582 
2583   AddInstTable(InstTable, "B"    , 0xf073, DecodePMAD);
2584   AddInstTable(InstTable, "BD"   , 0xf273, DecodePMAD);
2585   AddInstTable(InstTable, "CALL" , 0xf074, DecodePMAD);
2586   AddInstTable(InstTable, "CALLD", 0xf274, DecodePMAD);
2587   AddInstTable(InstTable, "RPTB" , 0xf072, DecodePMAD);
2588   AddInstTable(InstTable, "RPTBD", 0xf272, DecodePMAD);
2589 
2590   AddInstTable(InstTable, "BC"   , 0xf800, DecodePMADCond);
2591   AddInstTable(InstTable, "BCD"  , 0xfa00, DecodePMADCond);
2592   AddInstTable(InstTable, "CC"   , 0xf900, DecodePMADCond);
2593   AddInstTable(InstTable, "CCD"  , 0xfb00, DecodePMADCond);
2594 
2595   AddInstTable(InstTable, "FB"    , 0xf880, DecodeFPMAD);
2596   AddInstTable(InstTable, "FBD"   , 0xfa80, DecodeFPMAD);
2597   AddInstTable(InstTable, "FCALL" , 0xf980, DecodeFPMAD);
2598   AddInstTable(InstTable, "FCALLD", 0xfb80, DecodeFPMAD);
2599 
2600   AddInstTable(InstTable, "BANZ" , 0x6c00, DecodeBANZ);
2601   AddInstTable(InstTable, "BANZD", 0x6e00, DecodeBANZ);
2602 
2603   AddInstTable(InstTable, "INTR" , 0xf7c0, DecodeINTR);
2604   AddInstTable(InstTable, "TRAP" , 0xf4c0, DecodeINTR);
2605   AddInstTable(InstTable, "PSHM" , 0     , DecodePSHM);
2606   AddInstTable(InstTable, "LDM"  , 0     , DecodeLDM);
2607   AddInstTable(InstTable, "STLM" , 0     , DecodeSTLM);
2608   AddInstTable(InstTable, "STM"  , 0     , DecodeSTM);
2609   AddInstTable(InstTable, "CMPS" , 0     , DecodeCMPS);
2610 
2611   AddInstTable(InstTable, "RPT"  , 0     , DecodeRPT);
2612   AddInstTable(InstTable, "RPTZ" , 0     , DecodeRPTZ);
2613 
2614   AddInstTable(InstTable, "FRAME", 0     , DecodeFRAME);
2615   AddInstTable(InstTable, "IDLE" , 0     , DecodeIDLE);
2616 
2617   AddInstTable(InstTable, "RSBX" , 0xf4b0, DecodeSBIT);
2618   AddInstTable(InstTable, "SSBX" , 0xf5b0, DecodeSBIT);
2619 
2620   AddInstTable(InstTable, "XC"   , 0     , DecodeXC);
2621 
2622   AddInstTable(InstTable, "DST"  , 0     , DecodeDST);
2623 
2624   AddInstTable(InstTable, "SACCD", 0     , DecodeSACCD);
2625 
2626   AddInstTable(InstTable, "SRCCD", 0x9d00, DecodeStoreCC);
2627   AddInstTable(InstTable, "STRCD", 0x9c00, DecodeStoreCC);
2628 
2629   AddInstTable(InstTable, "MVDK" , 0x7100, DecodeMVDabs);
2630   AddInstTable(InstTable, "MVDP" , 0x7d00, DecodeMVDabs);
2631   AddInstTable(InstTable, "MVKD" , 0x7000, DecodeMVabsD);
2632   AddInstTable(InstTable, "MVPD" , 0x7c00, DecodeMVabsD);
2633   AddInstTable(InstTable, "MVDM" , 0x7200, DecodeMVdmadmmr);
2634   AddInstTable(InstTable, "MVMD" , 0x7300, DecodeMVdmadmmr);
2635   AddInstTable(InstTable, "MVMM" , 0x7300, DecodeMVMM);
2636 
2637   AddInstTable(InstTable, "PORTR", 0x7400, DecodePort);
2638   AddInstTable(InstTable, "PORTW", 0x7500, DecodePort);
2639 
2640   Conditions = (Condition*) malloc(sizeof(Condition) * ConditionCnt); InstrZ = 0;
2641   AddCondition("BIO"  , 0, 0x0003, 0x0003);
2642   AddCondition("NBIO" , 0, 0x0002, 0x0003);
2643   AddCondition("C"    , 0, 0x000c, 0x000c);
2644   AddCondition("NC"   , 0, 0x0008, 0x000c);
2645   AddCondition("TC"   , 0, 0x0030, 0x0030);
2646   AddCondition("NTC"  , 0, 0x0020, 0x0030);
2647   AddCondition("AEQ"  , 1, 0x0045, 0x000f);
2648   AddCondition("ANEQ" , 1, 0x0044, 0x000f);
2649   AddCondition("AGT"  , 1, 0x0046, 0x000f);
2650   AddCondition("AGEQ" , 1, 0x0042, 0x000f);
2651   AddCondition("ALT"  , 1, 0x0043, 0x000f);
2652   AddCondition("ALEQ" , 1, 0x0047, 0x000f);
2653   AddCondition("AOV"  , 1, 0x0070, 0x00f0);
2654   AddCondition("ANOV" , 1, 0x0060, 0x00f0);
2655   AddCondition("BEQ"  , 2, 0x004d, 0x000f);
2656   AddCondition("BNEQ" , 2, 0x004c, 0x000f);
2657   AddCondition("BGT"  , 2, 0x004e, 0x000f);
2658   AddCondition("BGEQ" , 2, 0x004a, 0x000f);
2659   AddCondition("BLT"  , 2, 0x004b, 0x000f);
2660   AddCondition("BLEQ" , 2, 0x004f, 0x000f);
2661   AddCondition("BOV"  , 2, 0x0078, 0x00f0);
2662   AddCondition("BNOV" , 2, 0x0068, 0x00f0);
2663   AddCondition("UNC"  , 3, 0x0000, 0x00ff);
2664 }
2665 
DeinitFields(void)2666 static void DeinitFields(void)
2667 {
2668   DestroyInstTable(InstTable);
2669   free(FixedOrders);
2670   free(AccOrders);
2671   free(Acc2Orders);
2672   free(MemOrders);
2673   free(XYOrders);
2674   free(MemAccOrders);
2675   free(MemConstOrders);
2676   free(MacOrders);
2677   free(Conditions);
2678 }
2679 
2680 /*-------------------------------------------------------------------------*/
2681 /* Linking Routines */
2682 
MakeCode_32054x(void)2683 static void MakeCode_32054x(void)
2684 {
2685   CodeLen = 0;
2686   DontPrint = False;
2687 
2688   ThisPar = !strcmp(LabPart.Str, "||");
2689   if ((strlen(OpPart.Str) > 2) && (!strncmp(OpPart.Str, "||", 2)))
2690   {
2691     ThisPar = True; strmov(OpPart.Str, OpPart.Str + 2);
2692   }
2693 
2694   /* zu ignorierendes */
2695 
2696   if (*OpPart.Str == '\0')
2697     return;
2698 
2699   if (DecodePseudo())
2700     return;
2701 
2702   if (DecodeTIPseudo())
2703     return;
2704 
2705   /* search */
2706 
2707   ThisRep = False;
2708   ForcePageZero = False;
2709   if (!LookupInstTable(InstTable, OpPart.Str))
2710     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2711   else
2712     LastOpCode = *WAsmCode;
2713   LastRep = ThisRep;
2714 }
2715 
InitCode_32054x(void)2716 static void InitCode_32054x(void)
2717 {
2718   Reg_CPL = 0;
2719   Reg_DP = 0;
2720   Reg_SP = 0;
2721 }
2722 
IsDef_32054x(void)2723 static Boolean IsDef_32054x(void)
2724 {
2725   return (!strcmp(LabPart.Str, "||"));
2726 }
2727 
SwitchFrom_32054x(void)2728 static void SwitchFrom_32054x(void)
2729 {
2730   DeinitFields();
2731 }
2732 
SwitchTo_32054x(void)2733 static void SwitchTo_32054x(void)
2734 {
2735 #define ASSUME3254xCount (sizeof(ASSUME3254xs) / sizeof(*ASSUME3254xs))
2736   static ASSUMERec ASSUME3254xs[] =
2737   {
2738     {"CPL", &Reg_CPL, 0,      1,       0, NULL},
2739     {"DP" , &Reg_DP , 0,  0x1ff,   0x200, NULL},
2740     {"SP" , &Reg_SP , 0, 0xffff, 0x10000, NULL}
2741   };
2742 
2743   PFamilyDescr FoundDescr;
2744 
2745   FoundDescr = FindFamilyByName("TMS320C54x");
2746 
2747   TurnWords = False;
2748   ConstMode = ConstModeIntel;
2749 
2750   PCSymbol = "$";
2751   HeaderID = FoundDescr->Id;
2752   NOPCode = 0xf495;
2753   DivideChars = ",";
2754   HasAttrs = False;
2755 
2756   ValidSegs = (1 << SegCode) | (1 << SegData) | (1 << SegIO);
2757   Grans[SegCode] = 2; ListGrans[SegCode] = 2; SegInits[SegCode] = 2; SegLimits[SegCode] = 0xffff;
2758   Grans[SegData] = 2; ListGrans[SegData] = 2; SegInits[SegData] = 2; SegLimits[SegData] = 0xffff;
2759   Grans[SegIO  ] = 2; ListGrans[SegIO  ] = 2; SegInits[SegIO  ] = 2; SegLimits[SegIO  ] = 0xffff;
2760 
2761   MakeCode = MakeCode_32054x;
2762   IsDef = IsDef_32054x;
2763 
2764   pASSUMERecs = ASSUME3254xs;
2765   ASSUMERecCnt = ASSUME3254xCount;
2766 
2767   InitFields();
2768   SwitchFrom = SwitchFrom_32054x;
2769   ThisRep = LastRep = False;
2770   LastOpCode = 0;
2771 }
2772 
2773 /*-------------------------------------------------------------------------*/
2774 /* Global Interface */
2775 
code32054x_init(void)2776 void code32054x_init(void)
2777 {
2778   CPU320C541 = AddCPU("320C541", SwitchTo_32054x);
2779 
2780   AddInitPassProc(InitCode_32054x);
2781 }
2782