1 /* code56k.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS-Portierung                                                             */
6 /*                                                                           */
7 /* AS-Codegeneratormodul fuer die DSP56K-Familie                             */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14 
15 #include "strutil.h"
16 #include "chunks.h"
17 #include "errmsg.h"
18 #include "asmdef.h"
19 #include "asmsub.h"
20 #include "asmpars.h"
21 #include "asmitree.h"
22 #include "codepseudo.h"
23 #include "codevars.h"
24 
25 #include "code56k.h"
26 
27 typedef struct
28 {
29   LongWord Code;
30   CPUVar MinCPU;
31 } FixedOrder;
32 
33 typedef enum
34 {
35   ParAB, ParABShl1, ParABShl2, ParXYAB, ParABXYnAB, ParABBA, ParXYnAB, ParMul, ParFixAB
36 } ParTyp;
37 typedef struct
38 {
39   ParTyp Typ;
40   Byte Code;
41 } ParOrder;
42 
43 #define FixedOrderCnt 14
44 #define ParOrderCnt 31
45 
46 #define CondCount (sizeof(CondNames) / sizeof(*CondNames))
47 static const char CondNames[][3] =
48 {
49   "CC", "GE", "NE", "PL", "NN", "EC", "LC", "GT", "CS", "LT", "EQ", "MI",
50   "NR", "ES", "LS", "LE", "HS", "LO"
51 };
52 
53 static const Byte MacTable[4][4] =
54 {
55   { 0, 2, 5, 4 },
56   { 2, 0xff, 6, 7 },
57   { 5, 6, 1, 3 },
58   { 4, 7, 3, 0xff }
59 };
60 
61 static const Byte Mac4Table[4][4] =
62 {
63   { 0, 13, 10, 4 },
64   { 5, 1, 14, 11 },
65   { 2, 6, 8, 15 },
66   { 12, 3, 7, 9 }
67 };
68 
69 static const Byte Mac2Table[4] =
70 {
71   1, 3, 2, 0
72 };
73 
74 enum
75 {
76   ModNone = -1,
77   ModImm = 0,
78   ModAbs = 1,
79   ModIReg = 2,
80   ModPreDec = 3,
81   ModPostDec = 4,
82   ModPostInc = 5,
83   ModIndex = 6,
84   ModModDec = 7,
85   ModModInc = 8,
86   ModDisp = 9
87 };
88 
89 #define MModImm (1 << ModImm)
90 #define MModAbs (1 << ModAbs)
91 #define MModIReg (1 << ModIReg)
92 #define MModPreDec (1 << ModPreDec)
93 #define MModPostDec (1 << ModPostDec)
94 #define MModPostInc (1 << ModPostInc)
95 #define MModIndex (1 << ModIndex)
96 #define MModModDec (1 << ModModDec)
97 #define MModModInc (1 << ModModInc)
98 #define MModDisp (1 << ModDisp)
99 
100 #define MModNoExt (MModIReg | MModPreDec | MModPostDec | MModPostInc | MModIndex | MModModDec | MModModInc)
101 #define MModNoImm (MModAbs | MModNoExt)
102 #define MModAll (MModNoImm | MModImm)
103 
104 #define SegLData (SegYData + 1)
105 
106 #define MSegCode (1 << SegCode)
107 #define MSegXData (1 << SegXData)
108 #define MSegYData (1 << SegYData)
109 #define MSegLData (1 << SegLData)
110 
111 typedef struct
112 {
113   ShortInt Type;
114   LongInt Mode, Val;
115   Byte Seg, ShortMode;
116   Boolean ForceImmLong;
117   tSymbolFlags AbsSymFlags;
118   int Cnt;
119 } tAdrResult;
120 
121 static CPUVar CPU56000, CPU56002, CPU56300;
122 static IntType AdrInt;
123 static LargeInt MemLimit;
124 
125 static tStrComp LeftComp, MidComp, RightComp, Left1Comp, Left2Comp, Right1Comp, Right2Comp;
126 
127 static FixedOrder *FixedOrders;
128 static ParOrder *ParOrders;
129 
130 /*----------------------------------------------------------------------------------------------*/
131 
SplitArg(const tStrComp * pOrig,tStrComp * pLDest,tStrComp * pRDest)132 static void SplitArg(const tStrComp *pOrig, tStrComp *pLDest, tStrComp *pRDest)
133 {
134   char *p;
135 
136   p = QuotPos(pOrig->Str, ',');
137   if (!p)
138   {
139     StrCompReset(pRDest);
140     StrCompCopy(pLDest, pOrig);
141   }
142   else
143     StrCompSplitCopy(pLDest, pRDest, pOrig, p);
144 }
145 
CutSize(const tStrComp * pArg,Byte * ShortMode)146 static unsigned CutSize(const tStrComp *pArg, Byte *ShortMode)
147 {
148   switch (*pArg->Str)
149   {
150     case '>':
151       *ShortMode = 2;
152       return 1;
153     case '<':
154       *ShortMode = 1;
155       return 1;
156     default:
157       *ShortMode = 0;
158       return 0;
159   }
160 }
161 
DecodeReg(char * Asc,LongInt * Erg)162 static Boolean DecodeReg(char *Asc, LongInt *Erg)
163 {
164 #define RegCount (sizeof(RegNames) / sizeof(*RegNames))
165   static const char RegNames[][3] =
166   {
167     "X0", "X1", "Y0", "Y1", "A0", "B0", "A2", "B2", "A1", "B1", "A", "B"
168   };
169   Word z;
170 
171   for (z = 0; z < RegCount; z++)
172     if (!as_strcasecmp(Asc, RegNames[z]))
173     {
174       *Erg = z + 4;
175       return True;
176     }
177   if ((strlen(Asc) == 2) && (Asc[1] >= '0') && (Asc[1] <= '7'))
178     switch (as_toupper(*Asc))
179     {
180       case 'R':
181         *Erg = 16 + Asc[1] - '0';
182         return True;
183       case 'N':
184         *Erg = 24 + Asc[1] - '0';
185         return True;
186     }
187   return False;
188 #undef RegCount
189 }
190 
DecodeALUReg(char * Asc,LongInt * Erg,Boolean MayX,Boolean MayY,Boolean MayAcc)191 static Boolean DecodeALUReg(char *Asc, LongInt *Erg,
192                             Boolean MayX, Boolean MayY, Boolean MayAcc)
193 {
194   Boolean Result = False;
195 
196   if (!DecodeReg(Asc, Erg))
197     return Result;
198 
199   switch (*Erg)
200   {
201     case 4:
202     case 5:
203       if (MayX)
204       {
205         Result = True;
206         (*Erg) -= 4;
207       }
208       break;
209     case 6:
210     case 7:
211       if (MayY)
212       {
213         Result = True;
214         (*Erg) -= 6;
215       }
216       break;
217     case 14:
218     case 15:
219       if (MayAcc)
220       {
221         Result = True;
222         (*Erg) -= (MayX || MayY) ? 12 : 14;
223       }
224       break;
225   }
226 
227   return Result;
228 }
229 
DecodeLReg(char * Asc,LongInt * Erg)230 static Boolean DecodeLReg(char *Asc, LongInt *Erg)
231 {
232 #define RegCount (sizeof(RegNames) / sizeof(*RegNames))
233   static const char RegNames[][4] =
234   {
235     "A10", "B10", "X", "Y", "A", "B", "AB", "BA"
236   };
237   Word z;
238 
239   for (z = 0; z < RegCount; z++)
240     if (!as_strcasecmp(Asc, RegNames[z]))
241     {
242       *Erg = z;
243       return True;
244     }
245 
246   return False;
247 #undef RegCount
248 }
249 
DecodeXYABReg(char * Asc,LongInt * Erg)250 static Boolean DecodeXYABReg(char *Asc, LongInt *Erg)
251 {
252 #define RegCount (sizeof(RegNames) / sizeof(*RegNames))
253   static const char RegNames[][3] =
254   {
255     "B", "A", "X", "Y", "X0", "Y0", "X1", "Y1"
256   };
257   Word z;
258 
259   for (z = 0; z < RegCount; z++)
260     if (!as_strcasecmp(Asc, RegNames[z]))
261     {
262       *Erg = z;
263       return True;
264     }
265 
266   return False;
267 #undef RegCount
268 }
269 
DecodeXYAB0Reg(char * Asc,LongInt * Erg)270 static Boolean DecodeXYAB0Reg(char *Asc, LongInt *Erg)
271 {
272 #define RegCount (sizeof(RegNames) / sizeof(*RegNames))
273   static const char RegNames[][3] =
274   {
275     "A0", "B0", "X0", "Y0", "X1", "Y1"
276   };
277   Word z;
278 
279   for (z = 0; z < RegCount; z++)
280     if (!as_strcasecmp(Asc, RegNames[z]))
281     {
282       *Erg = z + 2;
283       return True;
284     }
285 
286   return False;
287 #undef RegCount
288 }
289 
DecodeXYAB1Reg(char * Asc,LongInt * Erg)290 static Boolean DecodeXYAB1Reg(char *Asc, LongInt *Erg)
291 {
292 #define RegCount (sizeof(RegNames) / sizeof(*RegNames))
293   static const char RegNames[][3] =
294   {
295     "A1", "B1", "X0", "Y0", "X1", "Y1"
296   };
297   Word z;
298 
299   for (z = 0; z < RegCount; z++)
300     if (!as_strcasecmp(Asc, RegNames[z]))
301     {
302       *Erg = z + 2;
303       return True;
304     }
305 
306   return False;
307 #undef RegCount
308 }
309 
DecodePCReg(char * Asc,LongInt * Erg)310 static Boolean DecodePCReg(char *Asc, LongInt *Erg)
311 {
312 #define RegCount (sizeof(RegNames) / sizeof(*RegNames))
313                                 /** vvvv ab 56300 ? */
314   static const char RegNames[][4] =
315   {
316     "SZ", "SR", "OMR", "SP", "SSH", "SSL", "LA", "LC"
317   };
318   Word z;
319 
320   for (z = 0; z < RegCount; z++)
321     if (!as_strcasecmp(Asc, RegNames[z]))
322     {
323       (*Erg) = z;
324       return True;
325     }
326 
327   return False;
328 #undef RegCount
329 }
330 
DecodeAddReg(char * Asc,LongInt * Erg)331 static Boolean DecodeAddReg(char *Asc, LongInt *Erg)
332 {
333   if ((strlen(Asc) == 2) && (as_toupper(*Asc) == 'M') && (Asc[1] >= '0') && (Asc[1] <= '7'))
334   {
335     *Erg = Asc[1] - '0';
336     return True;
337   }
338   /* >=56300 ? */
339   if (!as_strcasecmp(Asc, "EP"))
340   {
341     *Erg = 0x0a;
342     return True;
343   }
344   if (!as_strcasecmp(Asc, "VBA"))
345   {
346     *Erg = 0x10;
347     return True;
348   }
349   if (!as_strcasecmp(Asc, "SC"))
350   {
351     *Erg = 0x11;
352     return True;
353   }
354 
355   return False;
356 }
357 
DecodeGeneralReg(char * Asc,LongInt * Erg)358 static Boolean DecodeGeneralReg(char *Asc, LongInt *Erg)
359 {
360   if (DecodeReg(Asc, Erg))
361     return True;
362   if (DecodePCReg(Asc, Erg))
363   {
364     (*Erg) += 0x38;
365     return True;
366   }
367   if (DecodeAddReg(Asc, Erg))
368   {
369     (*Erg) += 0x20;
370     return True;
371   }
372   return False;
373 }
374 
DecodeCtrlReg(char * Asc,LongInt * Erg)375 static Boolean DecodeCtrlReg(char *Asc, LongInt *Erg)
376 {
377   if (DecodeAddReg(Asc, Erg))
378     return True;
379   if (DecodePCReg(Asc, Erg))
380   {
381     (*Erg) += 0x18;
382     return True;
383   }
384   return False;
385 }
386 
DecodeControlReg(char * Asc,LongInt * Erg)387 static Boolean DecodeControlReg(char *Asc, LongInt *Erg)
388 {
389   Boolean Result = True;
390 
391   if (!as_strcasecmp(Asc, "MR"))
392     *Erg = 0;
393   else if (!as_strcasecmp(Asc, "CCR"))
394     *Erg = 1;
395   else if ((!as_strcasecmp(Asc, "OMR")) || (!as_strcasecmp(Asc, "COM")))
396     *Erg = 2;
397   else if ((!as_strcasecmp(Asc, "EOM")) && (MomCPU >= CPU56000))
398     *Erg = 3;
399   else
400     Result = False;
401 
402   return Result;
403 }
404 
DecodeAdr(const tStrComp * pArg,Word Erl,Byte ErlSeg,tAdrResult * pResult)405 static void DecodeAdr(const tStrComp *pArg, Word Erl, Byte ErlSeg, tAdrResult *pResult)
406 {
407   static const char ModMasks[ModModInc + 1][8] =
408   {
409     "","", "(Rx)", "-(Rx)", "(Rx)-", "(Rx)+", "(Rx+Nx)", "(Rx)-Nx", "(Rx)+Nx"
410   };
411   static const Byte ModCodes[ModModInc + 1] =
412   {
413     0, 0, 4, 7, 2, 3, 5, 0, 1
414   };
415 #define SegCount (sizeof(SegNames) / sizeof(*SegNames))
416   static const char SegNames[] =
417   {
418     'P', 'X', 'Y', 'L'
419   };
420   static Byte SegVals[] =
421   {
422     SegCode, SegXData, SegYData, SegLData
423   };
424   int z, l, ArgLen;
425   unsigned SegIndex, Offset;
426   Boolean OK;
427   tEvalResult EvalResult;
428   Byte OrdVal;
429   char *pp, *np, save;
430   tStrComp Arg;
431 
432   pResult->Type = ModNone;
433   pResult->Cnt = 0;
434   pResult->ShortMode = 0;
435 
436   /* Adressierungsmodi vom 56300 abschneiden */
437 
438   if (MomCPU < CPU56300)
439     Erl |= (~MModDisp);
440 
441   /* Defaultsegment herausfinden */
442 
443   if (ErlSeg & MSegXData)
444     pResult->Seg = SegXData;
445   else if (ErlSeg & MSegYData)
446     pResult->Seg = SegYData;
447   else if (ErlSeg & MSegCode)
448     pResult->Seg = SegCode;
449   else
450     pResult->Seg = SegNone;
451 
452   /* Zielsegment vorgegeben ? */
453 
454   Offset = 0;
455   for (SegIndex = 0; SegIndex < SegCount; SegIndex++)
456     if ((as_toupper(*pArg->Str) == SegNames[SegIndex]) && (pArg->Str[1] == ':'))
457     {
458       pResult->Seg = SegVals[SegIndex];
459       Offset = 2;
460     }
461   StrCompRefRight(&Arg, pArg, Offset);
462 
463   /* Adressausdruecke abklopfen: dazu mit Referenzstring vergleichen */
464 
465   ArgLen = strlen(Arg.Str);
466   for (z = ModIReg; z <= ModModInc; z++)
467     if (ArgLen == (int)strlen(ModMasks[z]))
468     {
469       pResult->Mode = 0xffff;
470       for (l = 0; l <= ArgLen; l++)
471         if (ModMasks[z][l] == 'x')
472         {
473           OrdVal = Arg.Str[l] - '0';
474           if (OrdVal > 7)
475             break;
476           else if (pResult->Mode == 0xffff)
477             pResult->Mode = OrdVal;
478           else if (pResult->Mode != OrdVal)
479           {
480             WrError(ErrNum_InvRegPair);
481             goto chk;
482           }
483         }
484         else if (ModMasks[z][l] != as_toupper(Arg.Str[l]))
485           break;
486       if (l > ArgLen)
487       {
488         pResult->Type = z;
489         pResult->Mode += ModCodes[z] << 3;
490         goto chk;
491       }
492     }
493 
494   /* immediate ? */
495 
496   if (*Arg.Str == '#')
497   {
498     if (Arg.Str[1] == '>')
499     {
500       pResult->ForceImmLong = TRUE;
501       pResult->Val = EvalStrIntExpressionOffs(&Arg, 2, Int24, &OK);
502     }
503     else
504     {
505       pResult->ForceImmLong = FALSE;
506       pResult->Val = EvalStrIntExpressionOffs(&Arg, 1, Int24, &OK);
507     }
508     if (OK)
509     {
510       pResult->Type = ModImm; pResult->Cnt = 1; pResult->Mode = 0x34;
511       goto chk;
512     }
513   }
514 
515   /* Register mit Displacement bei 56300 */
516 
517   if (IsIndirect(Arg.Str))
518   {
519     tStrComp IArg;
520 
521     Arg.Str[--ArgLen] = '\0'; Arg.Pos.Len--;
522     StrCompRefRight(&IArg, &Arg, 1);
523     pp = strchr(IArg.Str, '+');
524     np = strchr(IArg.Str, '-');
525     if ((!pp) || ((np) && (np < pp)))
526       pp = np;
527     if (pp)
528     {
529       save = *pp;
530       *pp = '\0';
531       if ((DecodeGeneralReg(IArg.Str, &pResult->Mode)) && (pResult->Mode >= 16) && (pResult->Mode <= 23))
532       {
533         *pp = save;
534         pResult->Mode -= 16;
535         pResult->Val = EvalStrIntExpressionOffsWithResult(&IArg, pp - IArg.Str, Int24, &EvalResult);
536         if (EvalResult.OK)
537         {
538           if (mFirstPassUnknown(EvalResult.Flags))
539             pResult->Val &= 63;
540           pResult->Type = ModDisp;
541         }
542         goto chk;
543       }
544       *pp = save;
545     }
546   }
547 
548   /* dann absolut */
549 
550   Offset = CutSize(&Arg, &pResult->ShortMode);
551   pResult->Val = EvalStrIntExpressionOffsWithResult(&Arg, Offset, AdrInt, &EvalResult);
552   if (EvalResult.OK)
553   {
554     pResult->Type = ModAbs;
555     pResult->AbsSymFlags = EvalResult.Flags;
556     pResult->Mode = 0x30; pResult->Cnt = 1;
557     if ((pResult->Seg & ((1 << SegCode) | (1 << SegXData) | (1 << SegYData))) != 0)
558       ChkSpace(pResult->Seg, EvalResult.AddrSpaceMask);
559     goto chk;
560   }
561 
562 chk:
563   if ((pResult->Type != ModNone) && (!(Erl & (1 << pResult->Type))))
564   {
565     WrError(ErrNum_InvAddrMode);
566     pResult->Cnt = 0;
567     pResult->Type = ModNone;
568   }
569   if ((pResult->Seg != SegNone) && (!(ErlSeg & (1 << pResult->Seg))))
570   {
571     WrError(ErrNum_InvSegment);
572     pResult->Cnt = 0;
573     pResult->Type = ModNone;
574   }
575 }
576 
DecodeOpPair(const tStrComp * pLeft,const tStrComp * pRight,Byte WorkSeg,LongInt * Dir,LongInt * Reg1,LongInt * Reg2,tAdrResult * pResult)577 static Boolean DecodeOpPair(const tStrComp *pLeft, const tStrComp *pRight, Byte WorkSeg,
578                             LongInt *Dir, LongInt *Reg1, LongInt *Reg2, tAdrResult *pResult)
579 {
580   Boolean Result = False;
581 
582   if (DecodeALUReg(pLeft->Str, Reg1, WorkSeg == SegXData, WorkSeg == SegYData, True))
583   {
584     if (DecodeALUReg(pRight->Str, Reg2, WorkSeg == SegXData, WorkSeg == SegYData, True))
585     {
586       *Dir = 2;
587       pResult->Type = ModNone;
588       pResult->Mode = 0;
589       pResult->Cnt = 0;
590       pResult->Val = 0;
591       Result = True;
592     }
593     else
594     {
595       *Dir = 0;
596       *Reg2 = -1;
597       DecodeAdr(pRight, MModNoImm, 1 << WorkSeg, pResult);
598       if (pResult->Type != ModNone)
599         Result = True;
600     }
601   }
602   else if (DecodeALUReg(pRight->Str, Reg1, WorkSeg == SegXData, WorkSeg == SegYData, True))
603   {
604     *Dir = 1;
605     *Reg2 = -1;
606     DecodeAdr(pLeft, MModAll, 1 << WorkSeg, pResult);
607     if (pResult->Type != ModNone)
608       Result = True;
609   }
610 
611   return Result;
612 }
613 
TurnXY(LongInt Inp)614 static LongInt TurnXY(LongInt Inp)
615 {
616   switch (Inp)
617   {
618     case 4:
619     case 7:
620       return Inp - 4;
621     case 5:
622     case 6:
623       return 7 - Inp;
624     default:  /* wird nie erreicht */
625       return 0;
626   }
627 }
628 
DecodeTFR(const tStrComp * pArg,LongInt * Erg)629 static Boolean DecodeTFR(const tStrComp *pArg, LongInt *Erg)
630 {
631   LongInt Part1, Part2;
632 
633   SplitArg(pArg, &LeftComp, &RightComp);
634   if (!DecodeALUReg(RightComp.Str, &Part2, False, False, True)) return False;
635   if (!DecodeReg(LeftComp.Str, &Part1)) return False;
636   if ((Part1 < 4) || ((Part1 > 7) && (Part1 < 14)) || (Part1 > 15)) return False;
637   if (Part1 > 13)
638   {
639     if (((Part1 ^ Part2) & 1) == 0) return False;
640     else
641       Part1 = 0;
642   }
643   else
644     Part1 = TurnXY(Part1) + 4;
645   *Erg = (Part1 << 1) + Part2;
646   return True;
647 }
648 
DecodeRR(const tStrComp * pArg,LongInt * Erg)649 static Boolean DecodeRR(const tStrComp *pArg, LongInt *Erg)
650 {
651   LongInt Part1, Part2;
652 
653   SplitArg(pArg, &LeftComp, &RightComp);
654   if (!DecodeGeneralReg(RightComp.Str, &Part2)) return False;
655   if ((Part2 < 16) || (Part2 > 23)) return False;
656   if (!DecodeGeneralReg(LeftComp.Str, &Part1)) return False;
657   if ((Part1 < 16) || (Part1 > 23)) return False;
658   *Erg = (Part2 & 7) + ((Part1 & 7) << 8);
659   return True;
660 }
661 
DecodeCondition(char * Asc,Word * Erg)662 static Boolean DecodeCondition(char *Asc, Word *Erg)
663 {
664   Boolean Result;
665 
666   (*Erg) = 0;
667   while ((*Erg < CondCount) && (as_strcasecmp(CondNames[*Erg], Asc)))
668     (*Erg)++;
669   if (*Erg == CondCount - 1)
670     *Erg = 8;
671   Result = (*Erg < CondCount);
672   *Erg &= 15;
673   return Result;
674 }
675 
DecodeMOVE_0(void)676 static Boolean DecodeMOVE_0(void)
677 {
678   DAsmCode[0] = 0x200000;
679   CodeLen = 1;
680   return True;
681 }
682 
DecodeMOVE_1(int Start)683 static Boolean DecodeMOVE_1(int Start)
684 {
685   LongInt RegErg, RegErg2, IsY, MixErg, l;
686   char c;
687   Word Condition;
688   Boolean Result = False;
689   Byte SegMask;
690 
691   if (!as_strncasecmp(ArgStr[Start].Str, "IF", 2))
692   {
693     l = strlen(ArgStr[Start].Str);
694     if (!as_strcasecmp(ArgStr[Start].Str + l - 2, ".U"))
695     {
696       RegErg = 0x1000;
697       l -= 2;
698     }
699     else
700       RegErg = 0;
701     c = ArgStr[Start].Str[l];
702     ArgStr[Start].Str[l] = '\0';
703     if (DecodeCondition(ArgStr[Start].Str + 2, &Condition))
704     {
705       if (ChkMinCPUExt(CPU56300, ErrNum_AddrModeNotSupported))
706       {
707         DAsmCode[0] = 0x202000 + (Condition << 8) + RegErg;
708         CodeLen = 1;
709         return True;
710       }
711     }
712     ArgStr[Start].Str[l] = c;
713   }
714 
715   SplitArg(&ArgStr[Start], &LeftComp, &RightComp);
716 
717   /* 1. Register-Update */
718 
719   if (*RightComp.Str == '\0')
720   {
721     tAdrResult AdrResult;
722 
723     DecodeAdr(&LeftComp, MModPostDec | MModPostInc | MModModDec | MModModInc, 0, &AdrResult);
724     if (AdrResult.Type != ModNone)
725     {
726       Result = True;
727       DAsmCode[0] = 0x204000 + (AdrResult.Mode << 8);
728       CodeLen = 1;
729     }
730     return Result;
731   }
732 
733   /* 2. Ziel ist Register */
734 
735   if (DecodeReg(RightComp.Str, &RegErg))
736   {
737     tAdrResult AdrResult;
738 
739     AdrResult.Seg = SegNone;
740     if (DecodeReg(LeftComp.Str, &RegErg2))
741     {
742       Result = True;
743       DAsmCode[0] = 0x200000 + (RegErg << 8) + (RegErg2 << 13);
744       CodeLen = 1;
745     }
746     else
747     {
748       /* A und B gehen auch als L:..., in L-Zweig zwingen! */
749 
750       SegMask = MSegXData + MSegYData;
751       if ((RegErg == 14) || (RegErg == 15))
752         SegMask |= MSegLData;
753       DecodeAdr(&LeftComp, MModAll | MModDisp, SegMask, &AdrResult);
754       if (AdrResult.Seg != SegLData)
755       {
756         IsY = Ord(AdrResult.Seg == SegYData);
757         MixErg = ((RegErg & 0x18) << 17) + (IsY << 19) + ((RegErg & 7) << 16);
758         if (AdrResult.Type == ModDisp)
759         {
760           if ((AdrResult.Val < 63) && (AdrResult.Val > -64) && (RegErg <= 15))
761           {
762             DAsmCode[0] = 0x020090 + ((AdrResult.Val & 1) << 6) + ((AdrResult.Val & 0x7e) << 10)
763                         + (AdrResult.Mode << 8) + (IsY << 5) + RegErg;
764             CodeLen = 1;
765           }
766           else
767           {
768             DAsmCode[0] = 0x0a70c0 + (AdrResult.Mode << 8) + (IsY << 16) + RegErg;
769             DAsmCode[1] = AdrResult.Val;
770             CodeLen = 2;
771           }
772         }
773         else if (!AdrResult.ForceImmLong && (AdrResult.Type == ModImm) && RangeCheck(AdrResult.Val, UInt8))
774         {
775           Result = True;
776           DAsmCode[0] = 0x200000 + (RegErg << 16) + ((AdrResult.Val & 0xff) << 8);
777           CodeLen = 1;
778         }
779         else if ((AdrResult.Type == ModAbs) && (AdrResult.Val <= 63) && (AdrResult.Val >= 0) && (AdrResult.ShortMode != 2))
780         {
781           Result = True;
782           DAsmCode[0] = 0x408000 + MixErg + (AdrResult.Val << 8);
783           CodeLen = 1;
784         }
785         else if (AdrResult.Type != ModNone)
786         {
787           Result = True;
788           DAsmCode[0] = 0x40c000 + MixErg + (AdrResult.Mode << 8);
789           DAsmCode[1] = AdrResult.Val;
790           CodeLen = 1 + AdrResult.Cnt;
791         }
792       }
793     }
794     if (AdrResult.Seg != SegLData)
795       return Result;
796   }
797 
798   /* 3. Quelle ist Register */
799 
800   if (DecodeReg(LeftComp.Str, &RegErg))
801   {
802     tAdrResult RightAdrResult;
803 
804     /* A und B gehen auch als L:..., in L-Zweig zwingen! */
805     SegMask = MSegXData + MSegYData;
806     if ((RegErg == 14) || (RegErg == 15))
807       SegMask |= MSegLData;
808     DecodeAdr(&RightComp, MModNoImm | MModDisp, SegMask, &RightAdrResult);
809     if (RightAdrResult.Seg != SegLData)
810     {
811       IsY = Ord(RightAdrResult.Seg == SegYData);
812       MixErg = ((RegErg & 0x18) << 17) + (IsY << 19) + ((RegErg & 7) << 16);
813       if (RightAdrResult.Type == ModDisp)
814       {
815         if ((RightAdrResult.Val < 63) && (RightAdrResult.Val > -64) && (RegErg <= 15))
816         {
817           DAsmCode[0] = 0x020080 + ((RightAdrResult.Val & 1) << 6) + ((RightAdrResult.Val & 0x7e) << 10)
818                       + (RightAdrResult.Mode << 8) + (IsY << 5) + RegErg;
819           CodeLen = 1;
820         }
821         else
822         {
823           DAsmCode[0] = 0x0a7080 + (RightAdrResult.Mode << 8) + (IsY << 16) + RegErg;
824           DAsmCode[1] = RightAdrResult.Val;
825           CodeLen = 2;
826         }
827       }
828       else if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val <= 63) && (RightAdrResult.Val >= 0) && (RightAdrResult.ShortMode != 2))
829       {
830         Result = True;
831         DAsmCode[0] = 0x400000 + MixErg + (RightAdrResult.Val << 8);
832         CodeLen = 1;
833       }
834       else if (RightAdrResult.Type != ModNone)
835       {
836         Result = True;
837         DAsmCode[0] = 0x404000 + MixErg + (RightAdrResult.Mode << 8);
838         DAsmCode[1] = RightAdrResult.Val;
839         CodeLen = 1 + RightAdrResult.Cnt;
840       }
841       return Result;
842     }
843   }
844 
845   /* 4. Ziel ist langes Register */
846 
847   if (DecodeLReg(RightComp.Str, &RegErg))
848   {
849     tAdrResult LeftAdrResult;
850 
851     DecodeAdr(&LeftComp, MModNoImm, MSegLData, &LeftAdrResult);
852     MixErg = ((RegErg & 4) << 17) + ((RegErg & 3) << 16);
853     if ((LeftAdrResult.Type == ModAbs) && (LeftAdrResult.Val <= 63) && (LeftAdrResult.Val >= 0) && (LeftAdrResult.ShortMode != 2))
854     {
855       Result = True;
856       DAsmCode[0] = 0x408000 + MixErg + (LeftAdrResult.Val << 8);
857       CodeLen = 1;
858     }
859     else
860     {
861       Result = True;
862       DAsmCode[0] = 0x40c000 + MixErg + (LeftAdrResult.Mode << 8);
863       DAsmCode[1] = LeftAdrResult.Val;
864       CodeLen = 1 + LeftAdrResult.Cnt;
865     }
866     return Result;
867   }
868 
869   /* 5. Quelle ist langes Register */
870 
871   if (DecodeLReg(LeftComp.Str, &RegErg))
872   {
873     tAdrResult RightAdrResult;
874 
875     DecodeAdr(&RightComp, MModNoImm, MSegLData, &RightAdrResult);
876     MixErg = ((RegErg & 4) << 17) + ((RegErg & 3) << 16);
877     if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val <= 63) && (RightAdrResult.Val >= 0) && (RightAdrResult.ShortMode != 2))
878     {
879       Result = True;
880       DAsmCode[0] = 0x400000 + MixErg + (RightAdrResult.Val << 8);
881       CodeLen = 1;
882     }
883     else
884     {
885       Result = True;
886       DAsmCode[0] = 0x404000 + MixErg + (RightAdrResult.Mode << 8);
887       DAsmCode[1] = RightAdrResult.Val;
888       CodeLen = 1 + RightAdrResult.Cnt;
889     }
890     return Result;
891   }
892 
893   WrError(ErrNum_InvAddrMode);
894   return Result;
895 }
896 
DecodeMOVE_2(int Start)897 static Boolean DecodeMOVE_2(int Start)
898 {
899   LongInt RegErg, Reg1L, Reg1R, Reg2L, Reg2R, Dir1, Dir2;
900   tAdrResult AdrResult1, AdrResult2;
901   Boolean Result = False;
902 
903   SplitArg(&ArgStr[Start], &Left1Comp, &Right1Comp);
904   SplitArg(&ArgStr[Start + 1], &Left2Comp, &Right2Comp);
905 
906   /* 1. Spezialfall X auf rechter Seite ? */
907 
908   if (!as_strcasecmp(Left2Comp.Str, "X0"))
909   {
910     if (!DecodeALUReg(Right2Comp.Str, &RegErg, False, False, True)) WrError(ErrNum_InvAddrMode);
911     else if (strcmp(Left1Comp.Str, Right2Comp.Str)) WrError(ErrNum_InvAddrMode);
912     else
913     {
914       DecodeAdr(&Right1Comp, MModNoImm, MSegXData, &AdrResult1);
915       if (AdrResult1.Type != ModNone)
916       {
917         CodeLen = 1 + AdrResult1.Cnt;
918         DAsmCode[0] = 0x080000 + (RegErg << 16) + (AdrResult1.Mode << 8);
919         DAsmCode[1] = AdrResult1.Val;
920         Result = True;
921       }
922     }
923     return Result;
924   }
925 
926   /* 2. Spezialfall Y auf linker Seite ? */
927 
928   if (!as_strcasecmp(Left1Comp.Str, "Y0"))
929   {
930     if (!DecodeALUReg(Right1Comp.Str, &RegErg, False, False, True)) WrError(ErrNum_InvAddrMode);
931     else if (strcmp(Left2Comp.Str, Right1Comp.Str)) WrError(ErrNum_InvAddrMode);
932     else
933     {
934       DecodeAdr(&Right2Comp, MModNoImm, MSegYData, &AdrResult2);
935       if (AdrResult2.Type != ModNone)
936       {
937         CodeLen = 1 + AdrResult2.Cnt;
938         DAsmCode[0] = 0x088000 + (RegErg << 16) + (AdrResult2.Mode << 8);
939         DAsmCode[1] = AdrResult2.Val;
940         Result = True;
941       }
942     }
943     return Result;
944   }
945 
946   /* der Rest..... */
947 
948   if ((DecodeOpPair(&Left1Comp, &Right1Comp, SegXData, &Dir1, &Reg1L, &Reg1R, &AdrResult1))
949    && (DecodeOpPair(&Left2Comp, &Right2Comp, SegYData, &Dir2, &Reg2L, &Reg2R, &AdrResult2)))
950   {
951     if ((Reg1R == -1) && (Reg2R == -1))
952     {
953       if ((AdrResult1.Mode >> 3 < 1) || (AdrResult1.Mode >> 3 > 4) || (AdrResult2.Mode >> 3 < 1) || (AdrResult2.Mode >> 3 > 4)) WrError(ErrNum_InvAddrMode);
954       else if (((AdrResult1.Mode ^ AdrResult2.Mode) & 4) == 0) WrError(ErrNum_InvRegPair);
955       else
956       {
957         DAsmCode[0] = 0x800000 + (Dir2 << 22) + (Dir1 << 15)
958                     + (Reg1L << 18) + (Reg2L << 16) + ((AdrResult1.Mode & 0x1f) << 8)
959                     + ((AdrResult2.Mode & 3) << 13) + ((AdrResult2.Mode & 24) << 17);
960         CodeLen = 1;
961         Result = True;
962       }
963     }
964     else if (Reg1R == -1)
965     {
966       if ((Reg2L < 2) || (Reg2R > 1)) WrError(ErrNum_InvAddrMode);
967       else
968       {
969         DAsmCode[0] = 0x100000 + (Reg1L << 18) + ((Reg2L - 2) << 17) + (Reg2R << 16)
970                     + (Dir1 << 15) + (AdrResult1.Mode << 8);
971         DAsmCode[1] = AdrResult1.Val;
972         CodeLen = 1 + AdrResult1.Cnt;
973         Result = True;
974       }
975     }
976     else if (Reg2R == -1)
977     {
978       if ((Reg1L < 2) || (Reg1R > 1)) WrError(ErrNum_InvAddrMode);
979       else
980       {
981         DAsmCode[0] = 0x104000 + (Reg2L << 16) + ((Reg1L - 2) << 19) + (Reg1R << 18)
982                     + (Dir2 << 15) + (AdrResult2.Mode << 8);
983         DAsmCode[1] = AdrResult2.Val;
984         CodeLen = 1 + AdrResult2.Cnt;
985         Result = True;
986       }
987     }
988     else
989       WrError(ErrNum_InvAddrMode);
990     return Result;
991   }
992 
993   WrError(ErrNum_InvAddrMode);
994   return Result;
995 }
996 
DecodeMOVE(int Start)997 static Boolean DecodeMOVE(int Start)
998 {
999   switch (ArgCnt - Start + 1)
1000   {
1001     case 0:
1002       return DecodeMOVE_0();
1003     case 1:
1004       return DecodeMOVE_1(Start);
1005     case 2:
1006       return DecodeMOVE_2(Start);
1007     default:
1008       (void)ChkArgCnt(0, 2);
1009       return False;
1010   }
1011 }
1012 
DecodePseudo(void)1013 static Boolean DecodePseudo(void)
1014 {
1015   Boolean OK;
1016   tSymbolFlags Flags;
1017   Word AdrWord, z, z2;
1018 /*   Byte Segment;*/
1019   TempResult t;
1020   LongInt HInt;
1021 
1022 
1023   if (Memo("XSFR"))
1024   {
1025     CodeEquate(SegXData, 0, MemLimit);
1026     return True;
1027   }
1028 
1029   if (Memo("YSFR"))
1030   {
1031     CodeEquate(SegYData, 0, MemLimit);
1032     return True;
1033   }
1034 
1035   if (Memo("DS"))
1036   {
1037     if (ChkArgCnt(1, 1))
1038     {
1039       AdrWord = EvalStrIntExpressionWithFlags(&ArgStr[1], AdrInt, &OK, &Flags);
1040       if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
1041       if (OK && !mFirstPassUnknown(Flags))
1042       {
1043         if (!AdrWord) WrError(ErrNum_NullResMem);
1044         CodeLen = AdrWord; DontPrint = True;
1045         BookKeeping();
1046       }
1047     }
1048     return True;
1049   }
1050 
1051   if (Memo("DC"))
1052   {
1053     if (ChkArgCnt(1, ArgCntMax))
1054     {
1055       OK = True;
1056       for (z = 1; OK && (z <= ArgCnt); z++)
1057       {
1058         EvalStrExpression(&ArgStr[z], &t);
1059         switch (t.Typ)
1060         {
1061           case TempString:
1062           {
1063             int BCount;
1064 
1065             if (MultiCharToInt(&t, 3))
1066               goto ToInt;
1067 
1068             BCount = 2; DAsmCode[CodeLen] = 0;
1069             for (z2 = 0; z2 < t.Contents.Ascii.Length; z2++)
1070             {
1071               HInt = t.Contents.Ascii.Contents[z2];
1072               HInt = CharTransTable[((usint) HInt) & 0xff];
1073               HInt <<= (BCount * 8);
1074               DAsmCode[CodeLen] |= HInt;
1075               if (--BCount < 0)
1076               {
1077                 BCount = 2; DAsmCode[++CodeLen] = 0;
1078               }
1079             }
1080             if (BCount != 2) CodeLen++;
1081             break;
1082           }
1083           ToInt:
1084           case TempInt:
1085             if (mFirstPassUnknown(t.Flags)) t.Contents.Int &= 0xffffff;
1086             if (!(OK = RangeCheck(t.Contents.Int, Int24))) WrError(ErrNum_OverRange);
1087             else
1088               DAsmCode[CodeLen++] = t.Contents.Int & 0xffffff;
1089             break;
1090           case TempFloat:
1091             WrStrErrorPos(ErrNum_StringOrIntButFloat, &ArgStr[z]);
1092             /* fall-through */
1093           default:
1094             OK = False;
1095         }
1096       }
1097       if (!OK) CodeLen = 0;
1098     }
1099     return True;
1100   }
1101 
1102   return False;
1103 }
1104 
1105 static tErrorNum ErrCode;
1106 static const tStrComp *pErrComp;
1107 
SetError(tErrorNum Code)1108 static void SetError(tErrorNum Code)
1109 {
1110   ErrCode = Code; pErrComp = NULL;
1111 }
1112 
SetXError(tErrorNum Code,const tStrComp * pNewErrComp)1113 static void SetXError(tErrorNum Code, const tStrComp *pNewErrComp)
1114 {
1115   ErrCode = Code; pErrComp = pNewErrComp;
1116 }
1117 
PrError(void)1118 static void PrError(void)
1119 {
1120   if (pErrComp) WrStrErrorPos(ErrCode, pErrComp);
1121   else if (ErrCode != 0) WrError(ErrCode);
1122 }
1123 
1124 /*----------------------------------------------------------------------------------------------*/
1125 
1126 /* ohne Argument */
1127 
DecodeFixed(Word Index)1128 static void DecodeFixed(Word Index)
1129 {
1130   const FixedOrder *pOrder = FixedOrders + Index;
1131 
1132   if (!ChkArgCnt(0, 0));
1133   else if (ChkMinCPU(pOrder->MinCPU))
1134   {
1135     CodeLen = 1;
1136     DAsmCode[0] = pOrder->Code;
1137   }
1138 }
1139 
1140 /* ALU */
1141 
DecodePar(Word Index)1142 static void DecodePar(Word Index)
1143 {
1144   const ParOrder *pOrder = ParOrders + Index;
1145   Boolean OK, DontAdd;
1146   tSymbolFlags Flags;
1147   tStrComp LeftRegComp;
1148   LargeInt LAddVal;
1149   LongInt AddVal, h = 0, Reg1, Reg2, Reg3;
1150 
1151   if (DecodeMOVE(2))
1152   {
1153     SetError((tErrorNum)0);
1154     DontAdd = False;
1155     switch (pOrder->Typ)
1156     {
1157       case ParAB:
1158         if (!DecodeALUReg(ArgStr[1].Str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &ArgStr[1]);
1159         else
1160           h = Reg1 << 3;
1161         break;
1162       case ParFixAB:
1163         if (as_strcasecmp(ArgStr[1].Str, "A,B")) SetError(ErrNum_InvRegPair);
1164         else
1165           h = 0;
1166         break;
1167       case ParABShl1:
1168         if (!strchr(ArgStr[1].Str, ','))
1169         {
1170           if (!DecodeALUReg(ArgStr[1].Str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &ArgStr[1]);
1171           else
1172             h = Reg1 << 3;
1173         }
1174         else if (ArgCnt != 1) SetError(ErrNum_ParNotPossible);
1175         else if (MomCPU < CPU56300) SetError(ErrNum_InstructionNotSupported);
1176         else
1177         {
1178           SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1179           if (!strchr(RightComp.Str, ','))
1180             StrCompCopy(&MidComp, &RightComp);
1181           else
1182             SplitArg(&RightComp, &MidComp, &RightComp);
1183           if (!DecodeALUReg(RightComp.Str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
1184           else if (!DecodeALUReg(MidComp.Str, &Reg2, False, False, True)) SetXError(ErrNum_InvReg, &MidComp);
1185           else if (*LeftComp.Str == '#')
1186           {
1187             AddVal = EvalStrIntExpressionOffs(&LeftComp, 1, UInt6, &OK);
1188             if (OK)
1189             {
1190               DAsmCode[0] = 0x0c1c00 + ((pOrder->Code & 0x10) << 4) + (Reg2 << 7)
1191                           + (AddVal << 1) + Reg1;
1192               CodeLen = 1;
1193               DontAdd = True;
1194             }
1195           }
1196           else if (!DecodeXYAB1Reg(LeftComp.Str, &Reg3)) SetXError(ErrNum_InvReg, &LeftComp);
1197           else
1198           {
1199             DAsmCode[0] = 0x0c1e60 - ((pOrder->Code & 0x10) << 2) + (Reg2 << 4)
1200                         + (Reg3 << 1) + Reg1;
1201             CodeLen = 1;
1202             DontAdd = True;
1203           }
1204         }
1205         break;
1206       case ParABShl2:
1207         if (!strchr(ArgStr[1].Str, ','))
1208         {
1209           if (!DecodeALUReg(ArgStr[1].Str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &ArgStr[1]);
1210           else
1211             h = Reg1 << 3;
1212         }
1213         else if (ArgCnt != 1) SetError(ErrNum_ParNotPossible);
1214         else if (MomCPU < CPU56300) SetError(ErrNum_InstructionNotSupported);
1215         else
1216         {
1217           SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1218           if (!DecodeALUReg(RightComp.Str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
1219           else if (*LeftComp.Str == '#')
1220           {
1221             AddVal = EvalStrIntExpressionOffs(&LeftComp, 1, UInt5, &OK);
1222             if (OK)
1223             {
1224               DAsmCode[0] = 0x0c1e80 + ((0x33 - pOrder->Code) << 2)
1225                           + (AddVal << 1) + Reg1;
1226               CodeLen = 1;
1227               DontAdd = True;
1228             }
1229           }
1230           else if (!DecodeXYAB1Reg(LeftComp.Str, &Reg3)) SetXError(ErrNum_InvReg, &LeftComp);
1231           else
1232           {
1233             DAsmCode[0] = 0x0c1e10 + ((0x33 - pOrder->Code) << 1)
1234                         + (Reg3 << 1) + Reg1;
1235             CodeLen = 1;
1236             DontAdd = True;
1237           }
1238         }
1239         break;
1240       case ParXYAB:
1241         SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1242         if (!DecodeALUReg(RightComp.Str, &Reg2, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
1243         else if (!DecodeLReg(LeftComp.Str, &Reg1)) SetXError(ErrNum_InvReg, &LeftComp);
1244         else if ((Reg1 < 2) || (Reg1 > 3)) SetXError(ErrNum_InvReg, &LeftComp);
1245         else
1246            h = (Reg2 << 3) + ((Reg1 - 2) << 4);
1247         break;
1248       case ParABXYnAB:
1249         SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1250         if (!DecodeALUReg(RightComp.Str, &Reg2, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
1251         else if (*LeftComp.Str == '#')
1252         {
1253           if (Memo("CMPM")) SetError(ErrNum_InvAddrMode);
1254           else if (MomCPU < CPU56300) SetError(ErrNum_InstructionNotSupported);
1255           else if (ArgCnt != 1) SetError(ErrNum_ParNotPossible);
1256           else
1257           {
1258             AddVal = EvalStrIntExpressionOffs(&LeftComp, 1, Int24, &OK);
1259             if (!OK) SetError((tErrorNum)-1);
1260             else if ((AddVal >= 0) && (AddVal <= 63))
1261             {
1262               DAsmCode[0] = 0x014000 + (AddVal << 8);
1263               h = 0x80 + (Reg2 << 3);
1264             }
1265             else
1266             {
1267               DAsmCode[0] = 0x014000; h = 0xc0 + (Reg2 << 3);
1268               DAsmCode[1] = AddVal & 0xffffff; CodeLen = 2;
1269             }
1270           }
1271         }
1272         else
1273         {
1274           if (!DecodeXYABReg(LeftComp.Str, &Reg1)) SetXError(ErrNum_InvReg, &LeftComp);
1275           else if ((Reg1 ^ Reg2) == 1) SetError(ErrNum_InvRegPair);
1276           else if ((Memo("CMPM")) && ((Reg1 &6) == 2)) SetXError(ErrNum_InvReg, &LeftComp);
1277           else
1278           {
1279             if (Reg1 < 2)
1280               Reg1 = Ord(!Memo("CMPM"));
1281             h = (Reg2 << 3) + (Reg1 << 4);
1282           }
1283         }
1284         break;
1285       case ParABBA:
1286         if  (!as_strcasecmp(ArgStr[1].Str, "B,A"))
1287           h = 0;
1288         else if (!as_strcasecmp(ArgStr[1].Str, "A,B"))
1289           h = 8;
1290         else
1291           SetXError(ErrNum_InvRegPair, &ArgStr[1]);
1292         break;
1293       case ParXYnAB:
1294         SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1295         if (!DecodeALUReg(RightComp.Str, &Reg2, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
1296         else if (*LeftComp.Str == '#')
1297         {
1298           if (MomCPU < CPU56300) SetError(ErrNum_InstructionNotSupported);
1299           else if (ArgCnt != 1) SetError(ErrNum_ParNotPossible);
1300           else
1301           {
1302             AddVal = EvalStrIntExpressionOffs(&LeftComp, 1, Int24, &OK);
1303             if (!OK) SetError((tErrorNum)-1);
1304             else if ((AddVal >= 0) && (AddVal <= 63))
1305             {
1306               DAsmCode[0] = 0x014080 + (AddVal << 8) + (Reg2 << 3) + (pOrder->Code & 7);
1307               CodeLen = 1;
1308               DontAdd = True;
1309             }
1310             else
1311             {
1312               DAsmCode[0] = 0x0140c0 + (Reg2 << 3) + (pOrder->Code & 7);
1313               DAsmCode[1] = AddVal & 0xffffff;
1314               CodeLen = 2;
1315               DontAdd = True;
1316             }
1317           }
1318         }
1319         else
1320         {
1321           if (!DecodeReg(LeftComp.Str, &Reg1)) SetXError(ErrNum_InvReg, &LeftComp);
1322           else if ((Reg1 < 4) || (Reg1 > 7)) SetXError(ErrNum_InvReg, &LeftComp);
1323           else
1324             h = (Reg2 << 3) + (TurnXY(Reg1) << 4);
1325         }
1326         break;
1327       case ParMul:
1328         SplitArg(&ArgStr[1], &LeftComp, &MidComp);
1329         SplitArg(&MidComp, &MidComp, &RightComp);
1330         h = 0;
1331         if (*LeftComp.Str == '-')
1332         {
1333           StrCompRefRight(&LeftRegComp, &LeftComp, 1);
1334           h += 4;
1335         }
1336         else if (*LeftComp.Str == '+')
1337           StrCompRefRight(&LeftRegComp, &LeftComp, 1);
1338         else
1339           StrCompRefRight(&LeftRegComp, &LeftComp, 0);
1340         if (!DecodeALUReg(RightComp.Str, &Reg3, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
1341         else if (!DecodeReg(LeftRegComp.Str, &Reg1)) SetXError(ErrNum_InvReg, &LeftRegComp);
1342         else if ((Reg1 < 4) || (Reg1 > 7)) SetXError(ErrNum_InvReg, &LeftRegComp);
1343         else if (*MidComp.Str == '#')
1344         {
1345           if (!ChkArgCnt(1, 1));
1346           else if (ChkMinCPU(CPU56300))
1347           {
1348             AddVal = EvalStrIntExpressionOffsWithFlags(&MidComp, 1, UInt24, &OK, &Flags);
1349             if (mFirstPassUnknown(Flags))
1350               AddVal = 1;
1351             if ((!(SingleBit(AddVal, &LAddVal))) || (LAddVal > 22)) WrError(ErrNum_NotOneBit);
1352             else
1353             {
1354               LAddVal = 23 - LAddVal;
1355               DAsmCode[0] = 0x010040 + (LAddVal << 8) + (Mac2Table[Reg1 & 3] << 4)
1356                           + (Reg3 << 3);
1357               CodeLen = 1;
1358             }
1359           }
1360         }
1361 
1362         else if (!DecodeReg(MidComp.Str, &Reg2)) SetXError(ErrNum_InvReg, &MidComp);
1363         else if ((Reg2 < 4) || (Reg2 > 7)) SetXError(ErrNum_InvReg, &MidComp);
1364         else if (MacTable[Reg1 - 4][Reg2 - 4] == 0xff) SetError(ErrNum_InvRegPair);
1365         else
1366           h += (Reg3 << 3) + (MacTable[Reg1 - 4][Reg2 - 4] << 4);
1367         break;
1368     }
1369     if (ErrCode == 0)
1370     {
1371       if (!DontAdd)
1372         DAsmCode[0] += pOrder->Code + h;
1373     }
1374     else
1375     {
1376       if (ErrCode > 0)
1377         PrError();
1378       CodeLen = 0;
1379     }
1380   }
1381 }
1382 
DecodeDIV(Word Code)1383 static void DecodeDIV(Word Code)
1384 {
1385   UNUSED(Code);
1386 
1387   if (ChkArgCnt(1, 1))
1388   {
1389     LongInt Reg2, Reg1;
1390 
1391     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1392     if ((*LeftComp.Str == '\0') || (*RightComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
1393     else if (!DecodeALUReg(RightComp.Str, &Reg2, False, False, True)) WrError(ErrNum_InvAddrMode);
1394     else if (!DecodeReg(LeftComp.Str, &Reg1)) WrError(ErrNum_InvAddrMode);
1395     else if ((Reg1 < 4) || (Reg1 > 7)) WrError(ErrNum_InvAddrMode);
1396     else
1397     {
1398       CodeLen = 1;
1399       DAsmCode[0] = 0x018040 + (Reg2 << 3) + (TurnXY(Reg1) << 4);
1400     }
1401   }
1402 }
1403 
DecodeImmMac(Word Code)1404 static void DecodeImmMac(Word Code)
1405 {
1406   tStrComp LeftArg;
1407   Boolean OK;
1408   LongInt h = 0, Reg1, Reg2;
1409 
1410   if (!ChkArgCnt(1, 1));
1411   else if (ChkMinCPU(CPU56300))
1412   {
1413     SplitArg(&ArgStr[1], &LeftComp, &MidComp);
1414     SplitArg(&MidComp, &MidComp, &RightComp);
1415     h = 0;
1416     StrCompRefRight(&LeftArg, &LeftComp, 0);
1417     switch (*LeftComp.Str)
1418     {
1419       case '-':
1420         h = 4;
1421         /* fall-through */
1422       case '+':
1423         StrCompRefRight(&LeftArg, &LeftComp, 1);
1424     }
1425     if ((*MidComp.Str == '\0') || (*RightComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
1426     else if (!DecodeALUReg(RightComp.Str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1427     else if (!DecodeXYABReg(MidComp.Str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1428     else if ((Reg2 < 4) || (Reg2 > 7)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1429     else if (*LeftArg.Str != '#') WrError(ErrNum_OnlyImmAddr);
1430     else
1431     {
1432       DAsmCode[1] = EvalStrIntExpressionOffs(&LeftArg, 1, Int24, &OK);
1433       if (OK)
1434       {
1435         DAsmCode[0] = 0x0141c0 + Code + h + (Reg1 << 3) + ((Reg2 & 3) << 4);
1436         CodeLen = 2;
1437       }
1438     }
1439   }
1440 }
1441 
DecodeDMAC(Word Code)1442 static void DecodeDMAC(Word Code)
1443 {
1444   if (!ChkArgCnt(1, 1));
1445   else if (ChkMinCPU(CPU56300))
1446   {
1447     LongInt Reg1, Reg2, Reg3;
1448     tStrComp LeftReg;
1449 
1450     SplitArg(&ArgStr[1], &LeftComp, &MidComp);
1451     SplitArg(&MidComp, &MidComp, &RightComp);
1452     if (*LeftComp.Str == '-')
1453     {
1454       StrCompRefRight(&LeftReg, &LeftComp, 1);
1455       Code += 16;
1456     }
1457     else if (*LeftComp.Str == '+')
1458       StrCompRefRight(&LeftReg, &LeftComp, 1);
1459     else
1460       StrCompRefRight(&LeftReg, &LeftComp, 0);
1461     if ((*MidComp.Str == '\0') || (*RightComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
1462     else if (!DecodeALUReg(RightComp.Str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1463     else if (!DecodeXYAB1Reg(MidComp.Str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1464     else if (Reg2 < 4) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1465     else if (!DecodeXYAB1Reg(LeftReg.Str, &Reg3)) WrStrErrorPos(ErrNum_InvReg, &LeftReg);
1466     else if (Reg3 < 4) WrStrErrorPos(ErrNum_InvReg, &LeftReg);
1467     else
1468     {
1469       DAsmCode[0] = 0x012480 + Code + (Reg1 << 5) + Mac4Table[Reg3 - 4][Reg2 - 4];
1470       CodeLen = 1;
1471     }
1472   }
1473 }
1474 
DecodeMAC_MPY(Word Code)1475 static void DecodeMAC_MPY(Word Code)
1476 {
1477   if (!ChkArgCnt(1, 1));
1478   else if (ChkMinCPU(CPU56300))
1479   {
1480     tStrComp LeftReg;
1481     LongInt Reg1, Reg2, Reg3;
1482 
1483     SplitArg(&ArgStr[1], &LeftComp, &MidComp);
1484     SplitArg(&MidComp, &MidComp, &RightComp);
1485     if (*LeftComp.Str == '-')
1486     {
1487       StrCompRefRight(&LeftReg, &LeftComp, 1);
1488       Code += 16;
1489     }
1490     else if (*LeftComp.Str == '+')
1491       StrCompRefRight(&LeftReg, &LeftComp, 1);
1492     else
1493       StrCompRefRight(&LeftReg, &LeftComp, 0);
1494     if ((*MidComp.Str == '\0') || (*RightComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
1495     else if (!DecodeALUReg(RightComp.Str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1496     else if (!DecodeXYAB1Reg(MidComp.Str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1497     else if (Reg2 < 4) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1498     else if (!DecodeXYAB1Reg(LeftReg.Str, &Reg3)) WrStrErrorPos(ErrNum_InvReg, &LeftReg);
1499     else if (Reg3 < 4) WrStrErrorPos(ErrNum_InvReg, &LeftReg);
1500     else
1501     {
1502       DAsmCode[0] = 0x012680 + Code + (Reg1 << 5) + Mac4Table[Reg3 - 4][Reg2 - 4];
1503       CodeLen = 1;
1504     }
1505   }
1506 }
1507 
DecodeINC_DEC(Word Code)1508 static void DecodeINC_DEC(Word Code)
1509 {
1510   LongInt Reg1;
1511 
1512   if (!ChkArgCnt(1, 1));
1513   else if (!ChkMinCPU(CPU56002));
1514   else if (!DecodeALUReg(ArgStr[1].Str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
1515   else
1516   {
1517     DAsmCode[0] = (LongWord)Code + Reg1;
1518     CodeLen = 1;
1519   }
1520 }
1521 
DecodeANDI_ORI(Word Code)1522 static void DecodeANDI_ORI(Word Code)
1523 {
1524   LongInt Reg1, h = 0;
1525   Boolean OK;
1526 
1527   if (ChkArgCnt(1, 1))
1528   {
1529     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1530     if ((*LeftComp.Str == '\0') || (*RightComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
1531     else if (!DecodeControlReg(RightComp.Str, &Reg1)) WrStrErrorPos(ErrNum_InvAddrMode, &RightComp);
1532     else if (*LeftComp.Str != '#') WrError(ErrNum_OnlyImmAddr);
1533     else
1534     {
1535       h = EvalStrIntExpressionOffs(&LeftComp, 1, Int8, &OK);
1536       if (OK)
1537       {
1538         CodeLen = 1;
1539         DAsmCode[0] = (LongWord)Code + ((h & 0xff) << 8) + Reg1;
1540       }
1541     }
1542   }
1543 }
1544 
DecodeNORM(Word Code)1545 static void DecodeNORM(Word Code)
1546 {
1547   LongInt Reg1, Reg2;
1548 
1549   UNUSED(Code);
1550 
1551   if (ChkArgCnt(1, 1))
1552   {
1553     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1554     if ((*LeftComp.Str == '\0') || (*RightComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
1555     else if (!DecodeALUReg(RightComp.Str, &Reg2, False, False, True)) WrError(ErrNum_InvAddrMode);
1556     else if (!DecodeReg(LeftComp.Str, &Reg1)) WrError(ErrNum_InvAddrMode);
1557     else if ((Reg1 < 16) || (Reg1 > 23)) WrError(ErrNum_InvAddrMode);
1558     else
1559     {
1560       CodeLen = 1;
1561       DAsmCode[0] = 0x01d815 + ((Reg1 & 7) << 8) + (Reg2 << 3);
1562     }
1563   }
1564 }
1565 
DecodeNORMF(Word Code)1566 static void DecodeNORMF(Word Code)
1567 {
1568   LongInt Reg1, Reg2;
1569 
1570   UNUSED(Code);
1571 
1572   if (ChkArgCnt(1, 1))
1573   {
1574     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1575     if (*RightComp.Str == '\0') WrError(ErrNum_CannotSplitArg);
1576     else if (!DecodeALUReg(RightComp.Str, &Reg2, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1577     else if (!DecodeXYAB1Reg(LeftComp.Str, &Reg1)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
1578     else
1579     {
1580       CodeLen = 1;
1581       DAsmCode[0] = 0x0c1e20 + Reg2 + (Reg1 << 1);
1582     }
1583   }
1584 }
1585 
DecodeBit(Word Code)1586 static void DecodeBit(Word Code)
1587 {
1588   LongInt Reg1, Reg2, Reg3, h = 0;
1589   Boolean OK;
1590   tSymbolFlags Flags;
1591 
1592   if (ChkArgCnt(1, 1))
1593   {
1594     Reg2 = ((Code & 1) << 5) + (((LongInt) Code >> 1) << 16);
1595     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1596     if ((*LeftComp.Str == '\0') || (*RightComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
1597     else if (*LeftComp.Str != '#') WrError(ErrNum_OnlyImmAddr);
1598     else
1599     {
1600       h = EvalStrIntExpressionOffsWithFlags(&LeftComp, 1, Int8, &OK, &Flags);
1601       if (mFirstPassUnknown(Flags)) h &= 15;
1602       if (OK)
1603       {
1604         if ((h < 0) || (h > 23)) WrError(ErrNum_OverRange);
1605         else if (DecodeGeneralReg(RightComp.Str, &Reg1))
1606         {
1607           CodeLen = 1;
1608           DAsmCode[0] = 0x0ac040 + h + (Reg1 << 8) + Reg2;
1609         }
1610         else
1611         {
1612           tAdrResult RightAdrResult;
1613 
1614           DecodeAdr(&RightComp, MModNoImm, MSegXData + MSegYData, &RightAdrResult);
1615           Reg3 = Ord(RightAdrResult.Seg == SegYData) << 6;
1616           if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val <= 63) && (RightAdrResult.Val >= 0) && (RightAdrResult.ShortMode != 2))
1617           {
1618             CodeLen = 1;
1619             DAsmCode[0] = 0x0a0000 + h + (RightAdrResult.Val << 8) + Reg3 + Reg2;
1620           }
1621           else if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val >= MemLimit - 0x3f) && (RightAdrResult.Val <= MemLimit) && (RightAdrResult.ShortMode != 2))
1622           {
1623             CodeLen = 1;
1624             DAsmCode[0] = 0x0a8000 + h + ((RightAdrResult.Val & 0x3f) << 8) + Reg3 + Reg2;
1625           }
1626           else if ((RightAdrResult.Type == ModAbs) && (MomCPU >= CPU56300) && (RightAdrResult.Val >= MemLimit - 0x7f) && (RightAdrResult.Val <= MemLimit - 0x40) && (RightAdrResult.ShortMode != 2))
1627           {
1628             Reg2 = ((Code & 1) << 5) + (((LongInt) Code >> 1) << 14);
1629             CodeLen = 1;
1630             DAsmCode[0] = 0x010000 + h + ((RightAdrResult.Val & 0x3f) << 8) + Reg3 + Reg2;
1631           }
1632           else if (RightAdrResult.Type != ModNone)
1633           {
1634             CodeLen = 1 + RightAdrResult.Cnt;
1635             DAsmCode[0] = 0x0a4000 + h + (RightAdrResult.Mode << 8) + Reg3 + Reg2;
1636             DAsmCode[1] = RightAdrResult.Val;
1637           }
1638         }
1639       }
1640     }
1641   }
1642 }
1643 
DecodeEXTRACT_EXTRACTU(Word Code)1644 static void DecodeEXTRACT_EXTRACTU(Word Code)
1645 {
1646   LongInt Reg1, Reg2, Reg3;
1647   Boolean OK;
1648 
1649   if (ChkArgCnt(1, 1)
1650    && ChkMinCPU(CPU56300))
1651   {
1652     SplitArg(&ArgStr[1], &LeftComp, &MidComp);
1653     SplitArg(&MidComp, &MidComp, &RightComp);
1654     if ((*MidComp.Str == '\0') || (*RightComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
1655     else if (!DecodeALUReg(RightComp.Str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1656     else if (!DecodeALUReg(MidComp.Str, &Reg2, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1657     else if (*LeftComp.Str == '#')
1658     {
1659       DAsmCode[1] = EvalStrIntExpressionOffs(&LeftComp, 1, Int24, &OK);
1660       if (OK)
1661       {
1662         DAsmCode[0] = 0x0c1800 + Code + Reg1 + (Reg2 << 4);
1663         CodeLen = 2;
1664       }
1665     }
1666     else if (!DecodeXYAB1Reg(LeftComp.Str, &Reg3)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
1667     else
1668     {
1669       DAsmCode[0] = 0x0c1a00 + Code + Reg1 + (Reg2 << 4) + (Reg3 << 1);
1670       CodeLen = 1;
1671     }
1672   }
1673 }
1674 
DecodeINSERT(Word Code)1675 static void DecodeINSERT(Word Code)
1676 {
1677   LongInt Reg1, Reg2, Reg3;
1678   Boolean OK;
1679 
1680   UNUSED(Code);
1681 
1682   if (ChkArgCnt(1, 1)
1683    && ChkMinCPU(CPU56300))
1684   {
1685     SplitArg(&ArgStr[1], &LeftComp, &MidComp);
1686     SplitArg(&MidComp, &MidComp, &RightComp);
1687     if ((*MidComp.Str == '\0') || (*RightComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
1688     else if (!DecodeALUReg(RightComp.Str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1689     else if (!DecodeXYAB0Reg(MidComp.Str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1690     else if (*LeftComp.Str == '#')
1691     {
1692       DAsmCode[1] = EvalStrIntExpressionOffs(&LeftComp, 1, Int24, &OK);
1693       if (OK)
1694       {
1695         DAsmCode[0] = 0x0c1900 + Reg1 + (Reg2 << 4);
1696         CodeLen = 2;
1697       }
1698     }
1699     else if (!DecodeXYAB1Reg(LeftComp.Str, &Reg3)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
1700     else
1701     {
1702       DAsmCode[0] = 0x0c1b00 + Reg1 + (Reg2 << 4) + (Reg3 << 1);
1703       CodeLen = 1;
1704     }
1705   }
1706 }
1707 
DecodeMERGE(Word Code)1708 static void DecodeMERGE(Word Code)
1709 {
1710   LongInt Reg1, Reg2;
1711 
1712   UNUSED(Code);
1713 
1714   if (ChkArgCnt(1, 1)
1715    && ChkMinCPU(CPU56300))
1716   {
1717     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1718     if (*RightComp.Str == '\0') WrError(ErrNum_CannotSplitArg);
1719     else if (!DecodeALUReg(RightComp.Str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1720     else if (!DecodeXYAB1Reg(LeftComp.Str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
1721     else
1722     {
1723       DAsmCode[0] = 0x0c1b80 + Reg1 + (Reg2 << 1);
1724       CodeLen = 1;
1725     }
1726   }
1727 }
1728 
DecodeCLB(Word Code)1729 static void DecodeCLB(Word Code)
1730 {
1731   LongInt Reg1, Reg2;
1732 
1733   UNUSED(Code);
1734 
1735   if (ChkArgCnt(1, 1)
1736    && ChkMinCPU(CPU56300))
1737   {
1738     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1739     if (*RightComp.Str == '\0') WrError(ErrNum_CannotSplitArg);
1740     else if (!DecodeALUReg(LeftComp.Str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
1741     else if (!DecodeALUReg(RightComp.Str, &Reg2, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1742     else
1743     {
1744       DAsmCode[0] = 0x0c1e00 + Reg2 + (Reg1 << 1);
1745       CodeLen = 1;
1746     }
1747   }
1748 }
1749 
DecodeCMPU(Word Code)1750 static void DecodeCMPU(Word Code)
1751 {
1752   LongInt Reg1, Reg2;
1753 
1754   UNUSED(Code);
1755 
1756   if (ChkArgCnt(1, 1)
1757    && ChkMinCPU(CPU56300))
1758   {
1759     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1760     if (*RightComp.Str == '\0') WrError(ErrNum_CannotSplitArg);
1761     else if (!DecodeALUReg(RightComp.Str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1762     else if (!DecodeXYABReg(LeftComp.Str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
1763     else if ((Reg1 ^ Reg2) == 1) WrError(ErrNum_InvRegPair);
1764     else if ((Reg2 & 6) == 2) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
1765     else
1766     {
1767       if (Reg2 < 2)
1768         Reg2 = 0;
1769       DAsmCode[0] = 0x0c1ff0 + (Reg2 << 1) + Reg1;
1770       CodeLen = 1;
1771     }
1772   }
1773 }
1774 
1775 /* Datentransfer */
1776 
DecodePlainMOVE(Word Code)1777 static void DecodePlainMOVE(Word Code)
1778 {
1779   UNUSED(Code);
1780 
1781   DecodeMOVE(1);
1782 }
1783 
DecodeMOVEC(Word Code)1784 static void DecodeMOVEC(Word Code)
1785 {
1786   LongInt Reg1, Reg2, Reg3;
1787 
1788   UNUSED(Code);
1789 
1790   if (ChkArgCnt(1, 1))
1791   {
1792     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1793     if (*RightComp.Str == '\0') WrError(ErrNum_CannotSplitArg);
1794     else if (DecodeCtrlReg(LeftComp.Str, &Reg1))
1795     {
1796       if (DecodeGeneralReg(RightComp.Str, &Reg2))
1797       {
1798         DAsmCode[0] = 0x0440a0 + (Reg2 << 8) + Reg1;
1799         CodeLen = 1;
1800       }
1801       else
1802       {
1803         tAdrResult RightAdrResult;
1804 
1805         DecodeAdr(&RightComp, MModNoImm, MSegXData + MSegYData, &RightAdrResult);
1806         Reg3 = (Ord(RightAdrResult.Seg == SegYData)) << 6;
1807         if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val <= 63) && (RightAdrResult.ShortMode != 2))
1808         {
1809           DAsmCode[0] = 0x050020 + (RightAdrResult.Val << 8) + Reg3 + Reg1;
1810           CodeLen = 1;
1811         }
1812         else
1813         {
1814           DAsmCode[0] = 0x054020 + (RightAdrResult.Mode << 8) + Reg3 + Reg1;
1815           DAsmCode[1] = RightAdrResult.Val; CodeLen = 1 + RightAdrResult.Cnt;
1816         }
1817       }
1818     }
1819     else if (!DecodeCtrlReg(RightComp.Str, &Reg1)) WrStrErrorPos(ErrNum_InvCtrlReg, &RightComp);
1820     else
1821     {
1822       if (DecodeGeneralReg(LeftComp.Str, &Reg2))
1823       {
1824         DAsmCode[0] = 0x04c0a0 + (Reg2 << 8) + Reg1;
1825         CodeLen = 1;
1826       }
1827       else
1828       {
1829         tAdrResult LeftAdrResult;
1830 
1831         DecodeAdr(&LeftComp, MModAll, MSegXData + MSegYData, &LeftAdrResult);
1832         Reg3 = (Ord(LeftAdrResult.Seg == SegYData)) << 6;
1833         if ((LeftAdrResult.Type == ModAbs) && (LeftAdrResult.Val <= 63) && (LeftAdrResult.ShortMode != 2))
1834         {
1835           DAsmCode[0] = 0x058020 + (LeftAdrResult.Val << 8) + Reg3 + Reg1;
1836           CodeLen = 1;
1837         }
1838         else if (!LeftAdrResult.ForceImmLong && (LeftAdrResult.Type == ModImm) && (LeftAdrResult.Val <= 255))
1839         {
1840           DAsmCode[0] = 0x0500a0 + (LeftAdrResult.Val << 8) + Reg1;
1841           CodeLen = 1;
1842         }
1843         else
1844         {
1845           DAsmCode[0] = 0x05c020 + (LeftAdrResult.Mode << 8) + Reg3 + Reg1;
1846           DAsmCode[1] = LeftAdrResult.Val; CodeLen = 1 + LeftAdrResult.Cnt;
1847         }
1848       }
1849     }
1850   }
1851 }
1852 
DecodeMOVEM(Word Code)1853 static void DecodeMOVEM(Word Code)
1854 {
1855   LongInt Reg1, Reg2;
1856 
1857   UNUSED(Code);
1858 
1859   if (ChkArgCnt(1, 1))
1860   {
1861     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1862     if ((*LeftComp.Str == '\0') || (*RightComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
1863     else if (DecodeGeneralReg(LeftComp.Str, &Reg1))
1864     {
1865       tAdrResult RightAdrResult;
1866 
1867       DecodeAdr(&RightComp, MModNoImm, MSegCode, &RightAdrResult);
1868       if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val >= 0) && (RightAdrResult.Val <= 63) && (RightAdrResult.ShortMode != 2))
1869       {
1870         CodeLen = 1;
1871         DAsmCode[0] = 0x070000 + Reg1 + (RightAdrResult.Val << 8);
1872       }
1873       else if (RightAdrResult.Type != ModNone)
1874       {
1875         CodeLen = 1 + RightAdrResult.Cnt;
1876         DAsmCode[1] = RightAdrResult.Val;
1877         DAsmCode[0] = 0x074080 + Reg1 + (RightAdrResult.Mode << 8);
1878       }
1879     }
1880     else if (!DecodeGeneralReg(RightComp.Str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1881     else
1882     {
1883       tAdrResult LeftAdrResult;
1884 
1885       DecodeAdr(&LeftComp, MModNoImm, MSegCode, &LeftAdrResult);
1886       if ((LeftAdrResult.Type == ModAbs) && (LeftAdrResult.Val >= 0) && (LeftAdrResult.Val <= 63) && (LeftAdrResult.ShortMode != 2))
1887       {
1888         CodeLen = 1;
1889         DAsmCode[0] = 0x078000 + Reg2 + (LeftAdrResult.Val << 8);
1890       }
1891       else if (LeftAdrResult.Type != ModNone)
1892       {
1893         CodeLen = 1 + LeftAdrResult.Cnt;
1894         DAsmCode[1] = LeftAdrResult.Val;
1895         DAsmCode[0] = 0x07c080 + Reg2 + (LeftAdrResult.Mode << 8);
1896       }
1897     }
1898   }
1899 }
1900 
DecodeMOVEP(Word Code)1901 static void DecodeMOVEP(Word Code)
1902 {
1903   LongInt Reg1, Reg2;
1904 
1905   UNUSED(Code);
1906 
1907   if (ChkArgCnt(1, 1))
1908   {
1909     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1910     if ((*LeftComp.Str == '\0') || (*RightComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
1911     else if (DecodeGeneralReg(LeftComp.Str, &Reg1))
1912     {
1913       tAdrResult RightAdrResult;
1914 
1915       DecodeAdr(&RightComp, MModAbs, MSegXData + MSegYData, &RightAdrResult);
1916       if (RightAdrResult.Type != ModNone)
1917       {
1918         if ((RightAdrResult.Val <= MemLimit) && (RightAdrResult.Val >= MemLimit - 0x3f))
1919         {
1920           CodeLen = 1;
1921           DAsmCode[0] = 0x08c000 + (Ord(RightAdrResult.Seg == SegYData) << 16)
1922                       + (RightAdrResult.Val & 0x3f) + (Reg1 << 8);
1923         }
1924         else if ((MomCPU >= CPU56300) && (RightAdrResult.Val <= MemLimit - 0x40) && (RightAdrResult.Val >= MemLimit - 0x7f))
1925         {
1926           CodeLen = 1;
1927           DAsmCode[0] = 0x04c000 + (Ord(RightAdrResult.Seg == SegYData) << 5)
1928                       + (Ord(RightAdrResult.Seg == SegXData) << 7)
1929                       + (RightAdrResult.Val & 0x1f) + ((RightAdrResult.Val & 0x20) << 1) + (Reg1 << 8);
1930         }
1931         else
1932           WrError(ErrNum_UnderRange);
1933       }
1934     }
1935     else if (DecodeGeneralReg(RightComp.Str, &Reg2))
1936     {
1937       tAdrResult LeftAdrResult;
1938 
1939       DecodeAdr(&LeftComp, MModAbs, MSegXData + MSegYData, &LeftAdrResult);
1940       if (LeftAdrResult.Type != ModNone)
1941       {
1942         if ((LeftAdrResult.Val <= MemLimit) && (LeftAdrResult.Val >= MemLimit - 0x3f))
1943         {
1944           CodeLen = 1;
1945           DAsmCode[0] = 0x084000 + (Ord(LeftAdrResult.Seg == SegYData) << 16)
1946                       + (LeftAdrResult.Val & 0x3f) + (Reg2 << 8);
1947         }
1948         else if ((MomCPU >= CPU56300) && (LeftAdrResult.Val <= MemLimit - 0x40) && (LeftAdrResult.Val >= MemLimit - 0x7f))
1949         {
1950           CodeLen = 1;
1951           DAsmCode[0] = 0x044000 + (Ord(LeftAdrResult.Seg == SegYData) << 5)
1952                       + (Ord(LeftAdrResult.Seg == SegXData) << 7)
1953                       + (LeftAdrResult.Val & 0x1f) + ((LeftAdrResult.Val & 0x20) << 1) + (Reg2 << 8);
1954         }
1955         else
1956           WrError(ErrNum_UnderRange);
1957       }
1958     }
1959     else
1960     {
1961       tAdrResult LeftAdrResult;
1962 
1963       DecodeAdr(&LeftComp, MModAll, MSegXData + MSegYData + MSegCode, &LeftAdrResult);
1964       if ((LeftAdrResult.Type == ModAbs) && (LeftAdrResult.Seg != SegCode) && (LeftAdrResult.Val >= MemLimit - 0x3f) && (LeftAdrResult.Val <= MemLimit))
1965       {
1966         LongInt HVal = LeftAdrResult.Val & 0x3f, HSeg = LeftAdrResult.Seg;
1967         tAdrResult RightAdrResult;
1968 
1969         DecodeAdr(&RightComp, MModNoImm, MSegXData + MSegYData + MSegCode, &RightAdrResult);
1970         if (RightAdrResult.Type != ModNone)
1971         {
1972           if (RightAdrResult.Seg == SegCode)
1973           {
1974             CodeLen = 1 + RightAdrResult.Cnt;
1975             DAsmCode[1] = RightAdrResult.Val;
1976             DAsmCode[0] = 0x084040 + HVal + (RightAdrResult.Mode << 8)
1977                         + (Ord(HSeg == SegYData) << 16);
1978           }
1979           else
1980           {
1981             CodeLen = 1 + RightAdrResult.Cnt;
1982             DAsmCode[1] = RightAdrResult.Val;
1983             DAsmCode[0] = 0x084080 + HVal + (RightAdrResult.Mode << 8)
1984                         + (Ord(HSeg == SegYData) << 16)
1985                         + (Ord(RightAdrResult.Seg == SegYData) << 6);
1986           }
1987         }
1988       }
1989       else if ((LeftAdrResult.Type == ModAbs) && (MomCPU >= CPU56300) && (LeftAdrResult.Seg != SegCode) && (LeftAdrResult.Val >= MemLimit - 0x7f) && (LeftAdrResult.Val <= MemLimit - 0x40) && (LeftAdrResult.ShortMode != 2))
1990       {
1991         LongInt HVal = LeftAdrResult.Val & 0x3f, HSeg = LeftAdrResult.Seg;
1992         tAdrResult RightAdrResult;
1993 
1994         DecodeAdr(&RightComp, MModNoImm, MSegXData + MSegYData + MSegCode, &RightAdrResult);
1995         if (RightAdrResult.Type != ModNone)
1996         {
1997           if (RightAdrResult.Seg == SegCode)
1998           {
1999             CodeLen = 1 + RightAdrResult.Cnt;
2000             DAsmCode[1] = RightAdrResult.Val;
2001             DAsmCode[0] = 0x008000 + HVal + (RightAdrResult.Mode << 8)
2002                         + (Ord(HSeg == SegYData) << 6);
2003           }
2004           else
2005           {
2006             CodeLen = 1 + RightAdrResult.Cnt;
2007             DAsmCode[1] = RightAdrResult.Val;
2008             DAsmCode[0] = 0x070000 + HVal + (RightAdrResult.Mode << 8)
2009                         + (Ord(HSeg == SegYData) << 7)
2010                         + (Ord(HSeg == SegXData) << 14)
2011                         + (Ord(RightAdrResult.Seg == SegYData) << 6);
2012           }
2013         }
2014       }
2015       else if (LeftAdrResult.Type != ModNone)
2016       {
2017         LongInt HVal = LeftAdrResult.Val,
2018                 HCnt = LeftAdrResult.Cnt,
2019                 HMode = LeftAdrResult.Mode,
2020                 HSeg = LeftAdrResult.Seg;
2021         tAdrResult RightAdrResult;
2022 
2023         DecodeAdr(&RightComp, MModAbs, MSegXData + MSegYData, &RightAdrResult);
2024         if (RightAdrResult.Type != ModNone)
2025         {
2026           if ((RightAdrResult.Val >= MemLimit - 0x3f) && (RightAdrResult.Val <= MemLimit))
2027           {
2028             if (HSeg == SegCode)
2029             {
2030               CodeLen = 1 + HCnt;
2031               DAsmCode[1] = HVal;
2032               DAsmCode[0] = 0x08c040 + (RightAdrResult.Val & 0x3f) + (HMode << 8)
2033                           + (Ord(RightAdrResult.Seg == SegYData) << 16);
2034             }
2035             else
2036             {
2037               CodeLen = 1 + HCnt;
2038               DAsmCode[1] = HVal;
2039               DAsmCode[0] = 0x08c080 + (((Word)RightAdrResult.Val) & 0x3f) + (HMode << 8)
2040                           + (Ord(RightAdrResult.Seg == SegYData) << 16)
2041                           + (Ord(HSeg == SegYData) << 6);
2042             }
2043           }
2044           else if ((MomCPU >= CPU56300) && (RightAdrResult.Val >= MemLimit - 0x7f) && (RightAdrResult.Val <= MemLimit - 0x40))
2045           {
2046             if (HSeg == SegCode)
2047             {
2048               CodeLen = 1 + HCnt;
2049               DAsmCode[1] = HVal;
2050               DAsmCode[0] = 0x00c000 + (RightAdrResult.Val & 0x3f) + (HMode << 8)
2051                           + (Ord(RightAdrResult.Seg == SegYData) << 6);
2052             }
2053             else
2054             {
2055               CodeLen = 1 + HCnt;
2056               DAsmCode[1] = HVal;
2057               DAsmCode[0] = 0x078000 + (((Word)RightAdrResult.Val) & 0x3f) + (HMode << 8)
2058                           + (Ord(RightAdrResult.Seg == SegYData) << 7)
2059                           + (Ord(RightAdrResult.Seg == SegXData) << 14)
2060                           + (Ord(HSeg == SegYData) << 6);
2061             }
2062           }
2063           else
2064             WrError(ErrNum_UnderRange);
2065         }
2066       }
2067     }
2068   }
2069 }
2070 
DecodePlainTFR(Word Code)2071 static void DecodePlainTFR(Word Code)
2072 {
2073   LongInt Reg1;
2074 
2075   UNUSED(Code);
2076 
2077   if (ChkArgCnt(1, ArgCntMax))
2078   if (DecodeMOVE(2))
2079   {
2080     if (DecodeTFR(&ArgStr[1], &Reg1))
2081     {
2082       DAsmCode[0] += 0x01 + (Reg1 << 3);
2083     }
2084     else
2085     {
2086       WrError(ErrNum_InvAddrMode);
2087       CodeLen = 0;
2088     }
2089   }
2090 }
2091 
DecodeTcc(Word Condition)2092 static void DecodeTcc(Word Condition)
2093 {
2094   LongInt Reg1, Reg2;
2095 
2096   if (!ChkArgCnt(1, 2));
2097   else if (DecodeTFR(&ArgStr[1], &Reg1))
2098   {
2099     if (ArgCnt == 1)
2100     {
2101       CodeLen = 1;
2102       DAsmCode[0] = 0x020000 + (Condition << 12) + (Reg1 << 3);
2103     }
2104     else if (!DecodeRR(&ArgStr[2], &Reg2)) WrError(ErrNum_InvAddrMode);
2105     else
2106     {
2107       CodeLen = 1;
2108       DAsmCode[0] = 0x030000 + (Condition << 12) + (Reg1 << 3) + Reg2;
2109     }
2110   }
2111   else if (!ChkArgCnt(1, 1));
2112   else if (!DecodeRR(&ArgStr[1], &Reg1)) WrError(ErrNum_InvAddrMode);
2113   else
2114   {
2115     DAsmCode[0] = 0x020800 + (Condition << 12) + Reg1;
2116     CodeLen = 1;
2117   }
2118 }
2119 
DecodeBitBr(Word Code)2120 static void DecodeBitBr(Word Code)
2121 {
2122   LongInt Reg1, Reg3, h = 0, h2, AddVal;
2123   Boolean OK;
2124   tSymbolFlags Flags;
2125 
2126   if (ChkArgCnt(1, 1)
2127    && ChkMinCPU(CPU56300))
2128   {
2129     h = (Code & 1) << 5;
2130     h2 = (((LongInt) Code) & 2) << 15;
2131     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
2132     SplitArg(&RightComp, &MidComp, &RightComp);
2133     if ((*LeftComp.Str == '\0') || (*RightComp.Str == '\0') || (*MidComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
2134     else if (*LeftComp.Str != '#') WrError(ErrNum_OnlyImmAddr);
2135     else
2136     {
2137       AddVal = EvalStrIntExpressionOffsWithFlags(&LeftComp, 1, Int8, &OK, &Flags);
2138       if (mFirstPassUnknown(Flags)) AddVal &= 15;
2139       if (OK)
2140       {
2141         if ((AddVal < 0) || (AddVal > 23)) WrError(ErrNum_OverRange);
2142         else if (DecodeGeneralReg(MidComp.Str, &Reg1))
2143         {
2144           CodeLen = 1;
2145           DAsmCode[0] = 0x0cc080 + AddVal + (Reg1 << 8) + h + h2;
2146         }
2147         else
2148         {
2149           tAdrResult AdrResult;
2150 
2151           DecodeAdr(&MidComp, MModNoImm, MSegXData + MSegYData, &AdrResult);
2152           Reg3 = Ord(AdrResult.Seg == SegYData) << 6;
2153           if ((AdrResult.Type == ModAbs) && (mFirstPassUnknown(AdrResult.AbsSymFlags))) AdrResult.Val &= 0x3f;
2154           if ((AdrResult.Type == ModAbs) && (AdrResult.Val <= 63) && (AdrResult.Val >= 0) && (AdrResult.ShortMode != 2))
2155           {
2156             CodeLen = 1;
2157             DAsmCode[0] = 0x0c8080 + AddVal + (AdrResult.Val << 8) + Reg3 + h + h2;
2158           }
2159           else if ((AdrResult.Type == ModAbs) && (AdrResult.Val >= MemLimit - 0x3f) && (AdrResult.Val <= MemLimit))
2160           {
2161             CodeLen = 1;
2162             DAsmCode[0] = 0x0cc000 + AddVal + ((AdrResult.Val & 0x3f) << 8) + Reg3 + h + h2;
2163           }
2164           else if ((AdrResult.Type == ModAbs) && (AdrResult.Val >= MemLimit - 0x7f) && (AdrResult.Val <= MemLimit - 0x40))
2165           {
2166             CodeLen = 1;
2167             DAsmCode[0] = 0x048000 + AddVal + ((AdrResult.Val & 0x3f) << 8) + Reg3 + h + (h2 >> 9);
2168           }
2169           else if (AdrResult.Type == ModAbs) WrError(ErrNum_InvAddrMode);
2170           else if (AdrResult.Type != ModNone)
2171           {
2172             CodeLen = 1;
2173             DAsmCode[0] = 0x0c8000 + AddVal + (AdrResult.Mode << 8) + Reg3 + h + h2;
2174           }
2175         }
2176       }
2177     }
2178     if (CodeLen == 1)
2179     {
2180       LongInt Dist = EvalStrIntExpression(&RightComp, AdrInt, &OK) - EProgCounter();
2181 
2182       if (OK)
2183       {
2184         DAsmCode[1] = Dist & 0xffffff;
2185         CodeLen = 2;
2186       }
2187       else
2188         CodeLen = 0;
2189     }
2190   }
2191 }
2192 
DecodeBRA_BSR(Word Code)2193 static void DecodeBRA_BSR(Word Code)
2194 {
2195   LongInt Reg1, Dist;
2196   Byte Size;
2197   Boolean OK;
2198   tSymbolFlags Flags;
2199 
2200   if (ChkArgCnt(1, 1)
2201    && ChkMinCPU(CPU56300)
2202    && DecodeReg(ArgStr[1].Str, &Reg1))
2203   {
2204     if ((Reg1 < 16) || (Reg1 > 23)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
2205     else
2206     {
2207       Reg1 -= 16;
2208       DAsmCode[0] = 0x0d1880 + (Reg1 << 8) + Code;
2209       CodeLen = 1;
2210     }
2211   }
2212   else
2213   {
2214     unsigned Offset = CutSize(&ArgStr[1], &Size);
2215 
2216     Dist = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], Offset, AdrInt, &OK, &Flags) - EProgCounter();
2217     if (Size == 0)
2218       Size = ((Dist> - 256) && (Dist < 255)) ? 1 : 2;
2219     switch (Size)
2220     {
2221       case 1:
2222         if (!mSymbolQuestionable(Flags) && ((Dist < -256) || (Dist > 255))) WrError(ErrNum_JmpDistTooBig);
2223         else
2224         {
2225           Dist &= 0x1ff;
2226           DAsmCode[0] = 0x050800 + (Code << 4) + ((Dist & 0x1e0) << 1) + (Dist & 0x1f);
2227           CodeLen = 1;
2228         }
2229         break;
2230       case 2:
2231         DAsmCode[0] = 0x0d1080 + Code;
2232         DAsmCode[1] = Dist & 0xffffff;
2233         CodeLen = 2;
2234         break;
2235     }
2236   }
2237 }
2238 
DecodeBcc(Word Condition)2239 static void DecodeBcc(Word Condition)
2240 {
2241   LongInt Dist, Reg1;
2242   Boolean OK;
2243   tSymbolFlags Flags;
2244   Byte Size;
2245 
2246   if (ChkArgCnt(1, 1)
2247    && ChkMinCPU(CPU56300)
2248    && DecodeReg(ArgStr[1].Str, &Reg1))
2249   {
2250     if ((Reg1 < 16) || (Reg1 > 23)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
2251     else
2252     {
2253       Reg1 -= 16;
2254       DAsmCode[0] = 0x0d1840 + (Reg1 << 8) + Condition;
2255       CodeLen = 1;
2256     }
2257   }
2258   else
2259   {
2260     unsigned Offset = CutSize(&ArgStr[1], &Size);
2261 
2262     Dist = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], Offset, AdrInt, &OK, &Flags) - EProgCounter();
2263     if (Size == 0)
2264       Size = ((Dist > -256) && (Dist < 255)) ? 1 : 2;
2265     switch (Size)
2266     {
2267       case 1:
2268         if (!mSymbolQuestionable(Flags) && ((Dist < -256) || (Dist > 255))) WrError(ErrNum_JmpDistTooBig);
2269         else
2270         {
2271           Dist &= 0x1ff;
2272           DAsmCode[0] = 0x050400 + (Condition << 12) + ((Dist & 0x1e0) << 1) + (Dist & 0x1f);
2273           CodeLen = 1;
2274         }
2275         break;
2276       case 2:
2277         DAsmCode[0] = 0x0d1040 + Condition;
2278         DAsmCode[1] = Dist & 0xffffff;
2279         CodeLen = 2;
2280         break;
2281     }
2282   }
2283 }
2284 
DecodeBScc(Word Condition)2285 static void DecodeBScc(Word Condition)
2286 {
2287   LongInt Reg1, Dist;
2288   Byte Size;
2289   Boolean OK;
2290   tSymbolFlags Flags;
2291 
2292   if (ChkArgCnt(1, 1)
2293    && ChkMinCPU(CPU56300)
2294    && DecodeReg(ArgStr[1].Str, &Reg1))
2295   {
2296     if ((Reg1 < 16) || (Reg1 > 23)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
2297     else
2298     {
2299       Reg1 -= 16;
2300       DAsmCode[0] = 0x0d1800 + (Reg1 << 8) + Condition;
2301       CodeLen = 1;
2302     }
2303   }
2304   else
2305   {
2306     unsigned Offset;
2307 
2308     Offset = CutSize(&ArgStr[1], &Size);
2309     Dist = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], Offset, AdrInt, &OK, &Flags) - EProgCounter();
2310     if (Size == 0)
2311       Size = ((Dist > -256) && (Dist < 255)) ? 1 : 2;
2312     switch (Size)
2313     {
2314       case 1:
2315         if (!mSymbolQuestionable(Flags) && ((Dist < -256) || (Dist > 255))) WrError(ErrNum_JmpDistTooBig);
2316         else
2317         {
2318           Dist &= 0x1ff;
2319           DAsmCode[0] = 0x050000 + (Condition << 12) + ((Dist & 0x1e0) << 1) + (Dist & 0x1f);
2320           CodeLen = 1;
2321         }
2322         break;
2323       case 2:
2324         DAsmCode[0] = 0x0d1000 + Condition;
2325         DAsmCode[1] = Dist & 0xffffff;
2326         CodeLen = 2;
2327         break;
2328     }
2329   }
2330 }
2331 
DecodeLUA_LEA(Word Code)2332 static void DecodeLUA_LEA(Word Code)
2333 {
2334   LongInt Reg1;
2335 
2336   UNUSED(Code);
2337 
2338   if (ChkArgCnt(1, 1))
2339   {
2340     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
2341     if ((*LeftComp.Str == '\0') || (*RightComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
2342     else if (!DecodeReg(RightComp.Str, &Reg1)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
2343     else if (Reg1 > 31) WrStrErrorPos(ErrNum_InvReg, &RightComp);
2344     else
2345     {
2346       tAdrResult AdrResult;
2347 
2348       DecodeAdr(&LeftComp, MModModInc | MModModDec | MModPostInc | MModPostDec | MModDisp, MSegXData, &AdrResult);
2349       if (AdrResult.Type == ModDisp)
2350       {
2351         if (ChkRange(AdrResult.Val, -64, 63))
2352         {
2353           AdrResult.Val &= 0x7f;
2354           DAsmCode[0] = 0x040000 + (Reg1 - 16) + (AdrResult.Mode << 8)
2355                       + ((AdrResult.Val & 0x0f) << 4)
2356                       + ((AdrResult.Val & 0x70) << 7);
2357            CodeLen = 1;
2358         }
2359       }
2360       else if (AdrResult.Type != ModNone)
2361       {
2362         CodeLen = 1;
2363         DAsmCode[0] = 0x044000 + (AdrResult.Mode << 8) + Reg1;
2364       }
2365     }
2366   }
2367 }
2368 
DecodeLRA(Word Code)2369 static void DecodeLRA(Word Code)
2370 {
2371   LongInt Reg1, Reg2;
2372   Boolean OK;
2373 
2374   UNUSED(Code);
2375 
2376   if (ChkArgCnt(1, 1)
2377    && ChkMinCPU(CPU56300))
2378   {
2379     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
2380     if (*RightComp.Str == '\0') WrError(ErrNum_CannotSplitArg);
2381     else if (!DecodeGeneralReg(RightComp.Str, &Reg1)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
2382     else if (Reg1 > 0x1f) WrStrErrorPos(ErrNum_InvReg, &RightComp);
2383     else if (DecodeGeneralReg(LeftComp.Str, &Reg2))
2384     {
2385       if ((Reg2 < 16) || (Reg2 > 23)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
2386       else
2387       {
2388         DAsmCode[0] = 0x04c000 + ((Reg2 & 7) << 8) + Reg1;
2389         CodeLen = 1;
2390       }
2391     }
2392     else
2393     {
2394       DAsmCode[1] = EvalStrIntExpression(&LeftComp, AdrInt, &OK) - EProgCounter();
2395       if (OK)
2396       {
2397         DAsmCode[0] = 0x044040 + Reg1;
2398         CodeLen = 2;
2399       }
2400     }
2401   }
2402 }
2403 
DecodePLOCK(Word Code)2404 static void DecodePLOCK(Word Code)
2405 {
2406   UNUSED(Code);
2407 
2408   if (ChkArgCnt(1, 1)
2409    && ChkMinCPU(CPU56300))
2410   {
2411     tAdrResult AdrResult;
2412 
2413     DecodeAdr(&ArgStr[1], MModNoImm, MSegCode, &AdrResult);
2414     if (AdrResult.Type != ModNone)
2415     {
2416       DAsmCode[0] = 0x0ac081 + (AdrResult.Mode << 8); DAsmCode[1] = AdrResult.Val;
2417       CodeLen = 2;
2418     }
2419   }
2420 }
2421 
DecodePLOCKR_PUNLOCKR(Word Code)2422 static void DecodePLOCKR_PUNLOCKR(Word Code)
2423 {
2424   if (ChkArgCnt(1, 1)
2425    && ChkMinCPU(CPU56300))
2426   {
2427     Boolean OK;
2428 
2429     DAsmCode[1] = (EvalStrIntExpression(&ArgStr[1],  AdrInt,  &OK) - EProgCounter()) & 0xffffff;
2430     if (OK)
2431     {
2432       DAsmCode[0] = Code;
2433       CodeLen = 2;
2434     }
2435   }
2436 }
2437 
2438 /* Spruenge */
2439 
DecodeJMP_JSR(Word Code)2440 static void DecodeJMP_JSR(Word Code)
2441 {
2442   if (ChkArgCnt(1, 1))
2443   {
2444     LongWord AddVal = (LongWord)Code << 16;
2445     tAdrResult AdrResult;
2446 
2447     DecodeAdr(&ArgStr[1], MModNoImm, MSegCode, &AdrResult);
2448     if (AdrResult.Type == ModAbs)
2449      if (((AdrResult.Val & 0xfff000) == 0) && (AdrResult.ShortMode != 2))
2450      {
2451        CodeLen = 1;
2452        DAsmCode[0] = 0x0c0000 + AddVal + (AdrResult.Val & 0xfff);
2453      }
2454      else
2455      {
2456        CodeLen = 2;
2457        DAsmCode[0] = 0x0af080 + AddVal;
2458        DAsmCode[1] = AdrResult.Val;
2459      }
2460     else if (AdrResult.Type != ModNone)
2461     {
2462       CodeLen = 1;
2463       DAsmCode[0] = 0x0ac080 + AddVal + (AdrResult.Mode << 8);
2464     }
2465   }
2466 }
2467 
DecodeJcc(Word Condition)2468 static void DecodeJcc(Word Condition)
2469 {
2470   if (ChkArgCnt(1, 1))
2471   {
2472     tAdrResult AdrResult;
2473 
2474     DecodeAdr(&ArgStr[1], MModNoImm, MSegCode, &AdrResult);
2475     if (AdrResult.Type == ModAbs)
2476     {
2477       if (((AdrResult.Val & 0xfff000) == 0) && (AdrResult.ShortMode != 2))
2478       {
2479         CodeLen = 1;
2480         DAsmCode[0] = 0x0e0000 + (Condition << 12) + (AdrResult.Val & 0xfff);
2481       }
2482       else
2483       {
2484         CodeLen = 2;
2485         DAsmCode[0] = 0x0af0a0 + Condition;
2486         DAsmCode[1] = AdrResult.Val;
2487       }
2488     }
2489     else if (AdrResult.Type != ModNone)
2490     {
2491       CodeLen = 1;
2492       DAsmCode[0] = 0x0ac0a0 + Condition + (AdrResult.Mode << 8);
2493     }
2494   }
2495 }
2496 
DecodeJScc(Word Condition)2497 static void DecodeJScc(Word Condition)
2498 {
2499   if (ChkArgCnt(1, 1))
2500   {
2501     tAdrResult AdrResult;
2502 
2503     DecodeAdr(&ArgStr[1], MModNoImm, MSegCode, &AdrResult);
2504     if (AdrResult.Type == ModAbs)
2505     {
2506       if (((AdrResult.Val & 0xfff000) == 0) && (AdrResult.ShortMode != 2))
2507       {
2508         CodeLen = 1;
2509         DAsmCode[0] = 0x0f0000 + (Condition << 12) + (AdrResult.Val & 0xfff);
2510       }
2511       else
2512       {
2513         CodeLen = 2;
2514         DAsmCode[0] = 0x0bf0a0 + Condition;
2515         DAsmCode[1] = AdrResult.Val;
2516       }
2517     }
2518     else if (AdrResult.Type != ModNone)
2519     {
2520       CodeLen = 1;
2521       DAsmCode[0] = 0x0bc0a0 + Condition + (AdrResult.Mode << 8);
2522     }
2523   }
2524 }
2525 
DecodeBitJmp(Word Code)2526 static void DecodeBitJmp(Word Code)
2527 {
2528   Boolean OK;
2529   tSymbolFlags Flags;
2530   LongInt h, Reg1, Reg2, Reg3;
2531 
2532   if (ChkArgCnt(1, 1))
2533   {
2534     SplitArg(&ArgStr[1], &LeftComp, &MidComp);
2535     SplitArg(&MidComp, &MidComp, &RightComp);
2536     if ((*LeftComp.Str == '\0') || (*MidComp.Str == '\0') || (*RightComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
2537     else if (*LeftComp.Str != '#') WrError(ErrNum_OnlyImmAddr);
2538     else
2539     {
2540       DAsmCode[1] = EvalStrIntExpression(&RightComp, AdrInt, &OK);
2541       if (OK)
2542       {
2543         h = EvalStrIntExpressionOffsWithFlags(&LeftComp, 1, Int8, &OK, &Flags);
2544         if (mFirstPassUnknown(Flags))
2545           h &= 15;
2546         if (OK)
2547         {
2548           if ((h < 0) || (h > 23)) WrError(ErrNum_OverRange);
2549           else
2550           {
2551             Reg2 = ((Code & 1) << 5) + (((LongInt)(Code >> 1)) << 16);
2552             if (DecodeGeneralReg(MidComp.Str, &Reg1))
2553             {
2554               CodeLen = 2;
2555               DAsmCode[0] = 0x0ac000 + h + Reg2 + (Reg1 << 8);
2556             }
2557             else
2558             {
2559               tAdrResult AdrResult;
2560 
2561               DecodeAdr(&MidComp, MModNoImm, MSegXData + MSegYData, &AdrResult);
2562               Reg3 = Ord(AdrResult.Seg == SegYData) << 6;
2563               if (AdrResult.Type == ModAbs)
2564               {
2565                 if ((AdrResult.Val >= 0) && (AdrResult.Val <= 63))
2566                 {
2567                   CodeLen = 2;
2568                   DAsmCode[0] = 0x0a0080 + h + Reg2 + Reg3 + (AdrResult.Val << 8);
2569                 }
2570                 else if ((AdrResult.Val >= MemLimit - 0x3f) && (AdrResult.Val <= MemLimit))
2571                 {
2572                   CodeLen = 2;
2573                   DAsmCode[0] = 0x0a8080 + h + Reg2 + Reg3 + ((AdrResult.Val & 0x3f) << 8);
2574                 }
2575                 else if ((MomCPU >= CPU56300) && (AdrResult.Val >= MemLimit - 0x7f) && (AdrResult.Val <= MemLimit - 0x40))
2576                 {
2577                   CodeLen = 2;
2578                   Reg2 = ((Code & 1) << 5) + (((LongInt)(Code >> 1)) << 14);
2579                   DAsmCode[0] = 0x018080 + h + Reg2 + Reg3 + ((AdrResult.Val & 0x3f) << 8);
2580                 }
2581                 else WrError(ErrNum_OverRange);
2582               }
2583               else if (AdrResult.Type != ModNone)
2584               {
2585                 CodeLen = 2;
2586                 DAsmCode[0] = 0x0a4080 + h + Reg2 + Reg3 + (AdrResult.Mode << 8);
2587               }
2588             }
2589           }
2590         }
2591       }
2592     }
2593   }
2594 }
2595 
DecodeDO_DOR(Word Code)2596 static void DecodeDO_DOR(Word Code)
2597 {
2598   if (ChkArgCnt(1, 1))
2599   {
2600     SplitArg(&ArgStr[1], &LeftComp, &RightComp);
2601     if ((*LeftComp.Str == '\0') || (*RightComp.Str == '\0')) WrError(ErrNum_CannotSplitArg);
2602     else
2603     {
2604       LongInt Reg1;
2605       tEvalResult EvalResult;
2606 
2607       DAsmCode[1] = EvalStrIntExpressionWithResult(&RightComp, AdrInt, &EvalResult) - 1;
2608       if (EvalResult.OK)
2609       {
2610         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
2611         if (!as_strcasecmp(LeftComp.Str, "FOREVER"))
2612         {
2613           if (ChkMinCPU(CPU56300))
2614           {
2615             DAsmCode[0] = 0x000203 - Code;
2616             CodeLen = 2;
2617           }
2618         }
2619         else if (DecodeGeneralReg(LeftComp.Str, &Reg1))
2620         {
2621           if (Reg1 == 0x3c) WrXError(ErrNum_InvReg, LeftComp.Str); /* kein SSH!! */
2622           else
2623           {
2624             CodeLen = 2;
2625             DAsmCode[0] = 0x06c000 + (Reg1 << 8) + (Code << 4);
2626           }
2627         }
2628         else if (*LeftComp.Str == '#')
2629         {
2630           Reg1 = EvalStrIntExpressionOffsWithResult(&LeftComp, 1, UInt12, &EvalResult);
2631           if (EvalResult.OK)
2632           {
2633             CodeLen = 2;
2634             DAsmCode[0] = 0x060080 + (Reg1 >> 8) + ((Reg1 & 0xff) << 8) + (Code << 4);
2635           }
2636         }
2637         else
2638         {
2639           tAdrResult AdrResult;
2640 
2641           DecodeAdr(&LeftComp, MModNoImm, MSegXData + MSegYData, &AdrResult);
2642           if (AdrResult.Type == ModAbs)
2643            if ((AdrResult.Val < 0) || (AdrResult.Val > 63)) WrError(ErrNum_OverRange);
2644            else
2645            {
2646              CodeLen = 2;
2647              DAsmCode[0] = 0x060000 + (AdrResult.Val << 8) + (Ord(AdrResult.Seg == SegYData) << 6) + (Code << 4);
2648            }
2649           else
2650           {
2651             CodeLen = 2;
2652             DAsmCode[0] = 0x064000 + (AdrResult.Mode << 8) + (Ord(AdrResult.Seg == SegYData) << 6) + (Code << 4);
2653           }
2654         }
2655       }
2656     }
2657   }
2658 }
2659 
DecodeBRKcc(Word Condition)2660 static void DecodeBRKcc(Word Condition)
2661 {
2662   if (ChkArgCnt(0, 0)
2663    && ChkMinCPU(CPU56300))
2664   {
2665     DAsmCode[0] = 0x00000210 + Condition;
2666     CodeLen = 1;
2667   }
2668 }
2669 
DecodeTRAPcc(Word Condition)2670 static void DecodeTRAPcc(Word Condition)
2671 {
2672   if (ChkArgCnt(0, 0)
2673    && ChkMinCPU(CPU56300))
2674   {
2675     DAsmCode[0] = 0x000010 + Condition;
2676     CodeLen = 1;
2677   }
2678 }
2679 
DecodeDEBUGcc(Word Condition)2680 static void DecodeDEBUGcc(Word Condition)
2681 {
2682   if (ChkArgCnt(0, 0)
2683    && ChkMinCPU(CPU56300))
2684   {
2685     DAsmCode[0] = 0x00000300 + Condition;
2686     CodeLen = 1;
2687   }
2688 }
2689 
DecodeREP(Word Code)2690 static void DecodeREP(Word Code)
2691 {
2692   LongInt Reg1;
2693 
2694   UNUSED(Code);
2695 
2696   if (!ChkArgCnt(1, 1));
2697   else if (DecodeGeneralReg(ArgStr[1].Str, &Reg1))
2698   {
2699     CodeLen = 1;
2700     DAsmCode[0] = 0x06c020 + (Reg1 << 8);
2701   }
2702   else
2703   {
2704     tAdrResult AdrResult;
2705 
2706     DecodeAdr(&ArgStr[1], MModAll, MSegXData + MSegYData, &AdrResult);
2707     if (AdrResult.Type == ModImm)
2708     {
2709       if ((AdrResult.Val < 0) || (AdrResult.Val > 0xfff)) WrError(ErrNum_OverRange);
2710       else
2711       {
2712         CodeLen = 1;
2713         DAsmCode[0] = 0x0600a0 + (AdrResult.Val >> 8) + ((AdrResult.Val & 0xff) << 8);
2714       }
2715     }
2716     else if (AdrResult.Type == ModAbs)
2717     {
2718       if ((AdrResult.Val < 0) || (AdrResult.Val > 63)) WrError(ErrNum_OverRange);
2719       else
2720       {
2721         CodeLen = 1;
2722         DAsmCode[0] = 0x060020 + (AdrResult.Val << 8) + (Ord(AdrResult.Seg == SegYData) << 6);
2723       }
2724     }
2725     else
2726     {
2727       CodeLen = 1 + AdrResult.Cnt;
2728       DAsmCode[1] = AdrResult.Val;
2729       DAsmCode[0] = 0x064020 + (AdrResult.Mode << 8) + (Ord(AdrResult.Seg == SegYData) << 6);
2730     }
2731   }
2732 }
2733 
2734 /*----------------------------------------------------------------------------------------------*/
2735 
AddFixed(const char * Name,LongWord Code,CPUVar NMin)2736 static void AddFixed(const char *Name, LongWord Code, CPUVar NMin)
2737 {
2738   if (InstrZ >= FixedOrderCnt) exit(255);
2739 
2740   FixedOrders[InstrZ].Code = Code;
2741   FixedOrders[InstrZ].MinCPU = NMin;
2742   AddInstTable(InstTable, Name, InstrZ++, DecodeFixed);
2743 }
2744 
AddPar(const char * Name,ParTyp Typ,LongWord Code)2745 static void AddPar(const char *Name, ParTyp Typ, LongWord Code)
2746 {
2747   if (InstrZ >= ParOrderCnt) exit(255);
2748 
2749   ParOrders[InstrZ].Typ = Typ;
2750   ParOrders[InstrZ].Code = Code;
2751   AddInstTable(InstTable, Name, InstrZ++, DecodePar);
2752 }
2753 
AddMix(const char * pName,Word Code,InstProc Proc,unsigned Mask)2754 static void AddMix(const char *pName, Word Code, InstProc Proc, unsigned Mask)
2755 {
2756   char TmpName[30];
2757 
2758   if (Mask & 1)
2759   {
2760     as_snprintf(TmpName, sizeof(TmpName), "%sSS", pName);
2761     AddInstTable(InstTable, TmpName, Code + 0x0000, Proc);
2762   }
2763   if (Mask & 2)
2764   {
2765     as_snprintf(TmpName, sizeof(TmpName), "%sSU", pName);
2766     AddInstTable(InstTable, TmpName, Code + 0x0100, Proc);
2767   }
2768   if (Mask & 4)
2769   {
2770     as_snprintf(TmpName, sizeof(TmpName), "%sUU", pName);
2771     AddInstTable(InstTable, TmpName, Code + 0x0140, Proc);
2772   }
2773 }
2774 
AddCondition(const char * pName,InstProc Proc)2775 static void AddCondition(const char *pName, InstProc Proc)
2776 {
2777   unsigned z;
2778   char TmpName[30];
2779   Word Code;
2780 
2781   for (z = 0; z < CondCount; z++)
2782   {
2783     as_snprintf(TmpName, sizeof(TmpName), "%s%s", pName, CondNames[z]);
2784     Code = (z == CondCount - 1) ? 8 : z & 15;
2785     AddInstTable(InstTable, TmpName, Code, Proc);
2786   }
2787 }
2788 
InitFields(void)2789 static void InitFields(void)
2790 {
2791   InstTable = CreateInstTable(307);
2792   SetDynamicInstTable(InstTable);
2793   AddInstTable(InstTable, "DIV", 0, DecodeDIV);
2794   AddInstTable(InstTable, "INC", 0x0008, DecodeINC_DEC);
2795   AddInstTable(InstTable, "DEC", 0x000a, DecodeINC_DEC);
2796   AddInstTable(InstTable, "ANDI", 0x00b8, DecodeANDI_ORI);
2797   AddInstTable(InstTable, "ORI", 0x00f8, DecodeANDI_ORI);
2798   AddInstTable(InstTable, "NORM", 0, DecodeNORM);
2799   AddInstTable(InstTable, "NORMF", 0, DecodeNORMF);
2800   AddInstTable(InstTable, "EXTRACT", 0, DecodeEXTRACT_EXTRACTU);
2801   AddInstTable(InstTable, "EXTRACTU", 128, DecodeEXTRACT_EXTRACTU);
2802   AddInstTable(InstTable, "INSERT", 0, DecodeINSERT);
2803   AddInstTable(InstTable, "MERGE", 0, DecodeMERGE);
2804   AddInstTable(InstTable, "CLB", 0, DecodeCLB);
2805   AddInstTable(InstTable, "CMPU", 0, DecodeCMPU);
2806   AddInstTable(InstTable, "MOVE", 0, DecodePlainMOVE);
2807   AddInstTable(InstTable, "MOVEC", 0, DecodeMOVEC);
2808   AddInstTable(InstTable, "MOVEM", 0, DecodeMOVEM);
2809   AddInstTable(InstTable, "MOVEP", 0, DecodeMOVEP);
2810   AddInstTable(InstTable, "TFR", 0, DecodePlainTFR);
2811   AddInstTable(InstTable, "BRA", 0x40, DecodeBRA_BSR);
2812   AddInstTable(InstTable, "BSR", 0x00, DecodeBRA_BSR);
2813   AddInstTable(InstTable, "LUA", 0, DecodeLUA_LEA);
2814   AddInstTable(InstTable, "LEA", 0, DecodeLUA_LEA);
2815   AddInstTable(InstTable, "LRA", 0, DecodeLRA);
2816   AddInstTable(InstTable, "PLOCK", 0, DecodePLOCK);
2817   AddInstTable(InstTable, "PLOCKR", 0x00000e, DecodePLOCKR_PUNLOCKR);
2818   AddInstTable(InstTable, "PUNLOCKR", 0x00000f, DecodePLOCKR_PUNLOCKR);
2819   AddInstTable(InstTable, "JMP", 0, DecodeJMP_JSR);
2820   AddInstTable(InstTable, "JSR", 1, DecodeJMP_JSR);
2821   AddInstTable(InstTable, "DO", 0, DecodeDO_DOR);
2822   AddInstTable(InstTable, "DOR", 1, DecodeDO_DOR);
2823   AddInstTable(InstTable, "REP", 0, DecodeREP);
2824 
2825   FixedOrders = (FixedOrder *) malloc(sizeof(FixedOrder)*FixedOrderCnt); InstrZ = 0;
2826   AddFixed("NOP"    , 0x000000, CPU56000);
2827   AddFixed("ENDDO"  , 0x00008c, CPU56000);
2828   AddFixed("ILLEGAL", 0x000005, CPU56000);
2829   AddFixed("RESET"  , 0x000084, CPU56000);
2830   AddFixed("RTI"    , 0x000004, CPU56000);
2831   AddFixed("RTS"    , 0x00000c, CPU56000);
2832   AddFixed("STOP"   , 0x000087, CPU56000);
2833   AddFixed("SWI"    , 0x000006, CPU56000);
2834   AddFixed("WAIT"   , 0x000086, CPU56000);
2835   AddFixed("DEBUG"  , 0x000200, CPU56300);
2836   AddFixed("PFLUSH" , 0x000003, CPU56300);
2837   AddFixed("PFLUSHUN",0x000001, CPU56300);
2838   AddFixed("PFREE"  , 0x000002, CPU56300);
2839   AddFixed("TRAP"   , 0x000006, CPU56300);
2840 
2841   ParOrders = (ParOrder *) malloc(sizeof(ParOrder)*ParOrderCnt); InstrZ = 0;
2842   AddPar("ABS" , ParAB,     0x26);
2843   AddPar("ASL" , ParABShl1, 0x32);
2844   AddPar("ASR" , ParABShl1, 0x22);
2845   AddPar("CLR" , ParAB,     0x13);
2846   AddPar("LSL" , ParABShl2, 0x33);
2847   AddPar("LSR" , ParABShl2, 0x23);
2848   AddPar("NEG" , ParAB,     0x36);
2849   AddPar("NOT" , ParAB,     0x17);
2850   AddPar("RND" , ParAB,     0x11);
2851   AddPar("ROL" , ParAB,     0x37);
2852   AddPar("ROR" , ParAB,     0x27);
2853   AddPar("TST" , ParAB,     0x03);
2854   AddPar("ADC" , ParXYAB,   0x21);
2855   AddPar("SBC" , ParXYAB,   0x25);
2856   AddPar("ADD" , ParABXYnAB,0x00);
2857   AddPar("CMP" , ParABXYnAB,0x05);
2858   AddPar("CMPM", ParABXYnAB,0x07);
2859   AddPar("SUB" , ParABXYnAB,0x04);
2860   AddPar("ADDL", ParABBA,   0x12);
2861   AddPar("ADDR", ParABBA,   0x02);
2862   AddPar("SUBL", ParABBA,   0x16);
2863   AddPar("SUBR", ParABBA,   0x06);
2864   AddPar("AND" , ParXYnAB,  0x46);
2865   AddPar("EOR" , ParXYnAB,  0x43);
2866   AddPar("OR"  , ParXYnAB,  0x42);
2867   AddPar("MAC" , ParMul,    0x82);
2868   AddPar("MACR", ParMul,    0x83);
2869   AddPar("MPY" , ParMul,    0x80);
2870   AddPar("MPYR", ParMul,    0x81);
2871   AddPar("MAX" , ParFixAB,  0x1d);
2872   AddPar("MAXM", ParFixAB,  0x15);
2873 
2874   InstrZ = 0;
2875   AddInstTable(InstTable, "MPYI", InstrZ++, DecodeImmMac);
2876   AddInstTable(InstTable, "MPYRI", InstrZ++, DecodeImmMac);
2877   AddInstTable(InstTable, "MACI", InstrZ++, DecodeImmMac);
2878   AddInstTable(InstTable, "MACRI", InstrZ++, DecodeImmMac);
2879 
2880   InstrZ = 0;
2881   AddInstTable(InstTable, "BCLR", InstrZ++, DecodeBit);
2882   AddInstTable(InstTable, "BSET", InstrZ++, DecodeBit);
2883   AddInstTable(InstTable, "BCHG", InstrZ++, DecodeBit);
2884   AddInstTable(InstTable, "BTST", InstrZ++, DecodeBit);
2885 
2886   InstrZ = 0;
2887   AddInstTable(InstTable, "BRCLR", InstrZ++, DecodeBitBr);
2888   AddInstTable(InstTable, "BRSET", InstrZ++, DecodeBitBr);
2889   AddInstTable(InstTable, "BSCLR", InstrZ++, DecodeBitBr);
2890   AddInstTable(InstTable, "BSSET", InstrZ++, DecodeBitBr);
2891 
2892   InstrZ = 0;
2893   AddInstTable(InstTable, "JCLR", InstrZ++, DecodeBitJmp);
2894   AddInstTable(InstTable, "JSET", InstrZ++, DecodeBitJmp);
2895   AddInstTable(InstTable, "JSCLR", InstrZ++, DecodeBitJmp);
2896   AddInstTable(InstTable, "JSSET", InstrZ++, DecodeBitJmp);
2897 
2898   AddMix("DMAC", 0, DecodeDMAC, 7);
2899   AddMix("MAC", 0xff00, DecodeMAC_MPY, 6);
2900   AddMix("MPY", 0, DecodeMAC_MPY, 6);
2901 
2902   AddCondition("T", DecodeTcc);
2903   AddCondition("B", DecodeBcc);
2904   AddCondition("BS", DecodeBScc);
2905   AddCondition("J", DecodeJcc);
2906   AddCondition("JS", DecodeJScc);
2907   AddCondition("BRK", DecodeBRKcc);
2908   AddCondition("TRAP", DecodeTRAPcc);
2909   AddCondition("DEBUG", DecodeDEBUGcc);
2910 
2911   StrCompAlloc(&LeftComp);
2912   StrCompAlloc(&MidComp);
2913   StrCompAlloc(&RightComp);
2914   StrCompAlloc(&Left1Comp);
2915   StrCompAlloc(&Left2Comp);
2916   StrCompAlloc(&Right1Comp);
2917   StrCompAlloc(&Right2Comp);
2918 }
2919 
DeinitFields(void)2920 static void DeinitFields(void)
2921 {
2922   DestroyInstTable(InstTable);
2923   free(FixedOrders);
2924   free(ParOrders);
2925 
2926   StrCompFree(&LeftComp);
2927   StrCompFree(&MidComp);
2928   StrCompFree(&RightComp);
2929   StrCompFree(&Left1Comp);
2930   StrCompFree(&Left2Comp);
2931   StrCompFree(&Right1Comp);
2932   StrCompFree(&Right2Comp);
2933 }
2934 
MakeCode_56K(void)2935 static void MakeCode_56K(void)
2936 {
2937   CodeLen = 0;
2938   DontPrint = False;
2939 
2940   /* zu ignorierendes */
2941 
2942   if (Memo(""))
2943     return;
2944 
2945   /* Pseudoanweisungen */
2946 
2947   if (DecodePseudo())
2948     return;
2949 
2950   if (!LookupInstTable(InstTable, OpPart.Str))
2951     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2952 }
2953 
IsDef_56K(void)2954 static Boolean IsDef_56K(void)
2955 {
2956   return ((Memo("XSFR")) || (Memo("YSFR")));
2957 }
2958 
SwitchFrom_56K(void)2959 static void SwitchFrom_56K(void)
2960 {
2961   DeinitFields();
2962 }
2963 
SwitchTo_56K(void)2964 static void SwitchTo_56K(void)
2965 {
2966   TurnWords = True;
2967   ConstMode = ConstModeMoto;
2968 
2969   PCSymbol = "*";
2970   HeaderID = 0x09;
2971   NOPCode = 0x000000;
2972   DivideChars = " \009";
2973   HasAttrs = False;
2974 
2975   if (MomCPU == CPU56300)
2976   {
2977     AdrInt = UInt24;
2978     MemLimit = 0xffffffl;
2979   }
2980   else
2981   {
2982     AdrInt = UInt16;
2983     MemLimit = 0xffff;
2984   }
2985 
2986   ValidSegs = (1 << SegCode) | (1 << SegXData) | (1 << SegYData);
2987   Grans[SegCode ] = 4; ListGrans[SegCode ] = 4; SegInits[SegCode ] = 0;
2988   SegLimits[SegCode ]  =  MemLimit;
2989   Grans[SegXData] = 4; ListGrans[SegXData] = 4; SegInits[SegXData] = 0;
2990   SegLimits[SegXData]  =  MemLimit;
2991   Grans[SegYData] = 4; ListGrans[SegYData] = 4; SegInits[SegYData] = 0;
2992   SegLimits[SegYData] = MemLimit;
2993 
2994   MakeCode = MakeCode_56K;
2995   IsDef = IsDef_56K;
2996   SwitchFrom = SwitchFrom_56K;
2997   InitFields();
2998 }
2999 
code56k_init(void)3000 void code56k_init(void)
3001 {
3002   CPU56000 = AddCPU("56000", SwitchTo_56K);
3003   CPU56002 = AddCPU("56002", SwitchTo_56K);
3004   CPU56300 = AddCPU("56300", SwitchTo_56K);
3005 }
3006