1 /* code90c141.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS-Portierung                                                             */
6 /*                                                                           */
7 /* Codegenerator Toshiba TLCS-90                                             */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14 
15 #include "nls.h"
16 #include "bpemu.h"
17 #include "strutil.h"
18 #include "asmdef.h"
19 #include "asmsub.h"
20 #include "asmpars.h"
21 #include "asmitree.h"
22 #include "codepseudo.h"
23 #include "intpseudo.h"
24 #include "codevars.h"
25 #include "errmsg.h"
26 
27 #include "code90c141.h"
28 
29 typedef struct
30 {
31   const char *Name;
32   Byte Code;
33 } Condition;
34 
35 #define AccReg 6
36 #define HLReg 2
37 
38 #define ConditionCnt 24
39 
40 enum
41 {
42   ModNone = -1,
43   ModReg8 = 0,
44   ModReg16 = 1,
45   ModIReg16 = 2,
46   ModIndReg = 3,
47   ModIdxReg = 4,
48   ModDir = 5,
49   ModMem = 6,
50   ModImm = 7
51 };
52 
53 #define MModReg8   (1 << ModReg8)
54 #define MModReg16  (1 << ModReg16)
55 #define MModIReg16 (1 << ModIReg16)
56 #define MModIndReg (1 << ModIndReg)
57 #define MModIdxReg (1 << ModIdxReg)
58 #define MModDir    (1 << ModDir)
59 #define MModMem    (1 << ModMem)
60 #define MModImm    (1 << ModImm)
61 
62 static unsigned DefaultCondition;
63 
64 static ShortInt AdrType;
65 static Byte AdrMode;
66 static ShortInt OpSize;
67 static Byte AdrVals[10];
68 static Boolean MinOneIs0;
69 
70 static Condition *Conditions;
71 
72 static CPUVar CPU90C141;
73 
74 /*---------------------------------------------------------------------------*/
75 
SetOpSize(ShortInt New)76 static void SetOpSize(ShortInt New)
77 {
78   if (OpSize == -1)
79     OpSize = New;
80   else if (OpSize != New)
81   {
82     WrError(ErrNum_ConfOpSizes);
83     AdrType = ModNone;
84     AdrCnt = 0;
85   }
86 }
87 
DecodeAdr(const tStrComp * pArg,Byte Erl)88 static void DecodeAdr(const tStrComp *pArg, Byte Erl)
89 {
90   static const char Reg8Names[][2] = { "B", "C", "D", "E", "H", "L", "A" };
91   static const int Reg8Cnt = sizeof(Reg8Names) / sizeof(*Reg8Names);
92   static const char Reg16Names[][3] = { "BC", "DE", "HL", "\0", "IX", "IY", "SP" };
93   static const int Reg16Cnt = sizeof(Reg16Names) / sizeof(*Reg16Names);
94   static const char IReg16Names[][3] =  {"IX", "IY", "SP" };
95   static const int IReg16Cnt = sizeof(IReg16Names) / sizeof(*IReg16Names);
96 
97   int z;
98   char *p;
99   LongInt DispAcc, DispVal;
100   Byte OccFlag, BaseReg;
101   Boolean ok, fnd, NegFlag, NNegFlag, Unknown;
102 
103   AdrType = ModNone; AdrCnt = 0;
104 
105   /* 1. 8-Bit-Register */
106 
107   for (z = 0; z < Reg8Cnt; z++)
108     if (!as_strcasecmp(pArg->Str, Reg8Names[z]))
109     {
110       AdrType = ModReg8;
111       AdrMode = z;
112       SetOpSize(0);
113       goto chk;
114     }
115 
116   /* 2. 16-Bit-Register, indiziert */
117 
118   if (Erl & MModIReg16)
119   {
120     for (z = 0; z < IReg16Cnt; z++)
121       if (!as_strcasecmp(pArg->Str, IReg16Names[z]))
122       {
123         AdrType = ModIReg16;
124         AdrMode = z;
125         SetOpSize(1);
126         goto chk;
127       }
128   }
129 
130   /* 3. 16-Bit-Register, normal */
131 
132   for (z = 0; z < Reg16Cnt; z++)
133    if (!as_strcasecmp(pArg->Str, Reg16Names[z]))
134    {
135      AdrType = ModReg16;
136      AdrMode = z;
137      SetOpSize(1);
138      goto chk;
139    }
140 
141   /* Speicheradresse */
142 
143   if (IsIndirect(pArg->Str))
144   {
145     tStrComp Arg, Remainder;
146 
147     OccFlag = 0;
148     BaseReg = 0;
149     DispAcc = 0;
150     ok = True;
151     NegFlag = False;
152     Unknown = False;
153     StrCompRefRight(&Arg, pArg, 1);
154     StrCompShorten(&Arg, 1);
155 
156     do
157     {
158       p = QuotMultPos(Arg.Str, "+-");
159       NNegFlag = p && (*p == '-');
160       if (p)
161         StrCompSplitRef(&Arg, &Remainder, &Arg, p);
162 
163       KillPrefBlanksStrComp(&Arg);
164       KillPostBlanksStrComp(&Arg);
165       fnd = False;
166 
167       if (!as_strcasecmp(Arg.Str, "A"))
168       {
169         fnd = True;
170         ok = ((!NegFlag) && (!(OccFlag & 1)));
171         if (ok)
172           OccFlag += 1;
173         else
174           WrError(ErrNum_InvAddrMode);
175       }
176 
177       if (!fnd)
178       {
179         for (z = 0; z < Reg16Cnt; z++)
180         {
181           if (!as_strcasecmp(Arg.Str, Reg16Names[z]))
182           {
183             fnd = True;
184             BaseReg = z;
185             ok = ((!NegFlag) && (!(OccFlag & 2)));
186             if (ok)
187               OccFlag += 2;
188             else
189               WrError(ErrNum_InvAddrMode);
190           }
191         }
192       }
193 
194       if (!fnd)
195       {
196         tSymbolFlags Flags;
197 
198         DispVal = EvalStrIntExpressionWithFlags(&Arg, Int32, &ok, &Flags);
199         if (ok)
200         {
201           DispAcc = NegFlag ? DispAcc - DispVal : DispAcc + DispVal;
202           if (mFirstPassUnknown(Flags))
203             Unknown = True;
204         }
205       }
206 
207       NegFlag = NNegFlag;
208       if (p)
209         Arg = Remainder;
210     }
211     while (p && ok);
212 
213     if (!ok)
214       return;
215     if (Unknown)
216       DispAcc &= 0x7f;
217 
218     switch (OccFlag)
219     {
220       case 1:
221         WrError(ErrNum_InvAddrMode);
222         break;
223       case 3:
224         if ((BaseReg != 2) || (DispAcc!=0)) WrError(ErrNum_InvAddrMode);
225         else
226         {
227           AdrType = ModIdxReg;
228           AdrMode = 3;
229         }
230         break;
231       case 2:
232         if ((DispAcc > 127) || (DispAcc < -128)) WrError(ErrNum_OverRange);
233         else if (DispAcc == 0)
234         {
235           AdrType = ModIndReg;
236           AdrMode = BaseReg;
237         }
238         else if (BaseReg < 4) WrError(ErrNum_InvAddrMode);
239         else
240         {
241           AdrType = ModIdxReg;
242           AdrMode = BaseReg - 4;
243           AdrCnt = 1;
244           AdrVals[0] = DispAcc & 0xff;
245         }
246         break;
247       case 0:
248         if (DispAcc > 0xffff) WrError(ErrNum_AdrOverflow);
249         else if ((Hi(DispAcc) == 0xff) && (Erl & MModDir))
250         {
251           AdrType = ModDir;
252           AdrCnt = 1;
253           AdrVals[0] = Lo(DispAcc);
254         }
255         else
256         {
257           AdrType = ModMem;
258           AdrCnt = 2;
259           AdrVals[0] = Lo(DispAcc);
260           AdrVals[1] = Hi(DispAcc);
261         }
262         break;
263     }
264   }
265 
266   /* immediate */
267 
268   else
269   {
270     if ((OpSize == -1) && (MinOneIs0))
271       OpSize = 0;
272     switch (OpSize)
273     {
274       case -1:
275         WrError(ErrNum_InvOpSize);
276         break;
277       case 0:
278         AdrVals[0] = EvalStrIntExpression(pArg, Int8, &ok);
279         if (ok)
280         {
281           AdrType = ModImm;
282           AdrCnt = 1;
283         }
284         break;
285       case 1:
286         DispVal = EvalStrIntExpression(pArg, Int16, &ok);
287         if (ok)
288         {
289           AdrType = ModImm;
290           AdrCnt = 2;
291           AdrVals[0] = Lo(DispVal);
292           AdrVals[1] = Hi(DispVal);
293         }
294         break;
295     }
296   }
297 
298   /* gefunden */
299 
300 chk:
301   if ((AdrType != ModNone) && (!((1 << AdrType) & Erl)))
302   {
303     WrError(ErrNum_InvAddrMode);
304     AdrType = ModNone;
305     AdrCnt = 0;
306   }
307 }
308 
ArgPair(const char * Arg1,const char * Arg2)309 static Boolean ArgPair(const char *Arg1, const char *Arg2)
310 {
311   return  (((!as_strcasecmp(ArgStr[1].Str, Arg1)) && (!as_strcasecmp(ArgStr[2].Str, Arg2)))
312         || ((!as_strcasecmp(ArgStr[1].Str, Arg2)) && (!as_strcasecmp(ArgStr[2].Str, Arg1))));
313 }
314 
DecodeCondition(char * pCondStr)315 static unsigned DecodeCondition(char *pCondStr)
316 {
317   int z;
318 
319   NLS_UpString(pCondStr);
320   for (z = 0; z < ConditionCnt; z++)
321     if (!strcmp(pCondStr, Conditions[z].Name))
322       break;
323   return z;
324 }
325 
326 /*-------------------------------------------------------------------------*/
327 
328 /* ohne Argument */
329 
DecodeFixed(Word Code)330 static void DecodeFixed(Word Code)
331 {
332   if (ChkArgCnt(0, 0))
333   {
334     CodeLen = 1;
335     BAsmCode[0] = Code;
336   }
337 }
338 
DecodeMove(Word Code)339 static void DecodeMove(Word Code)
340 {
341   if (ChkArgCnt(0, 0))
342   {
343     CodeLen = 2;
344     BAsmCode[0] = 0xfe;
345     BAsmCode[1] = Code;
346   }
347 }
348 
DecodeShift(Word Code)349 static void DecodeShift(Word Code)
350 {
351   if (ChkArgCnt(1, 1))
352   {
353     DecodeAdr(&ArgStr[1], (Hi(Code) ? MModReg8 : 0) | MModIndReg | MModIdxReg | MModMem | MModDir);
354     switch (AdrType)
355     {
356       case ModReg8:
357         CodeLen = 2;
358         BAsmCode[0] = 0xf8 + AdrMode;
359         BAsmCode[1] = Lo(Code);
360         if (AdrMode == AccReg)
361           WrError(ErrNum_ShortAddrPossible);
362         break;
363       case ModIndReg:
364         CodeLen = 2;
365         BAsmCode[0] = 0xe0 + AdrMode;
366         BAsmCode[1] = Lo(Code);
367         break;
368       case ModIdxReg:
369         CodeLen = 2 + AdrCnt;
370         BAsmCode[0] = 0xf0 + AdrMode;
371         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
372         BAsmCode[1 + AdrCnt] = Lo(Code);
373         break;
374       case ModDir:
375         CodeLen = 3;
376         BAsmCode[0] = 0xe7;
377         BAsmCode[1] = AdrVals[0];
378         BAsmCode[2] = Lo(Code);
379         break;
380       case ModMem:
381         CodeLen = 4;
382         BAsmCode[0] = 0xe3;
383         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
384         BAsmCode[3] = Lo(Code);
385         break;
386     }
387   }
388 }
389 
390 /* Logik */
391 
DecodeBit(Word Code)392 static void DecodeBit(Word Code)
393 {
394   Byte BitPos;
395   Boolean OK;
396 
397   if (ChkArgCnt(2, 2))
398   {
399     BitPos = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
400     if (OK)
401     {
402       DecodeAdr(&ArgStr[2], MModReg8 | MModIndReg | MModIdxReg | MModMem | MModDir);
403       switch (AdrType)
404       {
405         case ModReg8:
406           CodeLen = 2;
407           BAsmCode[0] = 0xf8 + AdrMode;
408           BAsmCode[1] = Code + BitPos;
409           break;
410         case ModIndReg:
411           CodeLen = 2;
412           BAsmCode[0] = 0xe0 + AdrMode;
413           BAsmCode[1] = Code + BitPos;
414           break;
415         case ModIdxReg:
416           CodeLen = 2 + AdrCnt;
417           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
418           BAsmCode[0] = 0xf0 + AdrMode;
419           BAsmCode[1 + AdrCnt] = Code + BitPos;
420           break;
421         case ModMem:
422           CodeLen = 4;
423           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
424           BAsmCode[0] = 0xe3;
425           BAsmCode[1 + AdrCnt] = Code + BitPos;
426           break;
427         case ModDir:
428           BAsmCode[1] = AdrVals[0];
429           if (Code == 0x18)
430           {
431             BAsmCode[0] = 0xe7;
432             BAsmCode[2] = Code + BitPos;
433             CodeLen = 3;
434           }
435           else
436           {
437             BAsmCode[0] = Code + BitPos;
438             CodeLen = 2;
439           }
440           break;
441       }
442     }
443   }
444 }
445 
DecodeAcc(Word Code)446 static void DecodeAcc(Word Code)
447 {
448   if (!ChkArgCnt(1, 1));
449   else if (as_strcasecmp(ArgStr[1].Str, "A")) WrError(ErrNum_InvAddrMode);
450   else
451   {
452     CodeLen = 1;
453     BAsmCode[0] = Code;
454   }
455 }
456 
DecodeALU2(Word Code)457 static void DecodeALU2(Word Code)
458 {
459   Byte HReg;
460 
461   if (ChkArgCnt(2, 2))
462   {
463     DecodeAdr(&ArgStr[1], MModReg8 | MModReg16 | MModIdxReg | MModIndReg | MModDir | MModMem);
464     switch (AdrType)
465     {
466       case ModReg8:
467         DecodeAdr(&ArgStr[2], MModImm | (((HReg = AdrMode) == AccReg) ? MModReg8 | MModIndReg | MModIdxReg | MModDir | MModMem:0));
468         switch(AdrType)
469         {
470           case ModReg8:
471             CodeLen = 2;
472             BAsmCode[0] = 0xf8 | AdrMode;
473             BAsmCode[1] = 0x60 | Code;
474             break;
475           case ModIndReg:
476             CodeLen = 2;
477             BAsmCode[0] = 0xe0 | AdrMode; BAsmCode[1] = 0x60 | Code;
478             break;
479           case ModIdxReg:
480             CodeLen = 2 + AdrCnt;
481             BAsmCode[0] = 0xf0 | AdrMode;
482             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
483             BAsmCode[1 + AdrCnt] = 0x60 | Code;
484             break;
485           case ModDir:
486             CodeLen = 2;
487             BAsmCode[0] = 0x60 | Code;
488             BAsmCode[1] = AdrVals[0];
489             break;
490           case ModMem:
491             CodeLen = 4;
492             BAsmCode[0] = 0xe3;
493             BAsmCode[3] = 0x60 | Code;
494             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
495             break;
496           case ModImm:
497             if (HReg == AccReg)
498             {
499               CodeLen = 2;
500               BAsmCode[0] = 0x68 | Code;
501               BAsmCode[1] = AdrVals[0];
502             }
503             else
504             {
505               CodeLen = 3;
506               BAsmCode[0] = 0xf8 | HReg;
507               BAsmCode[1] = 0x68 | Code;
508               BAsmCode[2] = AdrVals[0];
509             }
510             break;
511         }
512         break;
513       case ModReg16:
514         if ((AdrMode == 2) || ((Code == 0) && (AdrMode >= 4)))
515         {
516           HReg = AdrMode;
517           DecodeAdr(&ArgStr[2], MModReg16 | MModIndReg | MModIdxReg | MModDir | MModMem | MModImm);
518           switch (AdrType)
519           {
520             case ModReg16:
521               CodeLen = 2;
522               BAsmCode[0] = 0xf8 | AdrMode;
523               BAsmCode[1] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x70 + Code;
524               break;
525             case ModIndReg:
526               CodeLen = 2;
527               BAsmCode[0] = 0xe0 | AdrMode;
528               BAsmCode[1] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x70 + Code;
529               break;
530             case ModIdxReg:
531               CodeLen = 2 + AdrCnt;
532               BAsmCode[0] = 0xf0 | AdrMode;
533               memcpy(BAsmCode + 1,AdrVals, AdrCnt);
534               BAsmCode[1 + AdrCnt] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x70 + Code;
535               break;
536             case ModDir:
537               if (HReg >= 4)
538               {
539                 CodeLen = 3;
540                 BAsmCode[0] = 0xe7;
541                 BAsmCode[1] = AdrVals[0];
542                 BAsmCode[2] = 0x10 | HReg;
543               }
544               else
545               {
546                 CodeLen = 2;
547                 BAsmCode[0] = 0x70 | Code;
548                 BAsmCode[1] = AdrVals[0];
549               }
550               break;
551             case ModMem:
552               CodeLen = 4;
553               BAsmCode[0] = 0xe3;
554               memcpy(BAsmCode + 1, AdrVals, 2);
555               BAsmCode[3] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x70 + Code;
556               break;
557             case ModImm:
558               CodeLen = 3;
559               BAsmCode[0] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x78 + Code;
560               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
561               break;
562           }
563         }
564         else WrError(ErrNum_InvAddrMode);
565         break;
566       case ModIndReg:
567       case ModIdxReg:
568       case ModDir:
569       case ModMem:
570         OpSize = 0;
571         switch (AdrType)
572         {
573           case ModIndReg:
574             HReg = 3;
575             BAsmCode[0] = 0xe8 | AdrMode;
576             BAsmCode[1] = 0x68 | Code;
577             break;
578           case ModIdxReg:
579             HReg = 3 + AdrCnt;
580             BAsmCode[0] = 0xf4 | AdrMode;
581             BAsmCode[1 + AdrCnt] = 0x68 | Code;
582             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
583             break;
584           case ModDir:
585             HReg = 4;
586             BAsmCode[0] = 0xef;
587             BAsmCode[1] = AdrVals[0];
588             BAsmCode[2] = 0x68 | Code;
589             break;
590           case ModMem:
591             HReg = 5;
592             BAsmCode[0] = 0xeb;
593             memcpy(BAsmCode + 1, AdrVals, 2);
594             BAsmCode[3] = 0x68 | Code;
595             break;
596           default:
597             HReg = 0;
598         }
599         DecodeAdr(&ArgStr[2], MModImm);
600         if (AdrType == ModImm)
601         {
602           BAsmCode[HReg-1] = AdrVals[0];
603           CodeLen = HReg;
604         }
605         break;
606     }
607   }
608 }
609 
DecodeLD(Word Code)610 static void DecodeLD(Word Code)
611 {
612   Byte HReg;
613 
614   if (Hi(Code))
615     SetOpSize(1);
616 
617   if (ChkArgCnt(2, 2))
618   {
619     DecodeAdr(&ArgStr[1], MModReg8 | MModReg16 | MModIndReg | MModIdxReg | MModDir | MModMem);
620     switch (AdrType)
621     {
622       case ModReg8:
623         HReg = AdrMode;
624         DecodeAdr(&ArgStr[2], MModReg8 | MModIndReg | MModIdxReg | MModDir | MModMem | MModImm);
625         switch (AdrType)
626         {
627           case ModReg8:
628             if (HReg == AccReg)
629             {
630               CodeLen = 1;
631               BAsmCode[0] = 0x20 | AdrMode;
632             }
633             else if (AdrMode == AccReg)
634             {
635               CodeLen = 1;
636               BAsmCode[0] = 0x28 | HReg;
637             }
638             else
639             {
640               CodeLen = 2;
641               BAsmCode[0] = 0xf8 | AdrMode;
642               BAsmCode[1] = 0x30 | HReg;
643             }
644             break;
645           case ModIndReg:
646             CodeLen = 2;
647             BAsmCode[0] = 0xe0 | AdrMode;
648             BAsmCode[1] = 0x28 | HReg;
649             break;
650           case ModIdxReg:
651             CodeLen = 2 + AdrCnt;
652             BAsmCode[0] = 0xf0 | AdrMode;
653             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
654             BAsmCode[1 + AdrCnt] = 0x28 | HReg;
655             break;
656           case ModDir:
657             if (HReg == AccReg)
658             {
659               CodeLen = 2;
660               BAsmCode[0] = 0x27;
661               BAsmCode[1] = AdrVals[0];
662             }
663             else
664             {
665               CodeLen = 3;
666               BAsmCode[0] = 0xe7;
667               BAsmCode[1] = AdrVals[0];
668               BAsmCode[2] = 0x28 | HReg;
669             }
670             break;
671           case ModMem:
672             CodeLen = 4;
673             BAsmCode[0] = 0xe3;
674             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
675             BAsmCode[3] = 0x28 | HReg;
676             break;
677           case ModImm:
678             CodeLen = 2;
679             BAsmCode[0] = 0x30 | HReg;
680             BAsmCode[1] = AdrVals[0];
681             break;
682         }
683         break;
684       case ModReg16:
685         HReg = AdrMode;
686         DecodeAdr(&ArgStr[2], MModReg16 | MModIndReg | MModIdxReg | MModDir | MModMem | MModImm);
687         switch (AdrType)
688         {
689           case ModReg16:
690             if (HReg == HLReg)
691             {
692               CodeLen = 1;
693               BAsmCode[0] = 0x40 | AdrMode;
694             }
695             else if (AdrMode == HLReg)
696             {
697               CodeLen = 1;
698               BAsmCode[0] = 0x48 | HReg;
699             }
700             else
701             {
702               CodeLen = 2;
703               BAsmCode[0] = 0xf8 | AdrMode;
704               BAsmCode[1] = 0x38 | HReg;
705             }
706             break;
707           case ModIndReg:
708             CodeLen = 2;
709             BAsmCode[0] = 0xe0 | AdrMode;
710             BAsmCode[1] = 0x48 | HReg;
711             break;
712           case ModIdxReg:
713             CodeLen = 2 + AdrCnt;
714             BAsmCode[0] = 0xf0 | AdrMode;
715             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
716             BAsmCode[1 + AdrCnt] = 0x48 | HReg;
717             break;
718           case ModDir:
719             if (HReg == HLReg)
720             {
721               CodeLen = 2;
722               BAsmCode[0] = 0x47;
723               BAsmCode[1] = AdrVals[0];
724             }
725             else
726             {
727               CodeLen = 3;
728               BAsmCode[0] = 0xe7;
729               BAsmCode[1] = AdrVals[0];
730               BAsmCode[2] = 0x48 | HReg;
731             }
732             break;
733           case ModMem:
734             CodeLen = 4;
735             BAsmCode[0] = 0xe3;
736             BAsmCode[3] = 0x48 | HReg;
737             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
738             break;
739           case ModImm:
740             CodeLen = 3;
741             BAsmCode[0] = 0x38 | HReg;
742             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
743             break;
744         }
745         break;
746       case ModIndReg:
747       case ModIdxReg:
748       case ModDir:
749       case ModMem:
750         MinOneIs0 = True;
751         HReg = AdrCnt;
752         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
753         switch (AdrType)
754         {
755           case ModIndReg:
756             BAsmCode[0] = 0xe8 | AdrMode;
757             break;
758           case ModIdxReg:
759             BAsmCode[0] = 0xf4 | AdrMode;
760             break;
761           case ModMem:
762             BAsmCode[0] = 0xeb;
763             break;
764           case ModDir:
765             BAsmCode[0] = 0x0f;
766             break;
767         }
768         DecodeAdr(&ArgStr[2], MModReg16 | MModReg8 | MModImm);
769         if (BAsmCode[0] == 0x0f)
770          switch (AdrType)
771          {
772            case ModReg8:
773              if (AdrMode == AccReg)
774              {
775                CodeLen = 2;
776                BAsmCode[0] = 0x2f;
777              }
778              else
779              {
780                CodeLen = 3;
781                BAsmCode[0] = 0xef;
782                BAsmCode[2] = 0x20 | AdrMode;
783              }
784              break;
785            case ModReg16:
786              if (AdrMode == HLReg)
787              {
788                CodeLen = 2;
789                BAsmCode[0] = 0x4f;
790              }
791              else
792              {
793                CodeLen = 3;
794                BAsmCode[0] = 0xef;
795                BAsmCode[2] = 0x40 | AdrMode;
796              }
797              break;
798            case ModImm:
799              CodeLen = 3 + OpSize;
800              BAsmCode[0] = 0x37 | (OpSize << 3);
801              memcpy(BAsmCode + 2, AdrVals, AdrCnt);
802              break;
803          }
804          else
805          {
806            switch (AdrType)
807            {
808              case ModReg8:
809                BAsmCode[1 + HReg] = 0x20 | AdrMode;
810                break;
811              case ModReg16:
812                BAsmCode[1 + HReg] = 0x40 | AdrMode;
813                break;
814              case ModImm:
815                BAsmCode[1 + HReg] = 0x37 | (OpSize << 3);
816                break;
817            }
818            memcpy(BAsmCode + 2 + HReg, AdrVals, AdrCnt);
819            CodeLen = 1 + HReg + 1 + AdrCnt;
820          }
821         break;
822     }
823   }
824 }
825 
DecodePUSH_POP(Word Code)826 static void DecodePUSH_POP(Word Code)
827 {
828   if (ChkArgCnt(1, 1))
829   {
830     if (!as_strcasecmp(ArgStr[1].Str, "AF"))
831     {
832       CodeLen = 1;
833       BAsmCode[0] = 0x56 | Code;
834     }
835     else
836     {
837       DecodeAdr(&ArgStr[1], MModReg16);
838       if (AdrType == ModReg16)
839       {
840         if (AdrMode == 6) WrError(ErrNum_InvAddrMode);
841         else
842         {
843           CodeLen = 1;
844           BAsmCode[0] = 0x50 | Code | AdrMode;
845         }
846       }
847     }
848   }
849 }
850 
DecodeLDA(Word Code)851 static void DecodeLDA(Word Code)
852 {
853   Byte HReg;
854 
855   UNUSED(Code);
856 
857   if (ChkArgCnt(2, 2))
858   {
859     DecodeAdr(&ArgStr[1], MModReg16);
860     if (AdrType == ModReg16)
861     {
862       HReg = 0x38 + AdrMode;
863       DecodeAdr(&ArgStr[2], MModIndReg | MModIdxReg);
864       switch (AdrType)
865       {
866         case ModIndReg:
867           if (AdrMode < 4) WrError(ErrNum_InvAddrMode);
868           else
869           {
870             CodeLen = 3;
871             BAsmCode[0] = 0xf0 | AdrMode;
872             BAsmCode[1] = 0;
873             BAsmCode[2] = HReg;
874           }
875           break;
876         case ModIdxReg:
877           CodeLen = 2 + AdrCnt;
878           BAsmCode[0] = 0xf4 + AdrMode;
879           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
880           BAsmCode[1 + AdrCnt] = HReg;
881           break;
882       }
883     }
884   }
885 }
886 
DecodeLDAR(Word Code)887 static void DecodeLDAR(Word Code)
888 {
889   UNUSED(Code);
890 
891   if (!ChkArgCnt(2, 2));
892   else if (as_strcasecmp(ArgStr[1].Str, "HL")) WrError(ErrNum_InvAddrMode);
893   else
894   {
895     Boolean OK;
896     Integer AdrInt = EvalStrIntExpression(&ArgStr[2], Int16, &OK) - (EProgCounter() + 2);
897     if (OK)
898     {
899       CodeLen = 3;
900       BAsmCode[0] = 0x17;
901       BAsmCode[1] = Lo(AdrInt);
902       BAsmCode[2] = Hi(AdrInt);
903     }
904   }
905 }
906 
DecodeEX(Word Code)907 static void DecodeEX(Word Code)
908 {
909   Byte HReg;
910 
911   UNUSED(Code);
912 
913   /* work around the parser problem related to the ' character */
914 
915   if (!as_strncasecmp(ArgStr[2].Str, "AF\'", 3))
916     ArgStr[2].Str[3] = '\0';
917 
918   if (!ChkArgCnt(2, 2));
919   else if (ArgPair("DE", "HL"))
920   {
921     CodeLen = 1;
922     BAsmCode[0] = 0x08;
923   }
924   else if ((ArgPair("AF", "AF\'")) || (ArgPair("AF", "AF`")))
925   {
926     CodeLen = 1;
927     BAsmCode[0] = 0x09;
928   }
929   else
930   {
931     DecodeAdr(&ArgStr[1], MModReg16 | MModIndReg | MModIdxReg | MModMem | MModDir);
932     switch (AdrType)
933     {
934       case ModReg16:
935         HReg = 0x50 | AdrMode;
936         DecodeAdr(&ArgStr[2], MModIndReg | MModIdxReg | MModMem | MModDir);
937         switch (AdrType)
938         {
939           case ModIndReg:
940             CodeLen = 2;
941             BAsmCode[0] = 0xe0 | AdrMode;
942             BAsmCode[1] = HReg;
943             break;
944           case ModIdxReg:
945             CodeLen = 2 + AdrCnt;
946             BAsmCode[0] = 0xf0 | AdrMode;
947             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
948             BAsmCode[1 + AdrCnt] = HReg;
949             break;
950           case ModDir:
951             CodeLen = 3;
952             BAsmCode[0] = 0xe7;
953             BAsmCode[1] = AdrVals[0];
954             BAsmCode[2] = HReg;
955             break;
956           case ModMem:
957             CodeLen = 4;
958             BAsmCode[0] = 0xe3;
959             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
960             BAsmCode[3] = HReg;
961             break;
962         }
963         break;
964       case ModIndReg:
965       case ModIdxReg:
966       case ModDir:
967       case ModMem:
968         switch (AdrType)
969         {
970           case ModIndReg:
971             BAsmCode[0] = 0xe0 | AdrMode;
972             break;
973           case ModIdxReg:
974             BAsmCode[0] = 0xf0 | AdrMode;
975             break;
976           case ModDir:
977             BAsmCode[0] = 0xe7;
978             break;
979           case ModMem:
980             BAsmCode[0] = 0xe3;
981             break;
982         }
983         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
984         HReg = 2 + AdrCnt;
985         DecodeAdr(&ArgStr[2], MModReg16);
986         if (AdrType == ModReg16)
987         {
988           BAsmCode[HReg - 1] = 0x50 | AdrMode;
989           CodeLen = HReg;
990         }
991         break;
992     }
993   }
994 }
995 
DecodeINC_DEC(Word Code)996 static void DecodeINC_DEC(Word Code)
997 {
998   if (Hi(Code))
999     SetOpSize(1);
1000 
1001   if (ChkArgCnt(1, 1))
1002   {
1003     DecodeAdr(&ArgStr[1], MModReg8 | MModReg16 | MModIndReg | MModIdxReg | MModDir | MModMem);
1004     if (OpSize==-1)
1005       OpSize = 0;
1006     switch (AdrType)
1007     {
1008       case ModReg8:
1009         CodeLen = 1;
1010         BAsmCode[0] = 0x80 | Lo(Code) | AdrMode;
1011         break;
1012       case ModReg16:
1013         CodeLen = 1;
1014         BAsmCode[0] = 0x90 | Lo(Code) | AdrMode;
1015         break;
1016       case ModIndReg:
1017         CodeLen = 2;
1018         BAsmCode[0] = 0xe0 | AdrMode;
1019         BAsmCode[1] = 0x87 | (OpSize << 4) | Lo(Code);
1020         break;
1021       case ModIdxReg:
1022         CodeLen = 2 + AdrCnt;
1023         BAsmCode[0] = 0xf0 | AdrMode;
1024         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1025         BAsmCode[1 + AdrCnt] = 0x87 | (OpSize << 4) | Lo(Code);
1026         break;
1027       case ModDir:
1028         CodeLen = 2;
1029         BAsmCode[0] = 0x87 | (OpSize << 4) | Lo(Code);
1030         BAsmCode[1] = AdrVals[0];
1031         break;
1032       case ModMem:
1033         CodeLen = 4;
1034         BAsmCode[0] = 0xe3;
1035         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1036         BAsmCode[3] = 0x87 | (OpSize << 4) | Lo(Code);
1037         BAsmCode[1] = AdrVals[0];
1038         break;
1039     }
1040   }
1041 }
1042 
DecodeINCX_DECX(Word Code)1043 static void DecodeINCX_DECX(Word Code)
1044 {
1045   if (ChkArgCnt(1, 1))
1046   {
1047     DecodeAdr(&ArgStr[1], MModDir);
1048     if (AdrType == ModDir)
1049     {
1050       CodeLen = 2;
1051       BAsmCode[0] = Code;
1052       BAsmCode[1] = AdrVals[0];
1053     }
1054   }
1055 }
1056 
DecodeMUL_DIV(Word Code)1057 static void DecodeMUL_DIV(Word Code)
1058 {
1059   if (!ChkArgCnt(2, 2));
1060   else if (as_strcasecmp(ArgStr[1].Str, "HL")) WrError(ErrNum_InvAddrMode);
1061   else
1062   {
1063     OpSize = 0;
1064     DecodeAdr(&ArgStr[2], MModReg8 | MModIndReg | MModIdxReg | MModDir | MModMem | MModImm);
1065     switch (AdrType)
1066     {
1067       case ModReg8:
1068         CodeLen = 2;
1069         BAsmCode[0] = 0xf8 + AdrMode;
1070         BAsmCode[1] = Code;
1071         break;
1072       case ModIndReg:
1073         CodeLen = 2;
1074         BAsmCode[0] = 0xe0 + AdrMode;
1075         BAsmCode[1] = Code;
1076         break;
1077       case ModIdxReg:
1078         CodeLen = 2 + AdrCnt;
1079         BAsmCode[0] = 0xf0 + AdrMode;
1080         BAsmCode[1 + AdrCnt] = Code;
1081         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1082         break;
1083       case ModDir:
1084         CodeLen = 3;
1085         BAsmCode[0] = 0xe7;
1086         BAsmCode[1] = AdrVals[0];
1087         BAsmCode[2] = Code;
1088         break;
1089       case ModMem:
1090         CodeLen = 4;
1091         BAsmCode[0] = 0xe3;
1092         BAsmCode[3] = Code;
1093         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1094         break;
1095       case ModImm:
1096         CodeLen = 2;
1097         BAsmCode[0] = Code;
1098         BAsmCode[1] = AdrVals[0];
1099         break;
1100     }
1101   }
1102 }
1103 
DecodeJR(Word Code)1104 static void DecodeJR(Word Code)
1105 {
1106   UNUSED(Code);
1107 
1108   if (ChkArgCnt(1, 2))
1109   {
1110     int Cond = (ArgCnt == 1) ? DefaultCondition : DecodeCondition(ArgStr[1].Str);
1111     if (Cond >= ConditionCnt) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1112     else
1113     {
1114       Boolean OK;
1115       tSymbolFlags Flags;
1116       Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int16, &OK, &Flags) - (EProgCounter() + 2);
1117 
1118       if (OK)
1119       {
1120         if (!mSymbolQuestionable(Flags) && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
1121         else
1122         {
1123           CodeLen = 2;
1124           BAsmCode[0] = 0xc0 | Conditions[Cond].Code;
1125           BAsmCode[1] = AdrInt & 0xff;
1126         }
1127       }
1128     }
1129   }
1130 }
1131 
DecodeCALL_JP(Word Code)1132 static void DecodeCALL_JP(Word Code)
1133 {
1134   if (ChkArgCnt(1, 2))
1135   {
1136     unsigned Cond = (ArgCnt == 1) ? DefaultCondition : DecodeCondition(ArgStr[1].Str);
1137 
1138     if (Cond >= ConditionCnt) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1139     else
1140     {
1141       OpSize = 1;
1142       DecodeAdr(&ArgStr[ArgCnt], MModIndReg | MModIdxReg | MModMem |MModImm);
1143       if (AdrType == ModImm)
1144         AdrType = ModMem;
1145       switch (AdrType)
1146       {
1147         case ModIndReg:
1148           CodeLen = 2;
1149           BAsmCode[0] = 0xe8 | AdrMode;
1150           BAsmCode[1] = 0xc0 | (Code << 4) | Conditions[Cond].Code;
1151           break;
1152         case ModIdxReg:
1153           CodeLen = 2 + AdrCnt;
1154           BAsmCode[0] = 0xf4 | AdrMode;
1155           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1156           BAsmCode[1 + AdrCnt] = 0xc0 | (Code << 4) | Conditions[Cond].Code;
1157           break;
1158         case ModMem:
1159           if (Cond == DefaultCondition)
1160           {
1161             CodeLen = 3;
1162             BAsmCode[0] = 0x1a + (Code << 1);
1163             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1164           }
1165           else
1166           {
1167             CodeLen = 4;
1168             BAsmCode[0] = 0xeb;
1169             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1170             BAsmCode[3] = 0xc0 | (Code << 4) | Conditions[Cond].Code;
1171           }
1172           break;
1173       }
1174     }
1175   }
1176 }
1177 
DecodeRET(Word Code)1178 static void DecodeRET(Word Code)
1179 {
1180   UNUSED(Code);
1181 
1182   if (ChkArgCnt(0, 1))
1183   {
1184     unsigned Cond = (ArgCnt == 0) ? DefaultCondition : DecodeCondition(ArgStr[1].Str);
1185 
1186     if (Cond == DefaultCondition)
1187     {
1188       CodeLen = 1;
1189       BAsmCode[0] = 0x1e;
1190     }
1191     else if (Cond >= ConditionCnt) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1192     else
1193     {
1194       CodeLen = 2;
1195       BAsmCode[0] = 0xfe;
1196       BAsmCode[1] = 0xd0 | Conditions[Cond].Code;
1197     }
1198   }
1199 }
1200 
DecodeDJNZ(Word Code)1201 static void DecodeDJNZ(Word Code)
1202 {
1203   UNUSED(Code);
1204 
1205   if (ChkArgCnt(1, 2))
1206   {
1207     if (ArgCnt == 1)
1208     {
1209       AdrType = ModReg8;
1210       AdrMode = 0;
1211       OpSize = 0;
1212     }
1213     else
1214       DecodeAdr(&ArgStr[1], MModReg8 | MModReg16);
1215     if (AdrType != ModNone)
1216     {
1217       if (AdrMode != 0) WrError(ErrNum_InvAddrMode);
1218       else
1219       {
1220         Boolean OK;
1221         tSymbolFlags Flags;
1222         Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int16, &OK, &Flags) - (EProgCounter() + 2);
1223 
1224         if (OK)
1225         {
1226           if (!mSymbolQuestionable(Flags) && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
1227           else
1228           {
1229             CodeLen = 2;
1230             BAsmCode[0] = 0x18 | OpSize;
1231             BAsmCode[1] = AdrInt & 0xff;
1232           }
1233         }
1234       }
1235     }
1236   }
1237 }
1238 
DecodeJRL_CALR(Word Code)1239 static void DecodeJRL_CALR(Word Code)
1240 {
1241   if (ChkArgCnt(1, 1))
1242   {
1243     Boolean OK;
1244     Integer AdrInt = EvalStrIntExpression(&ArgStr[1], Int16, &OK) - (EProgCounter() + 2);
1245     if (OK)
1246     {
1247       CodeLen = 3;
1248       BAsmCode[0] = Code;
1249       if ((Code == 0x1b)
1250        && (AdrInt >= -128)
1251        && (AdrInt <= 127))
1252         WrError(ErrNum_ShortJumpPossible);
1253       BAsmCode[1] = Lo(AdrInt);
1254       BAsmCode[2] = Hi(AdrInt);
1255     }
1256   }
1257 }
1258 
1259 /*-------------------------------------------------------------------------*/
1260 
AddW(const char * Name,Word Code,InstProc Proc)1261 static void AddW(const char *Name, Word Code, InstProc Proc)
1262 {
1263   char Str[20];
1264 
1265   AddInstTable(InstTable, Name, Code, Proc);
1266   as_snprintf(Str, sizeof(Str), "%sW", Name);
1267   AddInstTable(InstTable, Str, Code | 0x100, Proc);
1268 }
1269 
AddFixed(const char * NName,Byte NCode)1270 static void AddFixed(const char *NName, Byte NCode)
1271 {
1272   AddInstTable(InstTable, NName, NCode, DecodeFixed);
1273 }
1274 
AddMove(const char * NName,Byte NCode)1275 static void AddMove(const char *NName, Byte NCode)
1276 {
1277   AddInstTable(InstTable, NName, NCode, DecodeMove);
1278 }
1279 
AddShift(const char * NName,Word NCode,Boolean NMay)1280 static void AddShift(const char *NName, Word NCode, Boolean NMay)
1281 {
1282   AddInstTable(InstTable, NName, NCode | (NMay ? 0x100 : 0), DecodeShift);
1283 }
1284 
AddBit(const char * NName,Byte NCode)1285 static void AddBit(const char *NName, Byte NCode)
1286 {
1287   AddInstTable(InstTable, NName, NCode, DecodeBit);
1288 }
1289 
AddAcc(const char * NName,Byte NCode)1290 static void AddAcc(const char *NName, Byte NCode)
1291 {
1292   AddInstTable(InstTable, NName, NCode, DecodeAcc);
1293 }
1294 
AddCondition(const char * NName,Byte NCode)1295 static void AddCondition(const char *NName, Byte NCode)
1296 {
1297   if (InstrZ >= ConditionCnt) exit(255);
1298   Conditions[InstrZ].Name = NName;
1299   Conditions[InstrZ++].Code = NCode;
1300 }
1301 
InitFields(void)1302 static void InitFields(void)
1303 {
1304   InstTable = CreateInstTable(207);
1305   SetDynamicInstTable(InstTable);
1306   AddW("LD", 0, DecodeLD);
1307   AddInstTable(InstTable, "PUSH", 0, DecodePUSH_POP);
1308   AddInstTable(InstTable, "POP" , 8, DecodePUSH_POP);
1309   AddInstTable(InstTable, "LDA", 0, DecodeLDA);
1310   AddInstTable(InstTable, "LDAR", 0, DecodeLDAR);
1311   AddInstTable(InstTable, "EX", 0, DecodeEX);
1312   AddW("INC", 0, DecodeINC_DEC);
1313   AddW("DEC", 8, DecodeINC_DEC);
1314   AddInstTable(InstTable, "INCX", 0x07, DecodeINCX_DECX);
1315   AddInstTable(InstTable, "DECX", 0x0f, DecodeINCX_DECX);
1316   AddInstTable(InstTable, "MUL", 0x12, DecodeMUL_DIV);
1317   AddInstTable(InstTable, "DIV", 0x13, DecodeMUL_DIV);
1318   AddInstTable(InstTable, "JR", 0, DecodeJR);
1319   AddInstTable(InstTable, "CALL", 1, DecodeCALL_JP);
1320   AddInstTable(InstTable, "JP", 0, DecodeCALL_JP);
1321   AddInstTable(InstTable, "RET", 0, DecodeRET);
1322   AddInstTable(InstTable, "DJNZ", 0, DecodeDJNZ);
1323   AddInstTable(InstTable, "JRL", 0x1b, DecodeJRL_CALR);
1324   AddInstTable(InstTable, "CALR", 0x1d, DecodeJRL_CALR);
1325 
1326   AddFixed("EXX" , 0x0a); AddFixed("CCF" , 0x0e);
1327   AddFixed("SCF" , 0x0d); AddFixed("RCF" , 0x0c);
1328   AddFixed("NOP" , 0x00); AddFixed("HALT", 0x01);
1329   AddFixed("DI"  , 0x02); AddFixed("EI"  , 0x03);
1330   AddFixed("SWI" , 0xff); AddFixed("RLCA", 0xa0);
1331   AddFixed("RRCA", 0xa1); AddFixed("RLA" , 0xa2);
1332   AddFixed("RRA" , 0xa3); AddFixed("SLAA", 0xa4);
1333   AddFixed("SRAA", 0xa5); AddFixed("SLLA", 0xa6);
1334   AddFixed("SRLA", 0xa7); AddFixed("RETI", 0x1f);
1335 
1336   AddMove("LDI" , 0x58);
1337   AddMove("LDIR", 0x59);
1338   AddMove("LDD" , 0x5a);
1339   AddMove("LDDR", 0x5b);
1340   AddMove("CPI" , 0x5c);
1341   AddMove("CPIR", 0x5d);
1342   AddMove("CPD" , 0x5e);
1343   AddMove("CPDR", 0x5f);
1344 
1345   AddShift("RLC", 0xa0, True );
1346   AddShift("RRC", 0xa1, True );
1347   AddShift("RL" , 0xa2, True );
1348   AddShift("RR" , 0xa3, True );
1349   AddShift("SLA", 0xa4, True );
1350   AddShift("SRA", 0xa5, True );
1351   AddShift("SLL", 0xa6, True );
1352   AddShift("SRL", 0xa7, True );
1353   AddShift("RLD", 0x10, False);
1354   AddShift("RRD", 0x11, False);
1355 
1356   AddBit("BIT" , 0xa8);
1357   AddBit("SET" , 0xb8);
1358   AddBit("RES" , 0xb0);
1359   AddBit("TSET", 0x18);
1360 
1361   AddAcc("DAA", 0x0b);
1362   AddAcc("CPL", 0x10);
1363   AddAcc("NEG", 0x11);
1364 
1365   InstrZ = 0;
1366   AddInstTable(InstTable, "ADD", InstrZ++, DecodeALU2);
1367   AddInstTable(InstTable, "ADC", InstrZ++, DecodeALU2);
1368   AddInstTable(InstTable, "SUB", InstrZ++, DecodeALU2);
1369   AddInstTable(InstTable, "SBC", InstrZ++, DecodeALU2);
1370   AddInstTable(InstTable, "AND", InstrZ++, DecodeALU2);
1371   AddInstTable(InstTable, "XOR", InstrZ++, DecodeALU2);
1372   AddInstTable(InstTable, "OR" , InstrZ++, DecodeALU2);
1373   AddInstTable(InstTable, "CP" , InstrZ++, DecodeALU2);
1374 
1375   Conditions = (Condition *) malloc(sizeof(Condition) * ConditionCnt); InstrZ = 0;
1376   AddCondition("F"  ,  0); DefaultCondition = InstrZ; AddCondition("T"  ,  8);
1377   AddCondition("Z"  ,  6); AddCondition("NZ" , 14);
1378   AddCondition("C"  ,  7); AddCondition("NC" , 15);
1379   AddCondition("PL" , 13); AddCondition("MI" ,  5);
1380   AddCondition("P"  , 13); AddCondition("M"  ,  5);
1381   AddCondition("NE" , 14); AddCondition("EQ" ,  6);
1382   AddCondition("OV" ,  4); AddCondition("NOV", 12);
1383   AddCondition("PE" ,  4); AddCondition("PO" , 12);
1384   AddCondition("GE" ,  9); AddCondition("LT" ,  1);
1385   AddCondition("GT" , 10); AddCondition("LE" ,  2);
1386   AddCondition("UGE", 15); AddCondition("ULT",  7);
1387   AddCondition("UGT", 11); AddCondition("ULE",  3);
1388 }
1389 
DeinitFields(void)1390 static void DeinitFields(void)
1391 {
1392   DestroyInstTable(InstTable);
1393 
1394   free(Conditions);
1395 }
1396 
MakeCode_90C141(void)1397 static void MakeCode_90C141(void)
1398 {
1399   CodeLen = 0; DontPrint = False; OpSize = -1;
1400 
1401   /* zu ignorierendes */
1402 
1403   if (Memo("")) return;
1404 
1405   /* Pseudoanweisungen */
1406 
1407   if (DecodeIntelPseudo(False)) return;
1408 
1409   if (!LookupInstTable(InstTable, OpPart.Str))
1410     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
1411 }
1412 
1413 /*-------------------------------------------------------------------------*/
1414 
IsDef_90C141(void)1415 static Boolean IsDef_90C141(void)
1416 {
1417   return False;
1418 }
1419 
SwitchFrom_90C141(void)1420 static void SwitchFrom_90C141(void)
1421 {
1422   DeinitFields();
1423 }
1424 
ChkMoreOneArg(void)1425 static Boolean ChkMoreOneArg(void)
1426 {
1427   return (ArgCnt > 1);
1428 }
1429 
SwitchTo_90C141(void)1430 static void SwitchTo_90C141(void)
1431 {
1432   TurnWords = False;
1433   ConstMode = ConstModeIntel;
1434   SetIsOccupiedFnc = ChkMoreOneArg;
1435 
1436   PCSymbol = "$";
1437   HeaderID = 0x53;
1438   NOPCode = 0x00;
1439   DivideChars = ",";
1440   HasAttrs = False;
1441 
1442   ValidSegs = 1 << SegCode;
1443   Grans[SegCode] = 1;
1444   ListGrans[SegCode] = 1;
1445   SegInits[SegCode] = 0;
1446   SegLimits[SegCode] = 0xffff;
1447 
1448   MakeCode = MakeCode_90C141;
1449   IsDef = IsDef_90C141;
1450   SwitchFrom = SwitchFrom_90C141;
1451   InitFields();
1452 }
1453 
code90c141_init(void)1454 void code90c141_init(void)
1455 {
1456   CPU90C141 = AddCPU("90C141", SwitchTo_90C141);
1457 }
1458