1 /* code97c241.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS-Portierung                                                             */
6 /*                                                                           */
7 /* Codegenerator TLCS-9000                                                   */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 #include "stdinc.h"
12 
13 #include <string.h>
14 #include <ctype.h>
15 #include <assert.h>
16 
17 #include "nls.h"
18 #include "strutil.h"
19 #include "bpemu.h"
20 #include "asmdef.h"
21 #include "asmsub.h"
22 #include "asmpars.h"
23 #include "asmallg.h"
24 #include "asmitree.h"
25 #include "codepseudo.h"
26 #include "intpseudo.h"
27 #include "codevars.h"
28 #include "errmsg.h"
29 
30 #include "code97c241.h"
31 
32 typedef struct
33 {
34   Byte Code;
35   Byte Mask;     /* B0..2=OpSizes, B4=-MayImm, B5=-MayReg */
36 } RMWOrder;
37 
38 typedef struct
39 {
40   const char *Name;
41   Byte Code;
42   Byte Mask;     /* B7: DD in A-Format gedreht */
43   enum { Equal, FirstCounts, SecondCounts, Op2Half } SizeType;
44   Boolean ImmKorr, ImmErl, RegErl;
45 } GAOrder;
46 
47 
48 #define ConditionCount 20
49 #define RMWOrderCount 14
50 
51 
52 static CPUVar CPU97C241;
53 
54 static int OpSize, OpSize2;
55 static Integer LowLim4, LowLim8;
56 
57 static Boolean AdrOK;
58 static Word AdrMode, AdrMode2;
59 static Byte AdrCnt2;
60 static Word AdrVals[2], AdrVals2[2];
61 static int AdrInc;
62 static Word Prefs[2];
63 static Boolean PrefUsed[2];
64 static char Format;
65 static Boolean MinOneIs0;
66 
67 static RMWOrder *RMWOrders;
68 static const char **Conditions;
69 
70 /*--------------------------------------------------------------------------*/
71 
CheckForcePrefix(const char * pArg,Boolean * pForce)72 static int CheckForcePrefix(const char *pArg, Boolean *pForce)
73 {
74   if (*pArg == '>')
75   {
76     *pForce = True;
77     return 1;
78   }
79   return 0;
80 }
81 
AddSignedPrefix(Byte Index,Byte MaxBits,LongInt Value,Boolean Force)82 static void AddSignedPrefix(Byte Index, Byte MaxBits, LongInt Value, Boolean Force)
83 {
84   LongInt Max;
85 
86   Max = 1l << (MaxBits -1);
87   if (Force || ((Value < -Max) || (Value >= Max)))
88   {
89     PrefUsed[Index] = True;
90     Prefs[Index] = (Value >> MaxBits) & 0x7ff;
91   }
92 }
93 
AddRelPrefix(Byte Index,Byte MaxBits,LongInt * Value,Boolean Force)94 static Boolean AddRelPrefix(Byte Index, Byte MaxBits, LongInt *Value, Boolean Force)
95 {
96   LongInt Max1,Max2;
97 
98   Max1 = 1l << (MaxBits - 1);
99   Max2 = 1l << (MaxBits + 10);
100   if ((*Value < -Max2) || (*Value >= Max2)) WrError(ErrNum_JmpDistTooBig);
101   else
102   {
103     if (Force || ((*Value < -Max1) || (*Value >= Max1)))
104     {
105       PrefUsed[Index] = True;
106       Prefs[Index] = ((*Value) >> MaxBits) & 0x7ff;
107     }
108     return True;
109   }
110   return False;
111 }
112 
AddAbsPrefix(Byte Index,Byte MaxBits,LongInt Value,Boolean Force)113 static void AddAbsPrefix(Byte Index, Byte MaxBits, LongInt Value, Boolean Force)
114 {
115   LongInt Dist;
116 
117   Dist = 1l << (MaxBits - 1);
118   if (Force || ((Value >= Dist) && (Value < 0x1000000 - Dist)))
119   {
120     PrefUsed[Index] = True;
121     Prefs[Index] = (Value >> MaxBits) & 0x7ff;
122   }
123 }
124 
InsertSinglePrefix(Byte Index)125 static void InsertSinglePrefix(Byte Index)
126 {
127   if (PrefUsed[Index])
128   {
129     memmove(WAsmCode + 1, WAsmCode + 0, CodeLen);
130     WAsmCode[0] = Prefs[Index] + 0xd000 + (((Word)Index) << 11);
131     CodeLen += 2;
132   }
133 }
134 
135 /*!------------------------------------------------------------------------
136  * \fn     DecodeRegCore(const char *pArg, Byte *pResult, tSymbolSize *pSize)
137  * \brief  check whether argument is a CPU register
138  * \param  pArg source argument
139  * \param  pResult register number if yes
140  * \param  pSize register size if yes
141  * \return True if yes
142  * ------------------------------------------------------------------------ */
143 
DecodeRegCore(const char * pArg,Byte * pResult,tSymbolSize * pSize)144 static Boolean DecodeRegCore(const char *pArg, Byte *pResult, tSymbolSize *pSize)
145 {
146   Boolean OK;
147   int l = strlen(pArg);
148 
149   if (as_toupper(*pArg) != 'R')
150     return False;
151   l = strlen(pArg);
152   if ((l > 4) || (l < 3))
153     return False;
154 
155   switch (as_toupper(pArg[1]))
156   {
157     case 'B':
158       *pSize = eSymbolSize8Bit;
159       break;
160     case 'W':
161       *pSize = eSymbolSize16Bit;
162       break;
163     case 'D':
164       *pSize = eSymbolSize32Bit;
165       break;
166     default:
167       return False;
168   }
169   *pResult = ConstLongInt(pArg + 2, &OK, 10);
170   if (!OK || (*pResult > 15))
171     return False;
172   if ((*pSize == eSymbolSize32Bit) && Odd(*pResult))
173     return False;
174   return True;
175 }
176 
177 /*!------------------------------------------------------------------------
178  * \fn     DissectReg_97C241(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
179  * \brief  dissect register symbols - TLCS-9000 variant
180  * \param  pDest destination buffer
181  * \param  DestSize destination buffer size
182  * \param  Value numeric register value
183  * \param  InpSize register size
184  * ------------------------------------------------------------------------ */
185 
DissectReg_97C241(char * pDest,size_t DestSize,tRegInt Value,tSymbolSize InpSize)186 static void DissectReg_97C241(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
187 {
188   switch (InpSize)
189   {
190     case eSymbolSize8Bit:
191       as_snprintf(pDest, DestSize, "RB%u", (unsigned)Value);
192       break;
193     case eSymbolSize16Bit:
194       as_snprintf(pDest, DestSize, "RW%u", (unsigned)Value);
195       break;
196     case eSymbolSize32Bit:
197       as_snprintf(pDest, DestSize, "RD%u", (unsigned)Value);
198       break;
199     default:
200       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
201   }
202 }
203 
204 /*!------------------------------------------------------------------------
205  * \fn     tRegEvalResult DecodeReg(const tStrComp *pArg, Byte *pResult, tSymbolSize *pSize, Boolean MustBeReg)
206  * \brief  check whether argument is a CPU register or register alias
207  * \param  pArg source argument
208  * \param  pResult register number if yes
209  * \param  pSize register size if yes
210  * \param  MustBeReg True if register is expected
211  * \return True if yes
212  * ------------------------------------------------------------------------ */
213 
DecodeReg(const tStrComp * pArg,Byte * pResult,tSymbolSize * pSize,Boolean MustBeReg)214 static tRegEvalResult DecodeReg(const tStrComp *pArg, Byte *pResult, tSymbolSize *pSize, Boolean MustBeReg)
215 {
216   tRegEvalResult RegEvalResult;
217   tEvalResult EvalResult;
218   tRegDescr RegDescr;
219 
220   if (DecodeRegCore(pArg->Str, pResult, pSize))
221     return eIsReg;
222 
223   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
224   if (eIsReg == RegEvalResult)
225   {
226     *pResult = RegDescr.Reg;
227     *pSize = EvalResult.DataSize;
228   }
229   return RegEvalResult;
230 }
231 
DecodeSpecReg(char * Asc,Byte * Result)232 static Boolean DecodeSpecReg(char *Asc, Byte *Result)
233 {
234   if (!as_strcasecmp(Asc, "SP")) *Result = 0x8c;
235   else if (!as_strcasecmp(Asc, "ISP")) *Result = 0x81;
236   else if (!as_strcasecmp(Asc, "ESP")) *Result = 0x83;
237   else if (!as_strcasecmp(Asc, "PBP")) *Result = 0x05;
238   else if (!as_strcasecmp(Asc, "CBP")) *Result = 0x07;
239   else if (!as_strcasecmp(Asc, "PSW")) *Result = 0x89;
240   else if (!as_strcasecmp(Asc, "IMC")) *Result = 0x0b;
241   else if (!as_strcasecmp(Asc, "CC"))  *Result = 0x0e;
242   else return False;
243   return True;
244 }
245 
DecodeRegAdr(const tStrComp * pArg,Byte * pResult)246 static Boolean DecodeRegAdr(const tStrComp *pArg, Byte *pResult)
247 {
248   tSymbolSize Size;
249 
250   if (DecodeReg(pArg, pResult, &Size, True) != eIsReg)
251     return False;
252   if (OpSize == eSymbolSizeUnknown)
253     OpSize = Size;
254   if (Size != OpSize)
255   {
256     WrError(ErrNum_ConfOpSizes);
257     return False;
258   }
259   *pResult &= 0x3f;
260   return True;
261 }
262 
DecodeAdr(const tStrComp * pArg,Byte PrefInd,Boolean MayImm,Boolean MayReg)263 static void DecodeAdr(const tStrComp *pArg, Byte PrefInd, Boolean MayImm, Boolean MayReg)
264 {
265 #define FreeReg 0xff
266 #define SPReg 0xfe
267 #define PCReg 0xfd
268 
269   Byte Reg;
270   String AdrPartStr;
271   tStrComp AdrPart, Remainder;
272   Boolean OK;
273   int ArgLen;
274   tSymbolSize Size;
275   tRegEvalResult RegEvalResult;
276 
277   AdrCnt = 0; AdrOK = False;
278   StrCompMkTemp(&AdrPart, AdrPartStr);
279 
280    /* I. Speicheradresse */
281 
282   if (IsIndirect(pArg->Str))
283   {
284     Boolean ForcePrefix = False, MinFlag, NMinFlag;
285     tStrComp Arg, TmpComp;
286     String Tmp;
287     char *PMPos, *EPos;
288     Byte BaseReg, IndReg, ScaleFact;
289     tSymbolSize BaseRegSize, IndRegSize;
290     LongInt DispAcc;
291 
292     StrCompMkTemp(&TmpComp, Tmp);
293 
294     /* I.1. vorkonditionieren */
295 
296     StrCompRefRight(&Arg, pArg, 1);
297     StrCompShorten(&Arg, 1);
298     KillPrefBlanksStrCompRef(&Arg);
299     KillPostBlanksStrComp(&Arg);
300 
301     /* I.2. Predekrement */
302 
303     if ((*Arg.Str == '-') && (Arg.Str[1] == '-'))
304     {
305       tStrComp RegComp;
306 
307       StrCompRefRight(&RegComp, &Arg, 2);
308       if (DecodeReg(&RegComp, &Reg, &Size, True) == eIsReg)
309       {
310         switch (Size)
311         {
312           case eSymbolSize16Bit:
313             AdrMode = 0x50 + (Reg & 15);
314             AdrOK = True;
315             break;
316           case eSymbolSize32Bit:
317             AdrMode = 0x71 + (Reg & 14);
318             AdrOK = True;
319             break;
320           default:
321             WrStrErrorPos(ErrNum_InvAddrMode, &Arg);
322             break;
323         }
324       }
325       return;
326     }
327 
328     /* I.3. Postinkrement */
329 
330     ArgLen = strlen(Arg.Str);
331     if ((Arg.Str[ArgLen - 1] == '+') && (Arg.Str[ArgLen - 2] == '+'))
332     {
333       StrCompCopy(&AdrPart, &Arg);
334       StrCompShorten(&AdrPart, 2);
335       if (DecodeReg(&AdrPart, &Reg, &Size, True) == eIsReg)
336       {
337         switch (Size)
338         {
339           case eSymbolSize16Bit:
340             AdrMode = 0x40 + (Reg & 15);
341             AdrOK = True;
342             break;
343           case eSymbolSize32Bit:
344             AdrMode = 0x70 + (Reg & 14);
345             AdrOK = True;
346             break;
347           default:
348             WrError(ErrNum_InvAddrMode);
349             break;
350         }
351         return;
352       }
353     }
354 
355     /* I.4. Adresskomponenten zerlegen */
356 
357     BaseReg = IndReg = FreeReg;
358     BaseRegSize = IndRegSize = eSymbolSizeUnknown;
359     ScaleFact = 0;
360     DispAcc = AdrInc;
361     MinFlag = False;
362     do
363     {
364       /* I.4.a. Trennzeichen suchen */
365 
366       PMPos = QuotMultPos(Arg.Str, "-+");
367       NMinFlag = (PMPos && (*PMPos == '-'));
368       if (PMPos)
369       {
370         StrCompSplitRef(&Arg, &Remainder, &Arg, PMPos);
371         KillPostBlanksStrComp(&Arg);
372         KillPrefBlanksStrCompRef(&Remainder);
373       }
374 
375       /* I.4.b. Indexregister mit Skalierung */
376 
377       EPos = QuotPos(Arg.Str, '*');
378       if (EPos)
379       {
380         StrCompCopy(&TmpComp, &Arg);
381         TmpComp.Str[EPos - Arg.Str] = '\0';
382         KillPostBlanksStrComp(&TmpComp);
383       }
384       ArgLen = strlen(Arg.Str);
385       if ((EPos == Arg.Str + ArgLen - 2)
386        && ((Arg.Str[ArgLen - 1] == '1') || (Arg.Str[ArgLen - 1] == '2') || (Arg.Str[ArgLen - 1] == '4') || (Arg.Str[ArgLen - 1] == '8'))
387        && ((RegEvalResult = DecodeReg(&TmpComp, &Reg, &Size, False)) != eIsNoReg))
388       {
389         if (RegEvalResult == eRegAbort)
390           return;
391         if ((Size == eSymbolSize8Bit) || MinFlag || (IndReg != FreeReg))
392         {
393           WrError(ErrNum_InvAddrMode);
394           return;
395         }
396         IndReg = Reg;
397         IndRegSize = Size;
398         switch (Arg.Str[ArgLen - 1])
399         {
400           case '1':
401             ScaleFact = 0;
402             break;
403           case '2':
404             ScaleFact = 1;
405             break;
406           case '4':
407             ScaleFact = 2;
408             break;
409           case '8':
410             ScaleFact = 3;
411             break;
412         }
413       }
414 
415       /* I.4.c. Basisregister */
416 
417       else if ((RegEvalResult = DecodeReg(&Arg, &Reg, &Size, False)) != eIsNoReg)
418       {
419         if (RegEvalResult == eRegAbort)
420           return;
421         if ((Size == eSymbolSize8Bit) || (MinFlag))
422         {
423           WrError(ErrNum_InvAddrMode);
424           return;
425         }
426         if (BaseReg == FreeReg)
427         {
428           BaseReg = Reg;
429           BaseRegSize = Size;
430         }
431         else if (IndReg == FreeReg)
432         {
433           IndReg = Reg;
434           IndRegSize = Size;
435           ScaleFact = 0;
436         }
437         else
438         {
439           WrStrErrorPos(ErrNum_InvAddrMode, &Arg);
440           return;
441         }
442       }
443 
444       /* I.4.d. Sonderregister */
445 
446       else if ((!as_strcasecmp(Arg.Str, "PC")) || (!as_strcasecmp(Arg.Str, "SP")))
447       {
448         if ((BaseReg != FreeReg) && (IndReg == FreeReg))
449         {
450           IndReg = BaseReg;
451           IndRegSize = BaseRegSize;
452           BaseReg = FreeReg;
453           ScaleFact = 0;
454         };
455         if ((BaseReg != FreeReg) || (MinFlag))
456         {
457           WrError(ErrNum_InvAddrMode);
458           return;
459         }
460 /*#warning here*/
461         BaseReg = as_strcasecmp(Arg.Str, "SP") ? PCReg : SPReg;
462       }
463 
464       /* I.4.e. Displacement */
465 
466       else
467       {
468         LongInt DispPart;
469         tSymbolFlags Flags;
470 
471         DispPart = EvalStrIntExpressionOffsWithFlags(&Arg, CheckForcePrefix(Arg.Str, &ForcePrefix), Int32, &OK, &Flags);
472         if (!OK)
473           return;
474         if (mFirstPassUnknown(Flags))
475           DispPart = 1;
476         DispAcc = MinFlag ? DispAcc - DispPart : DispAcc + DispPart;
477       }
478 
479       if (PMPos)
480         Arg = Remainder;
481       MinFlag = NMinFlag;
482     }
483     while (PMPos);
484 
485     /* I.5. Indexregister mit Skalierung 1 als Basis behandeln */
486 
487     if ((BaseReg == FreeReg) && (IndReg != FreeReg) && (ScaleFact == 0))
488     {
489       BaseReg = IndReg;
490       BaseRegSize = IndRegSize;
491       IndReg = FreeReg;
492     }
493 
494     /* I.6. absolut */
495 
496     if ((BaseReg == FreeReg) && (IndReg == FreeReg))
497     {
498       AdrMode = 0x20; /* 0x60 should be equivalent: adding 0 as RW0 or RD0 is irrelvant */
499       AdrVals[0] = 0xe000 + (DispAcc & 0x1fff); AdrCnt = 2;
500       AddAbsPrefix(PrefInd, 13, DispAcc, ForcePrefix);
501       AdrOK = True;
502       return;
503     }
504 
505     /* I.7. Basis [mit Displacement] */
506 
507     if ((BaseReg != FreeReg) && (IndReg == FreeReg))
508     {
509       /* I.7.a. Basis ohne Displacement */
510 
511       if (DispAcc == 0)
512       {
513         if (BaseRegSize == eSymbolSize16Bit)
514           AdrMode = 0x10 + (BaseReg & 15);
515         else
516           AdrMode = 0x61 + (BaseReg & 14);
517         AdrOK = True;
518         return;
519       }
520 
521       /* I.7.b. Nullregister mit Displacement muss in Erweiterungswort */
522 
523       else if (BaseReg == 0)
524       {
525         if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
526         else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
527         else
528         {
529           AdrMode = 0x20;
530           if (BaseRegSize == eSymbolSize16Bit)
531             AdrVals[0] = ((Word)BaseReg & 15) << 11;
532           else
533             AdrVals[0] = (((Word)BaseReg & 14) << 11) + 0x8000;
534           AdrVals[0] += DispAcc & 0x1ff;
535           AdrCnt = 2;
536           AddSignedPrefix(PrefInd, 9, DispAcc, ForcePrefix);
537           AdrOK = True;
538         }
539         return;
540       }
541 
542       /* I.7.c. Stack mit Displacement: Optimierung moeglich */
543 
544       else if (BaseReg == SPReg)
545       {
546         if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
547         else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
548         else if ((DispAcc >= 0) && (DispAcc <= 127))
549         {
550           AdrMode = 0x80 + (DispAcc & 0x7f);
551           AdrOK = True;
552         }
553         else
554         {
555           AdrMode = 0x20;
556           AdrVals[0] = 0xd000 + (DispAcc & 0x1ff); AdrCnt = 2;
557           AddSignedPrefix(PrefInd, 9, DispAcc, ForcePrefix);
558           AdrOK = True;
559         }
560         return;
561       }
562 
563       /* I.7.d. Programmzaehler mit Displacement: keine Optimierung */
564 
565       else if (BaseReg == PCReg)
566       {
567         if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
568         else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
569         else
570         {
571           AdrMode = 0x20;
572           AdrVals[0] = 0xd800 + (DispAcc & 0x1ff);
573           AdrCnt = 2;
574           AddSignedPrefix(PrefInd, 9, DispAcc, ForcePrefix);
575           AdrOK = True;
576         }
577         return;
578       }
579 
580       /* I.7.e. einfaches Basisregister mit Displacement */
581 
582       else
583       {
584         if (DispAcc > 0x7fffff) WrError(ErrNum_OverRange);
585         else if (DispAcc < -0x800000) WrError(ErrNum_UnderRange);
586         else
587         {
588           if (BaseRegSize == eSymbolSize16Bit)
589             AdrMode = 0x20 + (BaseReg & 15);
590           else
591             AdrMode = 0x60 + (BaseReg & 14);
592           AdrVals[0] = 0xe000 + (DispAcc & 0x1fff);
593           AdrCnt = 2;
594           AddSignedPrefix(PrefInd, 13, DispAcc, ForcePrefix);
595           AdrOK = True;
596         }
597         return;
598       }
599     }
600 
601     /* I.8. Index- [und Basisregister] */
602 
603     else
604     {
605       if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
606       else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
607       else if ((IndReg & 15) == 0) WrError(ErrNum_InvAddrMode);
608       else
609       {
610         if (IndRegSize == eSymbolSize16Bit)
611           AdrMode = 0x20 + (IndReg & 15);
612         else
613           AdrMode = 0x60 + (IndReg & 14);
614         switch (BaseReg)
615         {
616           case FreeReg:
617             AdrVals[0] = 0xc000; break;
618           case SPReg:
619             AdrVals[0] = 0xd000; break;
620           case PCReg:
621             AdrVals[0] = 0xd800; break;
622           default:
623             if (BaseRegSize == eSymbolSize16Bit)
624               AdrVals[0] = ((Word)BaseReg & 15) << 11;
625             else
626               AdrVals[0] = 0x8000 + (((Word)BaseReg & 14) << 10);
627         }
628         AdrVals[0] += (((Word)ScaleFact) << 9) + (DispAcc & 0x1ff);
629         AdrCnt = 2;
630         AddSignedPrefix(PrefInd, 9, DispAcc, ForcePrefix);
631         AdrOK = True;
632       }
633       return;
634     }
635   }
636 
637   /* II. Arbeitsregister */
638 
639   else if ((RegEvalResult = DecodeReg(pArg, &Reg, &Size, False)) != eIsNoReg)
640   {
641     if (RegEvalResult == eRegAbort)
642       return;
643     if (!MayReg) WrStrErrorPos(ErrNum_InvAddrMode, pArg);
644     else
645     {
646       if (OpSize == eSymbolSizeUnknown)
647         OpSize = Size;
648       if (Size != OpSize) WrError(ErrNum_ConfOpSizes);
649       else
650       {
651         AdrMode = Reg & 15;
652         AdrOK = True;
653       }
654     }
655     return;
656   }
657 
658   /* III. Spezialregister */
659 
660   else if (DecodeSpecReg(pArg->Str, &Reg))
661   {
662     if (!MayReg) WrError(ErrNum_InvAddrMode);
663     else
664     {
665       if (OpSize == -1)
666         OpSize=Reg >> 6;
667       if ((Reg >> 6) != OpSize) WrError(ErrNum_ConfOpSizes);
668       else
669       {
670         AdrMode = 0x30 + (Reg & 15);
671         AdrOK = True;
672       }
673     }
674     return;
675   }
676 
677   else if (!MayImm) WrError(ErrNum_InvAddrMode);
678   else
679   {
680     if ((OpSize == -1) && (MinOneIs0))
681       OpSize = 0;
682     if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
683     else
684     {
685       AdrMode = 0x30;
686       switch (OpSize)
687       {
688         case 0:
689           AdrVals[0] = EvalStrIntExpression(pArg, Int8, &OK) & 0xff;
690           if (OK)
691           {
692             AdrCnt = 2;
693             AdrOK = True;
694           }
695           break;
696         case 1:
697           AdrVals[0] = EvalStrIntExpression(pArg, Int16, &OK);
698           if (OK)
699           {
700             AdrCnt = 2;
701             AdrOK = True;
702           }
703           break;
704         case 2:
705         {
706           LongInt DispAcc = EvalStrIntExpression(pArg, Int32, &OK);
707 
708           if (OK)
709           {
710             AdrVals[0] = DispAcc & 0xffff;
711             AdrVals[1] = DispAcc >> 16;
712             AdrCnt = 4;
713             AdrOK = True;
714           }
715           break;
716         }
717       }
718     }
719   }
720 }
721 
CopyAdr(void)722 static void CopyAdr(void)
723 {
724   OpSize2 = OpSize;
725   AdrMode2 = AdrMode;
726   AdrCnt2 = AdrCnt;
727   memcpy(AdrVals2, AdrVals, AdrCnt);
728 }
729 
IsReg(void)730 static Boolean IsReg(void)
731 {
732   return (AdrMode <= 15);
733 }
734 
Is2Reg(void)735 static Boolean Is2Reg(void)
736 {
737   return (AdrMode2 <= 15);
738 }
739 
IsImmediate(void)740 static Boolean IsImmediate(void)
741 {
742   return (AdrMode == 0x30);
743 }
744 
Is2Immediate(void)745 static Boolean Is2Immediate(void)
746 {
747   return (AdrMode2 == 0x30);
748 }
749 
ImmVal(void)750 static LongInt ImmVal(void)
751 {
752   LongInt Tmp1;
753   Integer Tmp2;
754   ShortInt Tmp3;
755 
756   switch (OpSize)
757   {
758     case 0:
759       Tmp3 = AdrVals[0] & 0xff;
760       return Tmp3;
761     case 1:
762       Tmp2 = AdrVals[0];
763       return Tmp2;
764     case 2:
765       Tmp1 = (((LongInt)AdrVals[1]) << 16) + AdrVals[0];
766       return Tmp1;
767     default:
768       WrError(ErrNum_InternalError);
769       return 0;
770   }
771 }
772 
ImmVal2(void)773 static LongInt ImmVal2(void)
774 {
775   LongInt Tmp1;
776   Integer Tmp2;
777   ShortInt Tmp3;
778 
779   switch (OpSize)
780   {
781     case 0:
782       Tmp3 = AdrVals2[0] & 0xff;
783       return Tmp3;
784     case 1:
785       Tmp2 = AdrVals2[0];
786       return Tmp2;
787     case 2:
788       Tmp1 = (((LongInt)AdrVals2[1]) << 16) + AdrVals2[0];
789       return Tmp1;
790     default:
791       WrError(ErrNum_InternalError);
792       return 0;
793   }
794 }
795 
IsAbsolute(void)796 static Boolean IsAbsolute(void)
797 {
798   return (((AdrMode == 0x20) || (AdrMode == 0x60))
799        && (AdrCnt == 2)
800        && ((AdrVals[0] & 0xe000) == 0xe000));
801 }
802 
Is2Absolute(void)803 static Boolean Is2Absolute(void)
804 {
805   return (((AdrMode2 == 0x20) || (AdrMode2 == 0x60))
806        && (AdrCnt2 == 2)
807        && ((AdrVals2[0] & 0xe000) == 0xe000));
808 }
809 
IsShort(void)810 static Boolean IsShort(void)
811 {
812   if (AdrMode < 0x30)
813     return True;
814   else if (AdrMode == 0x30)
815   {
816     LongInt ImmValue = ImmVal();
817 
818     return ((ImmValue >= LowLim4) && (ImmValue <= 7));
819   }
820   else
821     return False;
822 }
823 
Is2Short(void)824 static Boolean Is2Short(void)
825 {
826   if (AdrMode2 < 0x30)
827     return True;
828   else if (AdrMode2 == 0x30)
829   {
830     LongInt ImmValue = ImmVal2();
831 
832     return ((ImmValue >= LowLim4) && (ImmValue <= 7));
833   }
834   else
835     return False;
836 }
837 
ConvertShort(void)838 static void ConvertShort(void)
839 {
840   if (AdrMode == 0x30)
841   {
842     AdrMode += ImmVal() & 15;
843     AdrCnt = 0;
844   }
845 }
846 
Convert2Short(void)847 static void Convert2Short(void)
848 {
849   if (AdrMode2 == 0x30)
850   {
851     AdrMode2 += ImmVal2() & 15;
852     AdrCnt2 = 0;
853   }
854 }
855 
SetULowLims(void)856 static void SetULowLims(void)
857 {
858   LowLim4 = 0;
859   LowLim8 = 0;
860 }
861 
DecodePseudo(void)862 static Boolean DecodePseudo(void)
863 {
864   return False;
865 }
866 
AddPrefixes(void)867 static void AddPrefixes(void)
868 {
869   if (CodeLen != 0)
870   {
871     InsertSinglePrefix(1);
872     InsertSinglePrefix(0);
873   }
874 }
875 
DecodeCondition(const char * pAsc,Word * pCondition)876 static Boolean DecodeCondition(const char *pAsc, Word *pCondition)
877 {
878   int z;
879 
880   for (z = 0; z < ConditionCount; z++)
881     if (!as_strcasecmp(pAsc, Conditions[z]))
882     {
883       *pCondition = z;
884       return True;
885     }
886   return False;
887 }
888 
DecideGA(void)889 static char DecideGA(void)
890 {
891   if (((IsShort()) && (Is2Absolute()))
892    || ((Is2Short()) && (IsAbsolute())))
893     return 'A';
894   else
895     return 'G';
896 }
897 
898 /*--------------------------------------------------------------------------*/
899 
DecodeFixed(Word Code)900 static void DecodeFixed(Word Code)
901 {
902   if (!ChkArgCnt(0, 0));
903   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
904   else
905   {
906     WAsmCode[0] = Code;
907     CodeLen = 2;
908   }
909 }
910 
DecodeRMW(Word Index)911 static void DecodeRMW(Word Index)
912 {
913   const RMWOrder *pOrder = RMWOrders + Index;
914 
915   if ((OpSize == -1) && (pOrder->Mask & 0x20))
916     OpSize = 2;
917   if (ChkArgCnt(1, 1))
918   {
919     tStrComp *pArg = &ArgStr[1];
920 
921     if ((!IsIndirect(ArgStr[1].Str)) && (pOrder->Mask & 0x20))
922     {
923       StrCompReset(&ArgStr[2]);
924       as_snprintf(ArgStr[2].Str, STRINGSIZE, "(%s)", ArgStr[1].Str);
925       pArg = &ArgStr[2];
926     }
927     DecodeAdr(pArg, 0, !(pOrder->Mask & 0x10), !(pOrder->Mask & 0x20));
928     if (AdrOK)
929     {
930       if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
931       else if (!(pOrder->Mask & (1 << OpSize))) WrError(ErrNum_InvOpSize);
932       else
933       {
934         WAsmCode[0] = (((Word)OpSize + 1) << 14) + (((Word)pOrder->Code) << 8) + AdrMode;
935         memcpy(WAsmCode + 1, AdrVals, AdrCnt);
936         CodeLen = 2 + AdrCnt;
937       }
938     }
939   }
940 }
941 
DecodeGASI1(Word Code)942 static void DecodeGASI1(Word Code)
943 {
944   if (ChkArgCnt(2, 2))
945   {
946     DecodeAdr(&ArgStr[1], 1, False, True);
947     if (AdrOK)
948     {
949       CopyAdr();
950       DecodeAdr(&ArgStr[2], 0, True, True);
951       if (AdrOK)
952       {
953         if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
954         else
955         {
956           LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
957 
958           if (Format == ' ')
959           {
960             if (((IsReg()) && (Is2Short()))
961              || ((Is2Reg()) && (IsShort())))
962               Format = 'S';
963             else if ((IsImmediate()) && (OpSize > 0) && ((ImmValue > 127) || (ImmValue < -128)))
964               Format = 'I';
965             else
966               Format = DecideGA();
967           }
968           switch (Format)
969           {
970             case 'G':
971               WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
972               if ((IsImmediate()) && (ImmValue <= 127) && (ImmValue >= -128))
973               {
974                 AdrMode = ImmValue & 0xff;
975                 AdrCnt = 0;
976               }
977               else
978                 WAsmCode[0] += 0x800;
979               WAsmCode[0] += AdrMode;
980               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
981               WAsmCode[1 + (AdrCnt >> 1)] = 0x8400 + (Code << 8) + AdrMode2;
982               memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
983               CodeLen = 4 + AdrCnt + AdrCnt2;
984               break;
985             case 'A':
986               if ((IsShort()) && (Is2Absolute()))
987               {
988                 ConvertShort();
989                 WAsmCode[0] = 0x3900
990                             + (((Word)OpSize + 1) << 14)
991                             + ((AdrMode & 0xf0) << 5)
992                             + (AdrMode & 15);
993                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
994                 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff) + (Code << 13);
995                 CodeLen = 4 + AdrCnt;
996               }
997               else if ((Is2Short()) && (IsAbsolute()))
998               {
999                 Convert2Short();
1000                 WAsmCode[0] = 0x3980
1001                             + (((Word)OpSize + 1) << 14)
1002                             + ((AdrMode2 & 0xf0) << 5)
1003                             + (AdrMode2 & 15);
1004                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1005                 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
1006                 CodeLen = 4 + AdrCnt2;
1007               }
1008               else WrError(ErrNum_InvAddrMode);
1009               break;
1010             case 'S':
1011               if ((IsShort()) && (Is2Reg()))
1012               {
1013                 ConvertShort();
1014                 WAsmCode[0] = 0x0000
1015                             + (((Word)OpSize + 1) << 14)
1016                             + (AdrMode & 15)
1017                             + ((AdrMode & 0xf0) << 5)
1018                             + ((AdrMode2 & 1) << 12)
1019                             + ((AdrMode2 & 14) << 4)
1020                             + ((Code & 1) << 4)
1021                             + ((Code & 2) << 10);
1022                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1023                 CodeLen = 2 + AdrCnt;
1024               }
1025               else if ((Is2Short()) && (IsReg()))
1026               {
1027                 Convert2Short();
1028                 WAsmCode[0] = 0x0100
1029                             + (((Word)OpSize + 1) << 14)
1030                             + (AdrMode2 & 15)
1031                             + ((AdrMode2 & 0xf0) << 5)
1032                             + ((AdrMode & 1) << 12)
1033                             + ((AdrMode & 14) << 4)
1034                             + ((Code & 1) << 4)
1035                             + ((Code & 2) << 11);
1036                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1037                 CodeLen = 2 + AdrCnt2;
1038               }
1039               else WrError(ErrNum_InvAddrMode);
1040               break;
1041             case 'I':
1042               if ((!IsImmediate()) || (OpSize == 0)) WrError(ErrNum_InvAddrMode);
1043               else
1044               {
1045                 WAsmCode[0] = AdrMode2 + (((Word)OpSize-1) << 11) + (Code << 8);
1046                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1047                 memcpy(WAsmCode + 1 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
1048                 CodeLen = 2 + AdrCnt + AdrCnt2;
1049               }
1050               break;
1051             default:
1052                WrError(ErrNum_InvFormat);
1053           }
1054         }
1055       }
1056     }
1057   }
1058 }
1059 
DecodeGASI2(Word Code)1060 static void DecodeGASI2(Word Code)
1061 {
1062   if (ChkArgCnt(2, 2))
1063   {
1064     DecodeAdr(&ArgStr[1], 1, False, True);
1065     if (AdrOK)
1066     {
1067       CopyAdr();
1068       DecodeAdr(&ArgStr[2], 0, True, True);
1069       if (AdrOK)
1070       {
1071         if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1072         else
1073         {
1074           LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1075 
1076           if (Format == ' ')
1077           {
1078             if ((IsReg()) && (Is2Reg()))
1079               Format = 'S';
1080             else if ((IsImmediate()) && (OpSize > 0) && ((ImmValue > 127) || (ImmValue < -128)))
1081               Format = 'I';
1082             else
1083               Format = DecideGA();
1084           }
1085           switch (Format)
1086           {
1087             case 'G':
1088               WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1089               if ((IsImmediate()) && (ImmValue <= 127) && (ImmValue >= -128))
1090               {
1091                 AdrMode = ImmValue & 0xff;
1092                 AdrCnt = 0;
1093               }
1094               else
1095                 WAsmCode[0] += 0x800;
1096               WAsmCode[0] += AdrMode;
1097               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1098               WAsmCode[1 + (AdrCnt >> 1)] = 0xc400 + (Code << 8) + AdrMode2;
1099               memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1100               CodeLen = 4 + AdrCnt + AdrCnt2;
1101               break;
1102             case 'A':
1103               if ((IsShort()) && (Is2Absolute()))
1104               {
1105                 ConvertShort();
1106                 WAsmCode[0] = 0x3940
1107                             + (((Word)OpSize+1) << 14)
1108                             + ((AdrMode & 0xf0) << 5)
1109                             + (AdrMode & 15);
1110                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1111                 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff) + (Code << 13);
1112                 CodeLen = 4 + AdrCnt;
1113               }
1114               else if ((Is2Short()) && (IsAbsolute()))
1115               {
1116                 Convert2Short();
1117                 WAsmCode[0] = 0x39c0
1118                             + (((Word)OpSize+1) << 14)
1119                             + ((AdrMode2 & 0xf0) << 5)
1120                             + (AdrMode2 & 15);
1121                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1122                 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
1123                 CodeLen = 4 + AdrCnt2;
1124               }
1125               else WrError(ErrNum_InvAddrMode);
1126               break;
1127             case 'S':
1128               if ((IsReg()) && (Is2Reg()))
1129               {
1130                 WAsmCode[0] = 0x3800
1131                             + (((Word)OpSize+1) << 14)
1132                             + (AdrMode & 15)
1133                             + (AdrMode2 << 4)
1134                             + (Code << 9);
1135                 CodeLen = 2;
1136               }
1137               else WrError(ErrNum_InvAddrMode);
1138               break;
1139             case 'I':
1140               if ((!IsImmediate()) || (OpSize == 0)) WrError(ErrNum_InvAddrMode);
1141               else
1142               {
1143                 WAsmCode[0] = 0x400 + AdrMode2 + (((Word)OpSize-1) << 11) + (Code << 8);
1144                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1145                 memcpy(WAsmCode + 1 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
1146                 CodeLen = 2 + AdrCnt + AdrCnt2;
1147               }
1148               break;
1149             default:
1150               WrError(ErrNum_InvFormat);
1151           }
1152         }
1153       }
1154     }
1155   }
1156 }
1157 
DecodeTrinom(Word Code)1158 static void DecodeTrinom(Word Code)
1159 {
1160   int Cnt;
1161   Byte Reg;
1162 
1163   if (Code == 2) /* MAC */
1164     LowLim8 = 0;
1165   if (!ChkArgCnt(3, 3));
1166   else if (DecodeRegAdr(&ArgStr[1], &Reg))
1167   {
1168     if (Code >= 2)
1169       OpSize--;
1170     if (OpSize < 0) WrError(ErrNum_InvOpSize);
1171     else
1172     {
1173       DecodeAdr(&ArgStr[3], 0, True, True);
1174       if (AdrOK)
1175       {
1176         LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1177 
1178         WAsmCode[0] = 0x700;
1179         if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1180         {
1181           AdrMode = ImmValue & 0xff;
1182           AdrCnt = 0;
1183         }
1184         else
1185           WAsmCode[0] += 0x800;
1186         WAsmCode[0] += (((Word)OpSize + 1) << 14) + AdrMode;
1187         memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1188         Cnt = AdrCnt;
1189         DecodeAdr(&ArgStr[2], 1, False, True);
1190         if (AdrOK)
1191         {
1192           WAsmCode[1 + (Cnt >> 1)] = AdrMode + (Code << 8) + (((Word)Reg) << 11);
1193           memcpy(WAsmCode + 2 + (Cnt >> 1), AdrVals, AdrCnt);
1194           CodeLen = 4 + Cnt + AdrCnt;
1195         }
1196       }
1197     }
1198   }
1199 }
1200 
DecodeRLM_RRM(Word Code)1201 static void DecodeRLM_RRM(Word Code)
1202 {
1203   int Cnt;
1204   Byte Reg;
1205   tSymbolSize Size;
1206 
1207   if (!ChkArgCnt(3, 3));
1208   else if (!DecodeReg(&ArgStr[2], &Reg, &Size, True));
1209   else if (Size != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[2]);
1210   else
1211   {
1212     Reg &= 0x3f;
1213     DecodeAdr(&ArgStr[3], 0, True, True);
1214     if (AdrOK)
1215     {
1216       LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1217 
1218       WAsmCode[0] = 0x700;
1219       if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > -128))
1220       {
1221         AdrMode = ImmValue & 0xff; AdrCnt = 0;
1222       }
1223       else
1224         WAsmCode[0] += 0x800;
1225       WAsmCode[0] += AdrMode;
1226       memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1227       Cnt = AdrCnt;
1228       DecodeAdr(&ArgStr[1], 1, False, True);
1229       if (AdrOK)
1230       {
1231         if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1232         else
1233         {
1234           WAsmCode[0] += ((Word)OpSize + 1) << 14;
1235           WAsmCode[1 + (Cnt >> 1)] = Code + (((Word)Reg) << 11)+AdrMode;
1236           memcpy(WAsmCode + 2 + (Cnt >> 1), AdrVals, AdrCnt);
1237           CodeLen = 4 + AdrCnt + Cnt;
1238         }
1239       }
1240     }
1241   }
1242 }
1243 
DecodeBit(Word Code)1244 static void DecodeBit(Word Code)
1245 {
1246   if (ChkArgCnt(2, 2))
1247   {
1248     DecodeAdr(&ArgStr[1], 1, False, True);
1249     if (AdrOK)
1250     {
1251       if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1252       else
1253       {
1254         CopyAdr();
1255         OpSize = -1;
1256         MinOneIs0 = True;
1257         DecodeAdr(&ArgStr[2], 0, True, True);
1258         if (AdrOK)
1259         {
1260           LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1261 
1262           OpSize = OpSize2;
1263           if (Format==' ')
1264           {
1265             if ((Is2Reg()) && (IsImmediate())
1266              && (ImmValue > 0)
1267              && (ImmValue < (1 << (OpSize + 3))))
1268               Format = 'S';
1269             else
1270               Format = DecideGA();
1271           }
1272           switch (Format)
1273           {
1274             case 'G':
1275               WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1276               if ((IsImmediate()) && (ImmValue >= LowLim8) && (ImmValue < 127))
1277               {
1278                 AdrMode = ImmValue & 0xff;
1279                 AdrCnt = 0;
1280               }
1281               else
1282                 WAsmCode[0] += 0x800;
1283               WAsmCode[0] += AdrMode;
1284               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1285               WAsmCode[1 + (AdrCnt >> 1)] = 0xd400 + (Code << 8) + AdrMode2;
1286               memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1287               CodeLen = 4 + AdrCnt + AdrCnt2;
1288               break;
1289             case 'A':
1290               if ((IsAbsolute()) && (Is2Short()))
1291               {
1292                 Convert2Short();
1293                 WAsmCode[0] = 0x39d0
1294                             + (((Word)OpSize+1) << 14)
1295                             + ((AdrMode2 & 0xf0) << 5)
1296                             + (AdrMode2 & 15);
1297                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1298                 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
1299                 CodeLen = 4 + AdrCnt2;
1300               }
1301               else if ((Is2Absolute()) && (IsShort()))
1302               {
1303                 ConvertShort();
1304                 WAsmCode[0] = 0x3950
1305                             + (((Word)OpSize+1) << 14)
1306                             + ((AdrMode & 0xf0) << 5)
1307                             + (AdrMode & 15);
1308                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1309                 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff) + (Code << 13);
1310                 CodeLen = 4 + AdrCnt;
1311               }
1312               else WrError(ErrNum_InvAddrMode);
1313               break;
1314             case 'S':
1315               if ((Is2Reg())
1316                && (IsImmediate())
1317                && (ImmVal() >= 0)
1318                && (ImmVal() < (1 << (3 + OpSize))))
1319               {
1320                 if (OpSize == 2)
1321                 {
1322                   if (ImmVal() >= 16)
1323                   {
1324                     AdrVals[0] -= 16;
1325                     AdrMode2++;
1326                   }
1327                   OpSize = 1;
1328                 }
1329                 if (OpSize == 1)
1330                 {
1331                   if (ImmVal() < 8)
1332                     OpSize=0;
1333                   else
1334                     AdrVals[0] -= 8;
1335                 }
1336                 WAsmCode[0] = 0x1700
1337                             + (((Word)OpSize + 1) << 14)
1338                             + ((Code & 1) << 7)
1339                             + ((Code & 2) << 10)
1340                             + (ImmVal() << 4)
1341                             + AdrMode2;
1342                 CodeLen = 2;
1343               }
1344               else WrError(ErrNum_InvAddrMode);
1345               break;
1346             default:
1347               WrError(ErrNum_InvFormat);
1348           }
1349         }
1350       }
1351     }
1352   }
1353 }
1354 
DecodeShift(Word Code)1355 static void DecodeShift(Word Code)
1356 {
1357   if (ChkArgCnt(2, 2))
1358   {
1359     DecodeAdr(&ArgStr[1], 1, False, True);
1360     if (AdrOK)
1361     {
1362       if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1363       else
1364       {
1365         CopyAdr();
1366         OpSize = -1;
1367         MinOneIs0 = True;
1368         DecodeAdr(&ArgStr[2], 0, True, True);
1369         if (AdrOK)
1370         {
1371           LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1372 
1373           OpSize = OpSize2;
1374           if (Format==' ')
1375           {
1376             if ((IsImmediate()) && (ImmValue == 1))
1377               Format = 'S';
1378             else
1379               Format = DecideGA();
1380           }
1381           switch (Format)
1382           {
1383             case 'G':
1384               WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1385               if ((IsImmediate()) && (ImmValue >= LowLim8) && (ImmVal() < 127))
1386               {
1387                 AdrMode = ImmValue & 0xff;
1388                 AdrCnt = 0;
1389               }
1390               else
1391                 WAsmCode[0] += 0x800;
1392               WAsmCode[0] += AdrMode;
1393               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1394               WAsmCode[1 + (AdrCnt >> 1)] = 0xb400
1395                                           + ((Code & 3) << 8)
1396                                           + ((Code & 4) << 9)
1397                                           + AdrMode2;
1398               memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1399               CodeLen = 4 + AdrCnt + AdrCnt2;
1400               break;
1401             case 'A':
1402               if ((IsAbsolute()) && (Is2Short()))
1403               {
1404                 Convert2Short();
1405                 WAsmCode[0] = 0x39b0
1406                             + (((Word)OpSize+1) << 14)
1407                             + ((AdrMode2 & 0xf0) << 5)
1408                             + (AdrMode2 & 15);
1409                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1410                 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
1411                 CodeLen = 4 + AdrCnt2;
1412               }
1413               else if ((Is2Absolute()) && (IsShort()))
1414               {
1415                 ConvertShort();
1416                 WAsmCode[0] = 0x3930
1417                             + (((Word)OpSize+1) << 14)
1418                             + ((AdrMode & 0xf0) << 5)
1419                             + (AdrMode & 15);
1420                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1421                 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)+ (Code << 13);
1422                 CodeLen = 4 + AdrCnt;
1423               }
1424               else WrError(ErrNum_InvAddrMode);
1425               break;
1426             case 'S':
1427               if ((IsImmediate()) && (ImmValue == 1))
1428               {
1429                 WAsmCode[0] = 0x2400
1430                             + (((Word)OpSize+1) << 14)
1431                             + AdrMode2
1432                             + ((Code & 3) << 8)
1433                             + ((Code & 4) << 9);
1434                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1435                 CodeLen =2 + AdrCnt2;
1436               }
1437               else WrError(ErrNum_InvAddrMode);
1438               break;
1439             default:
1440               WrError(ErrNum_InvFormat);
1441           }
1442         }
1443       }
1444     }
1445   }
1446 }
1447 
DecodeBField(Word Code)1448 static void DecodeBField(Word Code)
1449 {
1450   Byte Reg, Num1, Num2;
1451   Boolean OK;
1452   tSymbolFlags Flags;
1453   tSymbolSize Size;
1454 
1455   if (ChkArgCnt(4, 4))
1456   {
1457     tStrComp *pArg1 = (Code == 2) ? &ArgStr[2] : &ArgStr[1],
1458              *pArg2 = (Code == 2) ? &ArgStr[1] : &ArgStr[2];
1459 
1460     if (!DecodeReg(pArg1, &Reg, &Size, True));
1461     else if (Size != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, pArg1);
1462     else
1463     {
1464       Reg &= 0x3f;
1465       Num2 = EvalStrIntExpressionWithFlags(&ArgStr[4], Int5, &OK, &Flags);
1466       if (OK)
1467       {
1468         if (mFirstPassUnknown(Flags))
1469           Num2 &= 15;
1470         Num2--;
1471         if (Num2 > 15) WrError(ErrNum_OverRange);
1472         else if ((OpSize == -1) && (!DecodeRegAdr(pArg2, &Num1)));
1473         else
1474         {
1475           switch (OpSize)
1476           {
1477             case 0: Num1 = EvalStrIntExpression(&ArgStr[3], UInt3, &OK) & 7; break;
1478             case 1: Num1 = EvalStrIntExpression(&ArgStr[3], Int4, &OK) & 15; break;
1479             case 2: Num1 = EvalStrIntExpression(&ArgStr[3], Int5, &OK) & 31; break;
1480             default: assert(0);
1481           }
1482           if (OK)
1483           {
1484             if ((OpSize == 2) && (Num1 > 15))
1485               AdrInc = 2;
1486             DecodeAdr(pArg2, 1, False, True);
1487             if (AdrOK)
1488             {
1489               if ((OpSize == 2) && (Num1 > 15))
1490               {
1491                 Num1 -= 16;
1492                 OpSize--;
1493                 if (!(AdrMode & 0xf0))
1494                   AdrMode++;
1495               }
1496               WAsmCode[0] = 0x7000 + (((Word)OpSize + 1) << 8) + AdrMode;
1497               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1498               WAsmCode[1 + (AdrCnt >> 1)] = (((Word)Reg) << 11)
1499                                           + Num2
1500                                           + (((Word)Num1) << 5)
1501                                           + ((Code & 1) << 10)
1502                                           + ((Code & 2) << 14);
1503               CodeLen = 4 + AdrCnt;
1504             }
1505           }
1506         }
1507       }
1508     }
1509   }
1510 }
1511 
DecodeGAEq(Word Code)1512 static void DecodeGAEq(Word Code)
1513 {
1514   if (Hi(Code))
1515     SetULowLims();
1516   if (ChkArgCnt(2, 2))
1517   {
1518     DecodeAdr(&ArgStr[1], 1, False, True);
1519     if (AdrOK)
1520     {
1521       CopyAdr();
1522       DecodeAdr(&ArgStr[2], 0, True, True);
1523       if (AdrOK)
1524       {
1525         if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1526         else
1527         {
1528           if (OpSize == 0)
1529             LowLim8 = -128;
1530           if (Format == ' ')
1531             Format = DecideGA();
1532           switch (Format)
1533           {
1534             case 'G':
1535             {
1536               LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1537 
1538               WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1539               if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1540               {
1541                 AdrMode = ImmValue & 0xff;
1542                 AdrCnt = 0;
1543               }
1544               else
1545                 WAsmCode[0] += 0x800;
1546               WAsmCode[0] += AdrMode;
1547               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1548               WAsmCode[1 + (AdrCnt >> 1)] = 0x8400
1549                                           + AdrMode2
1550                                           + ((Code & 0xf0) << 8)
1551                                           + ((Code & 4) << 9)
1552                                           + ((Code & 3) << 8);
1553               memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1554               CodeLen = 4 + AdrCnt + AdrCnt2;
1555               break;
1556             }
1557             case 'A':
1558               if ((IsAbsolute()) && (Is2Short()))
1559               {
1560                 Convert2Short();
1561                 WAsmCode[0] = 0x3980
1562                             + (((Word)OpSize + 1) << 14)
1563                             + ((AdrMode2 & 0xf0) << 5)
1564                             + (AdrMode2 & 15)
1565                             + (Code & 0xf0);
1566                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1567                 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
1568                                              + ((Code & 15) << 13);
1569                 CodeLen = 4 + AdrCnt2;
1570               }
1571               else if ((Is2Absolute()) && (IsShort()))
1572               {
1573                 ConvertShort();
1574                 WAsmCode[0] = 0x3900
1575                             + (((Word)OpSize + 1) << 14)
1576                             + ((AdrMode & 0xf0) << 5)
1577                             + (AdrMode & 15)
1578                             + (Code & 0xf0);
1579                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1580                 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
1581                                             + ((Code & 15) << 13);
1582                 CodeLen = 4 + AdrCnt;
1583               }
1584               else WrError(ErrNum_InvAddrMode);
1585               break;
1586             default:
1587               WrError(ErrNum_InvFormat);
1588           }
1589         }
1590       }
1591     }
1592   }
1593 }
1594 
DecodeGAHalf(Word Code)1595 static void DecodeGAHalf(Word Code)
1596 {
1597   if (ChkArgCnt(2, 2))
1598   {
1599     DecodeAdr(&ArgStr[1], 1, False, True);
1600     if (AdrOK)
1601     {
1602       if (OpSize == 0) WrError(ErrNum_InvOpSize);
1603       else
1604       {
1605         if (OpSize != -1)
1606           OpSize--;
1607         CopyAdr();
1608         DecodeAdr(&ArgStr[2], 0, True, True);
1609         if (AdrOK)
1610         {
1611           if (OpSize == 2) WrError(ErrNum_InvOpSize);
1612           else if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1613           else
1614           {
1615             if (Format == ' ')
1616               Format = DecideGA();
1617             switch (Format)
1618             {
1619               case 'G':
1620               {
1621                 LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1622 
1623                 WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1624                 if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1625                 {
1626                   AdrMode = ImmValue & 0xff;
1627                   AdrCnt = 0;
1628                 }
1629                 else
1630                   WAsmCode[0] += 0x800;
1631                 WAsmCode[0] += AdrMode;
1632                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1633                 WAsmCode[1 + (AdrCnt >> 1)] = 0x8400
1634                                             + AdrMode2
1635                                             + ((Code & 0xf0) << 8)
1636                                             + ((Code & 4) << 9)
1637                                             + ((Code & 3) << 8);
1638                 memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1639                 CodeLen = 4 + AdrCnt + AdrCnt2;
1640                 break;
1641               }
1642               case 'A':
1643                 if ((IsAbsolute()) && (Is2Short()))
1644                 {
1645                   Convert2Short();
1646                   WAsmCode[0] = 0x3980
1647                               + (((Word)OpSize + 1) << 14)
1648                               + ((AdrMode2 & 0xf0) << 5)
1649                               + (AdrMode2 & 15)
1650                               + (Code & 0xf0);
1651                   memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1652                   WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
1653                                                + ((Code & 15) << 13);
1654                   CodeLen = 4 + AdrCnt2;
1655                 }
1656                 else if ((Is2Absolute()) && (IsShort()))
1657                 {
1658                   ConvertShort();
1659                   WAsmCode[0] = 0x3900
1660                               + (((Word)OpSize + 1) << 14)
1661                               + ((AdrMode & 0xf0) << 5)
1662                               + (AdrMode & 15)
1663                               + (Code & 0xf0);
1664                   memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1665                   WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
1666                                               + ((Code & 15) << 13);
1667                   CodeLen = 4 + AdrCnt;
1668                 }
1669                 else WrError(ErrNum_InvAddrMode);
1670                 break;
1671               default:
1672                 WrError(ErrNum_InvFormat);
1673             }
1674           }
1675         }
1676       }
1677     }
1678   }
1679 }
1680 
DecodeGAFirst(Word Code)1681 static void DecodeGAFirst(Word Code)
1682 {
1683   if (ChkArgCnt(2, 2))
1684   {
1685     DecodeAdr(&ArgStr[1], 1, !(Memo("STCF") || Memo("TSET")), True);
1686     if (AdrOK)
1687     {
1688       if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1689       else
1690       {
1691         CopyAdr();
1692         OpSize = -1;
1693         MinOneIs0 = True;
1694         DecodeAdr(&ArgStr[2], 0, True, True);
1695         OpSize = OpSize2;
1696         if (AdrOK)
1697         {
1698           if (Format == ' ')
1699             Format = DecideGA();
1700           switch (Format)
1701           {
1702             case 'G':
1703             {
1704               LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1705 
1706               WAsmCode[0] = 0x700
1707                           + (((Word)OpSize + 1) << 14);
1708               if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1709               {
1710                 AdrMode = ImmValue & 0xff;
1711                 AdrCnt = 0;
1712               }
1713               else WAsmCode[0] += 0x800;
1714               WAsmCode[0] += AdrMode;
1715               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1716               WAsmCode[1 + (AdrCnt >> 1)] = 0x8400
1717                                           + AdrMode2
1718                                           + ((Code & 0xf0) << 8)
1719                                           + ((Code & 4) << 9)
1720                                           + ((Code & 3) << 8);
1721               memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1722               CodeLen = 4 + AdrCnt + AdrCnt2;
1723               break;
1724             }
1725             case 'A':
1726               if ((IsAbsolute()) && (Is2Short()))
1727               {
1728                 Convert2Short();
1729                 WAsmCode[0] = 0x3980
1730                             + (((Word)OpSize + 1) << 14)
1731                             + ((AdrMode2 & 0xf0) << 5)
1732                             + (AdrMode2 & 15)
1733                             + (Code & 0xf0);
1734                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1735                 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
1736                                              + ((Code & 15) << 13);
1737                 CodeLen = 4 + AdrCnt2;
1738               }
1739               else if ((Is2Absolute()) && (IsShort()))
1740               {
1741                 ConvertShort();
1742                 WAsmCode[0] = 0x3900
1743                             + (((Word)OpSize + 1) << 14)
1744                             + ((AdrMode & 0xf0) << 5)
1745                             + (AdrMode & 15)
1746                             + (Code & 0xf0);
1747                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1748                 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
1749                                             + ((Code & 15) << 13);
1750                 CodeLen = 4 + AdrCnt;
1751               }
1752               else WrError(ErrNum_InvAddrMode);
1753               break;
1754             default:
1755               WrError(ErrNum_InvFormat);
1756           }
1757         }
1758       }
1759     }
1760   }
1761 }
1762 
DecodeGASecond(Word Code)1763 static void DecodeGASecond(Word Code)
1764 {
1765   if (ChkArgCnt(2, 2))
1766   {
1767     DecodeAdr(&ArgStr[2], 0, True, True);
1768     if (AdrOK)
1769     {
1770       if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1771       else
1772       {
1773         CopyAdr();
1774         OpSize = -1;
1775         DecodeAdr(&ArgStr[1], 1, False, True);
1776         OpSize = OpSize2;
1777         if (AdrOK)
1778         {
1779           if (Format == ' ')
1780             Format = DecideGA();
1781           switch (Format)
1782           {
1783             case 'G':
1784               WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1785               if ((Is2Immediate()) && (ImmVal2() < 127) && (ImmVal2() > LowLim8))
1786               {
1787                 AdrMode2 = ImmVal2() & 0xff;
1788                 AdrCnt = 0;
1789               }
1790               else
1791                 WAsmCode[0] += 0x800;
1792               WAsmCode[0] += AdrMode2;
1793               memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1794               WAsmCode[1 + (AdrCnt2 >> 1)] = 0x8400
1795                                            + AdrMode
1796                                            + ((Code & 0xf0) << 8)
1797                                            + ((Code & 4) << 9)
1798                                            + ((Code & 3) << 8);
1799               memcpy(WAsmCode + 2 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
1800               CodeLen = 4 + AdrCnt + AdrCnt2;
1801               break;
1802             case 'A':
1803               if ((IsAbsolute()) && (Is2Short()))
1804               {
1805                 Convert2Short();
1806                 WAsmCode[0] = 0x3900
1807                             + (((Word)OpSize + 1) << 14)
1808                             + ((AdrMode2 & 0xf0) << 5)
1809                             + (AdrMode2 & 15)
1810                             + (Code & 0xf0);
1811                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1812                 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
1813                                              + ((Code & 15) << 13);
1814                 CodeLen = 4 + AdrCnt2;
1815               }
1816               else if ((Is2Absolute()) && (IsShort()))
1817               {
1818                 ConvertShort();
1819                 WAsmCode[0] = 0x3980 + (((Word)OpSize + 1) << 14)
1820                                      + ((AdrMode & 0xf0) << 5)
1821                                      + (AdrMode & 15)
1822                                      + (Code & 0xf0);
1823                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1824                 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
1825                                             + ((Code & 15) << 13);
1826                 CodeLen = 4 + AdrCnt;
1827               }
1828               else WrError(ErrNum_InvAddrMode);
1829               break;
1830             default:
1831               WrError(ErrNum_InvFormat);
1832           }
1833         }
1834       }
1835     }
1836   }
1837 }
1838 
DecodeCHK_CHKS(Word IsSigned)1839 static void DecodeCHK_CHKS(Word IsSigned)
1840 {
1841   if (!IsSigned)
1842     SetULowLims();
1843   if (ChkArgCnt(2, 2))
1844   {
1845     DecodeAdr(&ArgStr[2], 1, False, True);
1846     if (AdrOK)
1847     {
1848       if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
1849       else if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1850       else
1851       {
1852         CopyAdr();
1853         DecodeAdr(&ArgStr[1], 0, False, False);
1854         if (AdrOK)
1855         {
1856           if (OpSize == 0)
1857             LowLim8 = -128;
1858           if (Format == ' ')
1859             Format = DecideGA();
1860           switch (Format)
1861           {
1862             case 'G':
1863               WAsmCode[0] = 0xf00 + (((Word)OpSize + 1) << 14) + AdrMode2;
1864               memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1865               WAsmCode[1 + (AdrCnt2 >> 1)] = 0xa600 + AdrMode
1866                                            + (IsSigned << 8);
1867               memcpy(WAsmCode + 2 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
1868               CodeLen = 4 + AdrCnt + AdrCnt2;
1869               break;
1870             case 'A':
1871               if ((IsAbsolute()) && (Is2Short()))
1872               {
1873                 Convert2Short();
1874                 WAsmCode[0] = 0x3920
1875                             + (((Word)OpSize + 1) << 14)
1876                             + ((AdrMode2 & 0xf0) << 5)
1877                             + (AdrMode2 & 15);
1878                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1879                 WAsmCode[1 + (AdrCnt2 >> 1)] = 0x4000
1880                                              + (AdrVals[0] & 0x1fff)
1881                                              + (IsSigned << 13);
1882                 CodeLen = 4 + AdrCnt2;
1883               }
1884               else if ((Is2Absolute()) && (IsShort()))
1885               {
1886                 ConvertShort();
1887                 WAsmCode[0] = 0x39a0
1888                             + (((Word)OpSize + 1) << 14)
1889                             + ((AdrMode & 0xf0) << 5)
1890                             + (AdrMode & 15);
1891                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1892                 WAsmCode[1 + (AdrCnt >> 1)] = 0x4000
1893                                             + (AdrVals2[0] & 0x1fff)
1894                                             + (IsSigned << 13);
1895                 CodeLen = 4 + AdrCnt;
1896               }
1897               else WrError(ErrNum_InvAddrMode);
1898               break;
1899             default:
1900               WrError(ErrNum_InvFormat);
1901           }
1902         }
1903       }
1904     }
1905   }
1906 }
1907 
DecodeString(Word Code)1908 static void DecodeString(Word Code)
1909 {
1910   Byte Reg;
1911   int Cnt;
1912   tSymbolSize Size;
1913 
1914   if (!ChkArgCnt(3, 3));
1915   else if (!DecodeReg(&ArgStr[3], &Reg, &Size, True));
1916   else if (Size != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[3]);
1917   else
1918   {
1919     Reg &= 0x3f;
1920     DecodeAdr(&ArgStr[2], 0, True, True);
1921     if (AdrOK)
1922     {
1923       LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1924 
1925       WAsmCode[0] = 0x700;
1926       if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1927       {
1928         AdrMode = ImmValue & 0xff;
1929         AdrCnt = 0;
1930       }
1931       else
1932         WAsmCode[0] += 0x800;
1933       WAsmCode[0] += AdrMode;
1934       memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1935       Cnt = AdrCnt;
1936       DecodeAdr(&ArgStr[1], 1, True, True);
1937       if (AdrOK)
1938       {
1939         if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1940         else
1941         {
1942           WAsmCode[0] += ((Word)OpSize + 1) << 14;
1943           WAsmCode[1 + (Cnt >> 1)] = 0x8000 + AdrMode + (Code << 8) + (((Word)Reg) << 11);
1944           memcpy(WAsmCode + 2 + (Cnt >> 1), AdrVals, AdrCnt);
1945           CodeLen = 4 + AdrCnt + Cnt;
1946         }
1947       }
1948     }
1949   }
1950 }
1951 
DecodeEX(Word Code)1952 static void DecodeEX(Word Code)
1953 {
1954   UNUSED(Code);
1955 
1956   if (ChkArgCnt(2, 2))
1957   {
1958     DecodeAdr(&ArgStr[1], 1, False, True);
1959     if (AdrOK)
1960     {
1961       CopyAdr();
1962       DecodeAdr(&ArgStr[2], 0, False, True);
1963       if (AdrOK)
1964       {
1965         if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1966         else
1967         {
1968           if (Format == ' ')
1969           {
1970             if ((IsReg()) && (Is2Reg()))
1971               Format = 'S';
1972             else
1973               Format = DecideGA();
1974           }
1975           switch (Format)
1976           {
1977             case 'G':
1978               WAsmCode[0] = 0x0f00 + (((Word)OpSize + 1) << 14) + AdrMode;
1979               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1980               WAsmCode[1 + (AdrCnt >> 1)] = 0x8f00 + AdrMode2;
1981               memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1982               CodeLen = 4 + AdrCnt + AdrCnt2;
1983               break;
1984             case 'A':
1985               if ((IsAbsolute()) && (Is2Short()))
1986               {
1987                 Convert2Short();
1988                 WAsmCode[0] = 0x3980
1989                             + (((Word)OpSize + 1) << 14)
1990                             + ((AdrMode2 & 0xf0) << 5)
1991                             + (AdrMode2 & 15);
1992                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1993                 WAsmCode[1 + (AdrCnt2 >> 1)] = AdrVals[0];
1994                 CodeLen = 4 + AdrCnt2;
1995               }
1996               else if ((Is2Absolute()) && (IsShort()))
1997               {
1998                 ConvertShort();
1999                 WAsmCode[0] = 0x3900
2000                             + (((Word)OpSize + 1) << 14)
2001                             + ((AdrMode & 0xf0) << 5)
2002                             + (AdrMode & 15);
2003                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
2004                 WAsmCode[1 + (AdrCnt >> 1)] = AdrVals2[0];
2005                 CodeLen = 4 + AdrCnt;
2006               }
2007               else WrError(ErrNum_InvAddrMode);
2008               break;
2009             case 'S':
2010               if ((IsReg()) && (Is2Reg()))
2011               {
2012                 WAsmCode[0] = 0x3e00
2013                             + (((Word)OpSize + 1) << 14)
2014                             + (AdrMode2 << 4)
2015                             + AdrMode;
2016                 CodeLen = 2;
2017               }
2018               else WrError(ErrNum_InvAddrMode);
2019               break;
2020             default:
2021               WrError(ErrNum_InvFormat);
2022           }
2023         }
2024       }
2025     }
2026   }
2027 }
2028 
DecodeCALR_JR(Word Code)2029 static void DecodeCALR_JR(Word Code)
2030 {
2031   if (!ChkArgCnt(1, 1));
2032   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
2033   else
2034   {
2035     LongInt AdrInt;
2036     Boolean OK, ForcePrefix = False;
2037 
2038     AdrInt = EvalStrIntExpressionOffs(&ArgStr[1], CheckForcePrefix(ArgStr[1].Str, &ForcePrefix), Int32, &OK) - EProgCounter();
2039     if ((OK) && (AddRelPrefix(0, 13, &AdrInt, ForcePrefix)))
2040     {
2041       if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2042       else
2043       {
2044         WAsmCode[0] = Code + (AdrInt & 0x1ffe);
2045         CodeLen = 2;
2046       }
2047     }
2048   }
2049 }
2050 
DecodeJRC(Word Code)2051 static void DecodeJRC(Word Code)
2052 {
2053   UNUSED(Code);
2054 
2055   if (!ChkArgCnt(2, 2));
2056   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
2057   else
2058   {
2059     Word Condition;
2060 
2061     if (!DecodeCondition(ArgStr[1].Str, &Condition)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
2062     else
2063     {
2064       LongInt AdrInt;
2065       Boolean OK, ForcePrefix = False;
2066 
2067       Condition %= 16;
2068       AdrInt = EvalStrIntExpressionOffs(&ArgStr[2], CheckForcePrefix(ArgStr[2].Str, &ForcePrefix), Int32, &OK) - EProgCounter();
2069       if ((OK) && (AddRelPrefix(0, 9, &AdrInt, ForcePrefix)))
2070       {
2071         if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2072         else
2073         {
2074           WAsmCode[0] = 0x1000 + ((Condition & 14) << 8) + (AdrInt & 0x1fe) + (Condition & 1);
2075           CodeLen = 2;
2076         }
2077       }
2078     }
2079   }
2080 }
2081 
DecodeJRBC_JRBS(Word Code)2082 static void DecodeJRBC_JRBS(Word Code)
2083 {
2084   if (!ChkArgCnt(3, 3));
2085   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
2086   else
2087   {
2088     int z;
2089     Boolean OK;
2090 
2091     z = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
2092     if (OK)
2093     {
2094       Boolean AdrLongPrefix = False;
2095       LongInt AdrLong;
2096 
2097       AdrLong = EvalStrIntExpressionOffs(&ArgStr[2], CheckForcePrefix(ArgStr[2].Str, &AdrLongPrefix), Int24, &OK);
2098       if (OK)
2099       {
2100         LongInt AdrInt;
2101         Boolean AdrIntPrefix = False;
2102 
2103         AddAbsPrefix(1, 13, AdrLong, AdrLongPrefix);
2104         AdrInt = EvalStrIntExpressionOffs(&ArgStr[3], CheckForcePrefix(ArgStr[3].Str, &AdrIntPrefix), Int32, &OK) - EProgCounter();
2105         if ((OK) && (AddRelPrefix(0, 9, &AdrInt, AdrIntPrefix)))
2106         {
2107           if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2108           else
2109           {
2110             CodeLen = 4;
2111             WAsmCode[1] = (z << 13) + (AdrLong & 0x1fff);
2112             WAsmCode[0] = Code + (AdrInt & 0x1fe);
2113           }
2114         }
2115       }
2116     }
2117   }
2118 }
2119 
DecodeDJNZ(Word Code)2120 static void DecodeDJNZ(Word Code)
2121 {
2122   UNUSED(Code);
2123 
2124   if (ChkArgCnt(2, 2))
2125   {
2126     DecodeAdr(&ArgStr[1], 0, False, True);
2127     if (AdrOK)
2128     {
2129       if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
2130       else
2131       {
2132         LongInt AdrInt;
2133         Boolean OK, ForcePrefix = False;
2134 
2135         AdrInt = EvalStrIntExpressionOffs(&ArgStr[2], CheckForcePrefix(ArgStr[2].Str, &ForcePrefix), Int32, &OK) - (EProgCounter() + 4 + AdrCnt +2 * Ord(PrefUsed[0]));
2136         if ((OK) && (AddRelPrefix(1, 13, &AdrInt, ForcePrefix)))
2137         {
2138           if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2139           else
2140           {
2141             WAsmCode[0] = 0x3700 + (((Word)OpSize + 1) << 14) + AdrMode;
2142             memcpy(WAsmCode + 1, AdrVals, AdrCnt);
2143             WAsmCode[1 + (AdrCnt >> 1)] = 0xe000 + (AdrInt & 0x1ffe);
2144             CodeLen = 4 + AdrCnt;
2145           }
2146         }
2147       }
2148     }
2149   }
2150 }
2151 
DecodeDJNZC(Word Code)2152 static void DecodeDJNZC(Word Code)
2153 {
2154   UNUSED(Code);
2155 
2156   if (ChkArgCnt(3, 3))
2157   {
2158     Word Condition;
2159 
2160     if (!DecodeCondition(ArgStr[2].Str, &Condition)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[2]);
2161     else
2162     {
2163       Condition %= 16;
2164       DecodeAdr(&ArgStr[1], 0, False, True);
2165       if (AdrOK)
2166       {
2167         if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
2168         else
2169         {
2170           Boolean OK, ForcePrefix = False;
2171           LongInt AdrInt;
2172 
2173           AdrInt = EvalStrIntExpressionOffs(&ArgStr[3], CheckForcePrefix(ArgStr[3].Str, &ForcePrefix), Int32, &OK) - EProgCounter();
2174           if ((OK) && (AddRelPrefix(1, 13, &AdrInt, ForcePrefix)))
2175           {
2176             if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2177             else
2178             {
2179               WAsmCode[0] = 0x3700 + (((Word)OpSize+1) << 14) + AdrMode;
2180               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
2181               WAsmCode[1 + (AdrCnt >> 1)] = ((Condition & 14) << 12) + (AdrInt & 0x1ffe) + (Condition & 1);
2182               CodeLen =4 + AdrCnt;
2183             }
2184           }
2185         }
2186       }
2187     }
2188   }
2189 }
2190 
DecodeLINK_RETD(Word Code)2191 static void DecodeLINK_RETD(Word Code)
2192 {
2193   if (!ChkArgCnt(1, 1));
2194   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
2195   else
2196   {
2197     LongInt AdrInt;
2198     Boolean OK, ForcePrefix = False;
2199     tSymbolFlags Flags;
2200 
2201     AdrInt = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], CheckForcePrefix(ArgStr[1].Str, &ForcePrefix), Int32, &OK, &Flags);
2202     if (mFirstPassUnknown(Flags))
2203       AdrInt &= 0x1fe;
2204     if (ChkRange(AdrInt, -0x80000, 0x7ffff))
2205     {
2206       if (Odd(AdrInt)) WrError(ErrNum_NotAligned);
2207       else
2208       {
2209         WAsmCode[0] = Code + (AdrInt & 0x1fe);
2210         AddSignedPrefix(0, 9, AdrInt, ForcePrefix);
2211         CodeLen = 2;
2212       }
2213     }
2214   }
2215 }
2216 
DecodeSWI(Word Code)2217 static void DecodeSWI(Word Code)
2218 {
2219   UNUSED(Code);
2220 
2221   if (!ChkArgCnt(1, 1));
2222   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
2223   else
2224   {
2225     Boolean OK;
2226 
2227     WAsmCode[0] = EvalStrIntExpression(&ArgStr[1], Int4, &OK) + 0x7f90;
2228     if (OK)
2229       CodeLen = 2;
2230   }
2231 }
2232 
DecodeLDA(Word Code)2233 static void DecodeLDA(Word Code)
2234 {
2235   UNUSED(Code);
2236 
2237   if (ChkArgCnt(2, 2))
2238   {
2239     DecodeAdr(&ArgStr[2], 0, False, False);
2240     if (AdrOK)
2241     {
2242       int z;
2243 
2244       WAsmCode[0] = 0x3000 + AdrMode;
2245       z = AdrCnt;
2246       memcpy(WAsmCode + 1, AdrVals, z);
2247       DecodeAdr(&ArgStr[1], 1, False, True);
2248       if (AdrOK)
2249       {
2250         if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
2251         else
2252         {
2253           WAsmCode[0] += ((Word)OpSize) << 14;
2254           WAsmCode[1 + (z >> 1)] = 0x9700 + AdrMode;
2255           memcpy(WAsmCode + 2 + (z >> 1), AdrVals, AdrCnt);
2256           CodeLen = 4 + z + AdrCnt;
2257         }
2258       }
2259     }
2260   }
2261 }
2262 
2263 /*--------------------------------------------------------------------------*/
2264 
AddFixed(const char * NName,Word NCode)2265 static void AddFixed(const char *NName, Word NCode)
2266 {
2267   AddInstTable(InstTable, NName, NCode, DecodeFixed);
2268 }
2269 
AddRMW(const char * NName,Byte NCode,Byte NMask)2270 static void AddRMW(const char *NName, Byte NCode, Byte NMask)
2271 {
2272   if (InstrZ >= RMWOrderCount) exit(255);
2273   RMWOrders[InstrZ].Mask = NMask;
2274   RMWOrders[InstrZ].Code = NCode;
2275   AddInstTable(InstTable, NName, InstrZ++, DecodeRMW);
2276 }
2277 
AddGAEq(const char * NName,Word NCode)2278 static void AddGAEq(const char *NName, Word NCode)
2279 {
2280   AddInstTable(InstTable, NName, NCode, DecodeGAEq);
2281 }
2282 
AddGAHalf(const char * NName,Word NCode)2283 static void AddGAHalf(const char *NName, Word NCode)
2284 {
2285   AddInstTable(InstTable, NName, NCode, DecodeGAHalf);
2286 }
2287 
AddGAFirst(const char * NName,Word NCode)2288 static void AddGAFirst(const char *NName, Word NCode)
2289 {
2290   AddInstTable(InstTable, NName, NCode, DecodeGAFirst);
2291 }
2292 
AddGASecond(const char * NName,Word NCode)2293 static void AddGASecond(const char *NName, Word NCode)
2294 {
2295   AddInstTable(InstTable, NName, NCode, DecodeGASecond);
2296 }
2297 
InitFields(void)2298 static void InitFields(void)
2299 {
2300   InstTable = CreateInstTable(301);
2301   AddInstTable(InstTable, "RLM", 0x0400, DecodeRLM_RRM);
2302   AddInstTable(InstTable, "RRM", 0x0500, DecodeRLM_RRM);
2303   AddInstTable(InstTable, "CHK", 0, DecodeCHK_CHKS);
2304   AddInstTable(InstTable, "CHKS", 1, DecodeCHK_CHKS);
2305   AddInstTable(InstTable, "EX", 0, DecodeEX);
2306   AddInstTable(InstTable, "CALR", 0x2001, DecodeCALR_JR);
2307   AddInstTable(InstTable, "JR", 0x2000, DecodeCALR_JR);
2308   AddInstTable(InstTable, "JRC", 0, DecodeJRC);
2309   AddInstTable(InstTable, "JRBC", 0x1e00, DecodeJRBC_JRBS);
2310   AddInstTable(InstTable, "JRBS", 0x1e01, DecodeJRBC_JRBS);
2311   AddInstTable(InstTable, "DJNZ", 0, DecodeDJNZ);
2312   AddInstTable(InstTable, "DJNZC", 0, DecodeDJNZC);
2313   AddInstTable(InstTable, "LINK", 0xc001, DecodeLINK_RETD);
2314   AddInstTable(InstTable, "RETD", 0xc801, DecodeLINK_RETD);
2315   AddInstTable(InstTable, "SWI", 0, DecodeSWI);
2316   AddInstTable(InstTable, "LDA", 0, DecodeLDA);
2317   AddInstTable(InstTable, "REG", 0, CodeREG);
2318 
2319   AddFixed("CCF" , 0x7f82);
2320   AddFixed("CSF" , 0x7f8a);
2321   AddFixed("CVF" , 0x7f86);
2322   AddFixed("CZF" , 0x7f8e);
2323   AddFixed("DI"  , 0x7fa1);
2324   AddFixed("EI"  , 0x7fa3);
2325   AddFixed("HALT", 0x7fa5);
2326   AddFixed("NOP" , 0x7fa0);
2327   AddFixed("RCF" , 0x7f80);
2328   AddFixed("RET" , 0x7fa4);
2329   AddFixed("RETI", 0x7fa9);
2330   AddFixed("RETS", 0x7fab);
2331   AddFixed("RSF" , 0x7f88);
2332   AddFixed("RVF" , 0x7f84);
2333   AddFixed("RZF" , 0x7f8c);
2334   AddFixed("SCF" , 0x7f81);
2335   AddFixed("SSF" , 0x7f89);
2336   AddFixed("SVF" , 0x7f85);
2337   AddFixed("SZF" , 0x7f8b);
2338   AddFixed("UNLK", 0x7fa2);
2339 
2340   RMWOrders = (RMWOrder *) malloc(sizeof(RMWOrder) * RMWOrderCount); InstrZ = 0;
2341   AddRMW("CALL" , 0x35, 0x36);
2342   AddRMW("CLR"  , 0x2b, 0x17);
2343   AddRMW("CPL"  , 0x28, 0x17);
2344   AddRMW("EXTS" , 0x33, 0x16);
2345   AddRMW("EXTZ" , 0x32, 0x16);
2346   AddRMW("JP"   , 0x34, 0x36);
2347   AddRMW("MIRR" , 0x23, 0x17);
2348   AddRMW("NEG"  , 0x29, 0x17);
2349   AddRMW("POP"  , 0x20, 0x17);
2350   AddRMW("PUSH" , 0x21, 0x07);
2351   AddRMW("PUSHA", 0x31, 0x36);
2352   AddRMW("RVBY" , 0x22, 0x17);
2353   AddRMW("TJP"  , 0x36, 0x16);
2354   AddRMW("TST"  , 0x2a, 0x17);
2355 
2356   InstrZ = 0;
2357   AddInstTable(InstTable, "ADD", InstrZ++, DecodeGASI1);
2358   AddInstTable(InstTable, "SUB", InstrZ++, DecodeGASI1);
2359   AddInstTable(InstTable, "CP" , InstrZ++, DecodeGASI1);
2360   AddInstTable(InstTable, "LD" , InstrZ++, DecodeGASI1);
2361 
2362   InstrZ = 0;
2363   AddInstTable(InstTable, "AND", InstrZ++, DecodeGASI2);
2364   AddInstTable(InstTable, "OR" , InstrZ++, DecodeGASI2);
2365   AddInstTable(InstTable, "XOR", InstrZ++, DecodeGASI2);
2366 
2367   InstrZ = 0;
2368   AddInstTable(InstTable, "ADD3", InstrZ++, DecodeTrinom);
2369   AddInstTable(InstTable, "SUB3", InstrZ++, DecodeTrinom);
2370   AddInstTable(InstTable, "MAC" , InstrZ++, DecodeTrinom);
2371   AddInstTable(InstTable, "MACS", InstrZ++, DecodeTrinom);
2372 
2373   InstrZ = 0;
2374   AddInstTable(InstTable, "BRES", InstrZ++, DecodeBit);
2375   AddInstTable(InstTable, "BSET", InstrZ++, DecodeBit);
2376   AddInstTable(InstTable, "BCHG", InstrZ++, DecodeBit);
2377   AddInstTable(InstTable, "BTST", InstrZ++, DecodeBit);
2378 
2379   InstrZ = 0;
2380   AddInstTable(InstTable, "SLL", InstrZ++, DecodeShift);
2381   AddInstTable(InstTable, "SRL", InstrZ++, DecodeShift);
2382   AddInstTable(InstTable, "SLA", InstrZ++, DecodeShift);
2383   AddInstTable(InstTable, "SRA", InstrZ++, DecodeShift);
2384   AddInstTable(InstTable, "RL" , InstrZ++, DecodeShift);
2385   AddInstTable(InstTable, "RR" , InstrZ++, DecodeShift);
2386   AddInstTable(InstTable, "RLC", InstrZ++, DecodeShift);
2387   AddInstTable(InstTable, "RRC", InstrZ++, DecodeShift);
2388 
2389   InstrZ = 0;
2390   AddInstTable(InstTable, "BFEX" , InstrZ++, DecodeBField);
2391   AddInstTable(InstTable, "BFEXS", InstrZ++, DecodeBField);
2392   AddInstTable(InstTable, "BFIN" , InstrZ++, DecodeBField);
2393 
2394   AddGAEq("ABCD" , 0x0110);
2395   AddGAEq("ADC"  , 0x0004);
2396   AddGAEq("CBCD" , 0x0112);
2397   AddGAEq("CPC"  , 0x0006);
2398   AddGAEq("MAX"  , 0x0116);
2399   AddGAEq("MAXS" , 0x0017);
2400   AddGAEq("MIN"  , 0x0114);
2401   AddGAEq("MINS" , 0x0015);
2402   AddGAEq("SBC"  , 0x0105);
2403   AddGAEq("SBCD" , 0x0111);
2404 
2405   AddGAHalf("DIV"  , 0x26);
2406   AddGAHalf("DIVS" , 0x27);
2407   AddGAHalf("MUL"  , 0x24);
2408   AddGAHalf("MULS" , 0x25);
2409 
2410   AddGAFirst("ANDCF", 0x44);
2411   AddGAFirst("LDCF" , 0x47);
2412   AddGAFirst("ORCF" , 0x45);
2413   AddGAFirst("STCF" , 0x43);
2414   AddGAFirst("TSET" , 0x70);
2415   AddGAFirst("XORCF", 0x46);
2416 
2417   AddGASecond("BS0B" , 0x54);
2418   AddGASecond("BS0F" , 0x55);
2419   AddGASecond("BS1B" , 0x56);
2420   AddGASecond("BS1F" , 0x57);
2421 
2422   AddInstTable(InstTable, "CPSZ", 0, DecodeString);
2423   AddInstTable(InstTable, "CPSN", 1, DecodeString);
2424   AddInstTable(InstTable, "LDS" , 3, DecodeString);
2425 
2426   Conditions = (const char **) malloc(sizeof(char *)*ConditionCount); InstrZ = 0;
2427   Conditions[InstrZ++] = "C";   Conditions[InstrZ++] = "NC";
2428   Conditions[InstrZ++] = "Z";   Conditions[InstrZ++] = "NZ";
2429   Conditions[InstrZ++] = "OV";  Conditions[InstrZ++] = "NOV";
2430   Conditions[InstrZ++] = "MI";  Conditions[InstrZ++] = "PL";
2431   Conditions[InstrZ++] = "LE";  Conditions[InstrZ++] = "GT";
2432   Conditions[InstrZ++] = "LT";  Conditions[InstrZ++] = "GE";
2433   Conditions[InstrZ++] = "ULE"; Conditions[InstrZ++] = "UGT";
2434   Conditions[InstrZ++] = "N";   Conditions[InstrZ++] = "A";
2435   Conditions[InstrZ++] = "ULT"; Conditions[InstrZ++] = "UGE";
2436   Conditions[InstrZ++] = "EQ";  Conditions[InstrZ++] = "NE";
2437 }
2438 
DeinitFields(void)2439 static void DeinitFields(void)
2440 {
2441   DestroyInstTable(InstTable);
2442 
2443   free(RMWOrders);
2444   free(Conditions);
2445 }
2446 
DecodeAttrPart_97C241(void)2447 static Boolean DecodeAttrPart_97C241(void)
2448 {
2449   char *p;
2450 
2451   switch (AttrSplit)
2452   {
2453     case '.':
2454       p = strchr(AttrPart.Str, ':');
2455       if (p)
2456       {
2457         Format = (p < AttrPart.Str + strlen(AttrPart.Str) - 1) ? p[1] : ' ';
2458         *p = '\0';
2459       }
2460       else
2461         Format = ' ';
2462       break;
2463     case ':':
2464       p = strchr(AttrPart.Str, '.');
2465       if (!p)
2466       {
2467         Format = (*AttrPart.Str);
2468         *AttrPart.Str = '\0';
2469       }
2470       else
2471       {
2472         Format = (p == AttrPart.Str) ? ' ' : *AttrPart.Str;
2473         strmov(AttrPart.Str, p + 1);
2474       }
2475       break;
2476     default:
2477       Format = ' ';
2478   }
2479   Format = as_toupper(Format);
2480 
2481   if (*AttrPart.Str)
2482     switch (as_toupper(*AttrPart.Str))
2483     {
2484       case 'B':
2485         AttrPartOpSize = eSymbolSize8Bit;
2486         break;
2487       case 'W':
2488         AttrPartOpSize = eSymbolSize16Bit;
2489         break;
2490       case 'D':
2491         AttrPartOpSize = eSymbolSize32Bit;
2492         break;
2493       default:
2494        WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
2495        return False;
2496     }
2497   return True;
2498 }
2499 
MakeCode_97C241(void)2500 static void MakeCode_97C241(void)
2501 {
2502   CodeLen = 0;
2503   DontPrint = False;
2504   PrefUsed[0] = False;
2505   PrefUsed[1] = False;
2506   AdrInc = 0;
2507   MinOneIs0 = False;
2508   LowLim4 = -8; LowLim8 = -128;
2509 
2510   /* zu ignorierendes */
2511 
2512   if (Memo(""))
2513     return;
2514 
2515   OpSize = AttrPartOpSize;
2516 
2517   /* Pseudoanweisungen */
2518 
2519   if (DecodePseudo()) return;
2520 
2521   if (DecodeIntelPseudo(False)) return;
2522 
2523   if (LookupInstTable(InstTable, OpPart.Str))
2524   {
2525     AddPrefixes();
2526     return;
2527   }
2528 
2529   WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2530 }
2531 
2532 /*!------------------------------------------------------------------------
2533  * \fn     InternSymbol_97C241(char *pArg, TempResult *pResult)
2534  * \brief  handle built-in symbols on TLCS-9000
2535  * \param  pArg source argument
2536  * \param  pResult result buffer
2537  * ------------------------------------------------------------------------ */
2538 
InternSymbol_97C241(char * pArg,TempResult * pResult)2539 static void InternSymbol_97C241(char *pArg, TempResult *pResult)
2540 {
2541   Byte Reg;
2542   tSymbolSize Size;
2543 
2544   if (DecodeRegCore(pArg, &Reg, &Size))
2545   {
2546     pResult->Typ = TempReg;
2547     pResult->DataSize = Size;
2548     pResult->Contents.RegDescr.Reg = Reg;
2549     pResult->Contents.RegDescr.Dissect = DissectReg_97C241;
2550   }
2551 }
2552 
IsDef_97C241(void)2553 static Boolean IsDef_97C241(void)
2554 {
2555   return Memo("REG");
2556 }
2557 
SwitchFrom_97C241(void)2558 static void SwitchFrom_97C241(void)
2559 {
2560   DeinitFields();
2561 }
2562 
SwitchTo_97C241(void)2563 static void SwitchTo_97C241(void)
2564 {
2565   TurnWords = False;
2566   ConstMode = ConstModeIntel;
2567 
2568   PCSymbol = "$";
2569   HeaderID = 0x56;
2570   NOPCode = 0x7fa0;
2571   DivideChars = ",";
2572   HasAttrs = True;
2573   AttrChars = ".:";
2574 
2575   ValidSegs = 1 << SegCode;
2576   Grans[SegCode] = 1;
2577   ListGrans[SegCode] = 2;
2578   SegInits[SegCode] = 0;
2579   SegLimits[SegCode] = 0xffffffl;
2580 
2581   DecodeAttrPart = DecodeAttrPart_97C241;
2582   MakeCode = MakeCode_97C241;
2583   IsDef = IsDef_97C241;
2584   InternSymbol = InternSymbol_97C241;
2585   DissectReg = DissectReg_97C241;
2586   SwitchFrom = SwitchFrom_97C241;
2587   InitFields();
2588 }
2589 
code97c241_init(void)2590 void code97c241_init(void)
2591 {
2592   CPU97C241 = AddCPU("97C241", SwitchTo_97C241);
2593 }
2594