1 /* codetms7.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS-Portierung                                                             */
6 /*                                                                           */
7 /* Codegenerator TMS7000-Familie                                             */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 #include "stdinc.h"
12 #include <ctype.h>
13 #include <string.h>
14 
15 #include "strutil.h"
16 #include "bpemu.h"
17 #include "nls.h"
18 #include "asmdef.h"
19 #include "asmsub.h"
20 #include "asmpars.h"
21 #include "asmitree.h"
22 #include "intpseudo.h"
23 #include "codevars.h"
24 #include "errmsg.h"
25 
26 #include "codetms7.h"
27 
28 #define ModNone (-1)
29 #define ModAccA 0
30 #define MModAccA (1 << ModAccA)       /* A */
31 #define ModAccB 1
32 #define MModAccB (1 << ModAccB)       /* B */
33 #define ModReg 2
34 #define MModReg (1 << ModReg)         /* Rn */
35 #define ModPort 3
36 #define MModPort (1 << ModPort)       /* Pn */
37 #define ModAbs 4
38 #define MModAbs (1 << ModAbs)         /* nnnn */
39 #define ModBRel 5
40 #define MModBRel (1 << ModBRel)       /* nnnn(B) */
41 #define ModIReg 6
42 #define MModIReg (1 << ModIReg)       /* *Rn */
43 #define ModImm 7
44 #define MModImm (1 << ModImm)         /* #nn */
45 #define ModImmBRel 8
46 #define MModImmBRel (1 << ModImmBRel) /* #nnnn(b) */
47 
48 
49 static CPUVar CPU70C40,CPU70C20,CPU70C00,
50               CPU70CT40,CPU70CT20,
51               CPU70C82,CPU70C42,CPU70C02,
52               CPU70C48,CPU70C08;
53 
54 static Byte OpSize;
55 static ShortInt AdrType;
56 static Byte AdrVals[2];
57 
58 /*---------------------------------------------------------------------------*/
59 /* helpers */
60 
ChkAdr(Word Mask)61 static void ChkAdr(Word Mask)
62 {
63   if ((AdrType != -1) && ((Mask & (1L << AdrType)) == 0))
64   {
65     WrError(ErrNum_InvAddrMode); AdrType = ModNone; AdrCnt = 0;
66   }
67 }
68 
DecodeAdr(tStrComp * pArg,Word Mask)69 static void DecodeAdr(tStrComp *pArg, Word Mask)
70 {
71   Integer HVal;
72   int Lev, l;
73   char *p;
74   Boolean OK;
75   tStrComp Expr;
76 
77   AdrType = ModNone; AdrCnt = 0;
78 
79   if (!as_strcasecmp(pArg->Str, "A"))
80   {
81     if (Mask & MModAccA) AdrType = ModAccA;
82     else if (Mask & MModReg)
83     {
84       AdrCnt = 1; AdrVals[0] = 0; AdrType = ModReg;
85     }
86     else
87     {
88       AdrCnt = 2; AdrVals[0] = 0; AdrVals[1] = 0; AdrType = ModAbs;
89     }
90     ChkAdr(Mask); return;
91   }
92 
93   if (!as_strcasecmp(pArg->Str, "B"))
94   {
95     if (Mask & MModAccB) AdrType = ModAccB;
96     else if (Mask & MModReg)
97     {
98       AdrCnt = 1; AdrVals[0] = 1; AdrType = ModReg;
99     }
100     else
101     {
102       AdrCnt = 2; AdrVals[0] = 0; AdrVals[1] = 1; AdrType = ModAbs;
103     }
104     ChkAdr(Mask); return;
105   }
106 
107   if ((*pArg->Str == '#') || (*pArg->Str == '%'))
108   {
109     tStrComp ImmComp;
110 
111     StrCompRefRight(&ImmComp, pArg, 1);
112     l = strlen(ImmComp.Str);
113     if ((l >= 3) & (!as_strcasecmp(ImmComp.Str + l - 3,"(B)")))
114     {
115       char Save;
116 
117       Save = ImmComp.Str[l - 3];
118       ImmComp.Str[l - 3] = '\0'; ImmComp.Pos.Len -= 3;
119       HVal = EvalStrIntExpression(&ImmComp, Int16, &OK);
120       ImmComp.Str[l - 3] = Save;
121       if (OK)
122       {
123         AdrVals[0] = Hi(HVal); AdrVals[1] = Lo(HVal);
124         AdrType = ModImmBRel; AdrCnt = 2;
125       }
126     }
127     else
128     {
129       switch (OpSize)
130       {
131         case 0:
132           AdrVals[0] = EvalStrIntExpression(&ImmComp, Int8, &OK);
133           break;
134         case 1:
135           HVal = EvalStrIntExpression(&ImmComp, Int16, &OK);
136           AdrVals[0] = Hi(HVal);
137           AdrVals[1] = Lo(HVal);
138           break;
139       }
140       if (OK)
141       {
142         AdrCnt = 1 + OpSize;
143         AdrType = ModImm;
144       }
145     }
146     ChkAdr(Mask); return;
147   }
148 
149   if (*pArg->Str == '*')
150   {
151     AdrVals[0] = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
152     if (OK)
153     {
154       AdrCnt = 1;
155       AdrType = ModIReg;
156     }
157     ChkAdr(Mask); return;
158   }
159 
160   StrCompRefRight(&Expr, pArg, !!(*pArg->Str == '@'));
161 
162   l = strlen(Expr.Str);
163   if ((*Expr.Str) && (Expr.Str[l - 1] == ')'))
164   {
165     p = Expr.Str + l - 2; Lev = 0;
166     while ((p >= Expr.Str) && (Lev != -1))
167     {
168       switch (*p)
169       {
170         case '(': Lev--; break;
171         case ')': Lev++; break;
172       }
173       if (Lev != -1) p--;
174     }
175     if (p < Expr.Str)
176     {
177       WrError(ErrNum_BrackErr);
178       p = NULL;
179     }
180   }
181   else
182     p = NULL;
183 
184   if (!p)
185   {
186     HVal = EvalStrIntExpression(&Expr, Int16, &OK);
187     if (OK)
188     {
189       if ((Mask & MModReg) && (!Hi(HVal)))
190       {
191         AdrVals[0] = Lo(HVal); AdrCnt = 1; AdrType = ModReg;
192       }
193       else if ((Mask & MModPort) && (Hi(HVal) == 0x01))
194       {
195         AdrVals[0] = Lo(HVal); AdrCnt = 1; AdrType = ModPort;
196       }
197       else
198       {
199         AdrVals[0] = Hi(HVal); AdrVals[1] = Lo(HVal); AdrCnt = 2;
200         AdrType = ModAbs;
201       }
202     }
203     ChkAdr(Mask); return;
204   }
205   else
206   {
207     tStrComp Left, Right;
208 
209     StrCompSplitRef(&Left, &Right, &Expr, p);
210     HVal = EvalStrIntExpression(&Left, Int16, &OK);
211     if (OK)
212     {
213       StrCompShorten(&Right, 1);
214       if (!as_strcasecmp(Right.Str, "B"))
215       {
216         AdrVals[0] = Hi(HVal); AdrVals[1] = Lo(HVal); AdrCnt = 2;
217         AdrType = ModBRel;
218       }
219       else WrStrErrorPos(ErrNum_InvReg, &Right);
220     }
221     ChkAdr(Mask); return;
222   }
223 }
224 
PutCode(Word Code)225 static void PutCode(Word Code)
226 {
227   if (Hi(Code))
228     BAsmCode[CodeLen++] = Hi(Code);
229   BAsmCode[CodeLen++] = Lo(Code);
230 }
231 
232 /*---------------------------------------------------------------------------*/
233 /* decoders */
234 
DecodeFixed(Word Index)235 static void DecodeFixed(Word Index)
236 {
237   if (ChkArgCnt(0, 0))
238     PutCode(Index);
239 }
240 
DecodeRel8(Word Index)241 static void DecodeRel8(Word Index)
242 {
243   if (ChkArgCnt(1, 1))
244   {
245     Boolean OK;
246     Integer AdrInt = EvalStrIntExpression(&ArgStr[1], UInt16, &OK) - (EProgCounter() + 2);
247 
248     if (OK)
249     {
250       if ((AdrInt > 127) || (AdrInt<-128)) WrError(ErrNum_JmpDistTooBig);
251       else
252       {
253         CodeLen = 2;
254         BAsmCode[0] = Index;
255         BAsmCode[1] = AdrInt & 0xff;
256       }
257     }
258   }
259 }
260 
DecodeALU1(Word Index)261 static void DecodeALU1(Word Index)
262 {
263   if (ChkArgCnt(2, 2))
264   {
265     DecodeAdr(&ArgStr[2], MModAccA | MModAccB | MModReg);
266     switch (AdrType)
267     {
268       case ModAccA:
269         DecodeAdr(&ArgStr[1], MModAccB | MModReg | MModImm);
270         switch (AdrType)
271         {
272           case ModAccB:
273             CodeLen = 1;
274             BAsmCode[0] = 0x60 | Index;
275             break;
276           case ModReg:
277             CodeLen = 2;
278             BAsmCode[0] = 0x10 | Index;
279             BAsmCode[1] = AdrVals[0];
280             break;
281           case ModImm:
282             CodeLen = 2;
283             BAsmCode[0] = 0x20 | Index;
284             BAsmCode[1] = AdrVals[0];
285             break;
286         }
287         break;
288       case ModAccB:
289         DecodeAdr(&ArgStr[1], MModReg | MModImm);
290         switch (AdrType)
291         {
292           case ModReg:
293             CodeLen = 2;
294             BAsmCode[0] = 0x30 | Index;
295             BAsmCode[1] = AdrVals[0];
296             break;
297           case ModImm:
298             CodeLen=2;
299             BAsmCode[0] = 0x50 | Index;
300             BAsmCode[1] = AdrVals[0];
301             break;
302         }
303         break;
304       case ModReg:
305         BAsmCode[2] = AdrVals[0];
306         DecodeAdr(&ArgStr[1], MModReg | MModImm);
307         switch (AdrType)
308         {
309           case ModReg:
310             CodeLen = 3;
311             BAsmCode[0] = 0x40 | Index;
312             BAsmCode[1] = AdrVals[0];
313             break;
314           case ModImm:
315             CodeLen = 3;
316             BAsmCode[0] = 0x70 | Index;
317             BAsmCode[1] = AdrVals[0];
318             break;
319         }
320         break;
321     }
322   }
323 }
324 
DecodeALU2(Word Index)325 static void DecodeALU2(Word Index)
326 {
327   Boolean IsP = ((Index & 0x8000) != 0),
328           IsRela = ((Index & 0x4000) != 0);
329 
330   Index &= ~0xc000;
331 
332   if (ChkArgCnt(IsRela ? 3 : 2, IsRela ? 3 : 2))
333   {
334     DecodeAdr(&ArgStr[2], MModPort | (IsP ? 0 : MModAccA | MModAccB | MModReg));
335     switch (AdrType)
336     {
337       case ModAccA:
338         DecodeAdr(&ArgStr[1], MModAccB | MModReg | MModImm);
339         switch (AdrType)
340         {
341           case ModAccB:
342             BAsmCode[0] = 0x60 | Index;
343             CodeLen = 1;
344             break;
345           case ModReg:
346             BAsmCode[0] = 0x10 | Index;
347             BAsmCode[1] = AdrVals[0];
348             CodeLen = 2;
349             break;
350           case ModImm:
351             BAsmCode[0] = 0x20 | Index;
352             BAsmCode[1] = AdrVals[0];
353             CodeLen = 2;
354             break;
355         }
356         break;
357       case ModAccB:
358         DecodeAdr(&ArgStr[1], MModReg | MModImm);
359         switch (AdrType)
360         {
361           case ModReg:
362             BAsmCode[0] = 0x30 | Index;
363             BAsmCode[1] = AdrVals[0];
364             CodeLen = 2;
365             break;
366           case ModImm:
367             BAsmCode[0] = 0x50 | Index;
368             BAsmCode[1] = AdrVals[0];
369             CodeLen = 2;
370             break;
371         }
372         break;
373       case ModReg:
374         BAsmCode[2] = AdrVals[0];
375         DecodeAdr(&ArgStr[1], MModReg | MModImm);
376         switch (AdrType)
377         {
378           case ModReg:
379             BAsmCode[0] = 0x40 | Index;
380             BAsmCode[1] = AdrVals[0];
381             CodeLen = 3;
382             break;
383           case ModImm:
384             BAsmCode[0] = 0x70 | Index;
385             BAsmCode[1] = AdrVals[0];
386             CodeLen = 3;
387         }
388         break;
389       case ModPort:
390         BAsmCode[1] = AdrVals[0];
391         DecodeAdr(&ArgStr[1], MModAccA | MModAccB | MModImm);
392         switch (AdrType)
393         {
394           case ModAccA:
395             BAsmCode[0] = 0x80 | Index;
396             CodeLen = 2;
397             break;
398           case ModAccB:
399             BAsmCode[0] = 0x90 | Index;
400             CodeLen = 2;
401             break;
402           case ModImm:
403             BAsmCode[0] = 0xa0 | Index;
404             BAsmCode[2] = BAsmCode[1];
405             BAsmCode[1] = AdrVals[0];
406             CodeLen = 3;
407         }
408         break;
409     }
410     if ((CodeLen != 0) && (IsRela))
411     {
412       Boolean OK;
413       tSymbolFlags Flags;
414       Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[3], Int16, &OK, &Flags) - (EProgCounter() + CodeLen + 1);
415 
416       if (!OK) CodeLen = 0;
417       else if (!mSymbolQuestionable(Flags) && ((AdrInt > 127) || (AdrInt < -128)))
418       {
419         WrError(ErrNum_JmpDistTooBig); CodeLen = 0;
420       }
421       else
422         BAsmCode[CodeLen++] = AdrInt & 0xff;
423     }
424   }
425 }
426 
DecodeJmp(Word Index)427 static void DecodeJmp(Word Index)
428 {
429   if (ChkArgCnt(1, 1))
430   {
431     DecodeAdr(&ArgStr[1], MModAbs | MModIReg | MModBRel);
432     switch (AdrType)
433     {
434       case ModAbs:
435         CodeLen = 3;
436         BAsmCode[0] = 0x80 | Index;
437         memcpy(BAsmCode + 1, AdrVals, 2);
438         break;
439       case ModIReg:
440         CodeLen = 2;
441         BAsmCode[0] = 0x90 | Index;
442         BAsmCode[1] = AdrVals[0];
443         break;
444       case ModBRel:
445         CodeLen = 3;
446         BAsmCode[0] = 0xa0 | Index;
447         memcpy(BAsmCode + 1, AdrVals, 2);
448         break;
449     }
450   }
451 }
452 
DecodeABReg(Word Index)453 static void DecodeABReg(Word Index)
454 {
455   if (!ChkArgCnt(Memo("DJNZ") ? 2 : 1, Memo("DJNZ") ? 2 : 1));
456   else if (!as_strcasecmp(ArgStr[1].Str, "ST"))
457   {
458     if ((Memo("PUSH")) || (Memo("POP")))
459     {
460       BAsmCode[0] = 8 | (Ord(Memo("PUSH")) * 6);
461       CodeLen = 1;
462     }
463     else WrError(ErrNum_InvAddrMode);
464   }
465   else
466   {
467     DecodeAdr(&ArgStr[1], MModAccA | MModAccB | MModReg);
468     switch (AdrType)
469     {
470       case ModAccA:
471         BAsmCode[0] = 0xb0 | Index;
472         CodeLen = 1;
473         break;
474       case ModAccB:
475         BAsmCode[0] = 0xc0 | Index;
476         CodeLen = 1;
477         break;
478       case ModReg:
479         BAsmCode[0] = 0xd0 | Index;
480         BAsmCode[1] = AdrVals[0];
481         CodeLen = 2;
482         break;
483     }
484     if ((Memo("DJNZ")) && (CodeLen != 0))
485     {
486       Boolean OK;
487       tSymbolFlags Flags;
488       Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt16, &OK, &Flags) - (EProgCounter() + CodeLen + 1);
489 
490       if (!OK)
491         CodeLen = 0;
492       else if (!mSymbolQuestionable(Flags) & ((AdrInt > 127) || (AdrInt < -128)))
493       {
494         WrError(ErrNum_JmpDistTooBig); CodeLen = 0;
495       }
496       else
497         BAsmCode[CodeLen++]=AdrInt & 0xff;
498     }
499   }
500 }
501 
DecodeMOV(Word IsMOVP)502 static void DecodeMOV(Word IsMOVP)
503 {
504   if (ChkArgCnt(2, 2))
505   {
506     DecodeAdr(&ArgStr[2], MModPort| MModAccA| MModAccB |
507                         (IsMOVP ? 0: MModReg| MModAbs | MModIReg| MModBRel));
508     switch (AdrType)
509     {
510       case ModAccA:
511         DecodeAdr(&ArgStr[1], MModPort+
512                             (IsMOVP ? 0 : MModReg | MModAbs | MModIReg | MModBRel | MModAccB | MModImm));
513         switch (AdrType)
514         {
515           case ModReg:
516             BAsmCode[0] = 0x12;
517             BAsmCode[1] = AdrVals[0];
518             CodeLen = 2;
519             break;
520           case ModAbs:
521             BAsmCode[0] = 0x8a;
522             memcpy(BAsmCode + 1, AdrVals, 2);
523             CodeLen = 3;
524             break;
525           case ModIReg:
526             BAsmCode[0] = 0x9a;
527             BAsmCode[1] = AdrVals[0];
528             CodeLen = 2;
529             break;
530           case ModBRel:
531             BAsmCode[0] = 0xaa;
532             memcpy(BAsmCode + 1, AdrVals, 2);
533             CodeLen = 3;
534             break;
535           case ModAccB:
536             BAsmCode[0] = 0x62;
537             CodeLen = 1;
538             break;
539           case ModPort:
540             BAsmCode[0] = 0x80;
541             BAsmCode[1] = AdrVals[0];
542             CodeLen = 2;
543             break;
544           case ModImm:
545             BAsmCode[0] = 0x22;
546             BAsmCode[1] = AdrVals[0];
547             CodeLen = 2;
548             break;
549         }
550         break;
551       case ModAccB:
552         DecodeAdr(&ArgStr[1], MModPort | (IsMOVP ? 0 : MModAccA | MModReg | MModImm));
553         switch (AdrType)
554         {
555           case ModAccA:
556             BAsmCode[0] = 0xc0;
557             CodeLen = 1;
558             break;
559           case ModReg:
560             BAsmCode[0] = 0x32;
561             BAsmCode[1] = AdrVals[0];
562             CodeLen = 2;
563             break;
564           case ModPort:
565             BAsmCode[0] = 0x91;
566             BAsmCode[1] = AdrVals[0];
567             CodeLen = 2;
568             break;
569           case ModImm:
570             BAsmCode[0] = 0x52;
571             BAsmCode[1] = AdrVals[0];
572             CodeLen = 2;
573             break;
574         }
575         break;
576       case ModReg:
577         BAsmCode[1] = BAsmCode[2] = AdrVals[0];
578         DecodeAdr(&ArgStr[1], MModAccA | MModAccB | MModReg | MModPort | MModImm);
579         switch (AdrType)
580         {
581           case ModAccA:
582             BAsmCode[0] = 0xd0;
583             CodeLen = 2;
584             break;
585           case ModAccB:
586             BAsmCode[0] = 0xd1;
587             CodeLen = 2;
588             break;
589           case ModReg:
590             BAsmCode[0] = 0x42;
591             BAsmCode[1] = AdrVals[0];
592             CodeLen=3;
593             break;
594           case ModPort:
595             BAsmCode[0] = 0xa2;
596             BAsmCode[1] = AdrVals[0];
597             CodeLen = 3;
598             break;
599           case ModImm:
600             BAsmCode[0] = 0x72;
601             BAsmCode[1] = AdrVals[0];
602             CodeLen = 3;
603             break;
604         }
605         break;
606       case ModPort:
607         BAsmCode[1] = BAsmCode[2] = AdrVals[0];
608         DecodeAdr(&ArgStr[1], MModAccA | MModAccB | MModImm);
609         switch (AdrType)
610         {
611           case ModAccA:
612             BAsmCode[0] = 0x82;
613             CodeLen = 2;
614             break;
615           case ModAccB:
616             BAsmCode[0] = 0x92;
617             CodeLen = 2;
618             break;
619           case ModImm:
620             BAsmCode[0] = 0xa2;
621             BAsmCode[1] = AdrVals[0];
622             CodeLen = 3;
623             break;
624         }
625         break;
626       case ModAbs:
627         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
628         DecodeAdr(&ArgStr[1], MModAccA);
629         if (AdrType != ModNone)
630         {
631           BAsmCode[0] = 0x8b;
632           CodeLen = 3;
633         }
634         break;
635       case ModIReg:
636         BAsmCode[1] = AdrVals[0];
637         DecodeAdr(&ArgStr[1], MModAccA);
638         if (AdrType != ModNone)
639         {
640           BAsmCode[0] = 0x9b;
641           CodeLen = 2;
642         }
643         break;
644       case ModBRel:
645         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
646         DecodeAdr(&ArgStr[1], MModAccA);
647         if (AdrType != ModNone)
648         {
649           BAsmCode[0] = 0xab;
650           CodeLen = 3;
651         }
652         break;
653     }
654   }
655 }
656 
DecodeLDA(Word Index)657 static void DecodeLDA(Word Index)
658 {
659   UNUSED(Index);
660 
661   if (ChkArgCnt(1, 1))
662   {
663     DecodeAdr(&ArgStr[1], MModAbs | MModBRel | MModIReg);
664     switch (AdrType)
665     {
666       case ModAbs:
667         BAsmCode[0] = 0x8a;
668         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
669         CodeLen = 1 + AdrCnt;
670         break;
671       case ModBRel:
672         BAsmCode[0] = 0xaa;
673         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
674         CodeLen = 1 + AdrCnt;
675         break;
676       case ModIReg:
677         BAsmCode[0] = 0x9a;
678         BAsmCode[1] = AdrVals[0];
679         CodeLen = 2;
680         break;
681     }
682   }
683 }
684 
DecodeSTA(Word Index)685 static void DecodeSTA(Word Index)
686 {
687   UNUSED(Index);
688 
689   if (ChkArgCnt(1, 1))
690   {
691     DecodeAdr(&ArgStr[1], MModAbs | MModBRel | MModIReg);
692     switch (AdrType)
693     {
694       case ModAbs:
695         BAsmCode[0] = 0x8b;
696         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
697         CodeLen = 1 + AdrCnt;
698         break;
699       case ModBRel:
700         BAsmCode[0] = 0xab;
701         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
702         CodeLen = 1 + AdrCnt;
703         break;
704       case ModIReg:
705         BAsmCode[0] = 0x9b;
706         BAsmCode[1] = AdrVals[0];
707         CodeLen = 2;
708         break;
709     }
710   }
711 }
712 
DecodeMOVWD(Word Index)713 static void DecodeMOVWD(Word Index)
714 {
715   UNUSED(Index);
716 
717   OpSize = 1;
718   if (ChkArgCnt(2, 2))
719   {
720     DecodeAdr(&ArgStr[2], MModReg);
721     if (AdrType != ModNone)
722     {
723       Byte z = AdrVals[0];
724 
725       DecodeAdr(&ArgStr[1], MModReg | MModImm | MModImmBRel);
726       switch (AdrType)
727       {
728         case ModReg:
729           BAsmCode[0] = 0x98;
730           BAsmCode[1] = AdrVals[0];
731           BAsmCode[2] = z;
732           CodeLen = 3;
733           break;
734         case ModImm:
735           BAsmCode[0] = 0x88;
736           memcpy(BAsmCode + 1, AdrVals, 2);
737           BAsmCode[3] = z;
738           CodeLen = 4;
739           break;
740         case ModImmBRel:
741           BAsmCode[0] = 0xa8;
742           memcpy(BAsmCode + 1, AdrVals, 2);
743           BAsmCode[3] = z;
744           CodeLen = 4;
745           break;
746       }
747     }
748   }
749 }
750 
DecodeCMP(Word IsCMPA)751 static void DecodeCMP(Word IsCMPA)
752 {
753   if (ChkArgCnt(IsCMPA ? 1 : 2, IsCMPA ? 1 : 2))
754   {
755     if (IsCMPA)
756       AdrType = ModAccA;
757     else
758       DecodeAdr(&ArgStr[2], MModAccA | MModAccB | MModReg);
759     switch (AdrType)
760     {
761       case ModAccA:
762         DecodeAdr(&ArgStr[1], MModAbs | MModIReg | MModBRel | MModAccB | MModReg | MModImm);
763         switch (AdrType)
764         {
765           case ModAbs:
766             BAsmCode[0] = 0x8d;
767             memcpy(BAsmCode + 1,AdrVals, 2);
768             CodeLen = 3;
769             break;
770           case ModIReg:
771             BAsmCode[0] = 0x9d;
772             BAsmCode[1] = AdrVals[0];
773             CodeLen = 2;
774             break;
775           case ModBRel:
776             BAsmCode[0] = 0xad;
777             memcpy(BAsmCode + 1, AdrVals, 2);
778             CodeLen = 3;
779             break;
780           case ModAccB:
781             BAsmCode[0] = 0x6d;
782             CodeLen = 1;
783             break;
784           case ModReg:
785             BAsmCode[0] = 0x1d;
786             BAsmCode[1] = AdrVals[0];
787             CodeLen = 2;
788             break;
789           case ModImm:
790             BAsmCode[0] = 0x2d;
791             BAsmCode[1] = AdrVals[0];
792             CodeLen = 2;
793             break;
794         }
795         break;
796       case ModAccB:
797         DecodeAdr(&ArgStr[1], MModReg | MModImm);
798         switch (AdrType)
799         {
800           case ModReg:
801             BAsmCode[0] = 0x3d;
802             BAsmCode[1] = AdrVals[0];
803             CodeLen = 2;
804             break;
805           case ModImm:
806             BAsmCode[0] = 0x5d;
807             BAsmCode[1] = AdrVals[0];
808             CodeLen = 2;
809             break;
810         }
811         break;
812       case ModReg:
813         BAsmCode[2] = AdrVals[0];
814         DecodeAdr(&ArgStr[1], MModReg | MModImm);
815         switch (AdrType)
816         {
817           case ModReg:
818             BAsmCode[0] = 0x4d;
819             BAsmCode[1] = AdrVals[0];
820             CodeLen = 3;
821             break;
822           case ModImm:
823             BAsmCode[0] = 0x7d;
824             BAsmCode[1] = AdrVals[0];
825             CodeLen = 3;
826             break;
827         }
828         break;
829     }
830   }
831 }
832 
DecodeTRAP(Word Index)833 static void DecodeTRAP(Word Index)
834 {
835   UNUSED(Index);
836 
837   if (ChkArgCnt(1, 1))
838   {
839     Boolean OK;
840     tSymbolFlags Flags;
841 
842     BAsmCode[0] = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt5, &OK, &Flags);
843     if (mFirstPassUnknown(Flags))
844       BAsmCode[0] &= 15;
845     if (OK)
846     {
847       if (BAsmCode[0] > 23) WrError(ErrNum_OverRange);
848       else
849       {
850         BAsmCode[0] = 0xff - BAsmCode[0];
851         CodeLen = 1;
852       }
853     }
854   }
855 }
856 
DecodeTST(Word Index)857 static void DecodeTST(Word Index)
858 {
859   UNUSED(Index);
860 
861   if (ChkArgCnt(1, 1))
862   {
863     DecodeAdr(&ArgStr[1], MModAccA | MModAccB);
864     switch (AdrType)
865     {
866       case ModAccA:
867         BAsmCode[0] = 0xb0;
868         CodeLen = 1;
869         break;
870       case ModAccB:
871         BAsmCode[0] = 0xc1;
872         CodeLen = 1;
873         break;
874     }
875   }
876 }
877 
878 /*---------------------------------------------------------------------------*/
879 /* dynamic instruction table handling */
880 
InitFixed(const char * NName,Word NCode)881 static void InitFixed(const char *NName, Word NCode)
882 {
883   AddInstTable(InstTable, NName, NCode, DecodeFixed);
884 }
885 
InitRel8(const char * NName,Word NCode)886 static void InitRel8(const char *NName, Word NCode)
887 {
888   AddInstTable(InstTable, NName, NCode, DecodeRel8);
889 }
890 
InitALU1(const char * NName,Word NCode)891 static void InitALU1(const char *NName, Word NCode)
892 {
893   AddInstTable(InstTable, NName, NCode, DecodeALU1);
894 }
895 
InitALU2(const char * NName,Word NCode)896 static void InitALU2(const char *NName, Word NCode)
897 {
898   AddInstTable(InstTable, NName, NCode, DecodeALU2);
899 }
900 
InitJmp(const char * NName,Word NCode)901 static void InitJmp(const char *NName, Word NCode)
902 {
903   AddInstTable(InstTable, NName, NCode, DecodeJmp);
904 }
905 
InitABReg(const char * NName,Word NCode)906 static void InitABReg(const char *NName, Word NCode)
907 {
908   AddInstTable(InstTable, NName, NCode, DecodeABReg);
909 }
910 
InitFields(void)911 static void InitFields(void)
912 {
913   InstTable = CreateInstTable(107);
914 
915   AddInstTable(InstTable, "MOV" , 0, DecodeMOV);
916   AddInstTable(InstTable, "MOVP", 1, DecodeMOV);
917   AddInstTable(InstTable, "LDA" , 0, DecodeLDA);
918   AddInstTable(InstTable, "STA" , 0, DecodeSTA);
919   AddInstTable(InstTable, "MOVW", 1, DecodeMOVWD);
920   AddInstTable(InstTable, "MOVD", 2, DecodeMOVWD);
921   AddInstTable(InstTable, "CMP" , 0, DecodeCMP);
922   AddInstTable(InstTable, "CMPA", 1, DecodeCMP);
923   AddInstTable(InstTable, "TRAP", 0, DecodeTRAP);
924   AddInstTable(InstTable, "TST" , 0, DecodeTST);
925 
926   InitFixed("CLRC" , 0x00b0); InitFixed("DINT" , 0x0006);
927   InitFixed("EINT" , 0x0005); InitFixed("IDLE" , 0x0001);
928   InitFixed("LDSP" , 0x000d); InitFixed("NOP"  , 0x0000);
929   InitFixed("RETI" , 0x000b); InitFixed("RTI"  , 0x000b);
930   InitFixed("RETS" , 0x000a); InitFixed("RTS"  , 0x000a);
931   InitFixed("SETC" , 0x0007); InitFixed("STSP" , 0x0009);
932   InitFixed("TSTA" , 0x00b0); InitFixed("TSTB" , 0x00c1);
933 
934   InitRel8("JMP", 0xe0); InitRel8("JC" , 0xe3); InitRel8("JEQ", 0xe2);
935   InitRel8("JHS", 0xe3); InitRel8("JL" , 0xe7); InitRel8("JN" , 0xe1);
936   InitRel8("JNC", 0xe7); InitRel8("JNE", 0xe6); InitRel8("JNZ", 0xe6);
937   InitRel8("JP" , 0xe4); InitRel8("JPZ", 0xe5); InitRel8("JZ" , 0xe2);
938 
939   InitALU1("ADC",  9); InitALU1("ADD",  8);
940   InitALU1("DAC", 14); InitALU1("DSB", 15);
941   InitALU1("SBB", 11); InitALU1("SUB", 10);
942   InitALU1("MPY", 12);
943 
944   InitALU2("AND"  , 0x0003); InitALU2("BTJO" , 0x4006);
945   InitALU2("BTJZ" , 0x4007); InitALU2("OR"   , 0x0004); InitALU2("XOR" , 0x0005);
946   InitALU2("ANDP" , 0x8003); InitALU2("BTJOP", 0xc006);
947   InitALU2("BTJZP", 0xc007); InitALU2("ORP"  , 0x8004); InitALU2("XORP", 0x8005);
948 
949   InitJmp("BR"  ,12); InitJmp("CALL" ,14);
950 
951   InitABReg("CLR"  , 5); InitABReg("DEC"  , 2); InitABReg("DECD" ,11);
952   InitABReg("INC"  , 3); InitABReg("INV"  , 4); InitABReg("POP"  , 9);
953   InitABReg("PUSH" , 8); InitABReg("RL"   ,14); InitABReg("RLC"  ,15);
954   InitABReg("RR"   ,12); InitABReg("RRC"  ,13); InitABReg("SWAP" , 7);
955   InitABReg("XCHB" , 6); InitABReg("DJNZ" ,10);
956 }
957 
DeinitFields(void)958 static void DeinitFields(void)
959 {
960   DestroyInstTable(InstTable);
961 }
962 
MakeCode_TMS7(void)963 static void MakeCode_TMS7(void)
964 {
965   CodeLen = 0; DontPrint = False; OpSize = 0;
966 
967   /* zu ignorierendes */
968 
969   if (Memo("")) return;
970 
971   /* Pseudoanweisungen */
972 
973   if (DecodeIntelPseudo(True)) return;
974 
975   /* remainder */
976 
977   if (!LookupInstTable(InstTable, OpPart.Str))
978     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
979 }
980 
IsDef_TMS7(void)981 static Boolean IsDef_TMS7(void)
982 {
983   return False;
984 }
985 
InternSymbol_TMS7(char * pAsc,TempResult * pErg)986 static void InternSymbol_TMS7(char *pAsc, TempResult *pErg)
987 {
988   String h;
989   Boolean Err;
990 
991   pErg->Typ = TempNone;
992   if ((strlen(pAsc) < 2) || ((as_toupper(*pAsc) != 'R') && (as_toupper(*pAsc) != 'P')))
993     return;
994 
995   strmaxcpy(h, pAsc + 1, STRINGSIZE);
996   if ((*h == '0') && (strlen(h) > 1))
997     *h = '$';
998   pErg->Contents.Int = ConstLongInt(h, &Err, 10);
999   if ((!Err) || (pErg->Contents.Int < 0) || (pErg->Contents.Int > 255))
1000     return;
1001 
1002   pErg->Typ = TempInt;
1003   if (as_toupper(*pAsc) == 'P')
1004     pErg->Contents.Int += 0x100;
1005 }
1006 
SwitchFrom_TMS7(void)1007 static void SwitchFrom_TMS7(void)
1008 {
1009   DeinitFields();
1010 }
1011 
SwitchTo_TMS7(void)1012 static void SwitchTo_TMS7(void)
1013 {
1014   TurnWords = False; ConstMode = ConstModeIntel;
1015 
1016   PCSymbol = "$"; HeaderID = 0x73; NOPCode = 0x00;
1017   DivideChars = ","; HasAttrs = False;
1018 
1019   ValidSegs=1 << SegCode;
1020   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
1021   SegLimits[SegCode] = 0xffff;
1022 
1023   MakeCode = MakeCode_TMS7; IsDef = IsDef_TMS7;
1024   SwitchFrom = SwitchFrom_TMS7; InternSymbol = InternSymbol_TMS7;
1025 
1026   InitFields();
1027 }
1028 
codetms7_init(void)1029 void codetms7_init(void)
1030 {
1031   CPU70C00  = AddCPU("TMS70C00", SwitchTo_TMS7);
1032   CPU70C20  = AddCPU("TMS70C20", SwitchTo_TMS7);
1033   CPU70C40  = AddCPU("TMS70C40", SwitchTo_TMS7);
1034   CPU70CT20 = AddCPU("TMS70CT20",SwitchTo_TMS7);
1035   CPU70CT40 = AddCPU("TMS70CT40",SwitchTo_TMS7);
1036   CPU70C02  = AddCPU("TMS70C02", SwitchTo_TMS7);
1037   CPU70C42  = AddCPU("TMS70C42", SwitchTo_TMS7);
1038   CPU70C82  = AddCPU("TMS70C82", SwitchTo_TMS7);
1039   CPU70C08  = AddCPU("TMS70C08", SwitchTo_TMS7);
1040   CPU70C48  = AddCPU("TMS70C48", SwitchTo_TMS7);
1041 }
1042