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