1 /* motpseudo.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS */
6 /* */
7 /* Commonly Used Motorola-Style Pseudo Instructions */
8 /* */
9 /*****************************************************************************/
10
11 /*****************************************************************************
12 * Includes
13 *****************************************************************************/
14
15 #include "stdinc.h"
16 #include <ctype.h>
17 #include <string.h>
18 #include <math.h>
19 #include <assert.h>
20
21 #include "bpemu.h"
22 #include "endian.h"
23 #include "ieeefloat.h"
24 #include "strutil.h"
25 #include "asmdef.h"
26 #include "asmsub.h"
27 #include "asmpars.h"
28 #include "asmitree.h"
29 #include "asmallg.h"
30 #include "asmcode.h"
31 #include "errmsg.h"
32
33 #include "motpseudo.h"
34
35 /*****************************************************************************
36 * Local Variables
37 *****************************************************************************/
38
39 static Boolean M16Turn = False;
40
41 /*****************************************************************************
42 * Local Functions
43 *****************************************************************************/
44
CutRep(tStrComp * pDest,const tStrComp * pSrc,LongInt * pErg,tSymbolFlags * pFlags)45 static Boolean CutRep(tStrComp *pDest, const tStrComp *pSrc, LongInt *pErg, tSymbolFlags *pFlags)
46 {
47 tStrComp Src = *pSrc;
48
49 if (pFlags)
50 *pFlags = eSymbolFlag_None;
51 KillPrefBlanksStrCompRef(&Src);
52 if (*Src.Str != '[')
53 {
54 *pErg = 1;
55 *pDest = *pSrc;
56 return True;
57 }
58 else
59 {
60 tStrComp RepArg;
61 char *pEnd;
62 Boolean OK;
63
64 pEnd = QuotPos(Src.Str + 1, ']');
65 if (!pEnd)
66 {
67 WrError(ErrNum_BrackErr);
68 return False;
69 }
70 else
71 {
72 StrCompSplitRef(&RepArg, pDest, &Src, pEnd);
73 StrCompIncRefLeft(&RepArg, 1);
74 *pErg = EvalStrIntExpressionWithFlags(&RepArg, Int32, &OK, pFlags);
75 return OK;
76 }
77 }
78 }
79
PutByte(Byte Value)80 static void PutByte(Byte Value)
81 {
82 if ((ListGran() == 1) || (!(CodeLen & 1)))
83 BAsmCode[CodeLen] = Value;
84 else if (M16Turn)
85 WAsmCode[CodeLen >> 1] = (((Word)BAsmCode[CodeLen -1]) << 8) | Value;
86 else
87 WAsmCode[CodeLen >> 1] = (((Word)Value) << 8) | BAsmCode[CodeLen -1];
88 CodeLen++;
89 }
90
DecodeMotoBYT(Word Index)91 void DecodeMotoBYT(Word Index)
92 {
93 UNUSED(Index);
94
95 if (ChkArgCnt(1, ArgCntMax))
96 {
97 ShortInt SpaceFlag = -1;
98 tStrComp *pArg, Arg;
99 LongInt Rep;
100 Boolean OK = True;
101
102 forallargs (pArg, OK)
103 {
104 if (!*pArg->Str)
105 {
106 OK = FALSE;
107 WrError(ErrNum_EmptyArgument);
108 break;
109 }
110
111 OK = CutRep(&Arg, pArg, &Rep, NULL);
112 if (!OK)
113 break;
114
115 if (!strcmp(Arg.Str, "?"))
116 {
117 if (SpaceFlag == 0)
118 {
119 WrError(ErrNum_MixDBDS);
120 OK = FALSE;
121 }
122 else
123 {
124 SpaceFlag = 1;
125 CodeLen += Rep;
126 }
127 }
128 else if (SpaceFlag == 1)
129 {
130 WrError(ErrNum_MixDBDS);
131 OK = FALSE;
132 }
133 else
134 {
135 TempResult t;
136
137 SpaceFlag = 0;
138
139 EvalStrExpression(&Arg, &t);
140 switch (t.Typ)
141 {
142 case TempInt:
143 ToInt:
144 if (!mFirstPassUnknownOrQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, Int8))
145 {
146 WrStrErrorPos(ErrNum_OverRange, &Arg);
147 OK = False;
148 }
149 else if (SetMaxCodeLen(CodeLen + Rep))
150 {
151 WrError(ErrNum_CodeOverflow);
152 OK = False;
153 }
154 else
155 {
156 LongInt z2;
157
158 for (z2 = 0; z2 < Rep; z2++)
159 PutByte(t.Contents.Int);
160 }
161 break;
162
163 case TempFloat:
164 WrStrErrorPos(ErrNum_StringOrIntButFloat, &Arg);
165 OK = False;
166 break;
167
168 case TempString:
169 {
170 int l;
171
172 if (MultiCharToInt(&t, 1))
173 goto ToInt;
174
175 l = t.Contents.Ascii.Length;
176 TranslateString(t.Contents.Ascii.Contents, l);
177
178 if (SetMaxCodeLen(CodeLen + (Rep * l)))
179 {
180 WrError(ErrNum_CodeOverflow);
181 OK = False;
182 }
183 else
184 {
185 LongInt z2;
186 int z3;
187
188 for (z2 = 0; z2 < Rep; z2++)
189 for (z3 = 0; z3 < l; z3++)
190 PutByte(t.Contents.Ascii.Contents[z3]);
191 }
192 break;
193 }
194
195 default:
196 OK = False;
197 break;
198 }
199 }
200 }
201
202 if (!OK)
203 CodeLen = 0;
204 else
205 {
206 if (SpaceFlag == 1)
207 DontPrint = True;
208 if (*LabPart.Str)
209 SetSymbolOrStructElemSize(&LabPart, eSymbolSize8Bit);
210 }
211 }
212 }
213
PutADR(Word Value)214 static void PutADR(Word Value)
215 {
216 if (ListGran() > 1)
217 {
218 WAsmCode[CodeLen >> 1] = Value;
219 CodeLen += 2;
220 }
221 else if (M16Turn)
222 {
223 BAsmCode[CodeLen++] = Hi(Value);
224 BAsmCode[CodeLen++] = Lo(Value);
225 }
226 else
227 {
228 BAsmCode[CodeLen++] = Lo(Value);
229 BAsmCode[CodeLen++] = Hi(Value);
230 }
231 }
232
DecodeMotoADR(Word Index)233 void DecodeMotoADR(Word Index)
234 {
235 UNUSED(Index);
236
237 if (ChkArgCnt(1, ArgCntMax))
238 {
239 tStrComp *pArg, Arg;
240 Boolean OK = True;
241 LongInt Rep;
242 ShortInt SpaceFlag = -1;
243
244 forallargs (pArg, OK)
245 {
246 if (!*pArg->Str)
247 {
248 OK = FALSE;
249 WrError(ErrNum_EmptyArgument);
250 break;
251 }
252
253 OK = CutRep(&Arg, pArg, &Rep, NULL);
254 if (!OK)
255 break;
256
257 if (!strcmp(Arg.Str, "?"))
258 {
259 if (SpaceFlag == 0)
260 {
261 WrError(ErrNum_MixDBDS);
262 OK = False;
263 }
264 else
265 {
266 SpaceFlag = 1;
267 CodeLen += 2 * Rep;
268 }
269 }
270 else if (SpaceFlag == 1)
271 {
272 WrError(ErrNum_MixDBDS);
273 OK = False;
274 }
275 else
276 {
277 TempResult Res;
278 LongInt z2, Cnt;
279
280 SpaceFlag = 0;
281 EvalStrExpression(&Arg, &Res);
282
283 switch (Res.Typ)
284 {
285 case TempInt:
286 ToInt:
287 if (mFirstPassUnknown(Res.Flags))
288 Res.Contents.Int &= 0xffff;
289 if (!mSymbolQuestionable(Res.Flags) && !RangeCheck(Res.Contents.Int, Int16))
290 {
291 WrError(ErrNum_OverRange);
292 Res.Typ = TempNone;
293 }
294 Cnt = 1;
295 break;
296 case TempString:
297 if (MultiCharToInt(&Res, 2))
298 goto ToInt;
299 Cnt = Res.Contents.Ascii.Length;
300 TranslateString(Res.Contents.Ascii.Contents, Res.Contents.Ascii.Length);
301 break;
302 case TempFloat:
303 WrStrErrorPos(ErrNum_StringOrIntButFloat, &Arg);
304 /* fall-through */
305 default:
306 Res.Typ = TempNone;
307 Cnt = 0;
308 break;
309 }
310 if (TempNone == Res.Typ)
311 {
312 OK = False;
313 break;
314 }
315
316 if (SetMaxCodeLen(CodeLen + ((Cnt * Rep) << 1)))
317 {
318 WrError(ErrNum_CodeOverflow);
319 OK = False;
320 break;
321 }
322
323 for (z2 = 0; z2 < Rep; z2++)
324 switch (Res.Typ)
325 {
326 case TempInt:
327 PutADR(Res.Contents.Int);
328 break;
329 case TempString:
330 {
331 unsigned z3;
332
333 for (z3 = 0; z3 < Res.Contents.Ascii.Length; z3++)
334 PutADR(Res.Contents.Ascii.Contents[z3]);
335 break;
336 }
337 default:
338 break;
339 }
340 }
341 }
342
343 if (!OK)
344 CodeLen = 0;
345 else
346 {
347 if (SpaceFlag)
348 DontPrint = True;
349 if (*LabPart.Str)
350 SetSymbolOrStructElemSize(&LabPart, eSymbolSize16Bit);
351 }
352 }
353 }
354
DecodeFCC(Word Index)355 static void DecodeFCC(Word Index)
356 {
357 String SVal;
358 Boolean OK;
359 tStrComp *pArg, Arg;
360 int z3, l;
361 LongInt Rep,z2;
362 UNUSED(Index);
363
364 if (ChkArgCnt(1, ArgCntMax))
365 {
366 OK = True;
367
368 forallargs (pArg, OK)
369 {
370 if (!*pArg->Str)
371 {
372 OK = FALSE;
373 WrError(ErrNum_EmptyArgument);
374 break;
375 }
376
377 OK = CutRep(&Arg, pArg, &Rep, NULL);
378 if (!OK)
379 break;
380
381 EvalStrStringExpression(&Arg, &OK, SVal);
382 if (OK)
383 {
384 if (SetMaxCodeLen(CodeLen + Rep * strlen(SVal)))
385 {
386 WrError(ErrNum_CodeOverflow);
387 OK = False;
388 }
389 else
390 {
391 l = strlen(SVal);
392 TranslateString(SVal, l);
393 for (z2 = 0; z2 < Rep; z2++)
394 for (z3 = 0; z3 < l; z3++)
395 PutByte(SVal[z3]);
396 }
397 }
398 }
399
400 if (!OK)
401 CodeLen = 0;
402 else if (*LabPart.Str)
403 SetSymbolOrStructElemSize(&LabPart, eSymbolSize8Bit);
404 }
405 }
406
DecodeMotoDFS(Word Index)407 void DecodeMotoDFS(Word Index)
408 {
409 UNUSED(Index);
410
411 if (ChkArgCnt(1, 1))
412 {
413 Word HVal16;
414 Boolean OK;
415 tSymbolFlags Flags;
416
417 HVal16 = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
418 if (mFirstPassUnknown(Flags))
419 WrError(ErrNum_FirstPassCalc);
420 else if (OK)
421 {
422 DontPrint = True;
423 CodeLen = HVal16;
424 if (!HVal16)
425 WrError(ErrNum_NullResMem);
426 BookKeeping();
427 if (*LabPart.Str)
428 SetSymbolOrStructElemSize(&LabPart, eSymbolSize8Bit);
429 }
430 }
431 }
432
433 /*****************************************************************************
434 * Global Functions
435 *****************************************************************************/
436
DecodeMotoPseudo(Boolean Turn)437 Boolean DecodeMotoPseudo(Boolean Turn)
438 {
439 static PInstTable InstTable = NULL;
440
441 if (!InstTable)
442 {
443 InstTable = CreateInstTable(17);
444 AddInstTable(InstTable, "BYT", 0, DecodeMotoBYT);
445 AddInstTable(InstTable, "FCB", 0, DecodeMotoBYT);
446 AddInstTable(InstTable, "ADR", 0, DecodeMotoADR);
447 AddInstTable(InstTable, "FDB", 0, DecodeMotoADR);
448 AddInstTable(InstTable, "FCC", 0, DecodeFCC);
449 AddInstTable(InstTable, "DFS", 0, DecodeMotoDFS);
450 AddInstTable(InstTable, "RMB", 0, DecodeMotoDFS);
451 }
452
453 M16Turn = Turn;
454 return LookupInstTable(InstTable, OpPart.Str);
455 }
456
DigIns(char Ch,int Pos,Byte * pDest)457 static void DigIns(char Ch, int Pos, Byte *pDest)
458 {
459 int bytepos = Pos >> 1, bitpos = (Pos & 1) << 2;
460 Byte dig = Ch - '0';
461
462 pDest[bytepos] |= (dig << bitpos);
463 }
464
ConvertMotoFloatDec(Double F,Byte * pDest,Boolean NeedsBig)465 void ConvertMotoFloatDec(Double F, Byte *pDest, Boolean NeedsBig)
466 {
467 char s[30], Man[30], Exp[30];
468 char *pSplit;
469 int z, ManLen, ExpLen;
470 Byte epos;
471
472 UNUSED(NeedsBig);
473
474 /* convert to ASCII, split mantissa & exponent */
475
476 as_snprintf(s, sizeof(s), "%0.16e", F);
477 pSplit = strchr(s, HexStartCharacter + ('e' - 'a'));
478 if (!pSplit)
479 {
480 strcpy(Man, s);
481 strcpy(Exp, "+0000");
482 }
483 else
484 {
485 *pSplit = '\0';
486 strcpy(Man, s);
487 strcpy(Exp, pSplit + 1);
488 }
489
490 memset(pDest, 0, 12);
491
492 /* handle mantissa sign */
493
494 if (*Man == '-')
495 {
496 pDest[11] |= 0x80; strmov(Man, Man + 1);
497 }
498 else if (*Man == '+')
499 strmov(Man, Man + 1);
500
501 /* handle exponent sign */
502
503 if (*Exp == '-')
504 {
505 pDest[11] |= 0x40;
506 strmov(Exp, Exp + 1);
507 }
508 else if (*Exp == '+')
509 strmov(Exp, Exp + 1);
510
511 /* integral part of mantissa (one digit) */
512
513 DigIns(*Man, 16, pDest);
514 strmov(Man, Man + 2);
515
516 /* truncate mantissa if we have more digits than we can represent */
517
518 if (strlen(Man) > 16)
519 Man[16] = '\0';
520
521 /* insert mantissa digits */
522
523 ManLen = strlen(Man);
524 for (z = 0; z < ManLen; z++)
525 DigIns(Man[z], 15 - z, pDest);
526
527 /* truncate exponent if we have more digits than we can represent - this should
528 never occur since an IEEE double is limited to ~1E308 and we have for digits */
529
530 if (strlen(Exp) > 4)
531 strmov(Exp, Exp + strlen(Exp) - 4);
532
533 /* insert exponent bits */
534
535 ExpLen = strlen(Exp);
536 for (z = ExpLen - 1; z >= 0; z--)
537 {
538 epos = ExpLen - 1 - z;
539 if (epos == 3)
540 DigIns(Exp[z], 19, pDest);
541 else
542 DigIns(Exp[z], epos + 20, pDest);
543 }
544
545 if (BigEndian)
546 WSwap(pDest, 12);
547 }
548
EnterByte(LargeWord b)549 static void EnterByte(LargeWord b)
550 {
551 if (((CodeLen & 1) == 1) && (!BigEndian) && (ListGran() != 1))
552 {
553 BAsmCode[CodeLen ] = BAsmCode[CodeLen - 1];
554 BAsmCode[CodeLen - 1] = b;
555 }
556 else
557 {
558 BAsmCode[CodeLen] = b;
559 }
560 CodeLen++;
561 }
562
EnterWord(LargeWord w)563 static void EnterWord(LargeWord w)
564 {
565 if (ListGran() == 1)
566 {
567 BAsmCode[CodeLen ] = Hi(w);
568 BAsmCode[CodeLen + 1] = Lo(w);
569 }
570 else
571 WAsmCode[CodeLen >> 1] = w;
572 CodeLen += 2;
573 }
574
EnterPointer(LargeWord w)575 static void EnterPointer(LargeWord w)
576 {
577 EnterByte((w >> 16) & 0xff);
578 EnterByte((w >> 8) & 0xff);
579 EnterByte((w ) & 0xff);
580 }
581
EnterLWord(LargeWord l)582 static void EnterLWord(LargeWord l)
583 {
584 if (ListGran() == 1)
585 {
586 BAsmCode[CodeLen ] = (l >> 24) & 0xff;
587 BAsmCode[CodeLen + 1] = (l >> 16) & 0xff;
588 BAsmCode[CodeLen + 2] = (l >> 8) & 0xff;
589 BAsmCode[CodeLen + 3] = (l ) & 0xff;
590 }
591 else
592 {
593 WAsmCode[(CodeLen >> 1) ] = (l >> 16) & 0xffff;
594 WAsmCode[(CodeLen >> 1) + 1] = (l ) & 0xffff;
595 }
596 CodeLen += 4;
597 }
598
EnterQWord(LargeWord q)599 static void EnterQWord(LargeWord q)
600 {
601 if (ListGran() == 1)
602 {
603 #ifdef HAS64
604 BAsmCode[CodeLen ] = (q >> 56) & 0xff;
605 BAsmCode[CodeLen + 1] = (q >> 48) & 0xff;
606 BAsmCode[CodeLen + 2] = (q >> 40) & 0xff;
607 BAsmCode[CodeLen + 3] = (q >> 32) & 0xff;
608 #else
609 /* TempResult is LargeInt, so sign-extend */
610 BAsmCode[CodeLen ] =
611 BAsmCode[CodeLen + 1] =
612 BAsmCode[CodeLen + 2] =
613 BAsmCode[CodeLen + 3] = (q & 0x80000000ul) ? 0xff : 0x00;
614 #endif
615 BAsmCode[CodeLen + 4] = (q >> 24) & 0xff;
616 BAsmCode[CodeLen + 5] = (q >> 16) & 0xff;
617 BAsmCode[CodeLen + 6] = (q >> 8) & 0xff;
618 BAsmCode[CodeLen + 7] = (q ) & 0xff;
619 }
620 else
621 {
622 #ifdef HAS64
623 WAsmCode[(CodeLen >> 1) ] = (q >> 48) & 0xffff;
624 WAsmCode[(CodeLen >> 1) + 1] = (q >> 32) & 0xffff;
625 #else
626 /* TempResult is LargeInt, so sign-extend */
627 WAsmCode[(CodeLen >> 1) ] =
628 WAsmCode[(CodeLen >> 1) + 1] = (q & 0x80000000ul) ? 0xffff : 0x00;
629 #endif
630 WAsmCode[(CodeLen >> 1) + 2] = (q >> 16) & 0xffff;
631 WAsmCode[(CodeLen >> 1) + 3] = (q ) & 0xffff;
632 }
633 CodeLen += 8;
634 }
635
EnterIEEE2(Word * pField)636 static void EnterIEEE2(Word *pField)
637 {
638 if (ListGran() == 1)
639 {
640 BAsmCode[CodeLen ] = Hi(pField[1]);
641 BAsmCode[CodeLen + 1] = Lo(pField[0]);
642 }
643 else
644 {
645 WAsmCode[(CodeLen >> 1) ] = pField[0];
646 }
647 CodeLen += 2;
648 }
649
EnterIEEE4(Word * pField)650 static void EnterIEEE4(Word *pField)
651 {
652 if (ListGran() == 1)
653 {
654 BAsmCode[CodeLen ] = Hi(pField[1]);
655 BAsmCode[CodeLen + 1] = Lo(pField[1]);
656 BAsmCode[CodeLen + 2] = Hi(pField[0]);
657 BAsmCode[CodeLen + 3] = Lo(pField[0]);
658 }
659 else
660 {
661 WAsmCode[(CodeLen >> 1) ] = pField[1];
662 WAsmCode[(CodeLen >> 1) + 1] = pField[0];
663 }
664 CodeLen += 4;
665 }
666
EnterIEEE8(Word * pField)667 static void EnterIEEE8(Word *pField)
668 {
669 if (ListGran() == 1)
670 {
671 BAsmCode[CodeLen ] = Hi(pField[3]);
672 BAsmCode[CodeLen + 1] = Lo(pField[3]);
673 BAsmCode[CodeLen + 2] = Hi(pField[2]);
674 BAsmCode[CodeLen + 3] = Lo(pField[2]);
675 BAsmCode[CodeLen + 4] = Hi(pField[1]);
676 BAsmCode[CodeLen + 5] = Lo(pField[1]);
677 BAsmCode[CodeLen + 6] = Hi(pField[0]);
678 BAsmCode[CodeLen + 7] = Lo(pField[0]);
679 }
680 else
681 {
682 WAsmCode[(CodeLen >> 1) ] = pField[3];
683 WAsmCode[(CodeLen >> 1) + 1] = pField[2];
684 WAsmCode[(CodeLen >> 1) + 2] = pField[1];
685 WAsmCode[(CodeLen >> 1) + 3] = pField[0];
686 }
687 CodeLen += 8;
688 }
689
EnterIEEE10(Word * pField)690 static void EnterIEEE10(Word *pField)
691 {
692 if (ListGran() == 1)
693 {
694 BAsmCode[CodeLen ] = Hi(pField[4]);
695 BAsmCode[CodeLen + 1] = Lo(pField[4]);
696 BAsmCode[CodeLen + 2] = 0;
697 BAsmCode[CodeLen + 3] = 0;
698 BAsmCode[CodeLen + 4] = Hi(pField[3]);
699 BAsmCode[CodeLen + 5] = Lo(pField[3]);
700 BAsmCode[CodeLen + 6] = Hi(pField[2]);
701 BAsmCode[CodeLen + 7] = Lo(pField[2]);
702 BAsmCode[CodeLen + 8] = Hi(pField[1]);
703 BAsmCode[CodeLen + 9] = Lo(pField[1]);
704 BAsmCode[CodeLen +10] = Hi(pField[0]);
705 BAsmCode[CodeLen +11] = Lo(pField[0]);
706 }
707 else
708 {
709 WAsmCode[(CodeLen >> 1) ] = pField[4];
710 WAsmCode[(CodeLen >> 1) + 1] = 0;
711 WAsmCode[(CodeLen >> 1) + 2] = pField[3];
712 WAsmCode[(CodeLen >> 1) + 3] = pField[2];
713 WAsmCode[(CodeLen >> 1) + 4] = pField[1];
714 WAsmCode[(CodeLen >> 1) + 5] = pField[0];
715 }
716 CodeLen += 12;
717 }
718
EnterMotoFloatDec(Word * pField)719 static void EnterMotoFloatDec(Word *pField)
720 {
721 if (ListGran() == 1)
722 {
723 BAsmCode[CodeLen ] = Hi(pField[5]);
724 BAsmCode[CodeLen + 1] = Lo(pField[5]);
725 BAsmCode[CodeLen + 2] = Hi(pField[4]);
726 BAsmCode[CodeLen + 3] = Lo(pField[4]);
727 BAsmCode[CodeLen + 4] = Hi(pField[3]);
728 BAsmCode[CodeLen + 5] = Lo(pField[3]);
729 BAsmCode[CodeLen + 6] = Hi(pField[2]);
730 BAsmCode[CodeLen + 7] = Lo(pField[2]);
731 BAsmCode[CodeLen + 8] = Hi(pField[1]);
732 BAsmCode[CodeLen + 9] = Lo(pField[1]);
733 BAsmCode[CodeLen +10] = Hi(pField[0]);
734 BAsmCode[CodeLen +11] = Lo(pField[0]);
735 }
736 else
737 {
738 WAsmCode[(CodeLen >> 1) ] = pField[5];
739 WAsmCode[(CodeLen >> 1) + 1] = pField[4];
740 WAsmCode[(CodeLen >> 1) + 2] = pField[3];
741 WAsmCode[(CodeLen >> 1) + 3] = pField[2];
742 WAsmCode[(CodeLen >> 1) + 4] = pField[1];
743 WAsmCode[(CodeLen >> 1) + 5] = pField[0];
744 }
745 CodeLen += 12;
746 }
747
Double_2_ieee2_wrap(Double Inp,Byte * pDest,Boolean BigEndian)748 static void Double_2_ieee2_wrap(Double Inp, Byte *pDest, Boolean BigEndian)
749 {
750 (void)Double_2_ieee2(Inp, pDest, BigEndian);
751 }
752
AddMoto16PseudoONOFF(void)753 void AddMoto16PseudoONOFF(void)
754 {
755 AddONOFF("PADDING", &DoPadding, DoPaddingName, False);
756 }
757
758 /*!------------------------------------------------------------------------
759 * \fn GetWSize(tSymbolSize OpSize)
760 * \brief return size in bytes of data type
761 * \param OpSize data type
762 * \return size in bytes
763 * ------------------------------------------------------------------------ */
764
GetWSize(tSymbolSize OpSize)765 static Word GetWSize(tSymbolSize OpSize)
766 {
767 switch (OpSize)
768 {
769 case eSymbolSize8Bit:
770 return 1;
771 case eSymbolSize16Bit:
772 return 2;
773 case eSymbolSize24Bit:
774 return 3;
775 case eSymbolSize32Bit:
776 return 4;
777 case eSymbolSize64Bit:
778 return 8;
779 case eSymbolSizeFloat32Bit:
780 return 4;
781 case eSymbolSizeFloat64Bit:
782 return 8;
783
784 /* NOTE: Double_2_ieee10() creates 10 bytes, but WSize is set to 12 (two
785 padding bytes in binary representation). This means that WSwap() will
786 swap 12 instead of 10 bytes, which doesn't hurt, since TurnField is
787 large enough and the two (garbage) bytes at the end will not be used
788 by EnterIEEE10() anyway: */
789
790 case eSymbolSizeFloat96Bit:
791 return 12;
792 case eSymbolSizeFloatDec96Bit:
793 return 12;
794 case eSymbolSizeFloat16Bit:
795 return 2;
796 default:
797 return 0;
798 }
799 }
800
801 /*!------------------------------------------------------------------------
802 * \fn DecodeMotoDC(void)
803 * \brief decode DC.x instruction
804 * ------------------------------------------------------------------------ */
805
DecodeMotoDC(tSymbolSize OpSize,Boolean Turn)806 void DecodeMotoDC(tSymbolSize OpSize, Boolean Turn)
807 {
808 ShortInt SpaceFlag;
809 tStrComp *pArg, Arg;
810 LongInt z2, WSize, Rep = 0;
811 char *zp;
812 Boolean OK;
813 TempResult t;
814 tSymbolFlags Flags;
815 void (*EnterInt)(LargeWord) = NULL;
816 void (*ConvertFloat)(Double, Byte*, Boolean) = NULL;
817 void (*EnterFloat)(Word*) = NULL;
818 void (*Swap)(void*, int) = NULL;
819 IntType IntTypeEnum = UInt1;
820 FloatType FloatTypeEnum = Float32;
821 Boolean PadBeforeStart = Odd(EProgCounter()) && DoPadding && (OpSize != eSymbolSize8Bit);
822
823 UNUSED(Turn);
824
825 if (*LabPart.Str)
826 SetSymbolOrStructElemSize(&LabPart, OpSize);
827
828 if (!ChkArgCnt(1, ArgCntMax))
829 return;
830
831 if (OpSize < 0)
832 OpSize = eSymbolSize16Bit;
833
834 WSize = GetWSize(OpSize);
835 switch (OpSize)
836 {
837 case eSymbolSize8Bit:
838 EnterInt = EnterByte;
839 IntTypeEnum = Int8;
840 break;
841 case eSymbolSize16Bit:
842 EnterInt = EnterWord;
843 IntTypeEnum = Int16;
844 break;
845 case eSymbolSize24Bit:
846 EnterInt = EnterPointer;
847 IntTypeEnum = Int24;
848 break;
849 case eSymbolSize32Bit:
850 EnterInt = EnterLWord;
851 IntTypeEnum = Int32;
852 break;
853 case eSymbolSize64Bit:
854 EnterInt = EnterQWord;
855 #ifdef HAS64
856 IntTypeEnum = Int64;
857 #else
858 IntTypeEnum = Int32;
859 #endif
860 break;
861 case eSymbolSizeFloat16Bit:
862 ConvertFloat = Double_2_ieee2_wrap;
863 EnterFloat = EnterIEEE2;
864 FloatTypeEnum = Float16;
865 Swap = WSwap;
866 break;
867 case eSymbolSizeFloat32Bit:
868 ConvertFloat = Double_2_ieee4;
869 EnterFloat = EnterIEEE4;
870 FloatTypeEnum = Float32;
871 Swap = DWSwap;
872 break;
873 case eSymbolSizeFloat64Bit:
874 ConvertFloat = Double_2_ieee8;
875 EnterFloat = EnterIEEE8;
876 FloatTypeEnum = Float64;
877 Swap = QWSwap;
878 break;
879
880 /* NOTE: Double_2_ieee10() creates 10 bytes, but WSize is set to 12 (two
881 padding bytes in binary representation). This means that WSwap() will
882 swap 12 instead of 10 bytes, which doesn't hurt, since TurnField is
883 large enough and the two (garbage) bytes at the end will not be used
884 by EnterIEEE10() anyway: */
885
886 case eSymbolSizeFloat96Bit:
887 ConvertFloat = Double_2_ieee10;
888 EnterFloat = EnterIEEE10;
889 FloatTypeEnum = Float80;
890 Swap = WSwap;
891 break;
892 case eSymbolSizeFloatDec96Bit:
893 ConvertFloat = ConvertMotoFloatDec;
894 EnterFloat = EnterMotoFloatDec;
895 FloatTypeEnum = FloatDec;
896 break;
897 default:
898 break;
899 }
900
901 OK = True;
902 SpaceFlag = -1;
903
904 forallargs (pArg, OK)
905 {
906 if (!*pArg->Str)
907 {
908 OK = FALSE;
909 WrError(ErrNum_EmptyArgument);
910 break;
911 }
912
913 OK = CutRep(&Arg, pArg, &Rep, &Flags);
914 if (!OK)
915 break;
916 if (mFirstPassUnknown(Flags))
917 {
918 OK = FALSE;
919 WrError(ErrNum_FirstPassCalc);
920 break;
921 }
922
923 if (!strcmp(Arg.Str, "?"))
924 {
925 if (SpaceFlag == 0)
926 {
927 WrError(ErrNum_MixDBDS);
928 OK = FALSE;
929 }
930 else
931 {
932 if (PadBeforeStart)
933 {
934 InsertPadding(1, True);
935 PadBeforeStart = False;
936 }
937
938 SpaceFlag = 1;
939 CodeLen += (Rep * WSize);
940 }
941 }
942 else if (SpaceFlag == 1)
943 {
944 WrError(ErrNum_MixDBDS);
945 OK = FALSE;
946 }
947 else
948 {
949 SpaceFlag = 0;
950
951 if (PadBeforeStart)
952 {
953 InsertPadding(1, False);
954 PadBeforeStart = False;
955 }
956
957 EvalStrExpression(&Arg, &t);
958
959 switch (t.Typ)
960 {
961 case TempInt:
962 ToInt:
963 if (!EnterInt)
964 {
965 if (ConvertFloat && EnterFloat)
966 {
967 t.Contents.Float = t.Contents.Int;
968 t.Typ = TempFloat;
969 goto HandleFloat;
970 }
971 else
972 {
973 WrStrErrorPos(ErrNum_StringOrIntButFloat, pArg);
974 OK = False;
975 }
976 }
977 else if (!mFirstPassUnknownOrQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, IntTypeEnum))
978 {
979 WrError(ErrNum_OverRange);
980 OK = False;
981 }
982 else if (SetMaxCodeLen(CodeLen + (Rep * WSize)))
983 {
984 WrError(ErrNum_CodeOverflow);
985 OK = False;
986 }
987 else
988 for (z2 = 0; z2 < Rep; z2++)
989 EnterInt(t.Contents.Int);
990 break;
991 HandleFloat:
992 case TempFloat:
993 if ((!ConvertFloat) || (!EnterFloat))
994 {
995 WrStrErrorPos(ErrNum_StringOrIntButFloat, pArg);
996 OK = False;
997 }
998 else if (!FloatRangeCheck(t.Contents.Float, FloatTypeEnum))
999 {
1000 WrError(ErrNum_OverRange);
1001 OK = False;
1002 }
1003 else if (SetMaxCodeLen(CodeLen + (Rep * WSize)))
1004 {
1005 WrError(ErrNum_CodeOverflow);
1006 OK = False;
1007 }
1008 else
1009 {
1010 Word TurnField[8];
1011
1012 ConvertFloat(t.Contents.Float, (Byte *) TurnField, BigEndian);
1013 if (BigEndian && Swap)
1014 Swap((void*) TurnField, WSize);
1015 for (z2 = 0; z2 < Rep; z2++)
1016 EnterFloat(TurnField);
1017 }
1018 break;
1019 case TempString:
1020 if (MultiCharToInt(&t, (WSize < 8) ? WSize : 8))
1021 goto ToInt;
1022 if (!EnterInt)
1023 {
1024 if (ConvertFloat && EnterFloat)
1025 {
1026 if (SetMaxCodeLen(CodeLen + (Rep * WSize * t.Contents.Ascii.Length)))
1027 {
1028 WrError(ErrNum_CodeOverflow);
1029 OK = False;
1030 }
1031 else
1032 {
1033 for (z2 = 0; z2 < Rep; z2++)
1034 for (zp = t.Contents.Ascii.Contents; zp < t.Contents.Ascii.Contents + t.Contents.Ascii.Length; zp++)
1035 {
1036 Word TurnField[8];
1037
1038 ConvertFloat(CharTransTable[(usint) (*zp & 0xff)], (Byte *) TurnField, BigEndian);
1039 if ((BigEndian) && (Swap))
1040 Swap((void*) TurnField, WSize);
1041 EnterFloat(TurnField);
1042 }
1043 }
1044 }
1045 else
1046 {
1047 WrError(ErrNum_FloatButString);
1048 OK = False;
1049 }
1050 }
1051 else if (SetMaxCodeLen(CodeLen + Rep * t.Contents.Ascii.Length))
1052 {
1053 WrError(ErrNum_CodeOverflow);
1054 OK = False;
1055 }
1056 else
1057 for (z2 = 0; z2 < Rep; z2++)
1058 for (zp = t.Contents.Ascii.Contents; zp < t.Contents.Ascii.Contents + t.Contents.Ascii.Length; EnterInt(CharTransTable[((usint) *(zp++)) & 0xff]));
1059 break;
1060 case TempNone:
1061 OK = False;
1062 break;
1063 default:
1064 assert(0);
1065 }
1066
1067 }
1068 }
1069
1070 /* purge results if an error occured */
1071
1072 if (!OK) CodeLen = 0;
1073
1074 /* just space reservation ? */
1075
1076 else if (SpaceFlag == 1)
1077 DontPrint = True;
1078 }
1079
DecodeMoto16Pseudo(tSymbolSize OpSize,Boolean Turn)1080 Boolean DecodeMoto16Pseudo(tSymbolSize OpSize, Boolean Turn)
1081 {
1082 LongInt NewPC, HVal;
1083 Boolean ValOK;
1084 tSymbolFlags Flags;
1085 Boolean PadBeforeStart;
1086
1087 if (OpSize < 0)
1088 OpSize = eSymbolSize16Bit;
1089
1090 PadBeforeStart = Odd(EProgCounter()) && DoPadding && (OpSize != eSymbolSize8Bit);
1091 if (*OpPart.Str != 'D')
1092 return False;
1093
1094 if (Memo("DC"))
1095 {
1096 DecodeMotoDC(OpSize, Turn);
1097 return True;
1098 }
1099
1100 if (Memo("DS"))
1101 {
1102 Word WSize = GetWSize(OpSize);
1103
1104 if (ChkArgCnt(1, 1))
1105 {
1106 HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &Flags);
1107 if (mFirstPassUnknown(Flags))
1108 WrError(ErrNum_FirstPassCalc);
1109 if (ValOK && !mFirstPassUnknown(Flags))
1110 {
1111 Boolean OddSize = (eSymbolSize8Bit == OpSize) || (eSymbolSize24Bit == OpSize);
1112
1113 if (PadBeforeStart)
1114 {
1115 InsertPadding(1, True);
1116 PadBeforeStart = False;
1117 }
1118
1119 DontPrint = True;
1120
1121 /* value of 0 means aligning the PC. Doesn't make sense for bytes and 24 bit values */
1122
1123 if ((HVal == 0) && !OddSize)
1124 {
1125 NewPC = EProgCounter() + WSize - 1;
1126 NewPC -= NewPC % WSize;
1127 CodeLen = NewPC - EProgCounter();
1128 if (CodeLen == 0)
1129 {
1130 DontPrint = False;
1131 if (WSize == 1)
1132 WrError(ErrNum_NullResMem);
1133 }
1134 }
1135 else
1136 CodeLen = HVal * WSize;
1137 if (DontPrint)
1138 BookKeeping();
1139 }
1140 }
1141 if (*LabPart.Str)
1142 SetSymbolOrStructElemSize(&LabPart, OpSize);
1143 return True;
1144 }
1145
1146 return False;
1147 }
1148
DecodeMoto16AttrSizeCore(char SizeSpec,tSymbolSize * pResult,Boolean Allow24)1149 static Boolean DecodeMoto16AttrSizeCore(char SizeSpec, tSymbolSize *pResult, Boolean Allow24)
1150 {
1151 switch (as_toupper(SizeSpec))
1152 {
1153 case 'B': *pResult = eSymbolSize8Bit; break;
1154 case 'W': *pResult = eSymbolSize16Bit; break;
1155 case 'L': *pResult = eSymbolSize32Bit; break;
1156 case 'Q': *pResult = eSymbolSize64Bit; break;
1157 case 'S': *pResult = eSymbolSizeFloat32Bit; break;
1158 case 'D': *pResult = eSymbolSizeFloat64Bit; break;
1159 case 'X': *pResult = eSymbolSizeFloat96Bit; break;
1160 case 'C': *pResult = eSymbolSizeFloat16Bit; break;
1161 case 'P': *pResult = Allow24 ? eSymbolSize24Bit : eSymbolSizeFloatDec96Bit; break;
1162 case '\0': break;
1163 default:
1164 return False;
1165 }
1166 return True;
1167 }
1168
1169 /*!------------------------------------------------------------------------
1170 * \fn DecodeMoto16AttrSize(char SizeSpec, tSymbolSize *pResult, Boolean Allow24)
1171 * \brief decode Motorola-style operand size character
1172 * \param SizeSpec size specifier character
1173 * \param pResult returns result size
1174 * \param Allow24 allow 'p' as specifier for 24 Bits (S12Z-specific)
1175 * \return True if decoded
1176 * ------------------------------------------------------------------------ */
1177
DecodeMoto16AttrSize(char SizeSpec,tSymbolSize * pResult,Boolean Allow24)1178 Boolean DecodeMoto16AttrSize(char SizeSpec, tSymbolSize *pResult, Boolean Allow24)
1179 {
1180 if (!DecodeMoto16AttrSizeCore(SizeSpec, pResult, Allow24))
1181 {
1182 WrError(ErrNum_UndefAttr);
1183 return False;
1184 }
1185 return True;
1186 }
1187
DecodeMoto16AttrSizeStr(const struct sStrComp * pSizeSpec,tSymbolSize * pResult,Boolean Allow24)1188 Boolean DecodeMoto16AttrSizeStr(const struct sStrComp *pSizeSpec, tSymbolSize *pResult, Boolean Allow24)
1189 {
1190 if ((strlen(pSizeSpec->Str) > 1)
1191 || !DecodeMoto16AttrSizeCore(*pSizeSpec->Str, pResult, Allow24))
1192 {
1193 WrStrErrorPos(ErrNum_UndefAttr, pSizeSpec);
1194 return False;
1195 }
1196 return True;
1197 }
1198