1 /* code3254x.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* Macro Assembler AS */
6 /* */
7 /* Code Generator for TI C54x DSP devices */
8 /* */
9 /*****************************************************************************/
10
11 /*-------------------------------------------------------------------------*/
12 /* Includes */
13
14 #include "stdinc.h"
15 #include <string.h>
16 #include <ctype.h>
17
18 #include "bpemu.h"
19 #include "strutil.h"
20 #include "chunks.h"
21 #include "asmdef.h"
22 #include "asmsub.h"
23 #include "asmpars.h"
24 #include "asmallg.h"
25 #include "asmrelocs.h"
26 #include "asmcode.h"
27 #include "codepseudo.h"
28 #include "tipseudo.h"
29 #include "asmitree.h"
30 #include "codevars.h"
31 #include "fileformat.h"
32 #include "headids.h"
33 #include "errmsg.h"
34
35 #include "code3254x.h"
36
37 /*-------------------------------------------------------------------------*/
38 /* Data Structures */
39
40 #define FixedOrderCnt 12
41 #define AccOrderCnt 16
42 #define Acc2OrderCnt 5
43 #define MemOrderCnt 9
44 #define XYOrderCnt 4
45 #define MemAccOrderCnt 17
46 #define MemConstOrderCnt 5
47 #define MacOrderCnt 3
48 #define ConditionCnt 23
49
50 typedef struct
51 {
52 Word Code;
53 Boolean IsRepeatable;
54 } FixedOrder;
55
56 typedef struct
57 {
58 Word Code;
59 Boolean IsRepeatable, Swap;
60 IntType ConstType;
61 } MemConstOrder;
62
63 typedef struct
64 {
65 const char *Name;
66 Word Class, Code, Mask;
67 } Condition;
68
69 typedef enum {ModNone = - 1, ModAcc, ModMem, ModImm, ModAReg} ModType;
70 #define MModAcc (1 << ModAcc)
71 #define MModMem (1 << ModMem)
72 #define MModImm (1 << ModImm)
73 #define MModAReg (1 << ModAReg)
74
75 static LongInt Reg_CPL, Reg_DP, Reg_SP;
76
77 static Boolean ThisRep, LastRep, ForcePageZero;
78
79 static FixedOrder *FixedOrders, *AccOrders, *Acc2Orders, *MemOrders, *XYOrders,
80 *MemAccOrders, *MacOrders;
81 static MemConstOrder *MemConstOrders;
82 static Condition *Conditions;
83
84 static CPUVar CPU320C541;
85
86 static IntType OpSize;
87 static ShortInt AdrMode;
88 static Word AdrVals[3];
89
90 static Boolean ThisPar;
91 static Word LastOpCode;
92
93 /*-------------------------------------------------------------------------*/
94 /* Address Decoder */
95
96 static const char ShortConds[4][4] =
97 {
98 "EQ", "LT", "GT", "NEQ"
99 };
100
IsAcc(char * Asc)101 static Boolean IsAcc(char *Asc)
102 {
103 return ((Asc[1] == '\0') && (as_toupper(*Asc) >= 'A') && (as_toupper(*Asc) <= 'B'));
104 }
105
DecodeAdr(const tStrComp * pArg,int Mask)106 static Boolean DecodeAdr(const tStrComp *pArg, int Mask)
107 {
108 #define IndirCnt 16
109 static const char Patterns[IndirCnt][9] = /* leading asterisk is omitted since constant */
110 {
111 "ARx", "ARx-", "ARx+", "+ARx",
112 "ARx-0B", "ARx-0", "ARx+0", "ARx+0B",
113 "ARx-%", "ARx-0%", "ARx+%", "ARx+0%",
114 "ARx(n)", "+ARx(n)", "+ARx(n)%", "(n)"
115 };
116 Boolean OK;
117
118 AdrMode = ModNone;
119 AdrCnt = 0;
120
121 /* accumulators */
122
123 if (IsAcc(pArg->Str))
124 {
125 AdrMode = ModAcc;
126 *AdrVals = as_toupper(*pArg->Str) - 'A';
127 goto done;
128 }
129
130 /* aux registers */
131
132 if ((strlen(pArg->Str) == 3) && (!as_strncasecmp(pArg->Str, "AR", 2)) && (pArg->Str[2] >= '0') && (pArg->Str[2] <= '7'))
133 {
134 AdrMode = ModAReg;
135 *AdrVals = pArg->Str[2] - '0';
136 goto done;
137 }
138
139 /* immediate */
140
141 if (*pArg->Str == '#')
142 {
143 *AdrVals = EvalStrIntExpressionOffs(pArg, 1, OpSize, &OK);
144 if (OK)
145 AdrMode = ModImm;
146 goto done;
147 }
148
149 /* indirect */
150
151 if (*pArg->Str == '*')
152 {
153 int z;
154 Word RegNum;
155 char *pConstStart, *pConstEnd;
156
157 /* check all possible patterns */
158
159 for (z = 0; z < IndirCnt; z++)
160 {
161 const char *pPattern = Patterns[z];
162 char *pComp = pArg->Str + 1;
163
164 /* pattern comparison */
165
166 RegNum = 0;
167 pConstStart = pConstEnd = NULL;
168 OK = TRUE;
169 while ((*pPattern) && (*pComp) && (OK))
170 {
171 switch (*pPattern)
172 {
173 case 'x': /* embedded number */
174 RegNum = *pComp - '0';
175 OK = RegNum < 8;
176 break;
177 case 'n': /* constant */
178 pConstStart = pComp;
179 pConstEnd = QuotPos(pComp, pPattern[1]);
180 if (pConstEnd)
181 pComp = pConstEnd - 1;
182 else
183 OK = False;
184 break;
185 default: /* compare verbatim */
186 if (as_toupper(*pPattern) != as_toupper(*pComp))
187 OK = False;
188 }
189 if (OK)
190 {
191 pPattern++;
192 pComp++;
193 }
194 }
195
196 /* for a successful comparison, we must have reached the end of both strings
197 simultaneously. */
198
199 OK = OK && (!*pPattern) && (!*pComp);
200 if (OK)
201 break;
202 }
203
204 if (!OK) WrError(ErrNum_InvAddrMode);
205 else
206 {
207 /* decode offset ? pConst... /must/ be set if such a pattern was successfully
208 decoded! */
209
210 if (strchr(Patterns[z], 'n'))
211 {
212 /* MMR-style instructions do not allow an extension word */
213
214 if (ForcePageZero)
215 {
216 WrError(ErrNum_InvAddrMode);
217 OK = False;
218 }
219 else
220 {
221 tStrComp Start, Remainder;
222 char Save;
223
224 StrCompRefRight(&Start, pArg, pConstStart - pArg->Str);
225 Save = StrCompSplitRef(&Start, &Remainder, &Start, pConstEnd);
226 AdrVals[1] = EvalStrIntExpression(&Start, Int16, &OK);
227 *pConstEnd = Save;
228 if (OK)
229 AdrCnt = 1;
230 }
231 }
232
233 /* all fine until now? Then do the rest... */
234
235 if (OK)
236 {
237 AdrMode = ModMem;
238 AdrVals[0] = 0x80 | (z << 3) | RegNum;
239 }
240 }
241
242 goto done;
243 }
244
245 /* then try absolute resp. immediate if absolute not allowed */
246
247 if (Mask & MModMem)
248 {
249 tSymbolFlags Flags;
250
251 *AdrVals = EvalStrIntExpressionWithFlags(pArg, UInt16, &OK, &Flags);
252 if (OK)
253 {
254 if (Reg_CPL) /* short address rel. to SP? */
255 {
256 *AdrVals -= Reg_SP;
257 if (!mFirstPassUnknown(Flags) && (*AdrVals > 127))
258 WrError(ErrNum_InAccPage);
259 }
260 else /* on DP page ? */
261 {
262 if (!mFirstPassUnknown(Flags) && ((*AdrVals >> 7) != (Reg_DP)))
263 WrError(ErrNum_InAccPage);
264 }
265 AdrVals[0] &= 127;
266 AdrMode = ModMem;
267 }
268 }
269 else
270 {
271 *AdrVals = EvalStrIntExpression(pArg, OpSize, &OK);
272 if (OK)
273 AdrMode = ModImm;
274 }
275
276 done:
277 if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
278 {
279 AdrMode = ModNone; AdrCnt = 0;
280 WrError(ErrNum_InvAddrMode);
281 }
282 return (AdrMode != ModNone);
283 }
284
MakeXY(Word * Dest,Boolean Quarrel)285 static Boolean MakeXY(Word *Dest, Boolean Quarrel)
286 {
287 Boolean Result = False;
288
289 if (AdrMode != ModMem); /* should never occur, if address mask specified correctly before */
290 else
291 {
292 Word Mode = (*AdrVals >> 3) & 15, Reg = *AdrVals & 7;
293
294 if ((Reg < 2) || (Reg > 5));
295 else if ((Mode != 0) && (Mode != 1) && (Mode != 2) && (Mode != 11));
296 else
297 {
298 *Dest = (Reg - 2) | ((Mode & 3) << 2);
299 Result = True;
300 }
301 }
302
303 if ((Quarrel) && (!Result))
304 WrError(ErrNum_InvAddrMode);
305
306 return Result;
307 }
308
DecodeCondition(int StartIndex,Word * Result,int * errindex,Boolean * ErrUnknown)309 static Boolean DecodeCondition(int StartIndex, Word *Result, int *errindex, Boolean *ErrUnknown)
310 {
311 int z, z2;
312 Word CurrClass, CurrMask;
313
314 *Result = CurrMask = 0; CurrClass = 0xffff; *ErrUnknown = False;
315
316 for (z = StartIndex; z <= ArgCnt; z++)
317 {
318 for (z2 = 0; z2 < ConditionCnt; z2++)
319 if (!as_strcasecmp(ArgStr[z].Str, Conditions[z2].Name))
320 break;
321 if (z2 >= ConditionCnt)
322 {
323 *ErrUnknown = True;
324 break;
325 }
326
327 if (CurrClass == 0xffff)
328 CurrClass = Conditions[z2].Class;
329 else if (CurrClass != Conditions[z2].Class)
330 break;
331
332 if (Conditions[z2].Mask & CurrMask)
333 break;
334
335 CurrMask |= Conditions[z2].Mask;
336 *Result |= Conditions[z2].Code;
337 }
338
339 *errindex = z;
340 return (CurrClass != 0xffff) && (z > ArgCnt);
341 }
342
343 /*-------------------------------------------------------------------------*/
344 /* Decoders */
345
DecodeFixed(Word Index)346 static void DecodeFixed(Word Index)
347 {
348 const FixedOrder *POrder = FixedOrders + Index;
349
350 if (!ChkArgCnt(0, 0));
351 else if (ThisPar) WrError(ErrNum_ParNotPossible);
352 else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
353 else
354 {
355 WAsmCode[0] = POrder->Code;
356 CodeLen = 1;
357 }
358 }
359
DecodeAcc(Word Index)360 static void DecodeAcc(Word Index)
361 {
362 const FixedOrder *POrder = AccOrders + Index;
363
364 if (!ChkArgCnt(1, 1));
365 else if (ThisPar) WrError(ErrNum_ParNotPossible);
366 else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
367 else
368 {
369 if (DecodeAdr(&ArgStr[1], MModAcc))
370 {
371 WAsmCode[0] = POrder->Code | (AdrVals[0] << 8);
372 CodeLen = 1;
373 }
374 }
375 }
376
DecodeAcc2(Word Index)377 static void DecodeAcc2(Word Index)
378 {
379 const FixedOrder *POrder = Acc2Orders + Index;
380 Boolean OK;
381
382 if (!ChkArgCnt(1, 2));
383 else if (ThisPar) WrError(ErrNum_ParNotPossible);
384 else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
385 else
386 {
387 OK = DecodeAdr(&ArgStr[1], MModAcc);
388 if (OK)
389 {
390 WAsmCode[0] = POrder->Code | (AdrVals[0] << 9);
391 if (ArgCnt == 2)
392 OK = DecodeAdr(&ArgStr[2], MModAcc);
393 if (OK)
394 {
395 WAsmCode[0] |= (AdrVals[0] << 8);
396 CodeLen = 1;
397 }
398 }
399 }
400 }
401
DecodeMem(Word Index)402 static void DecodeMem(Word Index)
403 {
404 const FixedOrder *POrder = MemOrders + Index;
405
406 if (!ChkArgCnt(1, 1));
407 else if (ThisPar) WrError(ErrNum_ParNotPossible);
408 else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
409 else if (DecodeAdr(&ArgStr[1], MModMem))
410 {
411 memcpy(WAsmCode, AdrVals, (AdrCnt + 1) << 1);
412 WAsmCode[0] |= POrder->Code;
413 CodeLen = 1 + AdrCnt;
414 }
415 }
416
DecodeXY(Word Index)417 static void DecodeXY(Word Index)
418 {
419 const FixedOrder *POrder = XYOrders + Index;
420 Word TmpX, TmpY;
421
422 if (ArgCnt != 2) WrError(ErrNum_InvAddrMode);
423 else if (ThisPar) WrError(ErrNum_ParNotPossible);
424 else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
425 else
426 {
427 if (DecodeAdr(&ArgStr[1], MModMem))
428 if (MakeXY(&TmpX, True))
429 if (DecodeAdr(&ArgStr[2], MModMem))
430 if (MakeXY(&TmpY, True))
431 {
432 WAsmCode[0] = POrder->Code | (TmpX << 4) | TmpY;
433 CodeLen = 1;
434 }
435 }
436 }
437
DecodeADDSUB(Word Index)438 static void DecodeADDSUB(Word Index)
439 {
440 Boolean OK;
441 Integer Shift;
442 Word DestAcc;
443
444 if (ChkArgCnt(2, 4))
445 {
446 OpSize = SInt16;
447 DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModImm);
448 switch (AdrMode)
449 {
450 case ModAcc: /* ADD src, SHIFT|ASM [,dst] */
451 if (!ChkArgCnt(2, 3));
452 else if (ThisPar) WrError(ErrNum_ParNotPossible);
453 else
454 {
455 Word SrcAcc = *AdrVals;
456
457 /* SrcAcc remains in AdrVals[0] if no 3rd operand, therefore
458 no extra assignment needed! */
459
460 if (ArgCnt == 3)
461 {
462 if (!DecodeAdr(&ArgStr[3], MModAcc))
463 break;
464 }
465
466 /* distinguish variants of shift specification: */
467
468 if (!as_strcasecmp(ArgStr[2].Str, "ASM"))
469 {
470 WAsmCode[0] = 0xf480 | Index | (SrcAcc << 9) | (*AdrVals << 8);
471 CodeLen = 1;
472 }
473 else
474 {
475 WAsmCode[0] = EvalStrIntExpression(&ArgStr[2], SInt5, &OK);
476 if (OK)
477 {
478 WAsmCode[0] = (WAsmCode[0] & 0x1f) | 0xf400 | (Index << 5) | (SrcAcc << 9) | (*AdrVals << 8);
479 CodeLen = 1;
480 }
481 }
482 }
483 break;
484
485 case ModMem: /* ADD mem[, TS | SHIFT | Ymem], src[, dst] */
486 {
487 int HCnt;
488
489 /* rescue decoded address values */
490
491 memcpy(WAsmCode, AdrVals, (AdrCnt + 1) << 1);
492 HCnt = AdrCnt;
493
494 /* no shift? this is the case for two operands or three operands and the second is an accumulator */
495
496 if (ArgCnt == 2)
497 Shift = 0;
498 else if ((ArgCnt == 3) && (IsAcc(ArgStr[2].Str)))
499 Shift = 0;
500
501 /* special shift value ? */
502
503 else if (!as_strcasecmp(ArgStr[2].Str, "TS"))
504 Shift = 255;
505
506 /* shift address operand ? */
507
508 else if (*ArgStr[2].Str == '*')
509 {
510 Word Tmp;
511
512 /* break down source operand to reduced variant */
513
514 if (!MakeXY(WAsmCode, True))
515 break;
516 WAsmCode[0] = WAsmCode[0] << 4;
517
518 /* merge in second operand */
519
520 if (!DecodeAdr(&ArgStr[2], MModMem))
521 break;
522 if (!MakeXY(&Tmp, True))
523 break;
524 WAsmCode[0] |= Tmp;
525 Shift = 254;
526 }
527
528 /* normal immediate shift */
529
530 else
531 {
532 tSymbolFlags Flags;
533
534 Shift = EvalStrIntExpressionWithFlags(&ArgStr[2], SInt6, &OK, &Flags);
535 if (!OK)
536 break;
537 if (mFirstPassUnknown(Flags) && (Shift > 16))
538 Shift &= 15;
539 if (!ChkRange(Shift, -16 ,16))
540 break;
541 }
542
543 /* decode destination accumulator */
544
545 if (!DecodeAdr(&ArgStr[ArgCnt], MModAcc))
546 break;
547 DestAcc = *AdrVals;
548
549 /* optionally decode source accumulator. If no second accumulator, result
550 again remains in AdrVals */
551
552 if ((ArgCnt == 4) || ((ArgCnt == 3) && (IsAcc(ArgStr[2].Str))))
553 {
554 if (!DecodeAdr(&ArgStr[ArgCnt - 1], MModAcc))
555 break;
556 }
557
558 /* now start applying the variants */
559
560 if (Shift == 255) /* TS case */
561 {
562 if (*AdrVals != DestAcc) WrError(ErrNum_InvAddrMode);
563 else if (ThisPar) WrError(ErrNum_ParNotPossible);
564 else
565 {
566 WAsmCode[0] |= 0x0400 | (Index << 11) | (DestAcc << 8);
567 CodeLen = 1 + HCnt;
568 }
569 }
570
571 else if (Shift == 254) /* XY case */
572 {
573 if (*AdrVals != DestAcc) WrError(ErrNum_InvAddrMode);
574 else if (ThisPar) WrError(ErrNum_ParNotPossible);
575 else
576 {
577 WAsmCode[0] |= 0xa000 | (Index << 9) | (DestAcc << 8);
578 CodeLen = 1;
579 }
580 }
581
582 else if (Shift == 16) /* optimization for 16 shifts */
583 {
584 if (ThisPar) WrError(ErrNum_ParNotPossible);
585 else
586 {
587 WAsmCode[0] |= (0x3c00 + (Index << 10)) | (*AdrVals << 9) | (DestAcc << 8);
588 CodeLen = 1 + HCnt;
589 }
590 }
591
592 else if ((DestAcc == *AdrVals) && (Shift == 0)) /* shortform without shift and with one accu only */
593 {
594 if (ThisPar)
595 {
596 AdrMode = ModMem; AdrVals[0] = WAsmCode[0];
597 if (MakeXY(AdrVals, True))
598 {
599 /* prev. operation must be STH src,0,Xmem */
600 if ((LastOpCode & 0xfe0f) != 0x9a00) WrError(ErrNum_ParNotPossible);
601 else
602 {
603 RetractWords(1);
604 WAsmCode[0] = 0xc000 | (Index << 10) | (DestAcc << 8) | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals << 4);
605 CodeLen = 1;
606 }
607 }
608 }
609 else
610 {
611 WAsmCode[0] |= 0x0000 | (Index << 11) | (DestAcc << 8);
612 CodeLen = 1 + HCnt;
613 }
614 }
615
616 else if (ThisPar) WrError(ErrNum_ParNotPossible);
617 else
618 {
619 Word SrcAcc = *AdrVals;
620
621 /* fool MakeXY a bit */
622
623 AdrMode = ModMem; AdrVals[0] = WAsmCode[0];
624
625 if ((Shift >= 0) && (DestAcc == SrcAcc) && (MakeXY(WAsmCode, False))) /* X-Addr and positive shift */
626 {
627 WAsmCode[0] = 0x9000 | (Index << 9) | (WAsmCode[0] << 4) | (DestAcc << 8) | Shift;
628 CodeLen = 1;
629 }
630 else /* last resort... */
631 {
632 WAsmCode[0] |= 0x6f00;
633 WAsmCode[2] = WAsmCode[1]; /* shift optional address offset */
634 WAsmCode[1] = 0x0c00 | (Index << 5) | (SrcAcc << 9) | (DestAcc << 8) | (Shift & 0x1f);
635 CodeLen = 2 + HCnt;
636 }
637 }
638
639 break;
640 }
641
642 case ModImm: /* ADD #lk[, SHIFT|16], src[, dst] */
643 {
644 if (ThisPar) WrError(ErrNum_ParNotPossible);
645 {
646 /* store away constant */
647
648 WAsmCode[1] = *AdrVals;
649
650 /* no shift? this is the case for two operands or three operands and the second is an accumulator */
651
652 if (ArgCnt == 2)
653 Shift = 0;
654 else if ((ArgCnt == 3) && (IsAcc(ArgStr[2].Str)))
655 Shift = 0;
656
657 /* otherwise shift is second argument */
658
659 else
660 {
661 tSymbolFlags Flags;
662
663 Shift = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt5, &OK, &Flags);
664 if (!OK)
665 break;
666 if (mFirstPassUnknown(Flags) && (Shift > 16))
667 Shift &= 15;
668 if (!ChkRange(Shift, 0 ,16))
669 break;
670 }
671
672 /* decode destination accumulator */
673
674 if (!DecodeAdr(&ArgStr[ArgCnt], MModAcc))
675 break;
676 DestAcc = *AdrVals;
677
678 /* optionally decode source accumulator. If no second accumulator, result
679 again remains in AdrVals */
680
681 if ((ArgCnt == 4) || ((ArgCnt == 3) && (IsAcc(ArgStr[2].Str))))
682 {
683 if (!DecodeAdr(&ArgStr[ArgCnt - 1], MModAcc))
684 break;
685 }
686
687 /* distinguish according to shift count */
688
689 if (Shift == 16)
690 {
691 WAsmCode[0] = 0xf060 | Index | (DestAcc << 8) | (*AdrVals << 9);
692 CodeLen = 2;
693 }
694 else
695 {
696 WAsmCode[0] = 0xf000 | (Index << 5) | (DestAcc << 8) | (*AdrVals << 9) | (Shift & 15);
697 CodeLen = 2;
698 }
699 }
700 break;
701 }
702 }
703 }
704 }
705
DecodeMemAcc(Word Index)706 static void DecodeMemAcc(Word Index)
707 {
708 FixedOrder *POrder = MemAccOrders + Index;
709
710 if (!ChkArgCnt(2, 2));
711 else if (ThisPar) WrError(ErrNum_ParNotPossible);
712 else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
713 else if (DecodeAdr(&ArgStr[2], MModAcc))
714 {
715 WAsmCode[0] = POrder->Code | (AdrVals[0] << 8);
716 if (DecodeAdr(&ArgStr[1], MModMem))
717 {
718 WAsmCode[0] |= *AdrVals;
719 if (AdrCnt)
720 WAsmCode[1] = AdrVals[1];
721 CodeLen = 1 + AdrCnt;
722 }
723 }
724 }
725
DecodeMemConst(Word Index)726 static void DecodeMemConst(Word Index)
727 {
728 MemConstOrder *POrder = MemConstOrders + Index;
729 int HCnt;
730
731 if (!ChkArgCnt(2, 2));
732 else if (ThisPar) WrError(ErrNum_ParNotPossible);
733 else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
734 else if (DecodeAdr(&ArgStr[2 - POrder->Swap], MModMem))
735 {
736 WAsmCode[0] = POrder->Code | 0[AdrVals];
737 HCnt = AdrCnt;
738 if (HCnt)
739 WAsmCode[1] = AdrVals[1];
740 OpSize = POrder->ConstType;
741 if (DecodeAdr(&ArgStr[1 + POrder->Swap], MModImm))
742 {
743 WAsmCode[1 + HCnt] = *AdrVals;
744 CodeLen = 2 + HCnt;
745 }
746 }
747 }
748
DecodeMPY(Word Index)749 static void DecodeMPY(Word Index)
750 {
751 Word DestAcc;
752
753 (void)Index;
754
755 if (!ChkArgCnt(2, 3));
756 else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
757 {
758 DestAcc = (*AdrVals) << 8;
759 if (ArgCnt == 3)
760 {
761 Word XMode;
762
763 if (ThisPar) WrError(ErrNum_ParNotPossible);
764 else if (DecodeAdr(&ArgStr[1], MModMem))
765 if (MakeXY(&XMode, True))
766 if (DecodeAdr(&ArgStr[2], MModMem))
767 if (MakeXY(WAsmCode, True))
768 {
769 *WAsmCode |= 0xa400 | DestAcc | (XMode << 4);
770 CodeLen = 1;
771 }
772 }
773 else
774 {
775 OpSize = SInt16;
776 DecodeAdr(&ArgStr[1], MModImm | MModMem);
777 switch (AdrMode)
778 {
779 case ModImm:
780 if (ThisPar) WrError(ErrNum_ParNotPossible);
781 else
782 {
783 WAsmCode[0] = 0xf066 | DestAcc;
784 WAsmCode[1] = *AdrVals;
785 CodeLen = 2;
786 }
787 break;
788 case ModMem:
789 if (ThisPar)
790 {
791 if (MakeXY(AdrVals, True))
792 {
793 /* previous op ST src, Ym */
794 if ((LastOpCode & 0xfe0f) != 0x9a00) WrError(ErrNum_ParNotPossible);
795 else
796 {
797 RetractWords(1);
798 *WAsmCode = 0xcc00 | DestAcc | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals);
799 CodeLen = 1;
800 }
801 }
802 }
803 else
804 {
805 WAsmCode[0] = 0x2000 | DestAcc | 0[AdrVals];
806 if (AdrCnt)
807 WAsmCode[1] = AdrVals[1];
808 CodeLen = 1 + AdrCnt;
809 }
810 break;
811 }
812 }
813 }
814 }
815
DecodeMPYA(Word Index)816 static void DecodeMPYA(Word Index)
817 {
818 (void) Index;
819
820 if (!ChkArgCnt(1, 1));
821 else if (ThisPar) WrError(ErrNum_ParNotPossible);
822 else
823 {
824 DecodeAdr(&ArgStr[1], MModAcc | MModMem);
825 switch (AdrMode)
826 {
827 case ModMem:
828 WAsmCode[0] = 0x3100 | AdrVals[0];
829 if (AdrCnt)
830 WAsmCode[1] = AdrVals[1];
831 CodeLen = 1 + AdrCnt;
832 break;
833 case ModAcc:
834 WAsmCode[0] = 0xf48c | (*AdrVals << 8);
835 CodeLen = 1;
836 break;
837 }
838 }
839 }
840
DecodeSQUR(Word Index)841 static void DecodeSQUR(Word Index)
842 {
843 (void)Index;
844
845 if (!ChkArgCnt(2, 2));
846 else if (ThisPar) WrError(ErrNum_ParNotPossible);
847 else if (DecodeAdr(&ArgStr[2], MModAcc))
848 {
849 0[WAsmCode] = *AdrVals << 8;
850 DecodeAdr(&ArgStr[1], MModAcc | MModMem);
851 switch (AdrMode)
852 {
853 case ModAcc:
854 if (*AdrVals) WrError(ErrNum_InvAddrMode);
855 else
856 {
857 WAsmCode[0] |= 0xf48d;
858 CodeLen = 1;
859 }
860 break;
861 case ModMem:
862 WAsmCode[0] |= 0x2600 | *AdrVals;
863 if (AdrCnt)
864 WAsmCode[1] = AdrVals[1];
865 CodeLen = 1 + AdrCnt;
866 break;
867 }
868 }
869 }
870
DecodeMAC(Word Index)871 static void DecodeMAC(Word Index)
872 {
873 (void) Index;
874
875 if (!ChkArgCnt(2, 4));
876 else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
877 {
878 *WAsmCode = (*AdrVals) << 8;
879 OpSize = SInt16;
880 DecodeAdr(&ArgStr[1], MModImm | MModMem);
881
882 /* handle syntax 3: immediate op first */
883
884 if (AdrMode == ModImm)
885 {
886 if (!ChkArgCnt(2, 3));
887 else if (ThisPar) WrError(ErrNum_ParNotPossible);
888 else
889 {
890 *WAsmCode |= 0xf067; WAsmCode[1] = *AdrVals;
891 if (ArgCnt == 2)
892 {
893 *WAsmCode |= ((*WAsmCode & 0x100) << 1);
894 CodeLen = 2;
895 }
896 else if (DecodeAdr(&ArgStr[2], MModAcc))
897 {
898 *WAsmCode |= ((*AdrVals) << 9);
899 CodeLen = 2;
900 }
901 }
902 }
903
904 /* syntax 1/2/4 have memory operand in front */
905
906 else if (AdrMode == ModMem)
907 {
908 /* save [first] memory operand */
909
910 Word HMode = *AdrVals, HCnt = AdrCnt;
911 if (AdrCnt)
912 WAsmCode[1] = AdrVals[1];
913
914 /* syntax 2+4 have at least 3 operands, handle syntax 1 */
915
916 if (ArgCnt == 2)
917 {
918 if (ThisPar)
919 {
920 if (MakeXY(AdrVals, True))
921 {
922 if ((LastOpCode & 0xfe0f) == 0x9400) /* previous op LD Xmem, src */
923 {
924 if ((LastOpCode & 0x0100) == (*WAsmCode & 0x0100)) WrError(ErrNum_ParNotPossible);
925 else
926 {
927 RetractWords(1);
928 *WAsmCode = 0xa800 | (LastOpCode & 0x01f0) | (*AdrVals);
929 CodeLen = 1;
930 }
931 }
932 else if ((LastOpCode & 0xfe0f) == 0x9a00) /* previous op ST src, Ymem */
933 {
934 RetractWords(1);
935 *WAsmCode |= 0xd000 | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals << 4);
936 CodeLen = 1;
937 }
938 else WrError(ErrNum_ParNotPossible);
939 }
940 }
941 else
942 {
943 *WAsmCode |= 0x2800 | HMode;
944 CodeLen = 1 + AdrCnt;
945 }
946 }
947 else if (ThisPar) WrError(ErrNum_ParNotPossible);
948 else
949 {
950 /* both syntax 2+4 have optional second accumulator */
951
952 if (ArgCnt == 3)
953 *WAsmCode |= ((*WAsmCode & 0x100) << 1);
954 else if (DecodeAdr(&ArgStr[3], MModAcc))
955 *WAsmCode |= ((*AdrVals) << 9);
956
957 /* if no second accu, AdrMode is still set from previous decode */
958
959 if (AdrMode != ModNone)
960 {
961 /* differentiate & handle syntax 2 & 4. OpSize still set from above! */
962
963 DecodeAdr(&ArgStr[2], MModMem | MModImm);
964 switch (AdrMode)
965 {
966 case ModMem:
967 if (MakeXY(AdrVals, TRUE))
968 {
969 WAsmCode[0] |= (*AdrVals);
970 *AdrVals = HMode;
971 if (MakeXY(&HMode, TRUE))
972 {
973 WAsmCode[0] |= 0xb000 | (HMode << 4);
974 CodeLen = 1;
975 }
976 }
977 break;
978 case ModImm:
979 WAsmCode[1 + HCnt] = *AdrVals;
980 WAsmCode[0] |= 0x6400 | HMode;
981 CodeLen = 2 + HCnt;
982 break;
983 }
984 }
985 }
986 }
987 }
988 }
989
DecodeMACDP(Word Index)990 static void DecodeMACDP(Word Index)
991 {
992 if (!ChkArgCnt(3, 3));
993 else if (ThisPar) WrError(ErrNum_ParNotPossible);
994 else if (DecodeAdr(&ArgStr[3], MModAcc))
995 {
996 *WAsmCode = Index | (0[AdrVals] << 8);
997 if (DecodeAdr(&ArgStr[1], MModMem))
998 {
999 tEvalResult EvalResult;
1000
1001 *WAsmCode |= *AdrVals;
1002 if (AdrCnt)
1003 WAsmCode[1] = AdrVals[1];
1004 WAsmCode[1 + AdrCnt] = EvalStrIntExpressionWithResult(&ArgStr[2], UInt16, &EvalResult);
1005 if (EvalResult.OK)
1006 {
1007 ChkSpace(Index & 0x200 ? SegData : SegCode, EvalResult.AddrSpaceMask);
1008 CodeLen = 2 + AdrCnt;
1009 }
1010 }
1011 }
1012 }
1013
DecodeFIRS(Word Index)1014 static void DecodeFIRS(Word Index)
1015 {
1016 (void)Index;
1017
1018 if (!ChkArgCnt(3, 3));
1019 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1020 else if (DecodeAdr(&ArgStr[1], MModMem))
1021 if (MakeXY(WAsmCode, TRUE))
1022 {
1023 0[WAsmCode] = 0xe000 | ((*WAsmCode) << 4);
1024 if (DecodeAdr(&ArgStr[2], MModMem))
1025 if (MakeXY(AdrVals, TRUE))
1026 {
1027 tEvalResult EvalResult;
1028
1029 0[WAsmCode] |= *AdrVals;
1030 WAsmCode[1] = EvalStrIntExpressionWithResult(&ArgStr[3], UInt16, &EvalResult);
1031 if (EvalResult.OK)
1032 {
1033 ChkSpace(SegCode, EvalResult.AddrSpaceMask);
1034 CodeLen = 2;
1035 }
1036 }
1037 }
1038 }
1039
DecodeBIT(Word Index)1040 static void DecodeBIT(Word Index)
1041 {
1042 Boolean OK;
1043
1044 (void)Index;
1045
1046 if (!ChkArgCnt(2, 2));
1047 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1048 else if (DecodeAdr(&ArgStr[1], MModMem))
1049 if (MakeXY(AdrVals, TRUE))
1050 {
1051 WAsmCode[0] = EvalStrIntExpression(&ArgStr[2], UInt4, &OK);
1052 if (OK)
1053 {
1054 WAsmCode[0] |= 0x9600 | (AdrVals[0] << 4);
1055 CodeLen = 1;
1056 }
1057 }
1058 }
1059
DecodeBITF(Word Index)1060 static void DecodeBITF(Word Index)
1061 {
1062 UNUSED(Index);
1063
1064 if (!ChkArgCnt(2, 2));
1065 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1066 else
1067 {
1068 OpSize = UInt16;
1069 if (DecodeAdr(&ArgStr[2], MModImm))
1070 {
1071 WAsmCode[1] = *AdrVals;
1072 if (DecodeAdr(&ArgStr[1], MModMem))
1073 {
1074 *WAsmCode = 0x6100 | *AdrVals;
1075 if (AdrCnt)
1076 {
1077 WAsmCode[2] = WAsmCode[1];
1078 WAsmCode[1] = AdrVals[1];
1079 }
1080 CodeLen = 2 + AdrCnt;
1081 }
1082 }
1083 }
1084 }
1085
DecodeMACR(Word Index)1086 static void DecodeMACR(Word Index)
1087 {
1088 (void) Index;
1089
1090 if (!ChkArgCnt(2, 4));
1091 else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
1092 {
1093 *WAsmCode = *AdrVals << 8;
1094 if (DecodeAdr(&ArgStr[1], MModMem))
1095 {
1096 if (ArgCnt == 2)
1097 {
1098 if (ThisPar)
1099 {
1100 if (MakeXY(AdrVals, True))
1101 {
1102 if ((LastOpCode & 0xfe0f) == 0x9400) /* previous op LD Xmem, src */
1103 {
1104 if ((LastOpCode & 0x0100) == (*WAsmCode & 0x0100)) WrError(ErrNum_ParNotPossible);
1105 else
1106 {
1107 RetractWords(1);
1108 *WAsmCode = 0xaa00 | (LastOpCode & 0x01f0) | (*AdrVals);
1109 CodeLen = 1;
1110 }
1111 }
1112 else if ((LastOpCode & 0xfe0f) == 0x9a00) /* previous op ST src, Ymem */
1113 {
1114 RetractWords(1);
1115 *WAsmCode |= 0xd400 | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals << 4);
1116 CodeLen = 1;
1117 }
1118 else WrError(ErrNum_ParNotPossible);
1119 }
1120 }
1121 else
1122 {
1123 WAsmCode[0] |= 0x2a00 | *AdrVals;
1124 if (AdrCnt)
1125 WAsmCode[1] = AdrVals[1];
1126 CodeLen = 1 + AdrCnt;
1127 }
1128 }
1129 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1130 else
1131 {
1132 if (MakeXY(AdrVals, True))
1133 {
1134 WAsmCode[0] |= 0xb400 | ((*AdrVals) << 4);
1135 if (DecodeAdr(&ArgStr[2], MModMem))
1136 if (MakeXY(AdrVals, True))
1137 {
1138 WAsmCode[0] |= *AdrVals;
1139 if (ArgCnt == 4)
1140 {
1141 if (DecodeAdr(&ArgStr[3], MModAcc))
1142 WAsmCode[0] |= (*AdrVals) << 9;
1143 }
1144 else
1145 *WAsmCode |= ((*WAsmCode & 0x100) << 1);
1146 if (AdrMode != ModNone)
1147 CodeLen = 1;
1148 }
1149 }
1150 }
1151 }
1152 }
1153 }
1154
DecodeMac(Word Index)1155 static void DecodeMac(Word Index)
1156 {
1157 FixedOrder *POrder = MacOrders + Index;
1158
1159 if (!ChkArgCnt(1, ArgCntMax));
1160 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1161 else if (!as_strcasecmp(ArgStr[1].Str, "T"))
1162 {
1163 if (!ChkArgCnt(1, 3));
1164 else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
1165 {
1166 WAsmCode[0] = 0xf480 | (POrder->Code & 0xff) | ((*AdrVals) << 8);
1167 if (ArgCnt == 3)
1168 DecodeAdr(&ArgStr[2], MModAcc);
1169 if (AdrMode != ModNone)
1170 {
1171 WAsmCode[0] |= ((*AdrVals) << 9);
1172 CodeLen = 1;
1173 }
1174 }
1175 }
1176 else if (!ChkArgCnt(1, 2));
1177 else
1178 {
1179 if ((ArgCnt == 2) && (as_strcasecmp(ArgStr[2].Str, "B"))) WrError(ErrNum_InvAddrMode);
1180 else if (DecodeAdr(&ArgStr[1], MModMem))
1181 {
1182 WAsmCode[0] = (POrder->Code & 0xff00) | (*AdrVals);
1183 if (AdrCnt)
1184 WAsmCode[1] = AdrVals[1];
1185 CodeLen = 1 + AdrCnt;
1186 }
1187 }
1188 }
1189
DecodeMACSU(Word Index)1190 static void DecodeMACSU(Word Index)
1191 {
1192 (void)Index;
1193
1194 if (!ChkArgCnt(3, 3));
1195 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1196 else if (DecodeAdr(&ArgStr[3], MModAcc))
1197 {
1198 *WAsmCode = 0xa600 | ((*AdrVals) << 8);
1199 if ((DecodeAdr(&ArgStr[1], MModMem))
1200 && (MakeXY(AdrVals, TRUE)))
1201 {
1202 *WAsmCode |= ((*AdrVals) << 4);
1203 if ((DecodeAdr(&ArgStr[2], MModMem))
1204 && (MakeXY(AdrVals, TRUE)))
1205 {
1206 *WAsmCode |= *AdrVals;
1207 CodeLen = 1;
1208 }
1209 }
1210 }
1211 }
1212
DecodeMAS(Word Index)1213 static void DecodeMAS(Word Index)
1214 {
1215 if (!ChkArgCnt(2, 4));
1216 else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
1217 {
1218 *WAsmCode = ((*AdrVals) << 8);
1219 if (DecodeAdr(&ArgStr[1], MModMem))
1220 {
1221 if (ArgCnt == 2)
1222 {
1223 if (ThisPar)
1224 {
1225 if (MakeXY(AdrVals, True))
1226 {
1227 if ((LastOpCode & 0xfe0f) == 0x9400) /* previous op LD Xmem, src */
1228 {
1229 if ((LastOpCode & 0x0100) == (*WAsmCode & 0x0100)) WrError(ErrNum_ParNotPossible);
1230 else
1231 {
1232 RetractWords(1);
1233 *WAsmCode = 0xac00 | Index | (LastOpCode & 0x01f0) | (*AdrVals);
1234 CodeLen = 1;
1235 }
1236 }
1237 else if ((LastOpCode & 0xfe0f) == 0x9a00) /* previous op ST src, Ymem */
1238 {
1239 RetractWords(1);
1240 *WAsmCode |= 0xd800 | (Index << 1) | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals << 4);
1241 CodeLen = 1;
1242 }
1243 else WrError(ErrNum_ParNotPossible);
1244 }
1245 }
1246 else
1247 {
1248 *WAsmCode |= 0x2c00 | Index | *AdrVals;
1249 if (AdrCnt)
1250 1[WAsmCode] = AdrVals[1];
1251 CodeLen = 1 + AdrCnt;
1252 }
1253 }
1254 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1255 else if (MakeXY(AdrVals, TRUE))
1256 {
1257 *WAsmCode |= 0xb800 | (Index << 1) | ((*AdrVals) << 4);
1258 if (DecodeAdr(&ArgStr[2], MModMem))
1259 if (MakeXY(AdrVals, TRUE))
1260 {
1261 *WAsmCode |= *AdrVals;
1262 if (ArgCnt == 4)
1263 {
1264 if (DecodeAdr(&ArgStr[3], MModAcc))
1265 *WAsmCode |= ((*AdrVals) << 9);
1266 }
1267 else
1268 *WAsmCode |= ((*WAsmCode & 0x100) << 1);
1269 if (AdrMode != ModNone)
1270 CodeLen = 1;
1271 }
1272 }
1273 }
1274 }
1275 }
1276
DecodeMASAR(Word Index)1277 static void DecodeMASAR(Word Index)
1278 {
1279 (void)Index;
1280
1281 if (!ChkArgCnt(2, 3));
1282 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1283 else if (as_strcasecmp(ArgStr[1].Str, "T")) WrError(ErrNum_InvAddrMode);
1284 else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
1285 {
1286 WAsmCode[0] = (*AdrVals << 8);
1287 if (ArgCnt == 3)
1288 DecodeAdr(&ArgStr[2], MModAcc);
1289 if (AdrMode != ModNone)
1290 {
1291 *WAsmCode |= 0xf48b | ((*AdrVals) << 9);
1292 CodeLen = 1;
1293 }
1294 }
1295 }
1296
DecodeDADD(Word Index)1297 static void DecodeDADD(Word Index)
1298 {
1299 (void)Index;
1300
1301 if (!ChkArgCnt(2, 3));
1302 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1303 else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
1304 {
1305 WAsmCode[0] = 0x5000 | (AdrVals[0] << 8);
1306 if (ArgCnt == 3)
1307 DecodeAdr(&ArgStr[2], MModAcc);
1308 if (AdrMode != ModNone)
1309 {
1310 WAsmCode[0] |= (AdrVals[0] << 9);
1311 if (DecodeAdr(&ArgStr[1], MModMem))
1312 {
1313 WAsmCode[0] |= AdrVals[0];
1314 if (AdrCnt)
1315 WAsmCode[1] = AdrVals[1];
1316 CodeLen = 1 + AdrCnt;
1317 }
1318 }
1319 }
1320 }
1321
DecodeLog(Word Index)1322 static void DecodeLog(Word Index)
1323 {
1324 Word Acc, Shift;
1325 Boolean OK;
1326
1327 if (!ChkArgCnt(1, 4));
1328 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1329 else
1330 {
1331 OpSize = UInt16;
1332 DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModImm);
1333 switch (AdrMode)
1334 {
1335 case ModAcc: /* Variant 4 */
1336 if (ChkArgCnt(1, 3))
1337 {
1338 Acc = *AdrVals << 9;
1339 *WAsmCode = 0xf080 | Acc | (Index << 5);
1340 Shift = 0; OK = True;
1341 if (((ArgCnt == 2) && IsAcc(ArgStr[2].Str)) || (ArgCnt == 3))
1342 {
1343 OK = DecodeAdr(&ArgStr[ArgCnt], MModAcc);
1344 if (OK)
1345 Acc = *AdrVals << 8;
1346 }
1347 else
1348 Acc = Acc >> 1;
1349 if (OK)
1350 if (((ArgCnt == 2) && (!IsAcc(ArgStr[2].Str))) || (ArgCnt == 3))
1351 {
1352 Shift = EvalStrIntExpression(&ArgStr[2], SInt5, &OK);
1353 }
1354 if (OK)
1355 {
1356 *WAsmCode |= Acc | (Shift & 0x1f);
1357 CodeLen = 1;
1358 }
1359 }
1360 break;
1361
1362 case ModMem: /* Variant 1 */
1363 if (ChkArgCnt(2, 2))
1364 {
1365 *WAsmCode = 0x1800 | (*AdrVals) | (Index << 9);
1366 if (AdrCnt)
1367 WAsmCode[1] = AdrVals[1];
1368 CodeLen = AdrCnt + 1;
1369 if (DecodeAdr(&ArgStr[2], MModAcc))
1370 *WAsmCode |= (*AdrVals) << 8;
1371 else
1372 CodeLen = 0;
1373 }
1374 break;
1375
1376 case ModImm: /* Variant 2,3 */
1377 if (ChkArgCnt(2, 4))
1378 {
1379 WAsmCode[1] = *AdrVals;
1380 if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
1381 {
1382 *WAsmCode = Acc = *AdrVals << 8;
1383 Shift = 0;
1384 OK = True;
1385 if (((ArgCnt == 3) && IsAcc(ArgStr[2].Str)) || (ArgCnt == 4))
1386 {
1387 OK = DecodeAdr(&ArgStr[ArgCnt - 1], MModAcc);
1388 if (OK)
1389 Acc = (*AdrVals) << 9;
1390 }
1391 else
1392 Acc = Acc << 1;
1393 if (OK)
1394 {
1395 if (((ArgCnt == 3) && (!IsAcc(ArgStr[2].Str))) || (ArgCnt == 4))
1396 {
1397 tSymbolFlags Flags;
1398
1399 Shift = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt5, &OK, &Flags);
1400 if (mFirstPassUnknown(Flags))
1401 Shift &= 15;
1402 OK = ChkRange(Shift, 0, 16);
1403 }
1404 }
1405 if (OK)
1406 {
1407 *WAsmCode |= Acc;
1408 if (Shift == 16) /* Variant 3 */
1409 {
1410 *WAsmCode |= 0xf063 + Index;
1411 }
1412 else /* Variant 2 */
1413 {
1414 *WAsmCode |= 0xf000 | ((Index + 3) << 4) | Shift;
1415 }
1416 CodeLen = 2;
1417 }
1418 }
1419 }
1420 break;
1421 }
1422 }
1423 }
1424
DecodeSFT(Word Index)1425 static void DecodeSFT(Word Index)
1426 {
1427 Boolean OK;
1428 int Shift;
1429
1430 if (!ChkArgCnt(2, 3));
1431 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1432 else if (DecodeAdr(&ArgStr[1], MModAcc))
1433 {
1434 0[WAsmCode] = Index | ((*AdrVals) << 9);
1435 if (ArgCnt == 3)
1436 DecodeAdr(&ArgStr[3], MModAcc);
1437 if (AdrMode != ModNone)
1438 {
1439 0[WAsmCode] |= ((*AdrVals) << 8);
1440 Shift = EvalStrIntExpression(&ArgStr[2], SInt5, &OK);
1441 if (OK)
1442 {
1443 0[WAsmCode] |= (Shift & 0x1f);
1444 CodeLen = 1;
1445 }
1446 }
1447 }
1448 }
1449
DecodeCMPR(Word Index)1450 static void DecodeCMPR(Word Index)
1451 {
1452 Word z;
1453 Boolean OK;
1454
1455 (void) Index;
1456
1457 if (!ChkArgCnt(2, 2));
1458 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1459 else if (DecodeAdr(&ArgStr[2], MModAReg))
1460 {
1461 OK = False;
1462 for (z = 0; z < 4; z++)
1463 if (!as_strcasecmp(ArgStr[1].Str, ShortConds[z]))
1464 {
1465 OK = True;
1466 break;
1467 }
1468 if (!OK)
1469 z = EvalStrIntExpression(&ArgStr[1], UInt2, &OK);
1470 if (OK)
1471 {
1472 0[WAsmCode] = 0xf4a8 | (*AdrVals) | (z << 8);
1473 CodeLen = 1;
1474 }
1475 }
1476 }
1477
DecodePMAD(Word Index)1478 static void DecodePMAD(Word Index)
1479 {
1480 if (!ChkArgCnt(1, 1));
1481 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1482 else if (LastRep) WrError(ErrNum_NotRepeatable);
1483 else
1484 {
1485 tEvalResult EvalResult;
1486
1487 WAsmCode[1] = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
1488 if (EvalResult.OK)
1489 {
1490 ChkSpace(SegCode, EvalResult.AddrSpaceMask);
1491 0[WAsmCode] = Index;
1492 CodeLen = 2;
1493 }
1494 }
1495 }
1496
DecodeBANZ(Word Index)1497 static void DecodeBANZ(Word Index)
1498 {
1499 if (!ChkArgCnt(2, 2));
1500 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1501 else if (LastRep) WrError(ErrNum_NotRepeatable);
1502 else if (DecodeAdr(&ArgStr[2], MModMem))
1503 {
1504 tEvalResult EvalResult;
1505
1506 if (CodeLen)
1507 WAsmCode[1] = 1[AdrVals];
1508 WAsmCode[1 + CodeLen] = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
1509 if (EvalResult.OK)
1510 {
1511 ChkSpace(SegCode, EvalResult.AddrSpaceMask);
1512 0[WAsmCode] = Index | (*AdrVals);
1513 CodeLen = 2 + AdrCnt;
1514 }
1515 }
1516 }
1517
DecodePMADCond(Word Index)1518 static void DecodePMADCond(Word Index)
1519 {
1520 int index;
1521 Boolean OK;
1522
1523 if (!ChkArgCnt(2, ArgCntMax));
1524 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1525 else if (LastRep) WrError(ErrNum_NotRepeatable);
1526 else if (!DecodeCondition(2, WAsmCode, &index, &OK))
1527 WrStrErrorPos(OK ? ErrNum_UndefCond : ErrNum_IncompCond, &ArgStr[index]);
1528 else
1529 {
1530 tEvalResult EvalResult;
1531
1532 WAsmCode[1] = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
1533 if (EvalResult.OK)
1534 {
1535 ChkSpace(SegCode, EvalResult.AddrSpaceMask);
1536 0[WAsmCode] |= Index;
1537 CodeLen = 2;
1538 }
1539 }
1540 }
1541
DecodeFPMAD(Word Index)1542 static void DecodeFPMAD(Word Index)
1543 {
1544 if (!ChkArgCnt(1, 1));
1545 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1546 else if (LastRep) WrError(ErrNum_NotRepeatable);
1547 else
1548 {
1549 tEvalResult EvalResult;
1550 LongWord Addr = EvalStrIntExpressionWithResult(&ArgStr[1], UInt23, &EvalResult);
1551 if (EvalResult.OK)
1552 {
1553 ChkSpace(SegCode, EvalResult.AddrSpaceMask);
1554 0[WAsmCode] = Index | (Addr >> 16);
1555 1[WAsmCode] = Addr & 0xffff;
1556 CodeLen = 2;
1557 }
1558 }
1559 }
1560
DecodeINTR(Word Index)1561 static void DecodeINTR(Word Index)
1562 {
1563 Boolean OK;
1564
1565 if (!ChkArgCnt(1, 1));
1566 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1567 else if (LastRep) WrError(ErrNum_NotRepeatable);
1568 else
1569 {
1570 *WAsmCode = Index | EvalStrIntExpression(&ArgStr[1], UInt5, &OK);
1571 if (OK)
1572 CodeLen = 1;
1573 }
1574 }
1575
DecodeRPT(Word Index)1576 static void DecodeRPT(Word Index)
1577 {
1578 UNUSED(Index);
1579
1580 if (!ChkArgCnt(1, 1));
1581 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1582 else if (LastRep) WrError(ErrNum_NotRepeatable);
1583 else
1584 {
1585 OpSize = UInt16;
1586 DecodeAdr(&ArgStr[1], MModImm | MModMem);
1587 switch (AdrMode)
1588 {
1589 case ModImm:
1590 if (!Hi(*AdrVals))
1591 {
1592 *WAsmCode = 0xec00 | (*AdrVals);
1593 CodeLen = 1;
1594 }
1595 else
1596 {
1597 *WAsmCode = 0xf070;
1598 WAsmCode[1] = *AdrVals;
1599 CodeLen = 2;
1600 }
1601 ThisRep = True;
1602 break;
1603 case ModMem:
1604 WAsmCode[0] = 0x4700 | (*AdrVals);
1605 if (AdrCnt)
1606 WAsmCode[1] = AdrVals[1];
1607 CodeLen = 1 + AdrCnt;
1608 ThisRep = True;
1609 break;
1610 }
1611 }
1612 }
1613
DecodeRPTZ(Word Index)1614 static void DecodeRPTZ(Word Index)
1615 {
1616 UNUSED(Index);
1617
1618 if (!ChkArgCnt(2, 2));
1619 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1620 else if (LastRep) WrError(ErrNum_NotRepeatable);
1621 else if (DecodeAdr(&ArgStr[1], MModAcc))
1622 {
1623 *WAsmCode = 0xf071 | (AdrVals[0] << 8);
1624 OpSize = UInt16;
1625 if (DecodeAdr(&ArgStr[2], MModImm))
1626 {
1627 WAsmCode[1] = *AdrVals;
1628 CodeLen = 2;
1629 ThisRep = True;
1630 }
1631 }
1632 }
1633
DecodeFRAME(Word Index)1634 static void DecodeFRAME(Word Index)
1635 {
1636 Boolean OK;
1637
1638 UNUSED(Index);
1639
1640 if (!ChkArgCnt(1, 1));
1641 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1642 else
1643 {
1644 *WAsmCode = 0xee00 | (EvalStrIntExpression(&ArgStr[1], SInt8, &OK) & 0xff);
1645 if (OK)
1646 CodeLen = 1;
1647 }
1648 }
1649
DecodeIDLE(Word Index)1650 static void DecodeIDLE(Word Index)
1651 {
1652 Boolean OK;
1653
1654 UNUSED(Index);
1655
1656 if (!ChkArgCnt(1, 1));
1657 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1658 else if (LastRep) WrError(ErrNum_NotRepeatable);
1659 else
1660 {
1661 tSymbolFlags Flags;
1662
1663 *WAsmCode = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt2, &OK, &Flags);
1664 if (mFirstPassUnknown(Flags))
1665 *WAsmCode = 1;
1666 if ((OK) && (ChkRange(*WAsmCode, 1, 3)))
1667 {
1668 if (*WAsmCode != 2)
1669 *WAsmCode = (*WAsmCode) >> 1;
1670 *WAsmCode = 0xf4e1 | (*WAsmCode << 8);
1671 CodeLen = 1;
1672 }
1673 }
1674 }
1675
DecodeSBIT(Word Index)1676 static void DecodeSBIT(Word Index)
1677 {
1678 Boolean OK;
1679 Word Bit;
1680
1681 if (!ChkArgCnt(1, 2));
1682 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1683 else if (LastRep) WrError(ErrNum_NotRepeatable);
1684 else
1685 {
1686 if (ArgCnt == 1)
1687 Bit = EvalStrIntExpression(&ArgStr[1], UInt5, &OK);
1688 else
1689 {
1690 Bit = EvalStrIntExpression(&ArgStr[1], UInt1, &OK) << 4;
1691 if (OK)
1692 Bit |= EvalStrIntExpression(&ArgStr[2], UInt4, &OK);
1693 }
1694 if (OK)
1695 {
1696 *WAsmCode = Index | ((Bit & 16) << 5) | (Bit & 15);
1697 CodeLen = 1;
1698 }
1699 }
1700 }
1701
DecodeXC(Word Index)1702 static void DecodeXC(Word Index)
1703 {
1704 Boolean OK;
1705 int errindex;
1706
1707 UNUSED(Index);
1708
1709 if (!ChkArgCnt(2, ArgCntMax));
1710 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1711 else if (LastRep) WrError(ErrNum_NotRepeatable);
1712 else if (!DecodeCondition(2, WAsmCode, &errindex, &OK))
1713 WrStrErrorPos(OK ? ErrNum_UndefCond : ErrNum_IncompCond, &ArgStr[errindex]);
1714 else
1715 {
1716 tSymbolFlags Flags;
1717
1718 errindex = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt2, &OK, &Flags);
1719 if (mFirstPassUnknown(Flags))
1720 errindex = 1;
1721 if ((OK) && (ChkRange(errindex, 1, 2)))
1722 {
1723 errindex--;
1724 0[WAsmCode] |= 0xfd00 | (errindex << 9);
1725 CodeLen = 1;
1726 }
1727 }
1728 }
1729
DecodeLD(Word Index)1730 static void DecodeLD(Word Index)
1731 {
1732 Integer Shift;
1733 Boolean OK;
1734
1735 UNUSED(Index);
1736
1737 if (!ChkArgCnt(2, 3));
1738
1739 else if (!as_strcasecmp(ArgStr[ArgCnt].Str, "T"))
1740 {
1741 if (!ChkArgCnt(2, 2));
1742 else if (DecodeAdr(&ArgStr[1], MModMem))
1743 {
1744 if (ThisPar)
1745 {
1746 if (MakeXY(AdrVals, TRUE))
1747 {
1748 /* prev. operation must be STH src,0,Xmem */
1749 if ((LastOpCode & 0xfe0f) != 0x9a00) WrError(ErrNum_ParNotPossible);
1750 else
1751 {
1752 RetractWords(1);
1753 *WAsmCode = 0xe400 | ((LastOpCode & 0x0100) << 1)
1754 | ((LastOpCode & 0x00f0) >> 4) | ((*AdrVals) << 4);
1755 CodeLen = 1;
1756 }
1757 }
1758 }
1759 else
1760 {
1761 WAsmCode[0] = 0x3000 | AdrVals[0];
1762 if (AdrCnt)
1763 WAsmCode[1] = AdrVals[1];
1764 CodeLen = 1 + AdrCnt;
1765 }
1766 }
1767 }
1768
1769 else if (!as_strcasecmp(ArgStr[ArgCnt].Str, "DP"))
1770 {
1771 if (!ChkArgCnt(2, 2));
1772 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1773 else
1774 {
1775 OpSize = UInt9;
1776 DecodeAdr(&ArgStr[1], MModMem | MModImm);
1777 switch (AdrMode)
1778 {
1779 case ModMem:
1780 WAsmCode[0] = 0x2600 | AdrVals[0];
1781 if (AdrCnt)
1782 WAsmCode[1] = AdrVals[1];
1783 CodeLen = 1 + AdrCnt;
1784 break;
1785 case ModImm:
1786 WAsmCode[0] = 0xea00 | (AdrVals[0] & 0x1ff);
1787 CodeLen = 1;
1788 break;
1789 }
1790 }
1791 }
1792
1793 else if (!as_strcasecmp(ArgStr[ArgCnt].Str, "ARP"))
1794 {
1795 if (!ChkArgCnt(2, 2));
1796 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1797 else
1798 {
1799 OpSize = UInt3;
1800 if (DecodeAdr(&ArgStr[1], MModImm))
1801 {
1802 WAsmCode[0] = 0xf4a0 | (AdrVals[0] & 7);
1803 CodeLen = 1;
1804 }
1805 }
1806 }
1807
1808 else if (!as_strcasecmp(ArgStr[2].Str, "ASM"))
1809 {
1810 if (ThisPar) WrError(ErrNum_ParNotPossible);
1811 else
1812 {
1813 OpSize = SInt5;
1814 DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModImm);
1815 switch (AdrMode)
1816 {
1817 case ModAcc:
1818 WAsmCode[0] = *AdrVals << 9;
1819 if (ArgCnt == 3)
1820 DecodeAdr(&ArgStr[3], MModAcc);
1821 if (AdrMode == ModAcc)
1822 {
1823 WAsmCode[0] |= 0xf482 | (AdrVals[0] << 8);
1824 CodeLen = 1;
1825 }
1826 break;
1827 case ModMem:
1828 if (ChkArgCnt(2, 2))
1829 {
1830 WAsmCode[0] = 0x3200 | AdrVals[0];
1831 if (AdrCnt)
1832 WAsmCode[1] = AdrVals[1];
1833 CodeLen = 1 + AdrCnt;
1834 }
1835 break;
1836 case ModImm:
1837 if (ChkArgCnt(2, 2))
1838 {
1839 WAsmCode[0] = 0xed00 | (AdrVals[0] & 0x1f);
1840 CodeLen = 1;
1841 }
1842 break;
1843 }
1844 }
1845 }
1846
1847 else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
1848 {
1849 *WAsmCode = *AdrVals << 8;
1850 if (ArgCnt == 3)
1851 {
1852 if (!as_strcasecmp(ArgStr[2].Str, "TS"))
1853 {
1854 Shift = 0xff;
1855 OK = True;
1856 }
1857 else
1858 {
1859 tSymbolFlags Flags;
1860
1861 Shift = EvalStrIntExpressionWithFlags(&ArgStr[2], SInt6, &OK, &Flags);
1862 if (mFirstPassUnknown(Flags))
1863 Shift = 0;
1864 if (OK)
1865 OK = ChkRange(Shift, -16, 16);
1866 }
1867 }
1868 else
1869 {
1870 Shift = 0;
1871 OK = True;
1872 }
1873 if (OK)
1874 {
1875 OpSize = UInt16;
1876 DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModImm);
1877 switch (AdrMode)
1878 {
1879 case ModAcc:
1880 if (ThisPar) WrError(ErrNum_ParNotPossible);
1881 else if (ChkRange(Shift, -16, 15))
1882 {
1883 *WAsmCode |= 0xf440 | (AdrVals[0] << 9) | (Shift & 0x1f);
1884 CodeLen = 1;
1885 }
1886 break;
1887 case ModMem:
1888 if (Shift == 0xff) /* TS ? */
1889 {
1890 if (ThisPar) WrError(ErrNum_ParNotPossible);
1891 else
1892 {
1893 *WAsmCode |= 0x1400 | AdrVals[0];
1894 if (AdrCnt)
1895 WAsmCode[1] = AdrVals[1];
1896 CodeLen = 1 + AdrCnt;
1897 }
1898 }
1899 else if ((Shift >= 0) && (MakeXY(WAsmCode + 1, False)))
1900 {
1901 if (ThisPar)
1902 {
1903 if (Shift) WrError(ErrNum_ParNotPossible);
1904 /* prev. operation must be STH src,0,Xmem */
1905 else if ((LastOpCode & 0xfe0f) != 0x9a00) WrError(ErrNum_ParNotPossible);
1906 else
1907 {
1908 RetractWords(1);
1909 *WAsmCode |= 0xc800 | ((LastOpCode & 0x0100) << 1)
1910 | ((LastOpCode & 0x00f0) >> 4) | (WAsmCode[1] << 4);
1911 CodeLen = 1;
1912 }
1913 }
1914 else
1915 {
1916 WAsmCode[0] |= 0x9400 | (WAsmCode[1] << 4) | Shift;
1917 CodeLen = 1;
1918 }
1919 }
1920 else if (Shift == 16)
1921 {
1922 if (ThisPar) WrError(ErrNum_ParNotPossible);
1923 else
1924 {
1925 WAsmCode[0] |= 0x4400 | AdrVals[0];
1926 if (AdrCnt)
1927 WAsmCode[1] = AdrVals[1];
1928 CodeLen = 1 + AdrCnt;
1929 }
1930 }
1931 else if (!Shift)
1932 {
1933 if (ThisPar) WrError(ErrNum_ParNotPossible);
1934 else
1935 {
1936 WAsmCode[0] |= 0x1000 | AdrVals[0];
1937 if (AdrCnt)
1938 WAsmCode[1] = AdrVals[1];
1939 CodeLen = 1 + AdrCnt;
1940 }
1941 }
1942 else
1943 {
1944 if (ThisPar) WrError(ErrNum_ParNotPossible);
1945 else
1946 {
1947 WAsmCode[1 + AdrCnt] = 0x0c40 | WAsmCode[0] | (Shift & 0x1f);
1948 WAsmCode[0] = 0x6f00 | AdrVals[0];
1949 if (AdrCnt)
1950 WAsmCode[1] = AdrVals[1];
1951 CodeLen = 2 + AdrCnt;
1952 }
1953 }
1954 break;
1955 case ModImm:
1956 if (Shift == 0xff) WrError(ErrNum_InvAddrMode);
1957 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1958 else if (ChkRange(Shift, 0, 16))
1959 {
1960 if ((Hi(AdrVals[0]) == 0) && (!Shift))
1961 {
1962 WAsmCode[0] |= 0xe800 | Lo(AdrVals[0]);
1963 CodeLen = 1;
1964 }
1965 else if (Shift == 16)
1966 {
1967 WAsmCode[0] |= 0xf062;
1968 WAsmCode[1] = AdrVals[0];
1969 CodeLen = 2;
1970 }
1971 else
1972 {
1973 WAsmCode[0] |= 0xf020 | (Shift & 15);
1974 WAsmCode[1] = AdrVals[0];
1975 CodeLen = 2;
1976 }
1977 }
1978 break;
1979 }
1980 }
1981 }
1982 }
1983
DecodePSHM(Word Index)1984 static void DecodePSHM(Word Index)
1985 {
1986 UNUSED(Index);
1987
1988 if (!ChkArgCnt(1, 1));
1989 else if (ThisPar) WrError(ErrNum_ParNotPossible);
1990 else
1991 {
1992 ForcePageZero = True;
1993 if (DecodeAdr(&ArgStr[1], MModMem))
1994 {
1995 *WAsmCode = 0x4a00 | (*AdrVals);
1996 CodeLen = 1;
1997 }
1998 }
1999 }
2000
DecodeLDM(Word Index)2001 static void DecodeLDM(Word Index)
2002 {
2003 UNUSED(Index);
2004
2005 if (!ChkArgCnt(2, 2));
2006 else if (ThisPar) WrError(ErrNum_ParNotPossible);
2007 else if (DecodeAdr(&ArgStr[2], MModAcc))
2008 {
2009 *WAsmCode = 0x4800 | (*AdrVals << 8);
2010 ForcePageZero = True;
2011 if (DecodeAdr(&ArgStr[1], MModMem))
2012 {
2013 *WAsmCode |= *AdrVals;
2014 CodeLen = 1;
2015 }
2016 }
2017 }
2018
DecodeSTLM(Word Index)2019 static void DecodeSTLM(Word Index)
2020 {
2021 UNUSED(Index);
2022
2023 if (!ChkArgCnt(2, 2));
2024 else if (ThisPar) WrError(ErrNum_ParNotPossible);
2025 else if (DecodeAdr(&ArgStr[1], MModAcc))
2026 {
2027 *WAsmCode = 0x8800 | (*AdrVals << 8);
2028 ForcePageZero = True;
2029 if (DecodeAdr(&ArgStr[2], MModMem))
2030 {
2031 *WAsmCode |= *AdrVals;
2032 CodeLen = 1;
2033 }
2034 }
2035 }
2036
DecodeSTM(Word Index)2037 static void DecodeSTM(Word Index)
2038 {
2039 UNUSED(Index);
2040
2041 if (!ChkArgCnt(2, 2));
2042 else if (ThisPar) WrError(ErrNum_ParNotPossible);
2043 else if (DecodeAdr(&ArgStr[1], MModImm))
2044 {
2045 WAsmCode[1] = *AdrVals;
2046 ForcePageZero = True;
2047 if (DecodeAdr(&ArgStr[2], MModMem))
2048 {
2049 *WAsmCode = 0x7700 | (*AdrVals);
2050 CodeLen = 2;
2051 }
2052 }
2053 }
2054
DecodeDST(Word Index)2055 static void DecodeDST(Word Index)
2056 {
2057 UNUSED(Index);
2058
2059 if (!ChkArgCnt(2, 2));
2060 else if (ThisPar) WrError(ErrNum_ParNotPossible);
2061 else if (DecodeAdr(&ArgStr[1], MModAcc))
2062 {
2063 *WAsmCode = 0x4e00 | (*AdrVals << 8);
2064 if (DecodeAdr(&ArgStr[2], MModMem))
2065 {
2066 *WAsmCode |= *AdrVals;
2067 if (AdrCnt)
2068 1[WAsmCode] = 1[AdrVals];
2069 CodeLen = 1 + AdrCnt;
2070 }
2071 }
2072 }
2073
DecodeST(Word Index)2074 static void DecodeST(Word Index)
2075 {
2076 Word Acc;
2077
2078 UNUSED(Index);
2079
2080 /* NOTE: we also allow the form 'ST src,Xmem' as an alias
2081 for 'STH src,Ymem' since the first form is used in parallel
2082 load-store instructions. */
2083
2084 if (!ChkArgCnt(2, 2));
2085 else if (ThisPar) WrError(ErrNum_ParNotPossible);
2086 else if (DecodeAdr(&ArgStr[2], MModMem))
2087 {
2088 *WAsmCode = *AdrVals;
2089 if (AdrCnt)
2090 1[WAsmCode] = 1[AdrVals];
2091 CodeLen = 1 + AdrCnt;
2092 OpSize = SInt16;
2093 if (!as_strcasecmp(ArgStr[1].Str, "T"))
2094 *WAsmCode |= 0x8c00;
2095 else if (!as_strcasecmp(ArgStr[1].Str, "TRN"))
2096 *WAsmCode |= 0x8d00;
2097 else
2098 {
2099 DecodeAdr(&ArgStr[1], MModImm | MModAcc);
2100 switch (AdrMode)
2101 {
2102 case ModImm:
2103 *WAsmCode |= 0x7600;
2104 (CodeLen++)[WAsmCode] = *AdrVals;
2105 break;
2106 case ModAcc:
2107 Acc = *AdrVals;
2108 *AdrVals = *WAsmCode;
2109 AdrMode = ModMem;
2110 if (MakeXY(AdrVals, True))
2111 {
2112 *WAsmCode = 0x9a00 | (Acc << 8) | (*AdrVals << 4);
2113 CodeLen = 1;
2114 }
2115 else
2116 CodeLen = 0;
2117 break;
2118 default:
2119 CodeLen = 0;
2120 }
2121 }
2122 }
2123 }
2124
DecodeSTLH(Word Index)2125 static void DecodeSTLH(Word Index)
2126 {
2127 Integer Shift;
2128 Boolean OK;
2129
2130 if (!ChkArgCnt(2, 3));
2131 else if (ThisPar) WrError(ErrNum_ParNotPossible);
2132 else if (DecodeAdr(&ArgStr[1], MModAcc))
2133 {
2134 *WAsmCode = Index | (*AdrVals << 8);
2135 OK = True;
2136 if (ArgCnt == 2)
2137 Shift = 0;
2138 else if (!as_strcasecmp(ArgStr[2].Str, "ASM"))
2139 Shift = 0xff;
2140 else
2141 Shift = EvalStrIntExpression(&ArgStr[2], SInt5, &OK);
2142 if ((OK) && (DecodeAdr(&ArgStr[ArgCnt], MModMem)))
2143 {
2144 if (AdrCnt)
2145 1[WAsmCode] = 1[AdrVals];
2146 CodeLen = 1 + AdrCnt;
2147 if (!Shift)
2148 *WAsmCode |= 0x8000 | *AdrVals;
2149 else if (Shift == 0xff)
2150 *WAsmCode |= 0x8400 | *AdrVals;
2151 else if ((MakeXY(WAsmCode + 2, False)) && (Shift > 0))
2152 *WAsmCode |= 0x9800 | (2[WAsmCode] << 4) | Shift;
2153 else
2154 {
2155 CodeLen[WAsmCode] = (0x0c80 | ((*WAsmCode) & 0x100) | (Shift & 0x1f)) - (Index >> 4);
2156 *WAsmCode = 0x6f00 | *AdrVals;
2157 CodeLen++;
2158 }
2159 }
2160 }
2161 }
2162
DecodeCMPS(Word Index)2163 static void DecodeCMPS(Word Index)
2164 {
2165 UNUSED(Index);
2166
2167 if (!ChkArgCnt(2, 2));
2168 else if (ThisPar) WrError(ErrNum_ParNotPossible);
2169 else if (DecodeAdr(&ArgStr[1], MModAcc))
2170 {
2171 *WAsmCode = 0x8e00 | (*AdrVals << 8);
2172 if (DecodeAdr(&ArgStr[2], MModMem))
2173 {
2174 *WAsmCode |= *AdrVals;
2175 if (AdrCnt)
2176 1[WAsmCode] = 1[AdrVals];
2177 CodeLen = 1 + AdrCnt;
2178 }
2179 }
2180 }
2181
DecodeSACCD(Word Index)2182 static void DecodeSACCD(Word Index)
2183 {
2184 int index;
2185 Boolean OK;
2186
2187 UNUSED(Index);
2188
2189 if (!ChkArgCnt(3, 3));
2190 else if (ThisPar) WrError(ErrNum_ParNotPossible);
2191 else if (DecodeAdr(&ArgStr[1], MModAcc))
2192 {
2193 *WAsmCode = 0x9e00 | ((*AdrVals) << 8);
2194 if ((DecodeAdr(&ArgStr[2], MModMem))
2195 && (MakeXY(AdrVals, True)))
2196 {
2197 *WAsmCode |= ((*AdrVals) << 4);
2198 if (!DecodeCondition(3, WAsmCode + 1, &index, &OK)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[index]);
2199 else if ((WAsmCode[1] & 0xf0) != 0x40) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[index]);
2200 else
2201 {
2202 *WAsmCode |= WAsmCode[1] & 15;
2203 CodeLen = 1;
2204 }
2205 }
2206 }
2207 }
2208
DecodeStoreCC(Word Index)2209 static void DecodeStoreCC(Word Index)
2210 {
2211 int index;
2212 Boolean OK;
2213
2214 UNUSED(Index);
2215
2216 if (!ChkArgCnt(2, 2));
2217 else if (ThisPar) WrError(ErrNum_ParNotPossible);
2218 else if ((DecodeAdr(&ArgStr[1], MModMem)) && (MakeXY(AdrVals, True)))
2219 {
2220 *WAsmCode = Index | ((*AdrVals) << 4);
2221 if (!DecodeCondition(2, WAsmCode + 1, &index, &OK)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[index]);
2222 else if ((WAsmCode[1] & 0xf0) != 0x40) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[index]);
2223 else
2224 {
2225 *WAsmCode |= WAsmCode[1] & 15;
2226 CodeLen = 1;
2227 }
2228 }
2229 }
2230
DecodeMVDabs(Word Index)2231 static void DecodeMVDabs(Word Index)
2232 {
2233 if (!ChkArgCnt(2, 2));
2234 else if (ThisPar) WrError(ErrNum_ParNotPossible);
2235 else if (DecodeAdr(&ArgStr[1], MModMem))
2236 {
2237 tEvalResult EvalResult;
2238
2239 *WAsmCode = Index | *AdrVals;
2240 if (AdrCnt)
2241 1[WAsmCode] = 1[AdrVals];
2242 WAsmCode[1 + AdrCnt] = EvalStrIntExpressionWithResult(&ArgStr[2], UInt16, &EvalResult);
2243 if (EvalResult.OK)
2244 {
2245 ChkSpace((Index == 0x7100) ? SegData : SegCode, EvalResult.AddrSpaceMask);
2246 CodeLen = 2 + AdrCnt;
2247 }
2248 }
2249 }
2250
DecodeMVabsD(Word Index)2251 static void DecodeMVabsD(Word Index)
2252 {
2253 if (!ChkArgCnt(2, 2));
2254 else if (ThisPar) WrError(ErrNum_ParNotPossible);
2255 else if (DecodeAdr(&ArgStr[2], MModMem))
2256 {
2257 tEvalResult EvalResult;
2258
2259 *WAsmCode = Index | *AdrVals;
2260 if (AdrCnt)
2261 1[WAsmCode] = 1[AdrVals];
2262 WAsmCode[1 + AdrCnt] = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
2263 if (EvalResult.OK)
2264 {
2265 ChkSpace((Index == 0x7000) ? SegData : SegCode, EvalResult.AddrSpaceMask);
2266 CodeLen = 2 + AdrCnt;
2267 }
2268 }
2269 }
2270
DecodeMVdmadmmr(Word Index)2271 static void DecodeMVdmadmmr(Word Index)
2272 {
2273 if (!ChkArgCnt(2, 2));
2274 else if (ThisPar) WrError(ErrNum_ParNotPossible);
2275 else
2276 {
2277 const tStrComp *pArg1 = (Index & 0x0100) ? &ArgStr[2] : &ArgStr[1],
2278 *pArg2 = (Index & 0x0100) ? &ArgStr[1] : &ArgStr[2];
2279
2280 ForcePageZero = True;
2281 if (DecodeAdr(pArg2, MModMem))
2282 {
2283 tEvalResult EvalResult;
2284
2285 *WAsmCode = Index | *AdrVals;
2286 WAsmCode[1] = EvalStrIntExpressionWithResult(pArg1, UInt16, &EvalResult);
2287 if (EvalResult.OK)
2288 {
2289 ChkSpace(SegData, EvalResult.AddrSpaceMask);
2290 CodeLen = 2;
2291 }
2292 }
2293 }
2294 }
2295
GetReg(const tStrComp * pArg,Word * Res)2296 static Boolean GetReg(const tStrComp *pArg, Word *Res)
2297 {
2298 tEvalResult EvalResult;
2299
2300 *Res = EvalStrIntExpressionWithResult(pArg, UInt8, &EvalResult);
2301 if (EvalResult.OK)
2302 {
2303 if (mFirstPassUnknown(EvalResult.Flags))
2304 *Res = 0x10;
2305 ChkSpace(SegData, EvalResult.AddrSpaceMask);
2306 EvalResult.OK = ChkRange(*Res, 0x10, 0x1f);
2307 if (EvalResult.OK)
2308 *Res -= 0x10;
2309 }
2310 return EvalResult.OK;
2311 }
2312
DecodeMVMM(Word Index)2313 static void DecodeMVMM(Word Index)
2314 {
2315 Word XReg, YReg;
2316 UNUSED(Index);
2317
2318 if (!ChkArgCnt(2, 2));
2319 else if (ThisPar) WrError(ErrNum_ParNotPossible);
2320 else if ((GetReg(&ArgStr[1], &XReg)) && (GetReg(&ArgStr[2], &YReg)))
2321 {
2322 *WAsmCode = 0xe700 | (XReg << 4) | YReg;
2323 CodeLen = 1;
2324 }
2325 }
2326
DecodePort(Word Index)2327 static void DecodePort(Word Index)
2328 {
2329 if (!ChkArgCnt(2, 2));
2330 else if (ThisPar) WrError(ErrNum_ParNotPossible);
2331 else
2332 {
2333 const tStrComp *pArg1 = (Index & 0x0100) ? &ArgStr[2] : &ArgStr[1],
2334 *pArg2 = (Index & 0x0100) ? &ArgStr[1] : &ArgStr[2];
2335
2336 if (DecodeAdr(pArg2, MModMem))
2337 {
2338 tEvalResult EvalResult;
2339
2340 *WAsmCode = Index | *AdrVals;
2341 if (AdrCnt)
2342 1[WAsmCode] = 1[AdrVals];
2343 WAsmCode[1 + AdrCnt] = EvalStrIntExpressionWithResult(pArg1, UInt16, &EvalResult);
2344 if (EvalResult.OK)
2345 {
2346 ChkSpace(SegIO, EvalResult.AddrSpaceMask);
2347 CodeLen = 2 + AdrCnt;
2348 }
2349 }
2350 }
2351 }
2352
2353 /*-------------------------------------------------------------------------*/
2354 /* Pseudo Instructions */
2355
DecodePseudo(void)2356 static Boolean DecodePseudo(void)
2357 {
2358 if (Memo("PORT"))
2359 {
2360 CodeEquate(SegIO, 0, 65535);
2361 return True;
2362 }
2363
2364 return False;
2365 }
2366
2367 /*-------------------------------------------------------------------------*/
2368 /* Code Table Handling */
2369
AddFixed(const char * Name,Word Code,Boolean IsRepeatable)2370 static void AddFixed(const char *Name, Word Code, Boolean IsRepeatable)
2371 {
2372 if (InstrZ >= FixedOrderCnt)
2373 exit(0);
2374
2375 FixedOrders[InstrZ].Code = Code;
2376 FixedOrders[InstrZ].IsRepeatable = IsRepeatable;
2377 AddInstTable(InstTable, Name, InstrZ++, DecodeFixed);
2378 }
2379
AddAcc(const char * Name,Word Code,Boolean IsRepeatable)2380 static void AddAcc(const char *Name, Word Code, Boolean IsRepeatable)
2381 {
2382 if (InstrZ >= AccOrderCnt)
2383 exit(0);
2384
2385 AccOrders[InstrZ].Code = Code;
2386 AccOrders[InstrZ].IsRepeatable = IsRepeatable;
2387 AddInstTable(InstTable, Name, InstrZ++, DecodeAcc);
2388 }
2389
AddAcc2(const char * Name,Word Code,Boolean IsRepeatable)2390 static void AddAcc2(const char *Name, Word Code, Boolean IsRepeatable)
2391 {
2392 if (InstrZ >= Acc2OrderCnt)
2393 exit(0);
2394
2395 Acc2Orders[InstrZ].Code = Code;
2396 Acc2Orders[InstrZ].IsRepeatable = IsRepeatable;
2397 AddInstTable(InstTable, Name, InstrZ++, DecodeAcc2);
2398 }
2399
AddMem(const char * Name,Word Code,Boolean IsRepeatable)2400 static void AddMem(const char *Name, Word Code, Boolean IsRepeatable)
2401 {
2402 if (InstrZ >= MemOrderCnt)
2403 exit(0);
2404
2405 MemOrders[InstrZ].Code = Code;
2406 MemOrders[InstrZ].IsRepeatable = IsRepeatable;
2407 AddInstTable(InstTable, Name, InstrZ++, DecodeMem);
2408 }
2409
AddXY(const char * Name,Word Code,Boolean IsRepeatable)2410 static void AddXY(const char *Name, Word Code, Boolean IsRepeatable)
2411 {
2412 if (InstrZ >= XYOrderCnt)
2413 exit(0);
2414
2415 XYOrders[InstrZ].Code = Code;
2416 XYOrders[InstrZ].IsRepeatable = IsRepeatable;
2417 AddInstTable(InstTable, Name, InstrZ++, DecodeXY);
2418 }
2419
AddMemAcc(const char * Name,Word Code,Boolean IsRepeatable)2420 static void AddMemAcc(const char *Name, Word Code, Boolean IsRepeatable)
2421 {
2422 if (InstrZ >= MemAccOrderCnt)
2423 exit(0);
2424
2425 MemAccOrders[InstrZ].Code = Code;
2426 MemAccOrders[InstrZ].IsRepeatable = IsRepeatable;
2427 AddInstTable(InstTable, Name, InstrZ++, DecodeMemAcc);
2428 }
2429
AddMemConst(const char * Name,Word Code,Boolean IsRepeatable,Boolean Swap,IntType ConstType)2430 static void AddMemConst(const char *Name, Word Code, Boolean IsRepeatable, Boolean Swap, IntType ConstType)
2431 {
2432 if (InstrZ >= MemConstOrderCnt)
2433 exit(0);
2434
2435 MemConstOrders[InstrZ].Code = Code;
2436 MemConstOrders[InstrZ].IsRepeatable = IsRepeatable;
2437 MemConstOrders[InstrZ].Swap = Swap;
2438 MemConstOrders[InstrZ].ConstType = ConstType;
2439 AddInstTable(InstTable, Name, InstrZ++, DecodeMemConst);
2440 }
2441
AddMac(const char * Name,Word Code,Boolean IsRepeatable)2442 static void AddMac(const char *Name, Word Code, Boolean IsRepeatable)
2443 {
2444 if (InstrZ >= MacOrderCnt)
2445 exit(0);
2446
2447 MacOrders[InstrZ].Code = Code;
2448 MacOrders[InstrZ].IsRepeatable = IsRepeatable;
2449 AddInstTable(InstTable, Name, InstrZ++, DecodeMac);
2450 }
2451
AddCondition(const char * NName,Word NClass,Word NCode,Word NMask)2452 static void AddCondition(const char *NName, Word NClass, Word NCode, Word NMask)
2453 {
2454 if (InstrZ >= ConditionCnt)
2455 exit(0);
2456 Conditions[InstrZ ].Name = NName;
2457 Conditions[InstrZ ].Class = NClass;
2458 Conditions[InstrZ ].Code = NCode;
2459 Conditions[InstrZ++].Mask = NMask;
2460 }
2461
InitFields(void)2462 static void InitFields(void)
2463 {
2464 InstTable = CreateInstTable(203);
2465
2466 AddInstTable(InstTable, "LD", 0, DecodeLD);
2467 AddInstTable(InstTable, "ST", 0, DecodeST);
2468 AddInstTable(InstTable, "STH", 0x200, DecodeSTLH);
2469 AddInstTable(InstTable, "STL", 0x000, DecodeSTLH);
2470
2471 FixedOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * FixedOrderCnt); InstrZ = 0;
2472 AddFixed("FRET" , 0xf4e4, FALSE);
2473 AddFixed("FRETD" , 0xf6e4, FALSE);
2474 AddFixed("FRETE" , 0xf4e5, FALSE);
2475 AddFixed("FRETED", 0xf6e5, FALSE);
2476 AddFixed("NOP" , NOPCode, TRUE);
2477 AddFixed("RESET" , 0xf7e0, FALSE);
2478 AddFixed("RET" , 0xfc00, FALSE);
2479 AddFixed("RETD" , 0xfe00, FALSE);
2480 AddFixed("RETE" , 0xf4eb, FALSE);
2481 AddFixed("RETED" , 0xf6eb, FALSE);
2482 AddFixed("RETF" , 0xf49b, FALSE);
2483 AddFixed("RETFD" , 0xf69b, FALSE);
2484
2485 AccOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * AccOrderCnt); InstrZ = 0;
2486 AddAcc ("EXP" , 0xf48e, TRUE );
2487 AddAcc ("MAX" , 0xf486, TRUE );
2488 AddAcc ("MIN" , 0xf487, TRUE );
2489 AddAcc ("SAT" , 0xf483, TRUE );
2490 AddAcc ("ROL" , 0xf491, TRUE );
2491 AddAcc ("ROLTC" , 0xf492, TRUE );
2492 AddAcc ("ROR" , 0xf490, TRUE );
2493 AddAcc ("SFTC" , 0xf494, TRUE );
2494 AddAcc ("CALA" , 0xf4e3, FALSE);
2495 AddAcc ("CALAD" , 0xf6e3, FALSE);
2496 AddAcc ("FCALA" , 0xf4e7, FALSE);
2497 AddAcc ("FCALAD", 0xf6e7, FALSE);
2498 AddAcc ("BACC" , 0xf4e2, FALSE);
2499 AddAcc ("BACCD" , 0xf6e2, FALSE);
2500 AddAcc ("FBACC" , 0xf4e6, FALSE);
2501 AddAcc ("FBACCD", 0xf6e6, FALSE);
2502
2503 Acc2Orders = (FixedOrder*) malloc(sizeof(FixedOrder) * Acc2OrderCnt); InstrZ = 0;
2504 AddAcc2 ("NEG" , 0xf484, TRUE );
2505 AddAcc2 ("NORM" , 0xf48f, TRUE );
2506 AddAcc2 ("RND" , 0xf49f, TRUE );
2507 AddAcc2 ("ABS" , 0xf485, TRUE );
2508 AddAcc2 ("CMPL" , 0xf493, TRUE );
2509
2510 MemOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * MemOrderCnt); InstrZ = 0;
2511 AddMem ("DELAY" , 0x4d00, TRUE );
2512 AddMem ("POLY" , 0x3600, TRUE );
2513 AddMem ("BITT" , 0x3400, TRUE );
2514 AddMem ("POPD" , 0x8b00, TRUE );
2515 AddMem ("PSHD" , 0x4b00, TRUE );
2516 AddMem ("MAR" , 0x6d00, TRUE );
2517 AddMem ("LTD" , 0x4c00, TRUE );
2518 AddMem ("READA" , 0x7e00, TRUE );
2519 AddMem ("WRITA" , 0x7f00, TRUE );
2520
2521 XYOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * XYOrderCnt); InstrZ = 0;
2522 AddXY ("ABDST" , 0xe300, TRUE );
2523 AddXY ("LMS" , 0xe100, TRUE );
2524 AddXY ("SQDST" , 0xe200, TRUE );
2525 AddXY ("MVDD" , 0xe500, TRUE );
2526
2527 AddInstTable(InstTable, "ADD", 0, DecodeADDSUB);
2528 AddInstTable(InstTable, "SUB", 1, DecodeADDSUB);
2529
2530 MemAccOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * MemAccOrderCnt); InstrZ = 0;
2531 AddMemAcc("ADDC" , 0x0600, TRUE );
2532 AddMemAcc("ADDS" , 0x0200, TRUE );
2533 AddMemAcc("SUBB" , 0x0e00, TRUE );
2534 AddMemAcc("SUBC" , 0x1e00, TRUE );
2535 AddMemAcc("SUBS" , 0x0a00, TRUE );
2536 AddMemAcc("MPYR" , 0x2200, TRUE );
2537 AddMemAcc("MPYU" , 0x2400, TRUE );
2538 AddMemAcc("SQURA", 0x3800, TRUE );
2539 AddMemAcc("SQURS", 0x3a00, TRUE );
2540 AddMemAcc("DADST", 0x5a00, TRUE );
2541 AddMemAcc("DRSUB", 0x5800, TRUE );
2542 AddMemAcc("DSADT", 0x5e00, TRUE );
2543 AddMemAcc("DSUB" , 0x5400, TRUE );
2544 AddMemAcc("DSUBT", 0x5c00, TRUE );
2545 AddMemAcc("DLD" , 0x5600, TRUE );
2546 AddMemAcc("LDR" , 0x1600, TRUE );
2547 AddMemAcc("LDU" , 0x1200, TRUE );
2548
2549 MacOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * MacOrderCnt); InstrZ = 0;
2550 AddMac("MACA" , 0x3508, TRUE );
2551 AddMac("MACAR" , 0x3709, TRUE );
2552 AddMac("MASA" , 0x330a, TRUE );
2553
2554 MemConstOrders = (MemConstOrder*) malloc(sizeof(MemConstOrder) * MemConstOrderCnt); InstrZ = 0;
2555 AddMemConst("ADDM", 0x6b00, FALSE, FALSE, SInt16);
2556 AddMemConst("ANDM", 0x6800, FALSE, FALSE, UInt16);
2557 AddMemConst("CMPM", 0x6000, TRUE , TRUE , SInt16);
2558 AddMemConst("ORM" , 0x6900, FALSE, FALSE, UInt16);
2559 AddMemConst("XORM", 0x6a00, FALSE, FALSE, UInt16);
2560
2561 AddInstTable(InstTable, "AND" , 0, DecodeLog);
2562 AddInstTable(InstTable, "OR" , 1, DecodeLog);
2563 AddInstTable(InstTable, "XOR" , 2, DecodeLog);
2564 AddInstTable(InstTable, "MPY" , 0, DecodeMPY);
2565 AddInstTable(InstTable, "MPYA" , 0, DecodeMPYA);
2566 AddInstTable(InstTable, "SQUR" , 0, DecodeSQUR);
2567 AddInstTable(InstTable, "MAC" , 0, DecodeMAC);
2568 AddInstTable(InstTable, "MACR" , 0, DecodeMACR);
2569 AddInstTable(InstTable, "MACD" , 0x7a00, DecodeMACDP);
2570 AddInstTable(InstTable, "MACP" , 0x7800, DecodeMACDP);
2571 AddInstTable(InstTable, "MACSU", 0, DecodeMACSU);
2572 AddInstTable(InstTable, "MAS" , 0x000, DecodeMAS);
2573 AddInstTable(InstTable, "MASR" , 0x200, DecodeMAS);
2574 AddInstTable(InstTable, "MASAR", 0, DecodeMASAR);
2575 AddInstTable(InstTable, "DADD" , 0, DecodeDADD);
2576 AddInstTable(InstTable, "FIRS" , 0, DecodeFIRS);
2577 AddInstTable(InstTable, "SFTA" , 0xf460, DecodeSFT);
2578 AddInstTable(InstTable, "SFTL" , 0xf0e0, DecodeSFT);
2579 AddInstTable(InstTable, "BIT" , 0, DecodeBIT);
2580 AddInstTable(InstTable, "BITF" , 0, DecodeBITF);
2581 AddInstTable(InstTable, "CMPR" , 0, DecodeCMPR);
2582
2583 AddInstTable(InstTable, "B" , 0xf073, DecodePMAD);
2584 AddInstTable(InstTable, "BD" , 0xf273, DecodePMAD);
2585 AddInstTable(InstTable, "CALL" , 0xf074, DecodePMAD);
2586 AddInstTable(InstTable, "CALLD", 0xf274, DecodePMAD);
2587 AddInstTable(InstTable, "RPTB" , 0xf072, DecodePMAD);
2588 AddInstTable(InstTable, "RPTBD", 0xf272, DecodePMAD);
2589
2590 AddInstTable(InstTable, "BC" , 0xf800, DecodePMADCond);
2591 AddInstTable(InstTable, "BCD" , 0xfa00, DecodePMADCond);
2592 AddInstTable(InstTable, "CC" , 0xf900, DecodePMADCond);
2593 AddInstTable(InstTable, "CCD" , 0xfb00, DecodePMADCond);
2594
2595 AddInstTable(InstTable, "FB" , 0xf880, DecodeFPMAD);
2596 AddInstTable(InstTable, "FBD" , 0xfa80, DecodeFPMAD);
2597 AddInstTable(InstTable, "FCALL" , 0xf980, DecodeFPMAD);
2598 AddInstTable(InstTable, "FCALLD", 0xfb80, DecodeFPMAD);
2599
2600 AddInstTable(InstTable, "BANZ" , 0x6c00, DecodeBANZ);
2601 AddInstTable(InstTable, "BANZD", 0x6e00, DecodeBANZ);
2602
2603 AddInstTable(InstTable, "INTR" , 0xf7c0, DecodeINTR);
2604 AddInstTable(InstTable, "TRAP" , 0xf4c0, DecodeINTR);
2605 AddInstTable(InstTable, "PSHM" , 0 , DecodePSHM);
2606 AddInstTable(InstTable, "LDM" , 0 , DecodeLDM);
2607 AddInstTable(InstTable, "STLM" , 0 , DecodeSTLM);
2608 AddInstTable(InstTable, "STM" , 0 , DecodeSTM);
2609 AddInstTable(InstTable, "CMPS" , 0 , DecodeCMPS);
2610
2611 AddInstTable(InstTable, "RPT" , 0 , DecodeRPT);
2612 AddInstTable(InstTable, "RPTZ" , 0 , DecodeRPTZ);
2613
2614 AddInstTable(InstTable, "FRAME", 0 , DecodeFRAME);
2615 AddInstTable(InstTable, "IDLE" , 0 , DecodeIDLE);
2616
2617 AddInstTable(InstTable, "RSBX" , 0xf4b0, DecodeSBIT);
2618 AddInstTable(InstTable, "SSBX" , 0xf5b0, DecodeSBIT);
2619
2620 AddInstTable(InstTable, "XC" , 0 , DecodeXC);
2621
2622 AddInstTable(InstTable, "DST" , 0 , DecodeDST);
2623
2624 AddInstTable(InstTable, "SACCD", 0 , DecodeSACCD);
2625
2626 AddInstTable(InstTable, "SRCCD", 0x9d00, DecodeStoreCC);
2627 AddInstTable(InstTable, "STRCD", 0x9c00, DecodeStoreCC);
2628
2629 AddInstTable(InstTable, "MVDK" , 0x7100, DecodeMVDabs);
2630 AddInstTable(InstTable, "MVDP" , 0x7d00, DecodeMVDabs);
2631 AddInstTable(InstTable, "MVKD" , 0x7000, DecodeMVabsD);
2632 AddInstTable(InstTable, "MVPD" , 0x7c00, DecodeMVabsD);
2633 AddInstTable(InstTable, "MVDM" , 0x7200, DecodeMVdmadmmr);
2634 AddInstTable(InstTable, "MVMD" , 0x7300, DecodeMVdmadmmr);
2635 AddInstTable(InstTable, "MVMM" , 0x7300, DecodeMVMM);
2636
2637 AddInstTable(InstTable, "PORTR", 0x7400, DecodePort);
2638 AddInstTable(InstTable, "PORTW", 0x7500, DecodePort);
2639
2640 Conditions = (Condition*) malloc(sizeof(Condition) * ConditionCnt); InstrZ = 0;
2641 AddCondition("BIO" , 0, 0x0003, 0x0003);
2642 AddCondition("NBIO" , 0, 0x0002, 0x0003);
2643 AddCondition("C" , 0, 0x000c, 0x000c);
2644 AddCondition("NC" , 0, 0x0008, 0x000c);
2645 AddCondition("TC" , 0, 0x0030, 0x0030);
2646 AddCondition("NTC" , 0, 0x0020, 0x0030);
2647 AddCondition("AEQ" , 1, 0x0045, 0x000f);
2648 AddCondition("ANEQ" , 1, 0x0044, 0x000f);
2649 AddCondition("AGT" , 1, 0x0046, 0x000f);
2650 AddCondition("AGEQ" , 1, 0x0042, 0x000f);
2651 AddCondition("ALT" , 1, 0x0043, 0x000f);
2652 AddCondition("ALEQ" , 1, 0x0047, 0x000f);
2653 AddCondition("AOV" , 1, 0x0070, 0x00f0);
2654 AddCondition("ANOV" , 1, 0x0060, 0x00f0);
2655 AddCondition("BEQ" , 2, 0x004d, 0x000f);
2656 AddCondition("BNEQ" , 2, 0x004c, 0x000f);
2657 AddCondition("BGT" , 2, 0x004e, 0x000f);
2658 AddCondition("BGEQ" , 2, 0x004a, 0x000f);
2659 AddCondition("BLT" , 2, 0x004b, 0x000f);
2660 AddCondition("BLEQ" , 2, 0x004f, 0x000f);
2661 AddCondition("BOV" , 2, 0x0078, 0x00f0);
2662 AddCondition("BNOV" , 2, 0x0068, 0x00f0);
2663 AddCondition("UNC" , 3, 0x0000, 0x00ff);
2664 }
2665
DeinitFields(void)2666 static void DeinitFields(void)
2667 {
2668 DestroyInstTable(InstTable);
2669 free(FixedOrders);
2670 free(AccOrders);
2671 free(Acc2Orders);
2672 free(MemOrders);
2673 free(XYOrders);
2674 free(MemAccOrders);
2675 free(MemConstOrders);
2676 free(MacOrders);
2677 free(Conditions);
2678 }
2679
2680 /*-------------------------------------------------------------------------*/
2681 /* Linking Routines */
2682
MakeCode_32054x(void)2683 static void MakeCode_32054x(void)
2684 {
2685 CodeLen = 0;
2686 DontPrint = False;
2687
2688 ThisPar = !strcmp(LabPart.Str, "||");
2689 if ((strlen(OpPart.Str) > 2) && (!strncmp(OpPart.Str, "||", 2)))
2690 {
2691 ThisPar = True; strmov(OpPart.Str, OpPart.Str + 2);
2692 }
2693
2694 /* zu ignorierendes */
2695
2696 if (*OpPart.Str == '\0')
2697 return;
2698
2699 if (DecodePseudo())
2700 return;
2701
2702 if (DecodeTIPseudo())
2703 return;
2704
2705 /* search */
2706
2707 ThisRep = False;
2708 ForcePageZero = False;
2709 if (!LookupInstTable(InstTable, OpPart.Str))
2710 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2711 else
2712 LastOpCode = *WAsmCode;
2713 LastRep = ThisRep;
2714 }
2715
InitCode_32054x(void)2716 static void InitCode_32054x(void)
2717 {
2718 Reg_CPL = 0;
2719 Reg_DP = 0;
2720 Reg_SP = 0;
2721 }
2722
IsDef_32054x(void)2723 static Boolean IsDef_32054x(void)
2724 {
2725 return (!strcmp(LabPart.Str, "||"));
2726 }
2727
SwitchFrom_32054x(void)2728 static void SwitchFrom_32054x(void)
2729 {
2730 DeinitFields();
2731 }
2732
SwitchTo_32054x(void)2733 static void SwitchTo_32054x(void)
2734 {
2735 #define ASSUME3254xCount (sizeof(ASSUME3254xs) / sizeof(*ASSUME3254xs))
2736 static ASSUMERec ASSUME3254xs[] =
2737 {
2738 {"CPL", &Reg_CPL, 0, 1, 0, NULL},
2739 {"DP" , &Reg_DP , 0, 0x1ff, 0x200, NULL},
2740 {"SP" , &Reg_SP , 0, 0xffff, 0x10000, NULL}
2741 };
2742
2743 PFamilyDescr FoundDescr;
2744
2745 FoundDescr = FindFamilyByName("TMS320C54x");
2746
2747 TurnWords = False;
2748 ConstMode = ConstModeIntel;
2749
2750 PCSymbol = "$";
2751 HeaderID = FoundDescr->Id;
2752 NOPCode = 0xf495;
2753 DivideChars = ",";
2754 HasAttrs = False;
2755
2756 ValidSegs = (1 << SegCode) | (1 << SegData) | (1 << SegIO);
2757 Grans[SegCode] = 2; ListGrans[SegCode] = 2; SegInits[SegCode] = 2; SegLimits[SegCode] = 0xffff;
2758 Grans[SegData] = 2; ListGrans[SegData] = 2; SegInits[SegData] = 2; SegLimits[SegData] = 0xffff;
2759 Grans[SegIO ] = 2; ListGrans[SegIO ] = 2; SegInits[SegIO ] = 2; SegLimits[SegIO ] = 0xffff;
2760
2761 MakeCode = MakeCode_32054x;
2762 IsDef = IsDef_32054x;
2763
2764 pASSUMERecs = ASSUME3254xs;
2765 ASSUMERecCnt = ASSUME3254xCount;
2766
2767 InitFields();
2768 SwitchFrom = SwitchFrom_32054x;
2769 ThisRep = LastRep = False;
2770 LastOpCode = 0;
2771 }
2772
2773 /*-------------------------------------------------------------------------*/
2774 /* Global Interface */
2775
code32054x_init(void)2776 void code32054x_init(void)
2777 {
2778 CPU320C541 = AddCPU("320C541", SwitchTo_32054x);
2779
2780 AddInitPassProc(InitCode_32054x);
2781 }
2782