1 /* code96c141.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS-Portierung                                                             */
6 /*                                                                           */
7 /* Codegenerator TLCS-900(L)                                                 */
8 /*                                                                           */
9 /* Historie: 27. 6.1996 Grundsteinlegung                                     */
10 /*                                                                           */
11 /*****************************************************************************/
12 
13 #include "stdinc.h"
14 #include <string.h>
15 #include <ctype.h>
16 
17 #include "nls.h"
18 #include "bpemu.h"
19 #include "strutil.h"
20 
21 #include "asmdef.h"
22 #include "asmsub.h"
23 #include "asmpars.h"
24 #include "asmallg.h"
25 #include "errmsg.h"
26 #include "codepseudo.h"
27 #include "intpseudo.h"
28 #include "asmitree.h"
29 #include "codevars.h"
30 #include "errmsg.h"
31 
32 #include "code96c141.h"
33 
34 /*-------------------------------------------------------------------------*/
35 /* Daten */
36 
37 typedef struct
38 {
39   Word Code;
40   Byte CPUFlag;
41   Boolean InSup;
42 } FixedOrder;
43 
44 typedef struct
45 {
46   Word Code;
47   Boolean InSup;
48   Byte MinMax,MaxMax;
49   ShortInt Default;
50 } ImmOrder;
51 
52 typedef struct
53 {
54   Word Code;
55   Byte OpMask;
56 } RegOrder;
57 
58 typedef struct
59 {
60   const char *Name;
61   Byte Code;
62 } Condition;
63 
64 #define FixedOrderCnt 13
65 #define ImmOrderCnt 3
66 #define RegOrderCnt 8
67 #define ConditionCnt 24
68 
69 #define ModNone (-1)
70 #define ModReg 0
71 #define MModReg (1  << ModReg)
72 #define ModXReg 1
73 #define MModXReg (1 << ModXReg)
74 #define ModMem 2
75 #define MModMem (1  << ModMem)
76 #define ModImm 3
77 #define MModImm (1  << ModImm)
78 #define ModCReg 4
79 #define MModCReg (1 << ModCReg)
80 
81 static FixedOrder *FixedOrders;
82 static RegOrder *RegOrders;
83 static ImmOrder *ImmOrders;
84 static Condition *Conditions;
85 static LongInt DefaultCondition;
86 
87 static ShortInt AdrType;
88 static ShortInt OpSize;        /* -1/0/1/2 = nix/Byte/Word/Long */
89 static Byte AdrMode;
90 static Byte AdrVals[10];
91 static Boolean MinOneIs0, AutoIncSizeNeeded;
92 
93 static CPUVar CPU96C141,CPU93C141;
94 
95 /*---------------------------------------------------------------------------*/
96 /* Adressparser */
97 
IsRegBase(Byte No,Byte Size)98 static Boolean IsRegBase(Byte No, Byte Size)
99 {
100   return ((Size == 2)
101        || ((Size == 1) && (No < 0xf0) && (!Maximum) && ((No & 3) == 0)));
102 }
103 
ChkMaximum(Boolean MustMax,Byte * Result)104 static void ChkMaximum(Boolean MustMax, Byte *Result)
105 {
106   if (Maximum != MustMax)
107   {
108     *Result = 1;
109     WrError((MustMax) ? ErrNum_OnlyInMaxmode : ErrNum_NotInMaxmode);
110   }
111 }
112 
IsQuot(char Ch)113 static Boolean IsQuot(char Ch)
114 {
115   return ((Ch == '\'') || (Ch == '`'));
116 }
117 
CodeEReg(char * Asc,Byte * ErgNo,Byte * ErgSize)118 static Byte CodeEReg(char *Asc, Byte *ErgNo, Byte *ErgSize)
119 {
120 #define RegCnt 8
121   static const char Reg8Names[RegCnt + 1] = "AWCBEDLH";
122   static const char Reg16Names[RegCnt][3] =
123   {
124     "WA" ,"BC" ,"DE" ,"HL" ,"IX" ,"IY" ,"IZ" ,"SP"
125   };
126   static const char Reg32Names[RegCnt][4] =
127   {
128     "XWA","XBC","XDE","XHL","XIX","XIY","XIZ","XSP"
129   };
130 
131   int z, l = strlen(Asc);
132   const char *pos;
133   String HAsc, Asc_N;
134   Byte Result;
135 
136   strmaxcpy(Asc_N, Asc, STRINGSIZE);
137   NLS_UpString(Asc_N);
138   Asc = Asc_N;
139 
140   Result = 2;
141 
142   /* mom. Bank ? */
143 
144   if (l == 1)
145   {
146     pos = strchr(Reg8Names, *Asc);
147     if (pos)
148     {
149      z = pos - Reg8Names;
150      *ErgNo = 0xe0 + ((z & 6) << 1) + (z & 1);
151      *ErgSize = 0;
152      return Result;
153     }
154   }
155   for (z = 0; z < RegCnt; z++)
156   {
157     if (!strcmp(Asc, Reg16Names[z]))
158     {
159       *ErgNo = 0xe0 + (z << 2);
160       *ErgSize = 1;
161       return Result;
162     }
163     if (!strcmp(Asc, Reg32Names[z]))
164     {
165       *ErgNo = 0xe0 + (z << 2);
166       *ErgSize = 2;
167       if (z < 4)
168         ChkMaximum(True, &Result);
169       return Result;
170     }
171   }
172 
173   /* Bankregister, 8 Bit ? */
174 
175   if ((l == 3) && ((*Asc == 'Q') || (*Asc == 'R')) && ((Asc[2] >= '0') && (Asc[2] <= '7')))
176   {
177     for (z = 0; z < RegCnt; z++)
178       if (Asc[1] == Reg8Names[z])
179       {
180         *ErgNo = ((Asc[2] - '0') << 4) + ((z & 6) << 1) + (z & 1);
181         if (*Asc == 'Q')
182         {
183           *ErgNo |= 2;
184           ChkMaximum(True, &Result);
185         }
186         if (((*Asc == 'Q') || (Maximum)) && (Asc[2] > '3'))
187         {
188           WrError(ErrNum_OverRange);
189           Result = 1;
190         }
191         *ErgSize = 0;
192         return Result;
193       }
194   }
195 
196   /* Bankregister, 16 Bit ? */
197 
198   if ((l == 4) && ((*Asc == 'Q') || (*Asc == 'R')) && ((Asc[3] >= '0') && (Asc[3] <= '7')))
199   {
200     strcpy(HAsc, Asc + 1);
201     HAsc[2] = '\0';
202     for (z = 0; z < RegCnt >> 1; z++)
203       if (!strcmp(HAsc, Reg16Names[z]))
204       {
205         *ErgNo = ((Asc[3] - '0') << 4) + (z << 2);
206         if (*Asc == 'Q')
207         {
208           *ErgNo |= 2;
209           ChkMaximum(True, &Result);
210         }
211         if (((*Asc == 'Q') || (Maximum)) && (Asc[3] > '3'))
212         {
213           WrError(ErrNum_OverRange);
214           Result = 1;
215         }
216         *ErgSize = 1;
217          return Result;
218       }
219   }
220 
221   /* Bankregister, 32 Bit ? */
222 
223   if ((l == 4) && ((Asc[3] >= '0') && (Asc[3] <= '7')))
224   {
225     for (z = 0; z < RegCnt >> 1; z++)
226      if (strncmp(Asc, Reg32Names[z], 3) == 0)
227      {
228        *ErgNo = ((Asc[3] - '0') << 4) + (z << 2);
229        ChkMaximum(True, &Result);
230        if (Asc[3] > '3')
231        {
232          WrError(ErrNum_OverRange); Result = 1;
233        }
234        *ErgSize = 2;
235        return Result;
236      }
237   }
238 
239   /* obere 8-Bit-Haelften momentaner Bank ? */
240 
241   if ((l == 2) && (*Asc == 'Q'))
242    for (z = 0; z < RegCnt; z++)
243     if (Asc[1] == Reg8Names[z])
244     {
245       *ErgNo = 0xe2 + ((z & 6) << 1) + (z & 1);
246       ChkMaximum(True, &Result);
247       *ErgSize = 0;
248       return Result;
249     }
250 
251   /* obere 16-Bit-Haelften momentaner Bank und von XIX..XSP ? */
252 
253   if ((l == 3) && (*Asc == 'Q'))
254   {
255     for (z = 0; z < RegCnt; z++)
256       if (!strcmp(Asc + 1, Reg16Names[z]))
257       {
258         *ErgNo = 0xe2 + (z << 2);
259         if (z < 4) ChkMaximum(True, &Result);
260         *ErgSize = 1;
261         return Result;
262       }
263   }
264 
265   /* 8-Bit-Teile von XIX..XSP ? */
266 
267   if (((l == 3) || ((l == 4) && (*Asc == 'Q')))
268   && ((Asc[l - 1] == 'L') || (Asc[l - 1] == 'H')))
269   {
270     strcpy(HAsc, Asc + (l - 3)); HAsc[2] = '\0';
271     for (z = 0; z < RegCnt >> 1; z++)
272       if (!strcmp(HAsc, Reg16Names[z + 4]))
273       {
274         *ErgNo = 0xf0 + (z << 2) + ((l - 3) << 1) + (Ord(Asc[l - 1] == 'H'));
275         *ErgSize = 0;
276         return Result;
277       }
278   }
279 
280   /* 8-Bit-Teile vorheriger Bank ? */
281 
282   if (((l == 2) || ((l == 3) && (*Asc == 'Q'))) && (IsQuot(Asc[l - 1])))
283    for (z = 0; z < RegCnt; z++)
284      if (Asc[l - 2] == Reg8Names[z])
285      {
286        *ErgNo = 0xd0 + ((z & 6) << 1) + ((strlen(Asc) - 2) << 1) + (z & 1);
287        if (l == 3) ChkMaximum(True, &Result);
288        *ErgSize = 0;
289        return Result;
290      }
291 
292   /* 16-Bit-Teile vorheriger Bank ? */
293 
294   if (((l == 3) || ((l == 4) && (*Asc == 'Q'))) && (IsQuot(Asc[l - 1])))
295   {
296     strcpy(HAsc, Asc + 1);
297     HAsc[l - 2] = '\0';
298     for (z = 0; z < RegCnt >> 1; z++)
299       if (!strcmp(HAsc, Reg16Names[z]))
300       {
301         *ErgNo = 0xd0 + (z << 2) + ((strlen(Asc) - 3) << 1);
302         if (l == 4) ChkMaximum(True, &Result);
303         *ErgSize = 1;
304         return Result;
305       }
306   }
307 
308   /* 32-Bit-Register vorheriger Bank ? */
309 
310   if ((l == 4) && (IsQuot(Asc[3])))
311   {
312     strcpy(HAsc, Asc); HAsc[3] = '\0';
313     for (z = 0; z < RegCnt >> 1; z++)
314       if (!strcmp(HAsc, Reg32Names[z]))
315       {
316         *ErgNo = 0xd0 + (z << 2);
317         ChkMaximum(True, &Result);
318         *ErgSize = 2;
319         return Result;
320       }
321   }
322 
323   return (Result = 0);
324 }
325 
ChkL(CPUVar Must,Byte * Result)326 static void ChkL(CPUVar Must, Byte *Result)
327 {
328   if (MomCPU != Must)
329   {
330     WrError(ErrNum_InvCtrlReg);
331     *Result = 0;
332   }
333 }
334 
CodeCReg(char * Asc,Byte * ErgNo,Byte * ErgSize)335 static Byte CodeCReg(char *Asc, Byte *ErgNo, Byte *ErgSize)
336 {
337   Byte Result = 2;
338 
339   if (!as_strcasecmp(Asc, "NSP"))
340   {
341     *ErgNo = 0x3c;
342     *ErgSize = 1;
343     ChkL(CPU96C141, &Result);
344     return Result;
345   }
346   if (!as_strcasecmp(Asc, "XNSP"))
347   {
348     *ErgNo = 0x3c;
349     *ErgSize = 2;
350     ChkL(CPU96C141, &Result);
351     return Result;
352   }
353   if (!as_strcasecmp(Asc,"INTNEST"))
354   {
355     *ErgNo = 0x3c;
356     *ErgSize = 1;
357     ChkL(CPU93C141, &Result);
358     return Result;
359   }
360   if ((strlen(Asc) == 5)
361    && (!as_strncasecmp(Asc, "DMA", 3))
362    && (Asc[4] >= '0') && (Asc[4] <= '3'))
363   {
364     switch (as_toupper(Asc[3]))
365     {
366       case 'S':
367         *ErgNo = (Asc[4] - '0') * 4;
368         *ErgSize = 2;
369         return Result;
370       case 'D':
371         *ErgNo = (Asc[4] - '0') * 4 + 0x10;
372         *ErgSize = 2;
373         return Result;
374       case 'M':
375         *ErgNo = (Asc[4] - '0') * 4 + 0x22;
376         *ErgSize = 0;
377         return Result;
378       case 'C':
379         *ErgNo = (Asc[4] - '0') * 4 + 0x20;
380         *ErgSize = 1;
381         return Result;
382     }
383   }
384 
385   return (Result = 0);
386 }
387 
388 
389 typedef struct
390 {
391   char *Name;
392   Byte Num;
393   Boolean InMax, InMin;
394 } RegDesc;
395 
396 
SetOpSize(ShortInt NewSize)397 static void SetOpSize(ShortInt NewSize)
398 {
399   if (OpSize == -1)
400     OpSize = NewSize;
401   else if (OpSize != NewSize)
402   {
403     WrError(ErrNum_ConfOpSizes);
404     AdrType = ModNone;
405   }
406 }
407 
IsRegCurrent(Byte No,Byte Size,Byte * Erg)408 static Boolean IsRegCurrent(Byte No, Byte Size, Byte *Erg)
409 {
410   switch (Size)
411   {
412     case 0:
413       if ((No & 0xf2) == 0xe0)
414       {
415         *Erg = ((No & 0x0c) >> 1) + ((No & 1) ^ 1);
416         return True;
417       }
418       else
419         return False;
420     case 1:
421     case 2:
422       if ((No & 0xe3) == 0xe0)
423       {
424         *Erg = ((No & 0x1c) >> 2);
425         return True;
426       }
427       else
428         return False;
429     default:
430       return False;
431   }
432 }
433 
434 static const char Sizes[] = "124";
435 
GetPostInc(const char * pArg,int ArgLen,ShortInt * pOpSize)436 static int GetPostInc(const char *pArg, int ArgLen, ShortInt *pOpSize)
437 {
438   const char *pPos;
439 
440   /* <reg>+ */
441 
442   if ((ArgLen > 2) && (pArg[ArgLen - 1] == '+'))
443   {
444     *pOpSize = eSymbolSizeUnknown;
445     return 1;
446   }
447 
448   /* <reg>++n, <reg>+:n */
449 
450   if ((ArgLen > 4) && (pArg[ArgLen - 3] == '+') && strchr(":+", pArg[ArgLen - 2]))
451   {
452     pPos = strchr(Sizes, pArg[ArgLen - 1]);
453     if (pPos)
454     {
455       *pOpSize = pPos - Sizes;
456       return 3;
457     }
458   }
459   return False;
460 }
461 
GetPreDec(const char * pArg,int ArgLen,ShortInt * pOpSize,int * pCutoffLeft,int * pCutoffRight)462 static Boolean GetPreDec(const char *pArg, int ArgLen, ShortInt *pOpSize, int *pCutoffLeft, int *pCutoffRight)
463 {
464   const char *pPos;
465 
466   /* n--<reg> */
467 
468   if ((ArgLen > 4) && (pArg[1] == '-') && (pArg[2] == '-'))
469   {
470     pPos = strchr(Sizes, pArg[0]);
471     if (pPos)
472     {
473       *pOpSize = pPos - Sizes;
474       *pCutoffLeft = 3;
475       *pCutoffRight = 0;
476       return True;
477     }
478   }
479 
480   if ((ArgLen > 2) && (pArg[0] == '-'))
481   {
482     *pCutoffLeft = 1;
483 
484     /* -<reg>:n */
485 
486     if ((ArgLen > 4) && (pArg[ArgLen - 2] == ':'))
487     {
488       pPos = strchr(Sizes, pArg[ArgLen - 1]);
489       if (pPos)
490       {
491         *pOpSize = pPos - Sizes;
492         *pCutoffRight = 2;
493         return True;
494       }
495     }
496 
497     /* -<reg> */
498 
499     else
500     {
501       *pOpSize = eSymbolSizeUnknown;
502       *pCutoffRight = 0;
503       return True;
504     }
505   }
506   return False;
507 }
508 
ChkAdr(Byte Erl)509 static void ChkAdr(Byte Erl)
510 {
511   if (AdrType != ModNone)
512    if (!(Erl & (1 << AdrType)))
513    {
514      WrError(ErrNum_InvAddrMode);
515      AdrType = ModNone;
516    }
517 }
518 
SplitSize(tStrComp * pArg)519 static tSymbolSize SplitSize(tStrComp *pArg)
520 {
521   int l = strlen(pArg->Str);
522 
523   if ((l >= 3) && !strcmp(pArg->Str + l - 2, ":8"))
524   {
525     StrCompShorten(pArg, 2);
526     return eSymbolSize8Bit;
527   }
528   if ((l >= 4) && !strcmp(pArg->Str + l - 3, ":16"))
529   {
530     StrCompShorten(pArg, 3);
531     return eSymbolSize16Bit;
532   }
533   if ((l >= 4) && !strcmp(pArg->Str + l - 3, ":24"))
534   {
535     StrCompShorten(pArg, 3);
536     return eSymbolSize24Bit;
537   }
538   return eSymbolSizeUnknown;
539 }
540 
DecodeAdrMem(const tStrComp * pArg)541 static void DecodeAdrMem(const tStrComp *pArg)
542 {
543   LongInt DispPart, DispAcc;
544   char *EPos;
545   tStrComp Arg, Remainder;
546   Boolean NegFlag, NNegFlag, FirstFlag, OK;
547   Byte BaseReg, BaseSize;
548   Byte IndReg, IndSize;
549   Byte PartMask;
550   Byte HNum, HSize;
551   int CutoffLeft, CutoffRight, ArgLen = strlen(pArg->Str);
552   ShortInt IncOpSize;
553   tSymbolSize DispSize;
554 
555   NegFlag = False;
556   NNegFlag = False;
557   FirstFlag = False;
558   PartMask = 0;
559   DispAcc = 0;
560   BaseReg = IndReg = BaseSize = IndSize = 0xff;
561 
562   AdrType = ModNone;
563   AutoIncSizeNeeded = False;
564 
565   /* post-increment */
566 
567   if ((ArgLen > 2)
568    && (CutoffRight = GetPostInc(pArg->Str, ArgLen, &IncOpSize)))
569   {
570     String Reg;
571     tStrComp RegComp;
572 
573     StrCompMkTemp(&RegComp, Reg);
574     StrCompCopy(&RegComp, pArg);
575     StrCompShorten(&RegComp, CutoffRight);
576     if (CodeEReg(RegComp.Str, &HNum, &HSize) == 2)
577     {
578       if (!IsRegBase(HNum, HSize)) WrStrErrorPos(ErrNum_InvAddrMode, &RegComp);
579       else
580       {
581         if (IncOpSize == eSymbolSizeUnknown)
582           IncOpSize = OpSize;
583         AdrType = ModMem;
584         AdrMode = 0x45;
585         AdrCnt = 1;
586         AdrVals[0] = HNum;
587         if (IncOpSize == eSymbolSizeUnknown)
588           AutoIncSizeNeeded = True;
589         else
590           AdrVals[0] += IncOpSize;
591       }
592       return;
593     }
594   }
595 
596   /* pre-decrement ? */
597 
598   if ((ArgLen > 2)
599    && GetPreDec(pArg->Str, ArgLen, &IncOpSize, &CutoffLeft, &CutoffRight))
600   {
601     String Reg;
602     tStrComp RegComp;
603 
604     StrCompMkTemp(&RegComp, Reg);
605     StrCompCopy(&RegComp, pArg);
606     StrCompIncRefLeft(&RegComp, CutoffLeft);
607     StrCompShorten(&RegComp, CutoffRight);
608     if (CodeEReg(RegComp.Str, &HNum, &HSize) == 2)
609     {
610       if (!IsRegBase(HNum, HSize)) WrError(ErrNum_InvAddrMode);
611       else
612       {
613         if (IncOpSize == eSymbolSizeUnknown)
614           IncOpSize = OpSize;
615         AdrType = ModMem;
616         AdrMode = 0x44;
617         AdrCnt = 1;
618         AdrVals[0] = HNum;
619         if (IncOpSize == eSymbolSizeUnknown)
620           AutoIncSizeNeeded = True;
621         else
622           AdrVals[0] += IncOpSize;
623       }
624       return;
625     }
626   }
627 
628   Arg = *pArg;
629   DispSize = eSymbolSizeUnknown;
630   do
631   {
632     EPos = QuotMultPos(Arg.Str, "+-");
633     NNegFlag = EPos && (*EPos == '-');
634     if ((EPos == Arg.Str) || (EPos == Arg.Str + strlen(Arg.Str) - 1))
635     {
636       WrError(ErrNum_InvAddrMode);
637       return;
638     }
639     if (EPos)
640       StrCompSplitRef(&Arg, &Remainder, &Arg, EPos);
641     KillPrefBlanksStrComp(&Arg);
642     KillPostBlanksStrComp(&Arg);
643 
644     switch (CodeEReg(Arg.Str, &HNum, &HSize))
645     {
646       case 0:
647       {
648         tSymbolSize ThisSize;
649         tSymbolFlags Flags;
650 
651         if ((ThisSize = SplitSize(&Arg)) != eSymbolSizeUnknown)
652           if (ThisSize > DispSize)
653             DispSize = ThisSize;
654         DispPart = EvalStrIntExpressionWithFlags(&Arg, Int32, &OK, &Flags);
655         if (mFirstPassUnknown(Flags)) FirstFlag = True;
656         if (!OK) return;
657         if (NegFlag)
658           DispAcc -= DispPart;
659         else
660           DispAcc += DispPart;
661         PartMask |= 1;
662         break;
663       }
664       case 1:
665         break;
666       case 2:
667         if (NegFlag)
668         {
669           WrError(ErrNum_InvAddrMode); return;
670         }
671         else
672         {
673           Boolean MustInd;
674 
675           if (HSize == 0)
676             MustInd = True;
677           else if (HSize == 2)
678             MustInd = False;
679           else if (!IsRegBase(HNum, HSize))
680             MustInd = True;
681           else if (PartMask & 4)
682             MustInd = True;
683           else
684             MustInd = False;
685           if (MustInd)
686           {
687             if (PartMask & 2)
688             {
689               WrError(ErrNum_InvAddrMode); return;
690             }
691             else
692             {
693               IndReg = HNum;
694               PartMask |= 2;
695               IndSize = HSize;
696             }
697           }
698           else
699           {
700             if (PartMask & 4)
701             {
702               WrError(ErrNum_InvAddrMode); return;
703             }
704             else
705             {
706               BaseReg = HNum;
707               PartMask |= 4;
708               BaseSize = HSize;
709             }
710           }
711         }
712         break;
713     }
714 
715     NegFlag = NNegFlag;
716     NNegFlag = False;
717     if (EPos)
718       Arg = Remainder;
719   }
720   while (EPos);
721 
722   /* auto-deduce address/displacement size? */
723 
724   if (DispSize == eSymbolSizeUnknown)
725   {
726     switch (PartMask)
727     {
728       case 1:
729         if (DispAcc <= 0xff)
730           DispSize = eSymbolSize8Bit;
731         else if (DispAcc < 0xffff)
732           DispSize = eSymbolSize16Bit;
733         else
734           DispSize = eSymbolSize24Bit;
735         break;
736       case 5:
737         if (!DispAcc)
738           PartMask &= ~1;
739         else if (RangeCheck(DispAcc, SInt8) && IsRegCurrent(BaseReg, BaseSize, &AdrMode))
740           DispSize = eSymbolSize8Bit;
741         else
742           DispSize = eSymbolSize16Bit;
743         break;
744     }
745   }
746 
747   switch (PartMask)
748   {
749     case 0:
750     case 2:
751     case 3:
752     case 7:
753       WrError(ErrNum_InvAddrMode);
754       break;
755     case 1:
756       switch (DispSize)
757       {
758         case eSymbolSize8Bit:
759           if (FirstFlag)
760             DispAcc &= 0xff;
761           if (DispAcc > 0xff) WrError(ErrNum_AdrOverflow);
762           else
763           {
764             AdrType = ModMem;
765             AdrMode = 0x40;
766             AdrCnt = 1;
767             AdrVals[0] = DispAcc;
768           }
769           break;
770         case eSymbolSize16Bit:
771           if (FirstFlag)
772             DispAcc &= 0xffff;
773           if (DispAcc > 0xffff) WrError(ErrNum_AdrOverflow);
774           else
775           {
776             AdrType = ModMem;
777             AdrMode = 0x41;
778             AdrCnt = 2;
779             AdrVals[0] = Lo(DispAcc);
780             AdrVals[1] = Hi(DispAcc);
781           }
782           break;
783         case eSymbolSize24Bit:
784           if (FirstFlag)
785             DispAcc &= 0xffffff;
786           if (DispAcc > 0xffffff) WrError(ErrNum_AdrOverflow);
787           else
788           {
789             AdrType = ModMem;
790             AdrMode = 0x42;
791             AdrCnt = 3;
792             AdrVals[0] = DispAcc         & 0xff;
793             AdrVals[1] = (DispAcc >>  8) & 0xff;
794             AdrVals[2] = (DispAcc >> 16) & 0xff;
795           }
796           break;
797         default:
798           break; /* assert(0)? */
799       }
800       break;
801     case 4:
802       if (IsRegCurrent(BaseReg, BaseSize, &AdrMode))
803       {
804         AdrType = ModMem;
805         AdrCnt = 0;
806       }
807       else
808       {
809         AdrType = ModMem;
810         AdrMode = 0x43;
811         AdrCnt = 1;
812         AdrVals[0] = BaseReg;
813       }
814       break;
815     case 5:
816       switch (DispSize)
817       {
818         case eSymbolSize8Bit:
819           if (FirstFlag)
820             DispAcc &= 0x7f;
821           if (!IsRegCurrent(BaseReg, BaseSize, &AdrMode)) WrError(ErrNum_InvAddrMode);
822           else if (ChkRange(DispAcc, -128, 127))
823           {
824             AdrType = ModMem;
825             AdrMode += 8;
826             AdrCnt = 1;
827             AdrVals[0] = DispAcc & 0xff;
828           }
829           break;
830         case eSymbolSize16Bit:
831           if (FirstFlag)
832             DispAcc &= 0x7fff;
833           if (ChkRange(DispAcc, -32768, 32767))
834           {
835             AdrType = ModMem;
836             AdrMode = 0x43;
837             AdrCnt = 3;
838             AdrVals[0] = BaseReg + 1;
839             AdrVals[1] = DispAcc & 0xff;
840             AdrVals[2] = (DispAcc >> 8) & 0xff;
841           }
842           break;
843         case eSymbolSize24Bit:
844           WrError(ErrNum_InvAddrMode);
845           break;
846         default:
847           break; /* assert(0)? */
848       }
849       break;
850     case 6:
851       AdrType = ModMem;
852       AdrMode = 0x43;
853       AdrCnt = 3;
854       AdrVals[0] = 3 + (IndSize << 2);
855       AdrVals[1] = BaseReg;
856       AdrVals[2] = IndReg;
857       break;
858   }
859 }
860 
DecodeAdr(const tStrComp * pArg,Byte Erl)861 static void DecodeAdr(const tStrComp *pArg, Byte Erl)
862 {
863   Byte HNum, HSize;
864   LongInt DispAcc;
865   Boolean OK;
866 
867   AdrType = ModNone;
868   AutoIncSizeNeeded = False;
869 
870   /* Register ? */
871 
872   switch (CodeEReg(pArg->Str, &HNum, &HSize))
873   {
874     case 1:
875       ChkAdr(Erl);
876       return;
877     case 2:
878       if (IsRegCurrent(HNum, HSize, &AdrMode))
879         AdrType = ModReg;
880       else
881       {
882        AdrType = ModXReg;
883        AdrMode = HNum;
884       }
885       SetOpSize(HSize);
886       ChkAdr(Erl);
887       return;
888   }
889 
890   /* Steuerregister ? */
891 
892   if (CodeCReg(pArg->Str, &HNum, &HSize) == 2)
893   {
894     AdrType = ModCReg;
895     AdrMode = HNum;
896     SetOpSize(HSize);
897     ChkAdr(Erl);
898     return;
899   }
900 
901   /* Speicheroperand ? */
902 
903   if (IsIndirect(pArg->Str))
904   {
905     tStrComp Arg;
906 
907     StrCompRefRight(&Arg, pArg, 1);
908     StrCompShorten(&Arg, 1);
909     DecodeAdrMem(&Arg);
910     ChkAdr(Erl); return;
911   }
912 
913   /* bleibt nur noch immediate... */
914 
915   if ((MinOneIs0) && (OpSize == -1))
916     OpSize = 0;
917   switch (OpSize)
918   {
919     case -1:
920       WrError(ErrNum_UndefOpSizes);
921       break;
922     case 0:
923       AdrVals[0] = EvalStrIntExpression(pArg, Int8, &OK);
924       if (OK)
925       {
926         AdrType = ModImm;
927         AdrCnt = 1;
928       }
929       break;
930     case 1:
931       DispAcc = EvalStrIntExpression(pArg, Int16, &OK);
932       if (OK)
933       {
934         AdrType = ModImm;
935         AdrCnt = 2;
936         AdrVals[0] = Lo(DispAcc);
937         AdrVals[1] = Hi(DispAcc);
938       }
939       break;
940     case 2:
941       DispAcc = EvalStrIntExpression(pArg, Int32, &OK);
942       if (OK)
943       {
944         AdrType = ModImm;
945         AdrCnt = 4;
946         AdrVals[0] = Lo(DispAcc);
947         AdrVals[1] = Hi(DispAcc);
948         AdrVals[2] = Lo(DispAcc >> 16);
949         AdrVals[3] = Hi(DispAcc >> 16);
950       }
951       break;
952   }
953 }
954 
955 /*---------------------------------------------------------------------------*/
956 
SetAutoIncSize(Byte AdrModePos,Byte FixupPos)957 static void SetAutoIncSize(Byte AdrModePos, Byte FixupPos)
958 {
959   if ((BAsmCode[AdrModePos] & 0x4e) == 0x44)
960     BAsmCode[FixupPos] = (BAsmCode[FixupPos] & 0xfc) | OpSize;
961 }
962 
ArgPair(const char * Val1,const char * Val2)963 static Boolean ArgPair(const char *Val1, const char *Val2)
964 {
965   return  (((!as_strcasecmp(ArgStr[1].Str, Val1)) && (!as_strcasecmp(ArgStr[2].Str, Val2)))
966         || ((!as_strcasecmp(ArgStr[1].Str, Val2)) && (!as_strcasecmp(ArgStr[2].Str, Val1))));
967 }
968 
ImmVal(void)969 static LongInt ImmVal(void)
970 {
971   LongInt tmp;
972 
973   tmp = AdrVals[0];
974   if (OpSize >= 1)
975     tmp += ((LongInt)AdrVals[1]) << 8;
976   if (OpSize == 2)
977   {
978     tmp += ((LongInt)AdrVals[2]) << 16;
979     tmp += ((LongInt)AdrVals[3]) << 24;
980   }
981   return tmp;
982 }
983 
IsPwr2(LongInt Inp,Byte * Erg)984 static Boolean IsPwr2(LongInt Inp, Byte *Erg)
985 {
986   LongInt Shift;
987 
988   Shift = 1;
989   *Erg = 0;
990   do
991   {
992     if (Inp == Shift)
993       return True;
994     Shift += Shift;
995     (*Erg)++;
996   }
997   while (Shift != 0);
998   return False;
999 }
1000 
IsShort(Byte Code)1001 static Boolean IsShort(Byte Code)
1002 {
1003   return ((Code & 0x4e) == 0x40);
1004 }
1005 
CheckSup(void)1006 static void CheckSup(void)
1007 {
1008   if ((MomCPU == CPU96C141)
1009    && (!SupAllowed))
1010     WrError(ErrNum_PrivOrder);
1011 }
1012 
DecodeCondition(const char * pAsc)1013 static int DecodeCondition(const char *pAsc)
1014 {
1015   int z;
1016 
1017   for (z = 0; (z < ConditionCnt) && (as_strcasecmp(pAsc, Conditions[z].Name)); z++);
1018   return z;
1019 }
1020 
SetInstrOpSize(Byte Size)1021 static void SetInstrOpSize(Byte Size)
1022 {
1023   if (Size != 255)
1024     OpSize = Size;
1025 }
1026 
1027 
1028 /*---------------------------------------------------------------------------*/
1029 
DecodeMULA(Word Index)1030 static void DecodeMULA(Word Index)
1031 {
1032   UNUSED(Index);
1033 
1034   if (ChkArgCnt(1, 1))
1035   {
1036     DecodeAdr(&ArgStr[1], MModReg | MModXReg);
1037     if ((AdrType != ModNone) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
1038     else switch (AdrType)
1039     {
1040       case ModReg:
1041         CodeLen = 2;
1042         BAsmCode[0] = 0xd8 + AdrMode;
1043         BAsmCode[1] = 0x19;
1044         break;
1045       case ModXReg:
1046         CodeLen = 3;
1047         BAsmCode[0] = 0xd7;
1048         BAsmCode[1] = AdrMode;
1049         BAsmCode[2] = 0x19;
1050         break;
1051     }
1052   }
1053 }
1054 
DecodeJPCALL(Word Index)1055 static void DecodeJPCALL(Word Index)
1056 {
1057   int z;
1058 
1059   if (ChkArgCnt(1, 2))
1060   {
1061     z = (ArgCnt == 1) ? DefaultCondition : DecodeCondition(ArgStr[1].Str);
1062     if (z >= ConditionCnt) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1063     else
1064     {
1065       OpSize = 2;
1066       DecodeAdr(&ArgStr[ArgCnt], MModMem | MModImm);
1067       if (AdrType == ModImm)
1068       {
1069         if (AdrVals[3] != 0)
1070         {
1071           WrError(ErrNum_OverRange);
1072           AdrType=ModNone;
1073         }
1074         else if (AdrVals[2] != 0)
1075         {
1076           AdrType = ModMem;
1077           AdrMode = 0x42;
1078           AdrCnt = 3;
1079         }
1080         else
1081         {
1082           AdrType = ModMem;
1083           AdrMode = 0x41;
1084           AdrCnt = 2;
1085         }
1086       }
1087       if (AdrType == ModMem)
1088       {
1089         if ((z == DefaultCondition) && ((AdrMode == 0x41) || (AdrMode == 0x42)))
1090         {
1091           CodeLen = 1 + AdrCnt;
1092           BAsmCode[0] = 0x1a + 2 * Index + (AdrCnt - 2);
1093           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1094         }
1095         else
1096         {
1097           CodeLen = 2 + AdrCnt;
1098           BAsmCode[0] = 0xb0 + AdrMode;
1099           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1100           BAsmCode[1 + AdrCnt] = 0xd0 + (Index << 4) + (Conditions[z].Code);
1101         }
1102       }
1103     }
1104   }
1105 }
1106 
DecodeJR(Word Index)1107 static void DecodeJR(Word Index)
1108 {
1109   Boolean OK;
1110   int z;
1111   LongInt AdrLong;
1112   tSymbolFlags Flags;
1113 
1114   if (ChkArgCnt(1, 2))
1115   {
1116     z = (ArgCnt==1) ? DefaultCondition : DecodeCondition(ArgStr[1].Str);
1117     if (z >= ConditionCnt) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1118     else
1119     {
1120       AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int32, &OK, &Flags);
1121       if (OK)
1122       {
1123         if (Index==1)
1124         {
1125           AdrLong -= EProgCounter() + 3;
1126           if (((AdrLong > 0x7fffl) || (AdrLong < -0x8000l)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_DistTooBig);
1127           else
1128           {
1129             CodeLen = 3;
1130             BAsmCode[0] = 0x70 + Conditions[z].Code;
1131             BAsmCode[1] = Lo(AdrLong);
1132             BAsmCode[2] = Hi(AdrLong);
1133             if (!mFirstPassUnknown(Flags))
1134             {
1135               AdrLong++;
1136               if ((AdrLong >= -128) && (AdrLong <= 127)) WrError(ErrNum_ShortJumpPossible);
1137             }
1138           }
1139         }
1140         else
1141         {
1142           AdrLong -= EProgCounter() + 2;
1143           if (((AdrLong > 127) || (AdrLong < -128)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_DistTooBig);
1144           else
1145           {
1146             CodeLen = 2;
1147             BAsmCode[0] = 0x60 + Conditions[z].Code;
1148             BAsmCode[1] = Lo(AdrLong);
1149           }
1150         }
1151       }
1152     }
1153   }
1154 }
1155 
DecodeCALR(Word Index)1156 static void DecodeCALR(Word Index)
1157 {
1158   LongInt AdrLong;
1159   Boolean OK;
1160   tSymbolFlags Flags;
1161 
1162   UNUSED(Index);
1163 
1164   if (ChkArgCnt(1, 1))
1165   {
1166     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags) - (EProgCounter() + 3);
1167     if (OK)
1168     {
1169       if (((AdrLong < -32768) || (AdrLong > 32767)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_DistTooBig);
1170       else
1171       {
1172         CodeLen = 3;
1173         BAsmCode[0] = 0x1e;
1174         BAsmCode[1] = Lo(AdrLong);
1175         BAsmCode[2] = Hi(AdrLong);
1176       }
1177     }
1178   }
1179 }
1180 
DecodeRET(Word Index)1181 static void DecodeRET(Word Index)
1182 {
1183   int z;
1184   UNUSED(Index);
1185 
1186   if (ChkArgCnt(0, 1))
1187   {
1188     z = (ArgCnt == 0) ? DefaultCondition : DecodeCondition(ArgStr[1].Str);
1189     if (z >= ConditionCnt) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1190     else if (z == DefaultCondition)
1191     {
1192       CodeLen = 1;
1193       BAsmCode[0] = 0x0e;
1194     }
1195     else
1196     {
1197       CodeLen = 2;
1198       BAsmCode[0] = 0xb0;
1199       BAsmCode[1] = 0xf0 + Conditions[z].Code;
1200     }
1201   }
1202 }
1203 
DecodeRETD(Word Index)1204 static void DecodeRETD(Word Index)
1205 {
1206   Word AdrWord;
1207   Boolean OK;
1208   UNUSED(Index);
1209 
1210   if (ChkArgCnt(1, 1))
1211   {
1212     AdrWord = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
1213     if (OK)
1214     {
1215       CodeLen = 3;
1216       BAsmCode[0] = 0x0f;
1217       BAsmCode[1] = Lo(AdrWord);
1218       BAsmCode[2] = Hi(AdrWord);
1219     }
1220   }
1221 }
1222 
DecodeDJNZ(Word Index)1223 static void DecodeDJNZ(Word Index)
1224 {
1225   LongInt AdrLong;
1226   Boolean OK;
1227   tSymbolFlags Flags;
1228 
1229   UNUSED(Index);
1230 
1231   if (ChkArgCnt(1, 2))
1232   {
1233     if (ArgCnt == 1)
1234     {
1235       AdrType = ModReg;
1236       AdrMode = 2;
1237       OpSize = 0;
1238     }
1239     else
1240       DecodeAdr(&ArgStr[1], MModReg | MModXReg);
1241     if (AdrType != ModNone)
1242     {
1243       if (OpSize == 2) WrError(ErrNum_InvOpSize);
1244       else
1245       {
1246         AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int32, &OK, &Flags) - (EProgCounter() + 3 + Ord(AdrType == ModXReg));
1247         if (OK)
1248         {
1249           if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
1250           else
1251            switch (AdrType)
1252            {
1253              case ModReg:
1254                CodeLen = 3;
1255                BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
1256                BAsmCode[1] = 0x1c;
1257                BAsmCode[2] = AdrLong & 0xff;
1258                break;
1259              case ModXReg:
1260                CodeLen = 4;
1261                BAsmCode[0] = 0xc7 + (OpSize << 4);
1262                BAsmCode[1] = AdrMode;
1263                BAsmCode[2] = 0x1c;
1264                BAsmCode[3] = AdrLong & 0xff;
1265                break;
1266            }
1267         }
1268       }
1269     }
1270   }
1271 }
1272 
DecodeEX(Word Index)1273 static void DecodeEX(Word Index)
1274 {
1275   Byte HReg;
1276   UNUSED(Index);
1277 
1278   /* work around the parser problem related to the ' character */
1279 
1280   if (!as_strncasecmp(ArgStr[2].Str, "F\'", 2))
1281     ArgStr[2].Str[2] = '\0';
1282 
1283   if (!ChkArgCnt(2, 2));
1284   else if ((ArgPair("F", "F\'")) || (ArgPair("F`", "F")))
1285   {
1286     CodeLen = 1;
1287     BAsmCode[0] = 0x16;
1288   }
1289   else
1290   {
1291     DecodeAdr(&ArgStr[1], MModReg | MModXReg | MModMem);
1292     if (OpSize == 2) WrError(ErrNum_InvOpSize);
1293     else
1294     {
1295       switch (AdrType)
1296       {
1297         case ModReg:
1298           HReg = AdrMode;
1299           DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem);
1300           switch (AdrType)
1301           {
1302             case ModReg:
1303               CodeLen = 2;
1304               BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
1305               BAsmCode[1] = 0xb8 + HReg;
1306               break;
1307             case ModXReg:
1308               CodeLen = 3;
1309               BAsmCode[0] = 0xc7 + (OpSize << 4);
1310               BAsmCode[1] = AdrMode;
1311               BAsmCode[2] = 0xb8 + HReg;
1312               break;
1313             case ModMem:
1314               CodeLen = 2 + AdrCnt;
1315               BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
1316               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1317               BAsmCode[1 + AdrCnt] = 0x30 + HReg;
1318               break;
1319           }
1320           break;
1321         case ModXReg:
1322           HReg = AdrMode;
1323           DecodeAdr(&ArgStr[2], MModReg);
1324           if (AdrType == ModReg)
1325           {
1326             CodeLen = 3;
1327             BAsmCode[0] = 0xc7 + (OpSize << 4);
1328             BAsmCode[1] = HReg;
1329             BAsmCode[2] = 0xb8 + AdrMode;
1330           }
1331           break;
1332         case ModMem:
1333         {
1334           Boolean FixupAutoIncSize = AutoIncSizeNeeded;
1335 
1336           MinOneIs0 = True;
1337           HReg = AdrCnt;
1338           BAsmCode[0] = AdrMode;
1339           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1340           DecodeAdr(&ArgStr[2], MModReg);
1341           if (AdrType == ModReg)
1342           {
1343             CodeLen = 2 + HReg;
1344             if (FixupAutoIncSize)
1345               SetAutoIncSize(0, 1);
1346             BAsmCode[0] += 0x80 + (OpSize << 4);
1347             BAsmCode[1 + HReg] = 0x30 + AdrMode;
1348           }
1349           break;
1350         }
1351       }
1352     }
1353   }
1354 }
1355 
DecodeBS1x(Word Index)1356 static void DecodeBS1x(Word Index)
1357 {
1358   if (!ChkArgCnt(2, 2));
1359   else if (as_strcasecmp(ArgStr[1].Str, "A")) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
1360   else
1361   {
1362     DecodeAdr(&ArgStr[2], MModReg | MModXReg);
1363     if (OpSize != 1) WrError(ErrNum_InvOpSize);
1364     else switch (AdrType)
1365     {
1366       case ModReg:
1367         CodeLen = 2;
1368         BAsmCode[0] = 0xd8 + AdrMode;
1369         BAsmCode[1] = 0x0e + Index; /* ANSI */
1370         break;
1371       case ModXReg:
1372         CodeLen = 3;
1373         BAsmCode[0] = 0xd7;
1374         BAsmCode[1] = AdrMode;
1375         BAsmCode[2] = 0x0e +Index; /* ANSI */
1376         break;
1377     }
1378   }
1379 }
1380 
DecodeLDA(Word Index)1381 static void DecodeLDA(Word Index)
1382 {
1383   Byte HReg;
1384   UNUSED(Index);
1385 
1386   if (ChkArgCnt(2, 2))
1387   {
1388     DecodeAdr(&ArgStr[1], MModReg);
1389     if (AdrType != ModNone)
1390     {
1391       if (OpSize < 1) WrError(ErrNum_InvOpSize);
1392       else
1393       {
1394         HReg = AdrMode;
1395         if (IsIndirect(ArgStr[2].Str))
1396           DecodeAdr(&ArgStr[2], MModMem);
1397         else
1398           DecodeAdrMem(&ArgStr[2]);
1399         if (AdrType != ModNone)
1400         {
1401           CodeLen = 2 + AdrCnt;
1402           BAsmCode[0] = 0xb0 + AdrMode;
1403           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1404           BAsmCode[1 + AdrCnt] = 0x20 + ((OpSize - 1) << 4) + HReg;
1405         }
1406       }
1407     }
1408   }
1409 }
1410 
DecodeLDAR(Word Index)1411 static void DecodeLDAR(Word Index)
1412 {
1413   LongInt AdrLong;
1414   Boolean OK;
1415   tSymbolFlags Flags;
1416 
1417   UNUSED(Index);
1418 
1419   if (ChkArgCnt(2, 2))
1420   {
1421     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[2], Int32, &OK, &Flags) - (EProgCounter() + 4);
1422     if (OK)
1423     {
1424       if (((AdrLong < -32768) || (AdrLong > 32767)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_DistTooBig);
1425       else
1426       {
1427         DecodeAdr(&ArgStr[1], MModReg);
1428         if (AdrType != ModNone)
1429         {
1430           if (OpSize < 1) WrError(ErrNum_InvOpSize);
1431           else
1432           {
1433             CodeLen = 5;
1434             BAsmCode[0] = 0xf3;
1435             BAsmCode[1] = 0x13;
1436             BAsmCode[2] = Lo(AdrLong);
1437             BAsmCode[3] = Hi(AdrLong);
1438             BAsmCode[4] = 0x20 + ((OpSize - 1) << 4) + AdrMode;
1439           }
1440         }
1441       }
1442     }
1443   }
1444 }
1445 
DecodeLDC(Word Index)1446 static void DecodeLDC(Word Index)
1447 {
1448   Byte HReg;
1449   UNUSED(Index);
1450 
1451   if (ChkArgCnt(2, 2))
1452   {
1453     DecodeAdr(&ArgStr[1], MModReg | MModXReg| MModCReg);
1454     HReg = AdrMode;
1455     switch (AdrType)
1456     {
1457       case ModReg:
1458         DecodeAdr(&ArgStr[2], MModCReg);
1459         if (AdrType != ModNone)
1460         {
1461           CodeLen = 3;
1462           BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
1463           BAsmCode[1] = 0x2f;
1464           BAsmCode[2] = AdrMode;
1465         }
1466         break;
1467       case ModXReg:
1468         DecodeAdr(&ArgStr[2], MModCReg);
1469         if (AdrType != ModNone)
1470         {
1471           CodeLen = 4;
1472           BAsmCode[0] = 0xc7 + (OpSize << 4);
1473           BAsmCode[1] = HReg;
1474           BAsmCode[2] = 0x2f;
1475           BAsmCode[3] = AdrMode;
1476         };
1477         break;
1478       case ModCReg:
1479         DecodeAdr(&ArgStr[2], MModReg | MModXReg);
1480         switch (AdrType)
1481         {
1482           case ModReg:
1483             CodeLen = 3;
1484             BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
1485             BAsmCode[1] = 0x2e;
1486             BAsmCode[2] = HReg;
1487             break;
1488           case ModXReg:
1489             CodeLen = 4;
1490             BAsmCode[0] = 0xc7 + (OpSize << 4);
1491             BAsmCode[1] = AdrMode;
1492             BAsmCode[2] = 0x2e;
1493             BAsmCode[3] = HReg;
1494             break;
1495         }
1496         break;
1497     }
1498   }
1499 }
1500 
DecodeLDX(Word Index)1501 static void DecodeLDX(Word Index)
1502 {
1503   Boolean OK;
1504   UNUSED(Index);
1505 
1506   if (ChkArgCnt(2, 2))
1507   {
1508     DecodeAdr(&ArgStr[1], MModMem);
1509     if (AdrType != ModNone)
1510     {
1511       if (AdrMode != 0x40) WrError(ErrNum_InvAddrMode);
1512       else
1513       {
1514         BAsmCode[4] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
1515         if (OK)
1516         {
1517           CodeLen = 6;
1518           BAsmCode[0] = 0xf7;
1519           BAsmCode[1] = 0;
1520           BAsmCode[2] = AdrVals[0];
1521           BAsmCode[3] = 0;
1522           BAsmCode[5] = 0;
1523         }
1524       }
1525     }
1526   }
1527 }
1528 
DecodeLINK(Word Index)1529 static void DecodeLINK(Word Index)
1530 {
1531   Word AdrWord;
1532   Boolean OK;
1533   UNUSED(Index);
1534 
1535   if (ChkArgCnt(2, 2))
1536   {
1537     AdrWord = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
1538     if (OK)
1539     {
1540       DecodeAdr(&ArgStr[1], MModReg | MModXReg);
1541       if ((AdrType != ModNone) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
1542       else
1543        switch (AdrType)
1544        {
1545          case ModReg:
1546            CodeLen = 4;
1547            BAsmCode[0] = 0xe8 + AdrMode;
1548            BAsmCode[1] = 0x0c;
1549            BAsmCode[2] = Lo(AdrWord);
1550            BAsmCode[3] = Hi(AdrWord);
1551            break;
1552          case ModXReg:
1553            CodeLen = 5;
1554            BAsmCode[0] = 0xe7;
1555            BAsmCode[1] = AdrMode;
1556            BAsmCode[2] = 0x0c;
1557            BAsmCode[3] = Lo(AdrWord);
1558            BAsmCode[4] = Hi(AdrWord);
1559            break;
1560        }
1561     }
1562   }
1563 }
1564 
DecodeLD(Word Code)1565 static void DecodeLD(Word Code)
1566 {
1567   Byte HReg;
1568   Boolean ShDest, ShSrc, OK;
1569 
1570   SetInstrOpSize(Hi(Code));
1571 
1572   if (ChkArgCnt(2, 2))
1573   {
1574     DecodeAdr(&ArgStr[1], MModReg | MModXReg | MModMem);
1575     switch (AdrType)
1576     {
1577       case ModReg:
1578         HReg = AdrMode;
1579         DecodeAdr(&ArgStr[2], MModReg | MModXReg| MModMem| MModImm);
1580         switch (AdrType)
1581         {
1582           case ModReg:
1583             CodeLen = 2;
1584             BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
1585             BAsmCode[1] = 0x88 + HReg;
1586             break;
1587           case ModXReg:
1588             CodeLen = 3;
1589             BAsmCode[0] = 0xc7 + (OpSize << 4);
1590             BAsmCode[1] = AdrMode;
1591             BAsmCode[2] = 0x88 + HReg;
1592             break;
1593           case ModMem:
1594             CodeLen = 2 + AdrCnt;
1595             BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
1596             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1597             BAsmCode[1 + AdrCnt] = 0x20 + HReg;
1598             break;
1599           case ModImm:
1600           {
1601             LongInt ImmValue = ImmVal();
1602 
1603             if ((ImmValue <= 7) && (ImmValue >= 0))
1604             {
1605               CodeLen = 2;
1606               BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
1607               BAsmCode[1] = 0xa8 + AdrVals[0];
1608             }
1609             else
1610             {
1611               CodeLen = 1 + AdrCnt;
1612               BAsmCode[0] = ((OpSize + 2) << 4) + HReg;
1613               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1614             }
1615             break;
1616           }
1617         }
1618         break;
1619       case ModXReg:
1620         HReg = AdrMode;
1621         DecodeAdr(&ArgStr[2], MModReg + MModImm);
1622         switch (AdrType)
1623         {
1624           case ModReg:
1625             CodeLen = 3;
1626             BAsmCode[0] = 0xc7 + (OpSize << 4);
1627             BAsmCode[1] = HReg;
1628             BAsmCode[2] = 0x98 + AdrMode;
1629             break;
1630           case ModImm:
1631           {
1632             LongInt ImmValue = ImmVal();
1633 
1634             if ((ImmValue <= 7) && (ImmValue >= 0))
1635             {
1636               CodeLen = 3;
1637               BAsmCode[0] = 0xc7 + (OpSize << 4);
1638               BAsmCode[1] = HReg;
1639               BAsmCode[2] = 0xa8 + AdrVals[0];
1640             }
1641             else
1642             {
1643               CodeLen = 3 + AdrCnt;
1644               BAsmCode[0] = 0xc7 + (OpSize << 4);
1645               BAsmCode[1] = HReg;
1646               BAsmCode[2] = 3;
1647               memcpy(BAsmCode + 3, AdrVals, AdrCnt);
1648             }
1649             break;
1650           }
1651         }
1652         break;
1653       case ModMem:
1654       {
1655         Boolean FixupAutoIncSize = AutoIncSizeNeeded;
1656 
1657         BAsmCode[0] = AdrMode;
1658         HReg = AdrCnt;
1659         MinOneIs0 = True;
1660         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1661         DecodeAdr(&ArgStr[2], MModReg | MModMem | MModImm);
1662         switch (AdrType)
1663         {
1664          case ModReg:
1665            CodeLen = 2 + HReg;
1666            BAsmCode[0] += 0xb0;
1667            if (FixupAutoIncSize)
1668              SetAutoIncSize(0, 1);
1669            BAsmCode[1 + HReg] = 0x40 + (OpSize << 4) + AdrMode;
1670            break;
1671          case ModMem:
1672            if (OpSize == -1) OpSize = 0;
1673            ShDest = IsShort(BAsmCode[0]);
1674            ShSrc = IsShort(AdrMode);
1675            if (!(ShDest || ShSrc)) WrError(ErrNum_InvAddrMode);
1676            else
1677            {
1678              if ((ShDest && (!ShSrc))) OK = True;
1679              else if (ShSrc && (!ShDest)) OK = False;
1680              else if (AdrMode == 0x40) OK = True;
1681              else OK = False;
1682              if (OK)  /* dest=(dir8/16) */
1683              {
1684                CodeLen = 4 + AdrCnt;
1685                HReg = BAsmCode[0];
1686                BAsmCode[3 + AdrCnt] = (BAsmCode[0] == 0x40) ? 0 : BAsmCode[2];
1687                BAsmCode[2 + AdrCnt] = BAsmCode[1];
1688                BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
1689                AdrMode = HReg;
1690                if (FixupAutoIncSize)
1691                  SetAutoIncSize(0, 1);
1692                memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1693                BAsmCode[1 + AdrCnt] = 0x19;
1694              }
1695              else
1696              {
1697                CodeLen = 4 + HReg;
1698                BAsmCode[2 + HReg] = AdrVals[0];
1699                BAsmCode[3 + HReg] = (AdrMode == 0x40) ? 0 : AdrVals[1];
1700                BAsmCode[0] += 0xb0;
1701                if (FixupAutoIncSize)
1702                  SetAutoIncSize(0, 1);
1703                BAsmCode[1 + HReg] = 0x14 + (OpSize << 1);
1704              }
1705            }
1706            break;
1707          case ModImm:
1708           if (BAsmCode[0] == 0x40)
1709           {
1710             CodeLen = 2 + AdrCnt;
1711             BAsmCode[0] = 0x08 + (OpSize << 1);
1712             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1713           }
1714           else
1715           {
1716             CodeLen = 2 + HReg + AdrCnt;
1717             BAsmCode[0] += 0xb0;
1718             BAsmCode[1 + HReg] = OpSize << 1;
1719             memcpy(BAsmCode + 2 + HReg, AdrVals, AdrCnt);
1720           }
1721           break;
1722         }
1723         break;
1724       }
1725     }
1726   }
1727 }
1728 
DecodeFixed(Word Index)1729 static void DecodeFixed(Word Index)
1730 {
1731   FixedOrder *FixedZ = FixedOrders + Index;
1732 
1733   if (ChkArgCnt(0, 0)
1734    && (ChkExactCPUMask(FixedZ->CPUFlag, CPU96C141) >= 0))
1735   {
1736     if (Hi(FixedZ->Code) == 0)
1737     {
1738       CodeLen = 1;
1739       BAsmCode[0] = Lo(FixedZ->Code);
1740     }
1741     else
1742     {
1743       CodeLen = 2;
1744       BAsmCode[0] = Hi(FixedZ->Code);
1745       BAsmCode[1] = Lo(FixedZ->Code);
1746     }
1747     if (FixedZ->InSup)
1748       CheckSup();
1749   }
1750 }
1751 
DecodeImm(Word Index)1752 static void DecodeImm(Word Index)
1753 {
1754   ImmOrder *ImmZ = ImmOrders + Index;
1755   Word AdrWord;
1756   Boolean OK;
1757 
1758   if (ChkArgCnt((ImmZ->Default == -1) ? 1 : 0, 1))
1759   {
1760     if (ArgCnt == 0)
1761     {
1762       AdrWord = ImmZ->Default;
1763       OK = True;
1764     }
1765     else
1766       AdrWord = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
1767     if (OK)
1768     {
1769       if (((Maximum) && (AdrWord > ImmZ->MaxMax)) || ((!Maximum) && (AdrWord > ImmZ->MinMax))) WrError(ErrNum_OverRange);
1770       else if (Hi(ImmZ->Code) == 0)
1771       {
1772         CodeLen = 1;
1773         BAsmCode[0] = Lo(ImmZ->Code) + AdrWord;
1774       }
1775       else
1776       {
1777         CodeLen = 2;
1778         BAsmCode[0] = Hi(ImmZ->Code);
1779         BAsmCode[1] = Lo(ImmZ->Code) + AdrWord;
1780       }
1781     }
1782     if (ImmZ->InSup)
1783       CheckSup();
1784   }
1785 }
1786 
1787 static void DecodeALU2(Word Code);
1788 
DecodeReg(Word Index)1789 static void DecodeReg(Word Index)
1790 {
1791   RegOrder *RegZ = RegOrders + Index;
1792 
1793   /* dispatch to CPL as compare-long with two args: */
1794 
1795   if ((Memo("CPL")) && (ArgCnt >= 2))
1796   {
1797     DecodeALU2(0x0207);
1798     return;
1799   }
1800 
1801   if (ChkArgCnt(1, 1))
1802   {
1803     DecodeAdr(&ArgStr[1], MModReg | MModXReg);
1804     if (AdrType != ModNone)
1805     {
1806       if (((1 << OpSize) & RegZ->OpMask) == 0) WrError(ErrNum_InvOpSize);
1807       else if (AdrType == ModReg)
1808       {
1809         BAsmCode[0] = Hi(RegZ->Code) + 8 + (OpSize << 4) + AdrMode;
1810         BAsmCode[1] = Lo(RegZ->Code);
1811         CodeLen = 2;
1812       }
1813       else
1814       {
1815         BAsmCode[0] = Hi(RegZ->Code) + 7 + (OpSize << 4);
1816         BAsmCode[1] = AdrMode;
1817         BAsmCode[2] = Lo(RegZ->Code);
1818         CodeLen = 3;
1819       }
1820     }
1821   }
1822 }
1823 
DecodeALU2(Word Code)1824 static void DecodeALU2(Word Code)
1825 {
1826   Byte HReg;
1827 
1828   SetInstrOpSize(Hi(Code));
1829   if (ChkArgCnt(2, 2))
1830   {
1831     DecodeAdr(&ArgStr[1], MModReg | MModXReg | MModMem);
1832     switch (AdrType)
1833     {
1834       case ModReg:
1835         HReg=AdrMode;
1836         DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem | MModImm);
1837         switch (AdrType)
1838         {
1839           case ModReg:
1840             CodeLen = 2;
1841             BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
1842             BAsmCode[1] = 0x80 + (Lo(Code) << 4) + HReg;
1843             break;
1844           case ModXReg:
1845             CodeLen = 3;
1846             BAsmCode[0] = 0xc7 + (OpSize << 4);
1847             BAsmCode[1] = AdrMode;
1848             BAsmCode[2] = 0x80 + (Lo(Code) << 4) + HReg;
1849             break;
1850           case ModMem:
1851             CodeLen = 2 + AdrCnt;
1852             BAsmCode[0] = 0x80 + AdrMode + (OpSize << 4);
1853             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1854             BAsmCode[1 + AdrCnt] = 0x80 + HReg + (Lo(Code) << 4);
1855             break;
1856           case ModImm:
1857             if ((Lo(Code) == 7) && (OpSize != 2) && (ImmVal() <= 7) && (ImmVal() >= 0))
1858             {
1859               CodeLen = 2;
1860               BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
1861               BAsmCode[1] = 0xd8 + AdrVals[0];
1862             }
1863             else
1864             {
1865               CodeLen = 2 + AdrCnt;
1866               BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
1867               BAsmCode[1] = 0xc8 + Lo(Code);
1868               memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1869             }
1870             break;
1871         }
1872         break;
1873       case ModXReg:
1874         HReg = AdrMode;
1875         DecodeAdr(&ArgStr[2], MModImm);
1876         switch (AdrType)
1877         {
1878           case ModImm:
1879             if ((Lo(Code) == 7) && (OpSize != 2) && (ImmVal() <= 7) && (ImmVal() >= 0))
1880             {
1881               CodeLen = 3;
1882               BAsmCode[0] = 0xc7 + (OpSize << 4);
1883               BAsmCode[1] = HReg;
1884               BAsmCode[2] = 0xd8 + AdrVals[0];
1885             }
1886             else
1887             {
1888               CodeLen = 3 + AdrCnt;
1889               BAsmCode[0] = 0xc7 + (OpSize << 4);
1890               BAsmCode[1] = HReg;
1891               BAsmCode[2] = 0xc8 + Lo(Code);
1892               memcpy(BAsmCode + 3, AdrVals, AdrCnt);
1893             }
1894             break;
1895         }
1896         break;
1897       case ModMem:
1898       {
1899         Boolean FixupAutoIncSize = AutoIncSizeNeeded;
1900 
1901         MinOneIs0 = True;
1902         HReg = AdrCnt;
1903         BAsmCode[0] = AdrMode;
1904         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1905         DecodeAdr(&ArgStr[2], MModReg | MModImm);
1906         switch (AdrType)
1907         {
1908           case ModReg:
1909             CodeLen = 2 + HReg;
1910             if (FixupAutoIncSize)
1911               SetAutoIncSize(0, 1);
1912             BAsmCode[0] += 0x80 + (OpSize << 4);
1913             BAsmCode[1 + HReg] = 0x88 + (Lo(Code) << 4) + AdrMode;
1914             break;
1915           case ModImm:
1916             CodeLen = 2 + HReg + AdrCnt;
1917             BAsmCode[0] += 0x80 + (OpSize << 4);
1918             BAsmCode[1 + HReg] = 0x38 + Lo(Code);
1919             memcpy(BAsmCode + 2 + HReg, AdrVals, AdrCnt);
1920             break;
1921         };
1922         break;
1923       }
1924     }
1925   }
1926 }
1927 
DecodePUSH_POP(Word Code)1928 static void DecodePUSH_POP(Word Code)
1929 {
1930   SetInstrOpSize(Hi(Code));
1931 
1932   if (!ChkArgCnt(1, 1));
1933   else if (!as_strcasecmp(ArgStr[1].Str, "F"))
1934   {
1935     CodeLen = 1;
1936     BAsmCode[0] = 0x18 + Lo(Code);
1937   }
1938   else if (!as_strcasecmp(ArgStr[1].Str, "A"))
1939   {
1940     CodeLen = 1;
1941     BAsmCode[0] = 0x14 + Lo(Code);
1942   }
1943   else if (!as_strcasecmp(ArgStr[1].Str, "SR"))
1944   {
1945     CodeLen = 1;
1946     BAsmCode[0] = 0x02 + Lo(Code);
1947     CheckSup();
1948   }
1949   else
1950   {
1951     MinOneIs0 = True;
1952     DecodeAdr(&ArgStr[1], MModReg | MModXReg | MModMem | (Lo(Code) ? 0 : MModImm));
1953     switch (AdrType)
1954     {
1955       case ModReg:
1956         if (OpSize == 0)
1957         {
1958           CodeLen = 2;
1959           BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
1960           BAsmCode[1] = 0x04 + Lo(Code);
1961         }
1962         else
1963         {
1964           CodeLen = 1;
1965           BAsmCode[0] = 0x28 + (Lo(Code) << 5) + ((OpSize - 1) << 4) + AdrMode;
1966         }
1967         break;
1968       case ModXReg:
1969         CodeLen = 3;
1970         BAsmCode[0] = 0xc7 + (OpSize << 4);
1971         BAsmCode[1] = AdrMode;
1972         BAsmCode[2] = 0x04 + Lo(Code);
1973         break;
1974       case ModMem:
1975         if (OpSize == -1)
1976           OpSize=0;
1977         CodeLen = 2 + AdrCnt;
1978         if (Lo(Code))
1979           BAsmCode[0] = 0xb0 + AdrMode;
1980         else
1981           BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
1982         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1983         if (Lo(Code))
1984           BAsmCode[1 + AdrCnt] = 0x04 + (OpSize << 1);
1985         else
1986           BAsmCode[1 + AdrCnt] = 0x04;
1987         break;
1988       case ModImm:
1989         if (OpSize == -1)
1990           OpSize = 0;
1991         BAsmCode[0] = 9 + (OpSize << 1);
1992         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1993         CodeLen = 1 + AdrCnt;
1994         break;
1995     }
1996   }
1997 }
1998 
DecodeShift(Word Code)1999 static void DecodeShift(Word Code)
2000 {
2001   Boolean OK;
2002   tSymbolFlags Flags;
2003   Byte HReg;
2004 
2005   SetInstrOpSize(Hi(Code));
2006 
2007   if (ChkArgCnt(1, 2))
2008   {
2009     OK = True;
2010     if (ArgCnt == 1)
2011       HReg = 1;
2012     else if (!as_strcasecmp(ArgStr[1].Str, "A"))
2013       HReg = 0xff;
2014     else
2015     {
2016       HReg = EvalStrIntExpressionWithFlags(&ArgStr[1], Int8, &OK, &Flags);
2017       if (OK)
2018       {
2019         if (mFirstPassUnknown(Flags))
2020           HReg &= 0x0f;
2021         else
2022         {
2023           if ((HReg == 0) || (HReg > 16))
2024           {
2025             WrError(ErrNum_OverRange);
2026             OK = False;
2027           }
2028           else
2029             HReg &= 0x0f;
2030         }
2031       }
2032     }
2033     if (OK)
2034     {
2035       DecodeAdr(&ArgStr[ArgCnt], MModReg | MModXReg | ((HReg == 0xff) ? 0 : MModMem));
2036       switch (AdrType)
2037       {
2038         case ModReg:
2039           CodeLen = 2 + Ord(HReg != 0xff);
2040           BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
2041           BAsmCode[1] = 0xe8 + Lo(Code);
2042           CodeLen = 2;
2043           if (HReg == 0xff)
2044             BAsmCode[1] += 0x10;
2045           else
2046             BAsmCode[CodeLen++] = HReg;
2047           break;
2048         case ModXReg:
2049           BAsmCode[0] = 0xc7+(OpSize << 4);
2050           BAsmCode[1] = AdrMode;
2051           BAsmCode[2] = 0xe8 + Lo(Code);
2052           CodeLen = 3;
2053           if (HReg == 0xff)
2054             BAsmCode[2] += 0x10;
2055           else
2056             BAsmCode[CodeLen++] = HReg;
2057           break;
2058         case ModMem:
2059           if (HReg != 1) WrError(ErrNum_InvAddrMode);
2060           else
2061           {
2062             if (OpSize == -1)
2063               OpSize = 0;
2064             CodeLen = 2 + AdrCnt;
2065             BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
2066             memcpy(BAsmCode + 1 , AdrVals, AdrCnt);
2067             BAsmCode[1 + AdrCnt] = 0x78 + Lo(Code);
2068           }
2069           break;
2070       }
2071     }
2072   }
2073 }
2074 
DecodeMulDiv(Word Code)2075 static void DecodeMulDiv(Word Code)
2076 {
2077   Byte HReg;
2078 
2079   if (ChkArgCnt(2, 2))
2080   {
2081     DecodeAdr(&ArgStr[1], MModReg | MModXReg);
2082     if (OpSize == 0) WrError(ErrNum_InvOpSize);
2083     else
2084     {
2085       if ((AdrType == ModReg) && (OpSize == 1))
2086       {
2087         if (AdrMode > 3)
2088         {
2089           AdrType = ModXReg;
2090           AdrMode = 0xe0 + (AdrMode << 2);
2091         }
2092         else
2093           AdrMode += 1 + AdrMode;
2094       }
2095       OpSize--;
2096       HReg = AdrMode;
2097       switch (AdrType)
2098       {
2099         case ModReg:
2100           DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem | MModImm);
2101           switch (AdrType)
2102           {
2103             case ModReg:
2104               CodeLen = 2;
2105               BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
2106               BAsmCode[1] = 0x40 + (Code << 3) + HReg;
2107               break;
2108             case ModXReg:
2109               CodeLen = 3;
2110               BAsmCode[0] = 0xc7 + (OpSize << 4);
2111               BAsmCode[1] = AdrMode;
2112               BAsmCode[2] = 0x40 + (Code << 3) + HReg;
2113               break;
2114             case ModMem:
2115               CodeLen = 2 + AdrCnt;
2116               BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
2117               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
2118               BAsmCode[1 + AdrCnt] = 0x40 + (Code << 3) + HReg;
2119               break;
2120             case ModImm:
2121               CodeLen = 2 + AdrCnt;
2122               BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
2123               BAsmCode[1] = 0x08 + Code;
2124               memcpy(BAsmCode + 2, AdrVals, AdrCnt);
2125               break;
2126           }
2127           break;
2128         case ModXReg:
2129           DecodeAdr(&ArgStr[2], MModImm);
2130           if (AdrType == ModImm)
2131           {
2132             CodeLen = 3 + AdrCnt;
2133             BAsmCode[0] = 0xc7 + (OpSize << 4);
2134             BAsmCode[1] = HReg;
2135             BAsmCode[2] = 0x08 + Code;
2136             memcpy(BAsmCode + 3, AdrVals, AdrCnt);
2137           }
2138           break;
2139       }
2140     }
2141   }
2142 }
2143 
DecodeBitCF(Word Code)2144 static void DecodeBitCF(Word Code)
2145 {
2146   Boolean OK;
2147   Byte BitPos;
2148 
2149   if (ChkArgCnt(2, 2))
2150   {
2151     DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem);
2152     if (AdrType!=ModNone)
2153     {
2154       if (OpSize == 2) WrError(ErrNum_InvOpSize);
2155       else
2156       {
2157         if (AdrType == ModMem)
2158           OpSize = 0;
2159         if (!as_strcasecmp(ArgStr[1].Str, "A"))
2160         {
2161           BitPos = 0xff;
2162           OK = True;
2163         }
2164         else
2165           BitPos = EvalStrIntExpression(&ArgStr[1], (OpSize == 0) ? UInt3 : Int4, &OK);
2166         if (OK)
2167          switch (AdrType)
2168          {
2169            case ModReg:
2170              BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
2171              BAsmCode[1] = 0x20 + Code;
2172              CodeLen = 2;
2173              if (BitPos == 0xff)
2174                BAsmCode[1] |= 0x08;
2175              else
2176                BAsmCode[CodeLen++] = BitPos;
2177              break;
2178            case ModXReg:
2179              BAsmCode[0] = 0xc7 + (OpSize << 4);
2180              BAsmCode[1] = AdrMode;
2181              BAsmCode[2] = 0x20 + Code;
2182              CodeLen = 3;
2183              if (BitPos == 0xff)
2184                BAsmCode[2] |= 0x08;
2185              else
2186                BAsmCode[CodeLen++] = BitPos;
2187              break;
2188            case ModMem:
2189              CodeLen = 2 + AdrCnt;
2190              BAsmCode[0] = 0xb0 + AdrMode;
2191              memcpy(BAsmCode + 1, AdrVals, AdrCnt);
2192              BAsmCode[1 + AdrCnt] = (BitPos == 0xff)
2193                                   ? 0x28 + Code
2194                                   : 0x80 + (Code << 3) + BitPos;
2195              break;
2196          }
2197       }
2198     }
2199   }
2200 }
2201 
DecodeBit(Word Code)2202 static void DecodeBit(Word Code)
2203 {
2204   Boolean OK;
2205   Byte BitPos;
2206 
2207   if (ChkArgCnt(2, 2))
2208   {
2209     DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem);
2210     if (AdrType == ModMem)
2211       OpSize = 0;
2212     if (AdrType != ModNone)
2213     {
2214       if (OpSize == 2) WrError(ErrNum_InvOpSize);
2215       else
2216       {
2217         BitPos = EvalStrIntExpression(&ArgStr[1], (OpSize == 0) ? UInt3 : Int4, &OK);
2218         if (OK)
2219         {
2220           switch (AdrType)
2221           {
2222             case ModReg:
2223               CodeLen = 3;
2224               BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
2225               BAsmCode[1] = 0x30 + Code;
2226               BAsmCode[2] = BitPos;
2227               break;
2228             case ModXReg:
2229               CodeLen = 4;
2230               BAsmCode[0] = 0xc7 + (OpSize << 4);
2231               BAsmCode[1] = AdrMode;
2232               BAsmCode[2] = 0x30 + Code;
2233               BAsmCode[3] = BitPos;
2234               break;
2235             case ModMem:
2236               CodeLen = 2 + AdrCnt;
2237               Code = (Code == 4) ? 0 : Code + 1;
2238               BAsmCode[0] = 0xb0 + AdrMode;
2239               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
2240               BAsmCode[1 + AdrCnt] = 0xa8 + (Code << 3) + BitPos;
2241               break;
2242           }
2243         }
2244       }
2245     }
2246   }
2247 }
2248 
DecodeINC_DEC(Word Code)2249 static void DecodeINC_DEC(Word Code)
2250 {
2251   Boolean OK;
2252   Byte Incr;
2253   tSymbolFlags Flags;
2254 
2255   SetInstrOpSize(Hi(Code));
2256 
2257   if (ChkArgCnt(1, 2))
2258   {
2259     if (ArgCnt == 1)
2260     {
2261       Incr = 1;
2262       OK = True;
2263       Flags = eSymbolFlag_None;
2264     }
2265     else
2266       Incr = EvalStrIntExpressionWithFlags(&ArgStr[1], Int4, &OK, &Flags);
2267     if (OK)
2268     {
2269       if (mFirstPassUnknown(Flags))
2270         Incr &= 7;
2271       else if ((Incr < 1) || (Incr > 8))
2272       {
2273         WrError(ErrNum_OverRange);
2274         OK = False;
2275       }
2276     }
2277     if (OK)
2278     {
2279       Incr &= 7;    /* 8-->0 */
2280       DecodeAdr(&ArgStr[ArgCnt], MModReg | MModXReg | MModMem);
2281       switch (AdrType)
2282       {
2283         case ModReg:
2284           CodeLen = 2;
2285           BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
2286           BAsmCode[1] = 0x60 + (Lo(Code) << 3) + Incr;
2287           break;
2288         case ModXReg:
2289           CodeLen = 3;
2290           BAsmCode[0] = 0xc7 + (OpSize << 4);
2291           BAsmCode[1] = AdrMode;
2292           BAsmCode[2] = 0x60 + (Lo(Code) << 3) + Incr;
2293           break;
2294         case ModMem:
2295           if (OpSize == -1)
2296             OpSize = 0;
2297           CodeLen = 2 + AdrCnt;
2298           BAsmCode[0] = 0x80 + AdrMode + (OpSize << 4);
2299           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
2300           BAsmCode[1 + AdrCnt] = 0x60 + (Lo(Code) << 3) + Incr;
2301           break;
2302       }
2303     }
2304   }
2305 }
2306 
DecodeCPxx(Word Code)2307 static void DecodeCPxx(Word Code)
2308 {
2309   Boolean OK;
2310 
2311   if (ChkArgCntExtEitherOr(ArgCnt, 0, 2))
2312   {
2313     OK = True;
2314     if (ArgCnt == 0)
2315     {
2316       OpSize = 0;
2317       AdrMode = 3;
2318     }
2319     else
2320     {
2321       Byte HReg;
2322       int l = strlen(ArgStr[2].Str);
2323       const char *CmpStr;
2324 
2325       if (!as_strcasecmp(ArgStr[1].Str, "A"))
2326         OpSize = 0;
2327       else if (!as_strcasecmp(ArgStr[1].Str, "WA"))
2328         OpSize = 1;
2329       CmpStr = (Code & 0x02) ? "-)" : "+)";
2330       if (OpSize == -1) OK = False;
2331       else if ((l < 2) || (*ArgStr[2].Str != '(') || (as_strcasecmp(ArgStr[2].Str + l - 2, CmpStr))) OK = False;
2332       else
2333       {
2334         ArgStr[2].Str[l - 2] = '\0';
2335         if (CodeEReg(ArgStr[2].Str + 1, &AdrMode, &HReg) != 2) OK = False;
2336         else if (!IsRegBase(AdrMode, HReg)) OK = False;
2337         else if (!IsRegCurrent(AdrMode, HReg, &AdrMode)) OK = False;
2338       }
2339       if (!OK)
2340         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
2341     }
2342     if (OK)
2343     {
2344       CodeLen = 2;
2345       BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
2346       BAsmCode[1] = Code;
2347     }
2348   }
2349 }
2350 
DecodeLDxx(Word Code)2351 static void DecodeLDxx(Word Code)
2352 {
2353   SetInstrOpSize(Hi(Code));
2354 
2355   if (OpSize == -1)
2356     OpSize = 0;
2357   if (OpSize == 2) WrError(ErrNum_InvOpSize);
2358   else if (ChkArgCntExtEitherOr(ArgCnt, 0, 2))
2359   {
2360     Boolean OK;
2361     Byte HReg = 0;
2362 
2363     if (ArgCnt == 0)
2364     {
2365       OK = True;
2366     }
2367     else
2368     {
2369       const char *CmpStr;
2370       int l1 = strlen(ArgStr[1].Str),
2371           l2 = strlen(ArgStr[2].Str);
2372 
2373       OK = True;
2374       CmpStr = (Code & 0x02) ? "-)" : "+)";
2375       if ((*ArgStr[1].Str != '(') || (*ArgStr[2].Str != '(')
2376        || (l1 < 3) || (l2 < 3)
2377        || (as_strcasecmp(ArgStr[1].Str + l1 - 2, CmpStr))
2378        || (as_strcasecmp(ArgStr[2].Str + l2 - 2, CmpStr)))
2379         OK = False;
2380       else
2381       {
2382         ArgStr[1].Str[l1 - 2] = '\0';
2383         ArgStr[2].Str[l2 - 2] = '\0';
2384         if ((!as_strcasecmp(ArgStr[1].Str + 1,"XIX")) && (!as_strcasecmp(ArgStr[2].Str + 1, "XIY")))
2385           HReg = 2;
2386         else if ((Maximum) && (!as_strcasecmp(ArgStr[1].Str + 1, "XDE")) && (!as_strcasecmp(ArgStr[2].Str + 1 , "XHL")));
2387         else if ((!Maximum) && (!as_strcasecmp(ArgStr[1].Str + 1, "DE")) && (!as_strcasecmp(ArgStr[2].Str + 1 , "HL")));
2388         else
2389           OK = False;
2390       }
2391     }
2392     if (!OK) WrError(ErrNum_InvAddrMode);
2393     else
2394     {
2395       CodeLen = 2;
2396       BAsmCode[0] = 0x83 + (OpSize << 4) + HReg;
2397       BAsmCode[1] = Lo(Code);
2398     }
2399   }
2400 }
2401 
DecodeMINC_MDEC(Word Code)2402 static void DecodeMINC_MDEC(Word Code)
2403 {
2404   if (ChkArgCnt(2, 2))
2405   {
2406     Word AdrWord;
2407     Boolean OK;
2408 
2409     AdrWord = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
2410     if (OK)
2411     {
2412       Byte Pwr;
2413       Byte ByteSizeLg2 = Code & 3, ByteSize = 1 << ByteSizeLg2;
2414 
2415       if (!IsPwr2(AdrWord, &Pwr)) WrStrErrorPos(ErrNum_NotPwr2, &ArgStr[1]);
2416       else if (Pwr <= ByteSizeLg2) WrStrErrorPos(ErrNum_UnderRange, &ArgStr[1]);
2417       else
2418       {
2419         AdrWord -= ByteSize;
2420         DecodeAdr(&ArgStr[2], MModReg | MModXReg);
2421         if ((AdrType != ModNone) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
2422         else
2423          switch (AdrType)
2424          {
2425            case ModReg:
2426              CodeLen = 4;
2427              BAsmCode[0] = 0xd8 + AdrMode;
2428              BAsmCode[1] = Code;
2429              BAsmCode[2] = Lo(AdrWord);
2430              BAsmCode[3] = Hi(AdrWord);
2431              break;
2432            case ModXReg:
2433              CodeLen = 5;
2434              BAsmCode[0] = 0xd7;
2435              BAsmCode[1] = AdrMode;
2436              BAsmCode[2] = Code;
2437              BAsmCode[3] = Lo(AdrWord);
2438              BAsmCode[4] = Hi(AdrWord);
2439              break;
2440          }
2441       }
2442     }
2443   }
2444 }
2445 
DecodeRLD_RRD(Word Code)2446 static void DecodeRLD_RRD(Word Code)
2447 {
2448   if (!ChkArgCnt(1, 2));
2449   else if ((ArgCnt == 2) && (as_strcasecmp(ArgStr[1].Str, "A"))) WrError(ErrNum_InvAddrMode);
2450   else
2451   {
2452     DecodeAdr(&ArgStr[ArgCnt], MModMem);
2453     if (AdrType != ModNone)
2454     {
2455       CodeLen = 2 + AdrCnt;
2456       BAsmCode[0] = 0x80 + AdrMode;
2457       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
2458       BAsmCode[1 + AdrCnt] = Code;
2459     }
2460   }
2461 }
2462 
DecodeSCC(Word Code)2463 static void DecodeSCC(Word Code)
2464 {
2465   UNUSED(Code);
2466 
2467   if (ChkArgCnt(2, 2))
2468   {
2469     int Cond = DecodeCondition(ArgStr[1].Str);
2470     if (Cond >= ConditionCnt) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
2471     else
2472     {
2473       DecodeAdr(&ArgStr[2], MModReg | MModXReg);
2474       if (OpSize > 1) WrError(ErrNum_UndefOpSizes);
2475       else
2476       {
2477          switch (AdrType)
2478          {
2479            case ModReg:
2480              CodeLen = 2;
2481              BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
2482              BAsmCode[1] = 0x70 + Conditions[Cond].Code;
2483              break;
2484            case ModXReg:
2485              CodeLen = 3;
2486              BAsmCode[0] = 0xc7 + (OpSize << 4);
2487              BAsmCode[1] = AdrMode;
2488              BAsmCode[2] = 0x70 + Conditions[Cond].Code;
2489              break;
2490          }
2491       }
2492     }
2493   }
2494   return;
2495 }
2496 
2497 /*---------------------------------------------------------------------------*/
2498 
AddSize(const char * NName,Byte NCode,InstProc Proc,Word SizeMask)2499 static void AddSize(const char *NName, Byte NCode, InstProc Proc, Word SizeMask)
2500 {
2501   int l;
2502   char SizeName[20];
2503 
2504   AddInstTable(InstTable, NName, 0xff00 | NCode, Proc);
2505   l = as_snprintf(SizeName, sizeof(SizeName), "%sB", NName);
2506   if (SizeMask & 1)
2507     AddInstTable(InstTable, SizeName, 0x0000 | NCode, Proc);
2508   if (SizeMask & 2)
2509   {
2510     SizeName[l - 1] = 'W';
2511     AddInstTable(InstTable, SizeName, 0x0100 | NCode, Proc);
2512   }
2513 
2514   /* CP(L) would generate conflict with CPL instruction - dispatch
2515      it from CPL single-op instruction if ArgCnt >= 2! */
2516 
2517   if ((SizeMask & 4) && (strcmp(NName, "CP")))
2518   {
2519     SizeName[l - 1] = 'L';
2520     AddInstTable(InstTable, SizeName, 0x0200 | NCode, Proc);
2521   }
2522 }
2523 
AddMod(const char * NName,Byte NCode)2524 static void AddMod(const char *NName, Byte NCode)
2525 {
2526   int l;
2527   char SizeName[20];
2528 
2529   l = as_snprintf(SizeName, sizeof(SizeName), "%s1", NName);
2530   AddInstTable(InstTable, SizeName, NCode, DecodeMINC_MDEC);
2531   SizeName[l - 1] = '2';
2532   AddInstTable(InstTable, SizeName, NCode | 1, DecodeMINC_MDEC);
2533   SizeName[l - 1] = '4';
2534   AddInstTable(InstTable, SizeName, NCode | 2, DecodeMINC_MDEC);
2535 }
2536 
AddFixed(const char * NName,Word NCode,Byte NFlag,Boolean NSup)2537 static void AddFixed(const char *NName, Word NCode, Byte NFlag, Boolean NSup)
2538 {
2539   if (InstrZ >= FixedOrderCnt) exit(255);
2540   FixedOrders[InstrZ].Code = NCode;
2541   FixedOrders[InstrZ].CPUFlag = NFlag;
2542   FixedOrders[InstrZ].InSup = NSup;
2543   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
2544 }
2545 
AddReg(const char * NName,Word NCode,Byte NMask)2546 static void AddReg(const char *NName, Word NCode, Byte NMask)
2547 {
2548   if (InstrZ >= RegOrderCnt) exit(255);
2549   RegOrders[InstrZ].Code = NCode;
2550   RegOrders[InstrZ].OpMask = NMask;
2551   AddInstTable(InstTable, NName, InstrZ++, DecodeReg);
2552 }
2553 
AddImm(const char * NName,Word NCode,Boolean NInSup,Byte NMinMax,Byte NMaxMax,ShortInt NDefault)2554 static void AddImm(const char *NName, Word NCode, Boolean NInSup,
2555                    Byte NMinMax, Byte NMaxMax, ShortInt NDefault)
2556 {
2557   if (InstrZ >= ImmOrderCnt) exit(255);
2558   ImmOrders[InstrZ].Code = NCode;
2559   ImmOrders[InstrZ].InSup = NInSup;
2560   ImmOrders[InstrZ].MinMax = NMinMax;
2561   ImmOrders[InstrZ].MaxMax = NMaxMax;
2562   ImmOrders[InstrZ].Default = NDefault;
2563   AddInstTable(InstTable, NName, InstrZ++, DecodeImm);
2564 }
2565 
AddALU2(const char * NName,Byte NCode)2566 static void AddALU2(const char *NName, Byte NCode)
2567 {
2568   AddSize(NName, NCode, DecodeALU2, 7);
2569 }
2570 
AddShift(const char * NName)2571 static void AddShift(const char *NName)
2572 {
2573   AddSize(NName, InstrZ++, DecodeShift, 7);
2574 }
2575 
AddMulDiv(const char * NName)2576 static void AddMulDiv(const char *NName)
2577 {
2578   AddInstTable(InstTable, NName, InstrZ++, DecodeMulDiv);
2579 }
2580 
AddBitCF(const char * NName,Byte NCode)2581 static void AddBitCF(const char *NName, Byte NCode)
2582 {
2583   AddInstTable(InstTable, NName, NCode, DecodeBitCF);
2584 }
2585 
AddBit(const char * NName)2586 static void AddBit(const char *NName)
2587 {
2588   AddInstTable(InstTable, NName, InstrZ++, DecodeBit);
2589 }
2590 
AddCondition(const char * NName,Byte NCode)2591 static void AddCondition(const char *NName, Byte NCode)
2592 {
2593   if (InstrZ >= ConditionCnt) exit(255);
2594   Conditions[InstrZ].Name = NName;
2595   Conditions[InstrZ++].Code = NCode;
2596 }
2597 
InitFields(void)2598 static void InitFields(void)
2599 {
2600   InstTable = CreateInstTable(301);
2601   SetDynamicInstTable(InstTable);
2602 
2603   AddInstTable(InstTable, "MULA"  , 0, DecodeMULA);
2604   AddInstTable(InstTable, "JP"    , 0, DecodeJPCALL);
2605   AddInstTable(InstTable, "CALL"  , 1, DecodeJPCALL);
2606   AddInstTable(InstTable, "JR"    , 0, DecodeJR);
2607   AddInstTable(InstTable, "JRL"   , 1, DecodeJR);
2608   AddInstTable(InstTable, "CALR"  , 0, DecodeCALR);
2609   AddInstTable(InstTable, "RET"   , 0, DecodeRET);
2610   AddInstTable(InstTable, "RETD"  , 0, DecodeRETD);
2611   AddInstTable(InstTable, "DJNZ"  , 0, DecodeDJNZ);
2612   AddInstTable(InstTable, "EX"    , 0, DecodeEX);
2613   AddInstTable(InstTable, "BS1F"  , 0, DecodeBS1x);
2614   AddInstTable(InstTable, "BS1B"  , 1, DecodeBS1x);
2615   AddInstTable(InstTable, "LDA"   , 0, DecodeLDA);
2616   AddInstTable(InstTable, "LDAR"  , 0, DecodeLDAR);
2617   AddInstTable(InstTable, "LDC"   , 0, DecodeLDC);
2618   AddInstTable(InstTable, "LDX"   , 0, DecodeLDX);
2619   AddInstTable(InstTable, "LINK"  , 0, DecodeLINK);
2620   AddSize("LD", 0, DecodeLD, 7);
2621   AddSize("PUSH", 0, DecodePUSH_POP, 7);
2622   AddSize("POP" , 1, DecodePUSH_POP, 7);
2623   AddSize("INC" , 0, DecodeINC_DEC, 7);
2624   AddSize("DEC" , 1, DecodeINC_DEC, 7);
2625   AddInstTable(InstTable, "CPI"  , 0x14, DecodeCPxx);
2626   AddInstTable(InstTable, "CPIR" , 0x15, DecodeCPxx);
2627   AddInstTable(InstTable, "CPD"  , 0x16, DecodeCPxx);
2628   AddInstTable(InstTable, "CPDR" , 0x17, DecodeCPxx);
2629   AddSize("LDI", 0x10 , DecodeLDxx, 3);
2630   AddSize("LDIR", 0x11, DecodeLDxx, 3);
2631   AddSize("LDD", 0x12 , DecodeLDxx, 3);
2632   AddSize("LDDR", 0x13, DecodeLDxx, 3);
2633   AddMod("MINC", 0x38);
2634   AddMod("MDEC", 0x3c);
2635   AddInstTable(InstTable, "RLD", 0x06, DecodeRLD_RRD);
2636   AddInstTable(InstTable, "RRD", 0x07, DecodeRLD_RRD);
2637   AddInstTable(InstTable, "SCC", 0, DecodeSCC);
2638 
2639   FixedOrders = (FixedOrder *) malloc(sizeof(FixedOrder) * FixedOrderCnt); InstrZ = 0;
2640   AddFixed("CCF"   , 0x0012, 3, False);
2641   AddFixed("DECF"  , 0x000d, 3, False);
2642   AddFixed("DI"    , 0x0607, 3, True );
2643   AddFixed("HALT"  , 0x0005, 3, True );
2644   AddFixed("INCF"  , 0x000c, 3, False);
2645   AddFixed("MAX"   , 0x0004, 1, True );
2646   AddFixed("MIN"   , 0x0004, 2, True );
2647   AddFixed("NOP"   , 0x0000, 3, False);
2648   AddFixed("NORMAL", 0x0001, 1, True );
2649   AddFixed("RCF"   , 0x0010, 3, False);
2650   AddFixed("RETI"  , 0x0007, 3, True );
2651   AddFixed("SCF"   , 0x0011, 3, False);
2652   AddFixed("ZCF"   , 0x0013, 3, False);
2653 
2654   RegOrders = (RegOrder *) malloc(sizeof(RegOrder) * RegOrderCnt); InstrZ = 0;
2655   AddReg("CPL" , 0xc006, 3);
2656   AddReg("DAA" , 0xc010, 1);
2657   AddReg("EXTS", 0xc013, 6);
2658   AddReg("EXTZ", 0xc012, 6);
2659   AddReg("MIRR", 0xc016, 2);
2660   AddReg("NEG" , 0xc007, 3);
2661   AddReg("PAA" , 0xc014, 6);
2662   AddReg("UNLK", 0xc00d, 4);
2663 
2664   ImmOrders = (ImmOrder *) malloc(sizeof(ImmOrder) * ImmOrderCnt); InstrZ = 0;
2665   AddImm("EI"  , 0x0600, True,  7, 7,  0);
2666   AddImm("LDF" , 0x1700, False, 7, 3, -1);
2667   AddImm("SWI" , 0x00f8, False, 7, 7,  7);
2668 
2669   AddALU2("ADC", 1);
2670   AddALU2("ADD", 0);
2671   AddALU2("AND", 4);
2672   AddALU2("OR" , 6);
2673   AddALU2("SBC", 3);
2674   AddALU2("SUB", 2);
2675   AddALU2("XOR", 5);
2676   AddALU2("CP" , 7);
2677 
2678   InstrZ = 0;
2679   AddShift("RLC");
2680   AddShift("RRC");
2681   AddShift("RL");
2682   AddShift("RR");
2683   AddShift("SLA");
2684   AddShift("SRA");
2685   AddShift("SLL");
2686   AddShift("SRL");
2687 
2688   InstrZ = 0;
2689   AddMulDiv("MUL");
2690   AddMulDiv("MULS");
2691   AddMulDiv("DIV");
2692   AddMulDiv("DIVS");
2693 
2694   AddBitCF("ANDCF" , 0);
2695   AddBitCF("LDCF"  , 3);
2696   AddBitCF("ORCF"  , 1);
2697   AddBitCF("STCF"  , 4);
2698   AddBitCF("XORCF" , 2);
2699 
2700   InstrZ = 0;
2701   AddBit("RES");
2702   AddBit("SET");
2703   AddBit("CHG");
2704   AddBit("BIT");
2705   AddBit("TSET");
2706 
2707   Conditions = (Condition *) malloc(sizeof(Condition) * ConditionCnt); InstrZ = 0;
2708   AddCondition("F"   ,  0);
2709   DefaultCondition = InstrZ;  AddCondition("T"   ,  8);
2710   AddCondition("Z"   ,  6); AddCondition("NZ"  , 14);
2711   AddCondition("C"   ,  7); AddCondition("NC"  , 15);
2712   AddCondition("PL"  , 13); AddCondition("MI"  ,  5);
2713   AddCondition("P"   , 13); AddCondition("M"   ,  5);
2714   AddCondition("NE"  , 14); AddCondition("EQ"  ,  6);
2715   AddCondition("OV"  ,  4); AddCondition("NOV" , 12);
2716   AddCondition("PE"  ,  4); AddCondition("PO"  , 12);
2717   AddCondition("GE"  ,  9); AddCondition("LT"  ,  1);
2718   AddCondition("GT"  , 10); AddCondition("LE"  ,  2);
2719   AddCondition("UGE" , 15); AddCondition("ULT" ,  7);
2720   AddCondition("UGT" , 11); AddCondition("ULE" ,  3);
2721 }
2722 
DeinitFields(void)2723 static void DeinitFields(void)
2724 {
2725   DestroyInstTable(InstTable);
2726   free(FixedOrders);
2727   free(RegOrders);
2728   free(ImmOrders);
2729   free(Conditions);
2730 }
2731 
MakeCode_96C141(void)2732 static void MakeCode_96C141(void)
2733 {
2734   CodeLen = 0;
2735   DontPrint = False;
2736   OpSize = -1;
2737   MinOneIs0 = False;
2738 
2739   /* zu ignorierendes */
2740 
2741   if (Memo("")) return;
2742 
2743   /* Pseudoanweisungen */
2744 
2745   if (DecodeIntelPseudo(False)) return;
2746 
2747   /* vermischt */
2748 
2749   if (!LookupInstTable(InstTable, OpPart.Str))
2750     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2751 }
2752 
ChkPC_96C141(LargeWord Addr)2753 static Boolean ChkPC_96C141(LargeWord Addr)
2754 {
2755   Boolean ok;
2756 
2757   switch (ActPC)
2758   {
2759     case SegCode:
2760       if (Maximum) ok = (Addr <= 0xffffff);
2761               else ok = (Addr <= 0xffff);
2762       break;
2763     default:
2764       ok = False;
2765   }
2766   return (ok);
2767 }
2768 
2769 
IsDef_96C141(void)2770 static Boolean IsDef_96C141(void)
2771 {
2772   return False;
2773 }
2774 
SwitchFrom_96C141(void)2775 static void SwitchFrom_96C141(void)
2776 {
2777   DeinitFields();
2778   ClearONOFF();
2779 }
2780 
ChkMoreOneArg(void)2781 static Boolean ChkMoreOneArg(void)
2782 {
2783   return (ArgCnt > 1);
2784 }
2785 
SwitchTo_96C141(void)2786 static void SwitchTo_96C141(void)
2787 {
2788   TurnWords = False;
2789   ConstMode = ConstModeIntel;
2790   SetIsOccupiedFnc = ChkMoreOneArg;
2791 
2792   PCSymbol = "$";
2793   HeaderID = 0x52;
2794   NOPCode = 0x00;
2795   DivideChars = ",";
2796   HasAttrs = False;
2797 
2798   ValidSegs = (1 << SegCode);
2799   Grans[SegCode] = 1;
2800   ListGrans[SegCode] = 1;
2801   SegInits[SegCode] = 0;
2802 
2803   MakeCode = MakeCode_96C141;
2804   ChkPC = ChkPC_96C141;
2805   IsDef = IsDef_96C141;
2806   SwitchFrom = SwitchFrom_96C141;
2807   AddONOFF("MAXMODE", &Maximum   , MaximumName   , False);
2808   AddONOFF("SUPMODE", &SupAllowed, SupAllowedName, False);
2809 
2810   InitFields();
2811 }
2812 
code96c141_init(void)2813 void code96c141_init(void)
2814 {
2815   CPU96C141 = AddCPU("96C141", SwitchTo_96C141);
2816   CPU93C141 = AddCPU("93C141", SwitchTo_96C141);
2817 }
2818