Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1126 savelij 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 "be_le.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 "onoff_common.h"
31
#include "chartrans.h"
32
#include "asmcode.h"
33
#include "errmsg.h"
34
#include "aplfloat.h"
35
 
36
#include "motpseudo.h"
37
 
38
#define LEAVE goto func_exit
39
 
40
/*****************************************************************************
41
 * Local Functions
42
 *****************************************************************************/
43
 
44
static Boolean CutRep(tStrComp *pDest, const tStrComp *pSrc, LongInt *pErg, tSymbolFlags *pFlags)
45
{
46
  tStrComp Src;
47
 
48
  if (pFlags)
49
    *pFlags = eSymbolFlag_None;
50
  StrCompRefRight(&Src, pSrc, 0);
51
  KillPrefBlanksStrCompRef(&Src);
52
  if (*Src.str.p_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.p_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
 
80
static void PutByte(Byte Value, Boolean big_endian)
81
{
82
  if ((ListGran() == 1) || (!(CodeLen & 1)))
83
    BAsmCode[CodeLen] = Value;
84
  else if (big_endian)
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
 
91
void DecodeMotoBYT(Word big_endian)
92
{
93
  if (ChkArgCnt(1, ArgCntMax))
94
  {
95
    ShortInt SpaceFlag = -1;
96
    tStrComp *pArg, Arg;
97
    LongInt Rep;
98
    Boolean OK = True;
99
 
100
    forallargs (pArg, OK)
101
    {
102
      if (!*pArg->str.p_str)
103
      {
104
        OK = FALSE;
105
        WrError(ErrNum_EmptyArgument);
106
        break;
107
      }
108
 
109
      OK = CutRep(&Arg, pArg, &Rep, NULL);
110
      if (!OK)
111
        break;
112
 
113
      if (!strcmp(Arg.str.p_str, "?"))
114
      {
115
        if (SpaceFlag == 0)
116
        {
117
          WrError(ErrNum_MixDBDS);
118
          OK = FALSE;
119
        }
120
        else
121
        {
122
          SpaceFlag = 1;
123
          CodeLen += Rep;
124
        }
125
      }
126
      else if (SpaceFlag == 1)
127
      {
128
        WrError(ErrNum_MixDBDS);
129
        OK = FALSE;
130
      }
131
      else
132
      {
133
        TempResult t;
134
 
135
        SpaceFlag = 0;
136
 
137
        as_tempres_ini(&t);
138
        EvalStrExpression(&Arg, &t);
139
        switch (t.Typ)
140
        {
141
          case TempInt:
142
          ToInt:
143
            if (!mFirstPassUnknownOrQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, Int8))
144
            {
145
              WrStrErrorPos(ErrNum_OverRange, &Arg);
146
              OK = False;
147
            }
148
            else if (SetMaxCodeLen(CodeLen + Rep))
149
            {
150
              WrError(ErrNum_CodeOverflow);
151
              OK = False;
152
            }
153
            else
154
            {
155
              LongInt z2;
156
 
157
              for (z2 = 0; z2 < Rep; z2++)
158
                PutByte(t.Contents.Int, big_endian);
159
            }
160
            break;
161
 
162
          case TempFloat:
163
            WrStrErrorPos(ErrNum_StringOrIntButFloat, &Arg);
164
            OK = False;
165
            break;
166
 
167
          case TempString:
168
          {
169
            int l;
170
 
171
            if (MultiCharToInt(&t, 1))
172
              goto ToInt;
173
 
174
            if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, &Arg))
175
              OK = False;
176
            else
177
            {
178
              l = t.Contents.str.len;
179
 
180
              if (SetMaxCodeLen(CodeLen + (Rep * l)))
181
              {
182
                WrError(ErrNum_CodeOverflow);
183
                OK = False;
184
              }
185
              else
186
              {
187
                LongInt z2;
188
                int z3;
189
 
190
                for (z2 = 0; z2 < Rep; z2++)
191
                  for (z3 = 0; z3 < l; z3++)
192
                    PutByte(t.Contents.str.p_str[z3], big_endian);
193
              }
194
            }
195
            break;
196
          }
197
 
198
          default:
199
            OK = False;
200
            break;
201
        }
202
        as_tempres_free(&t);
203
      }
204
    }
205
 
206
    if (!OK)
207
      CodeLen = 0;
208
    else
209
    {
210
      if (SpaceFlag == 1)
211
        DontPrint = True;
212
      if (*LabPart.str.p_str)
213
        SetSymbolOrStructElemSize(&LabPart, eSymbolSize8Bit);
214
    }
215
  }
216
}
217
 
218
static void PutADR(Word Value, Boolean big_endian)
219
{
220
  if (ListGran() > 1)
221
  {
222
    WAsmCode[CodeLen >> 1] = Value;
223
    CodeLen += 2;
224
  }
225
  else if (big_endian)
226
  {
227
    BAsmCode[CodeLen++] = Hi(Value);
228
    BAsmCode[CodeLen++] = Lo(Value);
229
  }
230
  else
231
  {
232
    BAsmCode[CodeLen++] = Lo(Value);
233
    BAsmCode[CodeLen++] = Hi(Value);
234
  }
235
}
236
 
237
void DecodeMotoADR(Word big_endian)
238
{
239
  if (ChkArgCnt(1, ArgCntMax))
240
  {
241
    tStrComp *pArg, Arg;
242
    Boolean OK = True;
243
    LongInt Rep;
244
    ShortInt SpaceFlag = -1;
245
 
246
    forallargs (pArg, OK)
247
    {
248
      if (!*pArg->str.p_str)
249
      {
250
        OK = FALSE;
251
        WrError(ErrNum_EmptyArgument);
252
        break;
253
      }
254
 
255
      OK = CutRep(&Arg, pArg, &Rep, NULL);
256
      if (!OK)
257
        break;
258
 
259
      if (!strcmp(Arg.str.p_str, "?"))
260
      {
261
        if (SpaceFlag == 0)
262
        {
263
          WrError(ErrNum_MixDBDS);
264
          OK = False;
265
        }
266
        else
267
        {
268
          SpaceFlag = 1;
269
          CodeLen += 2 * Rep;
270
        }
271
      }
272
      else if (SpaceFlag == 1)
273
      {
274
        WrError(ErrNum_MixDBDS);
275
        OK = False;
276
      }
277
      else
278
      {
279
        TempResult Res;
280
        LongInt z2, Cnt;
281
 
282
        SpaceFlag = 0;
283
        as_tempres_ini(&Res);
284
        EvalStrExpression(&Arg, &Res);
285
 
286
        switch (Res.Typ)
287
        {
288
          case TempInt:
289
          ToInt:
290
            if (mFirstPassUnknown(Res.Flags))
291
              Res.Contents.Int &= 0xffff;
292
            if (!mSymbolQuestionable(Res.Flags) && !RangeCheck(Res.Contents.Int, Int16))
293
            {
294
              WrError(ErrNum_OverRange);
295
              Res.Typ = TempNone;
296
            }
297
            Cnt = 1;
298
            break;
299
          case TempString:
300
            if (MultiCharToInt(&Res, 2))
301
              goto ToInt;
302
            if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &Res.Contents.str, &Arg))
303
              Res.Typ = TempNone;
304
            else
305
              Cnt = Res.Contents.str.len;
306
            break;
307
          case TempFloat:
308
            WrStrErrorPos(ErrNum_StringOrIntButFloat, &Arg);
309
            /* fall-through */
310
          default:
311
            Res.Typ = TempNone;
312
            Cnt = 0;
313
            break;
314
        }
315
        if (TempNone == Res.Typ)
316
        {
317
          OK = False;
318
          break;
319
        }
320
 
321
        if (SetMaxCodeLen(CodeLen + ((Cnt * Rep) << 1)))
322
        {
323
          WrError(ErrNum_CodeOverflow);
324
          OK = False;
325
          break;
326
        }
327
 
328
        for (z2 = 0; z2 < Rep; z2++)
329
          switch (Res.Typ)
330
          {
331
            case TempInt:
332
              PutADR(Res.Contents.Int, big_endian);
333
              break;
334
            case TempString:
335
            {
336
              unsigned z3;
337
 
338
              for (z3 = 0; z3 < Res.Contents.str.len; z3++)
339
                PutADR(Res.Contents.str.p_str[z3], big_endian);
340
              break;
341
            }
342
            default:
343
              break;
344
          }
345
        as_tempres_free(&Res);
346
      }
347
    }
348
 
349
    if (!OK)
350
      CodeLen = 0;
351
    else
352
    {
353
      if (SpaceFlag)
354
        DontPrint = True;
355
      if (*LabPart.str.p_str)
356
        SetSymbolOrStructElemSize(&LabPart, eSymbolSize16Bit);
357
    }
358
  }
359
}
360
 
361
void DecodeMotoDCM(Word big_endian)
362
{
363
  if (ChkArgCnt(1, ArgCntMax))
364
  {
365
    tStrComp *pArg, Arg;
366
    Boolean OK = True;
367
    LongInt Rep;
368
    ShortInt SpaceFlag = -1;
369
 
370
    forallargs (pArg, OK)
371
    {
372
      if (!*pArg->str.p_str)
373
      {
374
        OK = FALSE;
375
        WrError(ErrNum_EmptyArgument);
376
        break;
377
      }
378
 
379
      OK = CutRep(&Arg, pArg, &Rep, NULL);
380
      if (!OK)
381
        break;
382
 
383
      if (!strcmp(Arg.str.p_str, "?"))
384
      {
385
        if (SpaceFlag == 0)
386
        {
387
          WrError(ErrNum_MixDBDS);
388
          OK = False;
389
        }
390
        else
391
        {
392
          SpaceFlag = 1;
393
          CodeLen += 4 * Rep;
394
        }
395
      }
396
      else if (SpaceFlag == 1)
397
      {
398
        WrError(ErrNum_MixDBDS);
399
        OK = False;
400
      }
401
      else
402
      {
403
        TempResult Res;
404
        LongInt z2;
405
        int ret;
406
        Word buf[2];
407
 
408
        SpaceFlag = 0;
409
        as_tempres_ini(&Res);
410
        EvalStrExpression(&Arg, &Res);
411
 
412
        switch (Res.Typ)
413
        {
414
          case TempInt:
415
            TempResultToFloat(&Res);
416
            break;
417
          case TempFloat:
418
            break;
419
          case TempString:
420
            WrStrErrorPos(ErrNum_FloatButString, &Arg);
421
            /* fall-through */
422
          default:
423
            Res.Typ = TempNone;
424
            break;
425
        }
426
        if (TempNone == Res.Typ)
427
        {
428
          OK = False;
429
          break;
430
        }
431
 
432
        if (SetMaxCodeLen(CodeLen + (Rep << 2)))
433
        {
434
          WrError(ErrNum_CodeOverflow);
435
          OK = False;
436
          break;
437
        }
438
 
439
        ret = Double_2_apl4(Res.Contents.Float, buf);
440
        if (!check_apl_fp_dispose_result(ret, &Arg))
441
        {
442
          OK = False;
443
          break;
444
        }
445
 
446
        for (z2 = 0; z2 < Rep; z2++)
447
        {
448
          PutADR(buf[0], big_endian);
449
          PutADR(buf[1], big_endian);
450
        }
451
        as_tempres_free(&Res);
452
      }
453
    }
454
 
455
    if (!OK)
456
      CodeLen = 0;
457
    else
458
    {
459
      if (SpaceFlag)
460
        DontPrint = True;
461
      if (*LabPart.str.p_str)
462
        SetSymbolOrStructElemSize(&LabPart, eSymbolSize16Bit);
463
    }
464
  }
465
}
466
 
467
static void DecodeFCC(Word big_endian)
468
{
469
  if (ChkArgCnt(1, ArgCntMax))
470
  {
471
    Boolean OK = True;
472
    tStrComp *pArg, Arg;
473
    TempResult t;
474
 
475
    as_tempres_ini(&t);
476
    forallargs (pArg, OK)
477
    {
478
      LongInt Rep;
479
 
480
      if (!*pArg->str.p_str)
481
      {
482
        OK = FALSE;
483
        WrError(ErrNum_EmptyArgument);
484
        break;
485
      }
486
 
487
      OK = CutRep(&Arg, pArg, &Rep, NULL);
488
      if (!OK)
489
        break;
490
 
491
      EvalStrExpression(&Arg, &t);
492
      switch (t.Typ)
493
      {
494
        case TempString:
495
        {
496
          int l;
497
 
498
          if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, &Arg))
499
            OK = False;
500
          else
501
          {
502
            l = t.Contents.str.len;
503
            if (SetMaxCodeLen(CodeLen + Rep * l))
504
            {
505
              WrError(ErrNum_CodeOverflow);
506
              OK = False;
507
            }
508
            else
509
            {
510
              LongInt z2;
511
              int z3;
512
 
513
              for (z2 = 0; z2 < Rep; z2++)
514
                for (z3 = 0; z3 < l; z3++)
515
                  PutByte(t.Contents.str.p_str[z3], big_endian);
516
            }
517
          }
518
          break;
519
        }
520
        case TempNone:
521
          OK = False;
522
          break;
523
        default:
524
          WrStrErrorPos(ErrNum_ExpectString, &Arg);
525
          OK = False;
526
      }
527
    }
528
    as_tempres_free(&t);
529
 
530
    if (!OK)
531
      CodeLen = 0;
532
    else if (*LabPart.str.p_str)
533
      SetSymbolOrStructElemSize(&LabPart, eSymbolSize8Bit);
534
  }
535
}
536
 
537
void DecodeMotoDFS(Word Index)
538
{
539
  UNUSED(Index);
540
 
541
  if (ChkArgCnt(1, 1))
542
  {
543
    Word HVal16;
544
    Boolean OK;
545
    tSymbolFlags Flags;
546
 
547
    HVal16 = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
548
    if (mFirstPassUnknown(Flags))
549
      WrError(ErrNum_FirstPassCalc);
550
    else if (OK)
551
    {
552
      DontPrint = True;
553
      CodeLen = HVal16;
554
      if (!HVal16)
555
        WrError(ErrNum_NullResMem);
556
      BookKeeping();
557
      if (*LabPart.str.p_str)
558
        SetSymbolOrStructElemSize(&LabPart, eSymbolSize8Bit);
559
    }
560
  }
561
}
562
 
563
/*****************************************************************************
564
 * Global Functions
565
 *****************************************************************************/
566
 
567
static PInstTable inst_table_moto8 = NULL;
568
 
569
void init_moto8_pseudo(PInstTable p_inst_table, unsigned flags)
570
{
571
  if (!p_inst_table)
572
    p_inst_table = inst_table_moto8 = CreateInstTable(23);
573
  AddInstTable(p_inst_table, "BYT", !!(flags & e_moto_8_be), DecodeMotoBYT);
574
  AddInstTable(p_inst_table, "FCB", !!(flags & e_moto_8_be), DecodeMotoBYT);
575
  if (flags & e_moto_8_db)
576
    AddInstTable(p_inst_table, "DB", !!(flags & e_moto_8_be), DecodeMotoBYT);
577
  AddInstTable(p_inst_table, "ADR", !!(flags & e_moto_8_be), DecodeMotoADR);
578
  AddInstTable(p_inst_table, "FDB", !!(flags & e_moto_8_be), DecodeMotoADR);
579
  if (flags & e_moto_8_dw)
580
    AddInstTable(p_inst_table, "DW", !!(flags & e_moto_8_be), DecodeMotoADR);
581
  if (flags & e_moto_8_ddb)
582
    AddInstTable(p_inst_table, "DDB", True, DecodeMotoADR);
583
  if (flags & e_moto_8_dcm)
584
    AddInstTable(p_inst_table, "DCM", True, DecodeMotoDCM);
585
  AddInstTable(p_inst_table, "FCC", !!(flags & e_moto_8_be), DecodeFCC);
586
  AddInstTable(p_inst_table, "DFS", 0, DecodeMotoDFS);
587
  AddInstTable(p_inst_table, "RMB", 0, DecodeMotoDFS);
588
  if (flags & e_moto_8_ds)
589
    AddInstTable(p_inst_table, "DS", 0, DecodeMotoDFS);
590
}
591
 
592
Boolean decode_moto8_pseudo(void)
593
{
594
  return LookupInstTable(inst_table_moto8, OpPart.str.p_str);
595
}
596
 
597
void deinit_moto8_pseudo(void)
598
{
599
  DestroyInstTable(inst_table_moto8);
600
  inst_table_moto8 = NULL;
601
}
602
 
603
static void DigIns(char Ch, int Pos, Byte *pDest)
604
{
605
  int bytepos = Pos >> 1, bitpos = (Pos & 1) << 2;
606
  Byte dig = Ch - '0';
607
 
608
  pDest[bytepos] |= (dig << bitpos);
609
}
610
 
611
void ConvertMotoFloatDec(Double F, Byte *pDest, Boolean NeedsBig)
612
{
613
  char s[30], Man[30], Exp[30];
614
  char *pSplit;
615
  int z, ManLen, ExpLen;
616
  Byte epos;
617
 
618
  UNUSED(NeedsBig);
619
 
620
  /* convert to ASCII, split mantissa & exponent */
621
 
622
  as_snprintf(s, sizeof(s), "%0.16e", F);
623
  pSplit = strchr(s, HexStartCharacter + ('e' - 'a'));
624
  if (!pSplit)
625
  {
626
    strcpy(Man, s);
627
    strcpy(Exp, "+0000");
628
  }
629
  else
630
  {
631
    *pSplit = '\0';
632
    strcpy(Man, s);
633
    strcpy(Exp, pSplit + 1);
634
  }
635
 
636
  memset(pDest, 0, 12);
637
 
638
  /* handle mantissa sign */
639
 
640
  if (*Man == '-')
641
  {
642
    pDest[11] |= 0x80; strmov(Man, Man + 1);
643
  }
644
  else if (*Man == '+')
645
    strmov(Man, Man + 1);
646
 
647
  /* handle exponent sign */
648
 
649
  if (*Exp == '-')
650
  {
651
    pDest[11] |= 0x40;
652
    strmov(Exp, Exp + 1);
653
  }
654
  else if (*Exp == '+')
655
    strmov(Exp, Exp + 1);
656
 
657
  /* integral part of mantissa (one digit) */
658
 
659
  DigIns(*Man, 16, pDest);
660
  strmov(Man, Man + 2);
661
 
662
  /* truncate mantissa if we have more digits than we can represent */
663
 
664
  if (strlen(Man) > 16)
665
    Man[16] = '\0';
666
 
667
  /* insert mantissa digits */
668
 
669
  ManLen = strlen(Man);
670
  for (z = 0; z < ManLen; z++)
671
    DigIns(Man[z], 15 - z, pDest);
672
 
673
  /* truncate exponent if we have more digits than we can represent - this should
674
     never occur since an IEEE double is limited to ~1E308 and we have for digits */
675
 
676
  if (strlen(Exp) > 4)
677
    strmov(Exp, Exp + strlen(Exp) - 4);
678
 
679
  /* insert exponent bits */
680
 
681
  ExpLen = strlen(Exp);
682
  for (z = ExpLen - 1; z >= 0; z--)
683
  {
684
    epos = ExpLen - 1 - z;
685
    if (epos == 3)
686
      DigIns(Exp[z], 19, pDest);
687
    else
688
      DigIns(Exp[z], epos + 20, pDest);
689
  }
690
 
691
  if (HostBigEndian)
692
    WSwap(pDest, 12);
693
}
694
 
695
static void EnterByte(LargeWord b, Boolean BigEndian)
696
{
697
  UNUSED(BigEndian);
698
  if (((CodeLen & 1) == 1) && (!HostBigEndian) && (ListGran() != 1))
699
  {
700
    BAsmCode[CodeLen    ] = BAsmCode[CodeLen - 1];
701
    BAsmCode[CodeLen - 1] = b;
702
  }
703
  else
704
  {
705
    BAsmCode[CodeLen] = b;
706
  }
707
  CodeLen++;
708
}
709
 
710
static void EnterWord(LargeWord w, Boolean BigEndian)
711
{
712
  if (ListGran() == 1)
713
  {
714
    if (BigEndian)
715
    {
716
      BAsmCode[CodeLen    ] = Hi(w);
717
      BAsmCode[CodeLen + 1] = Lo(w);
718
    }
719
    else
720
    {
721
      BAsmCode[CodeLen    ] = Lo(w);
722
      BAsmCode[CodeLen + 1] = Hi(w);
723
    }
724
  }
725
  else
726
    WAsmCode[CodeLen >> 1] = w;
727
  CodeLen += 2;
728
}
729
 
730
static void EnterPointer(LargeWord w, Boolean BigEndian)
731
{
732
  if (BigEndian)
733
  {
734
    EnterByte((w >> 16) & 0xff, BigEndian);
735
    EnterByte((w >>  8) & 0xff, BigEndian);
736
    EnterByte((w      ) & 0xff, BigEndian);
737
  }
738
  else
739
  {
740
    EnterByte((w      ) & 0xff, BigEndian);
741
    EnterByte((w >>  8) & 0xff, BigEndian);
742
    EnterByte((w >> 16) & 0xff, BigEndian);
743
  }
744
}
745
 
746
static void EnterLWord(LargeWord l, Boolean BigEndian)
747
{
748
  if (ListGran() == 1)
749
  {
750
    if (BigEndian)
751
    {
752
      BAsmCode[CodeLen    ] = (l >> 24) & 0xff;
753
      BAsmCode[CodeLen + 1] = (l >> 16) & 0xff;
754
      BAsmCode[CodeLen + 2] = (l >>  8) & 0xff;
755
      BAsmCode[CodeLen + 3] = (l      ) & 0xff;
756
    }
757
    else
758
    {
759
      BAsmCode[CodeLen    ] = (l      ) & 0xff;
760
      BAsmCode[CodeLen + 1] = (l >>  8) & 0xff;
761
      BAsmCode[CodeLen + 2] = (l >> 16) & 0xff;
762
      BAsmCode[CodeLen + 3] = (l >> 24) & 0xff;
763
    }
764
  }
765
  else
766
  {
767
    WAsmCode[(CodeLen >> 1)    ] = (l >> 16) & 0xffff;
768
    WAsmCode[(CodeLen >> 1) + 1] = (l      ) & 0xffff;
769
  }
770
  CodeLen += 4;
771
}
772
 
773
static void EnterQWord(LargeWord q, Boolean BigEndian)
774
{
775
  if (ListGran() == 1)
776
  {
777
    if (BigEndian)
778
    {
779
#ifdef HAS64
780
      BAsmCode[CodeLen    ] = (q >> 56) & 0xff;
781
      BAsmCode[CodeLen + 1] = (q >> 48) & 0xff;
782
      BAsmCode[CodeLen + 2] = (q >> 40) & 0xff;
783
      BAsmCode[CodeLen + 3] = (q >> 32) & 0xff;
784
#else
785
      /* TempResult is LargeInt, so sign-extend */
786
      BAsmCode[CodeLen    ] =
787
      BAsmCode[CodeLen + 1] =
788
      BAsmCode[CodeLen + 2] =
789
      BAsmCode[CodeLen + 3] = (q & 0x80000000ul) ? 0xff : 0x00;
790
#endif
791
      BAsmCode[CodeLen + 4] = (q >> 24) & 0xff;
792
      BAsmCode[CodeLen + 5] = (q >> 16) & 0xff;
793
      BAsmCode[CodeLen + 6] = (q >>  8) & 0xff;
794
      BAsmCode[CodeLen + 7] = (q      ) & 0xff;
795
    }
796
    else
797
    {
798
      BAsmCode[CodeLen    ] = (q      ) & 0xff;
799
      BAsmCode[CodeLen + 1] = (q >>  8) & 0xff;
800
      BAsmCode[CodeLen + 2] = (q >> 16) & 0xff;
801
      BAsmCode[CodeLen + 3] = (q >> 24) & 0xff;
802
#ifdef HAS64
803
      BAsmCode[CodeLen + 4] = (q >> 32) & 0xff;
804
      BAsmCode[CodeLen + 5] = (q >> 40) & 0xff;
805
      BAsmCode[CodeLen + 6] = (q >> 48) & 0xff;
806
      BAsmCode[CodeLen + 7] = (q >> 56) & 0xff;
807
#else
808
      /* TempResult is LargeInt, so sign-extend */
809
      BAsmCode[CodeLen + 4] =
810
      BAsmCode[CodeLen + 5] =
811
      BAsmCode[CodeLen + 6] =
812
      BAsmCode[CodeLen + 7] = (q & 0x80000000ul) ? 0xff : 0x00;
813
#endif
814
    }
815
  }
816
  else
817
  {
818
#ifdef HAS64
819
    WAsmCode[(CodeLen >> 1)    ] = (q >> 48) & 0xffff;
820
    WAsmCode[(CodeLen >> 1) + 1] = (q >> 32) & 0xffff;
821
#else
822
    /* TempResult is LargeInt, so sign-extend */
823
    WAsmCode[(CodeLen >> 1)    ] =
824
    WAsmCode[(CodeLen >> 1) + 1] = (q & 0x80000000ul) ? 0xffff : 0x00;
825
#endif
826
    WAsmCode[(CodeLen >> 1) + 2] = (q >> 16) & 0xffff;
827
    WAsmCode[(CodeLen >> 1) + 3] = (q      ) & 0xffff;
828
  }
829
  CodeLen += 8;
830
}
831
 
832
static void EnterIEEE2(Word *pField, Boolean BigEndian)
833
{
834
  if (ListGran() == 1)
835
  {
836
    if (BigEndian)
837
    {
838
      BAsmCode[CodeLen    ] = Hi(pField[0]);
839
      BAsmCode[CodeLen + 1] = Lo(pField[0]);
840
    }
841
    else
842
    {
843
      BAsmCode[CodeLen    ] = Lo(pField[0]);
844
      BAsmCode[CodeLen + 1] = Hi(pField[0]);
845
    }
846
  }
847
  else
848
  {
849
    WAsmCode[(CodeLen >> 1)    ] = pField[0];
850
  }
851
  CodeLen += 2;
852
}
853
 
854
static void EnterIEEE4(Word *pField, Boolean BigEndian)
855
{
856
  if (ListGran() == 1)
857
  {
858
    if (BigEndian)
859
    {
860
      BAsmCode[CodeLen    ] = Hi(pField[1]);
861
      BAsmCode[CodeLen + 1] = Lo(pField[1]);
862
      BAsmCode[CodeLen + 2] = Hi(pField[0]);
863
      BAsmCode[CodeLen + 3] = Lo(pField[0]);
864
    }
865
    else
866
    {
867
      BAsmCode[CodeLen    ] = Lo(pField[0]);
868
      BAsmCode[CodeLen + 1] = Hi(pField[0]);
869
      BAsmCode[CodeLen + 2] = Lo(pField[1]);
870
      BAsmCode[CodeLen + 3] = Hi(pField[1]);
871
    }
872
  }
873
  else
874
  {
875
    WAsmCode[(CodeLen >> 1)    ] = pField[1];
876
    WAsmCode[(CodeLen >> 1) + 1] = pField[0];
877
  }
878
  CodeLen += 4;
879
}
880
 
881
static void EnterIEEE8(Word *pField, Boolean BigEndian)
882
{
883
  if (ListGran() == 1)
884
  {
885
    if (BigEndian)
886
    {
887
      BAsmCode[CodeLen    ] = Hi(pField[3]);
888
      BAsmCode[CodeLen + 1] = Lo(pField[3]);
889
      BAsmCode[CodeLen + 2] = Hi(pField[2]);
890
      BAsmCode[CodeLen + 3] = Lo(pField[2]);
891
      BAsmCode[CodeLen + 4] = Hi(pField[1]);
892
      BAsmCode[CodeLen + 5] = Lo(pField[1]);
893
      BAsmCode[CodeLen + 6] = Hi(pField[0]);
894
      BAsmCode[CodeLen + 7] = Lo(pField[0]);
895
    }
896
    else
897
    {
898
      BAsmCode[CodeLen    ] = Lo(pField[0]);
899
      BAsmCode[CodeLen + 1] = Hi(pField[0]);
900
      BAsmCode[CodeLen + 2] = Lo(pField[1]);
901
      BAsmCode[CodeLen + 3] = Hi(pField[1]);
902
      BAsmCode[CodeLen + 4] = Lo(pField[2]);
903
      BAsmCode[CodeLen + 5] = Hi(pField[2]);
904
      BAsmCode[CodeLen + 6] = Lo(pField[3]);
905
      BAsmCode[CodeLen + 7] = Hi(pField[3]);
906
    }
907
  }
908
  else
909
  {
910
    WAsmCode[(CodeLen >> 1)    ] = pField[3];
911
    WAsmCode[(CodeLen >> 1) + 1] = pField[2];
912
    WAsmCode[(CodeLen >> 1) + 2] = pField[1];
913
    WAsmCode[(CodeLen >> 1) + 3] = pField[0];
914
  }
915
  CodeLen += 8;
916
}
917
 
918
static void EnterIEEE10(Word *pField, Boolean BigEndian)
919
{
920
  if (ListGran() == 1)
921
  {
922
    if (BigEndian)
923
    {
924
      BAsmCode[CodeLen    ] = Hi(pField[4]);
925
      BAsmCode[CodeLen + 1] = Lo(pField[4]);
926
      BAsmCode[CodeLen + 2] = 0;
927
      BAsmCode[CodeLen + 3] = 0;
928
      BAsmCode[CodeLen + 4] = Hi(pField[3]);
929
      BAsmCode[CodeLen + 5] = Lo(pField[3]);
930
      BAsmCode[CodeLen + 6] = Hi(pField[2]);
931
      BAsmCode[CodeLen + 7] = Lo(pField[2]);
932
      BAsmCode[CodeLen + 8] = Hi(pField[1]);
933
      BAsmCode[CodeLen + 9] = Lo(pField[1]);
934
      BAsmCode[CodeLen +10] = Hi(pField[0]);
935
      BAsmCode[CodeLen +11] = Lo(pField[0]);
936
    }
937
    else
938
    {
939
      BAsmCode[CodeLen    ] = Lo(pField[0]);
940
      BAsmCode[CodeLen + 1] = Hi(pField[0]);
941
      BAsmCode[CodeLen + 2] = Lo(pField[1]);
942
      BAsmCode[CodeLen + 3] = Hi(pField[1]);
943
      BAsmCode[CodeLen + 4] = Lo(pField[2]);
944
      BAsmCode[CodeLen + 5] = Hi(pField[2]);
945
      BAsmCode[CodeLen + 6] = Lo(pField[3]);
946
      BAsmCode[CodeLen + 7] = Hi(pField[3]);
947
      BAsmCode[CodeLen + 8] = 0;
948
      BAsmCode[CodeLen + 9] = 0;
949
      BAsmCode[CodeLen +10] = Lo(pField[4]);
950
      BAsmCode[CodeLen +11] = Hi(pField[4]);
951
    }
952
  }
953
  else
954
  {
955
    WAsmCode[(CodeLen >> 1)    ] = pField[4];
956
    WAsmCode[(CodeLen >> 1) + 1] = 0;
957
    WAsmCode[(CodeLen >> 1) + 2] = pField[3];
958
    WAsmCode[(CodeLen >> 1) + 3] = pField[2];
959
    WAsmCode[(CodeLen >> 1) + 4] = pField[1];
960
    WAsmCode[(CodeLen >> 1) + 5] = pField[0];
961
  }
962
  CodeLen += 12;
963
}
964
 
965
static void EnterMotoFloatDec(Word *pField, Boolean BigEndian)
966
{
967
  if (ListGran() == 1)
968
  {
969
    if (BigEndian)
970
    {
971
      BAsmCode[CodeLen    ] = Hi(pField[5]);
972
      BAsmCode[CodeLen + 1] = Lo(pField[5]);
973
      BAsmCode[CodeLen + 2] = Hi(pField[4]);
974
      BAsmCode[CodeLen + 3] = Lo(pField[4]);
975
      BAsmCode[CodeLen + 4] = Hi(pField[3]);
976
      BAsmCode[CodeLen + 5] = Lo(pField[3]);
977
      BAsmCode[CodeLen + 6] = Hi(pField[2]);
978
      BAsmCode[CodeLen + 7] = Lo(pField[2]);
979
      BAsmCode[CodeLen + 8] = Hi(pField[1]);
980
      BAsmCode[CodeLen + 9] = Lo(pField[1]);
981
      BAsmCode[CodeLen +10] = Hi(pField[0]);
982
      BAsmCode[CodeLen +11] = Lo(pField[0]);
983
    }
984
    else
985
    {
986
      BAsmCode[CodeLen    ] = Lo(pField[0]);
987
      BAsmCode[CodeLen + 1] = Hi(pField[0]);
988
      BAsmCode[CodeLen + 2] = Lo(pField[1]);
989
      BAsmCode[CodeLen + 3] = Hi(pField[1]);
990
      BAsmCode[CodeLen + 4] = Lo(pField[2]);
991
      BAsmCode[CodeLen + 5] = Hi(pField[2]);
992
      BAsmCode[CodeLen + 6] = Lo(pField[3]);
993
      BAsmCode[CodeLen + 7] = Hi(pField[3]);
994
      BAsmCode[CodeLen + 8] = Lo(pField[4]);
995
      BAsmCode[CodeLen + 9] = Hi(pField[4]);
996
      BAsmCode[CodeLen +10] = Lo(pField[5]);
997
      BAsmCode[CodeLen +11] = Hi(pField[5]);
998
    }
999
  }
1000
  else
1001
  {
1002
    WAsmCode[(CodeLen >> 1)    ] = pField[5];
1003
    WAsmCode[(CodeLen >> 1) + 1] = pField[4];
1004
    WAsmCode[(CodeLen >> 1) + 2] = pField[3];
1005
    WAsmCode[(CodeLen >> 1) + 3] = pField[2];
1006
    WAsmCode[(CodeLen >> 1) + 4] = pField[1];
1007
    WAsmCode[(CodeLen >> 1) + 5] = pField[0];
1008
  }
1009
  CodeLen += 12;
1010
}
1011
 
1012
static void Double_2_ieee2_wrap(Double Inp, Byte *pDest, Boolean BigEndian)
1013
{
1014
  (void)Double_2_ieee2(Inp, pDest, BigEndian);
1015
}
1016
 
1017
void AddMoto16PseudoONOFF(Boolean default_padding_value)
1018
{
1019
  SetFlag(&DoPadding, DoPaddingName, default_padding_value);
1020
  AddONOFF(DoPaddingName, &DoPadding, DoPaddingName, False);
1021
}
1022
 
1023
/*!------------------------------------------------------------------------
1024
 * \fn     GetWSize(tSymbolSize OpSize)
1025
 * \brief  return size in bytes of data type
1026
 * \param  OpSize data type
1027
 * \return size in bytes
1028
 * ------------------------------------------------------------------------ */
1029
 
1030
static Word GetWSize(tSymbolSize OpSize)
1031
{
1032
  switch (OpSize)
1033
  {
1034
    case eSymbolSize8Bit:
1035
      return 1;
1036
    case eSymbolSize16Bit:
1037
      return 2;
1038
    case eSymbolSize24Bit:
1039
      return 3;
1040
    case eSymbolSize32Bit:
1041
      return 4;
1042
    case eSymbolSize64Bit:
1043
      return 8;
1044
    case eSymbolSizeFloat32Bit:
1045
      return 4;
1046
    case eSymbolSizeFloat64Bit:
1047
      return 8;
1048
 
1049
    /* NOTE: Double_2_ieee10() creates 10 bytes, but WSize is set to 12 (two
1050
       padding bytes in binary representation).  This means that WSwap() will
1051
       swap 12 instead of 10 bytes, which doesn't hurt, since TurnField is
1052
       large enough and the two (garbage) bytes at the end will not be used
1053
       by EnterIEEE10() anyway: */
1054
 
1055
    case eSymbolSizeFloat96Bit:
1056
      return 12;
1057
    case eSymbolSizeFloatDec96Bit:
1058
      return 12;
1059
    case eSymbolSizeFloat16Bit:
1060
      return 2;
1061
    default:
1062
      return 0;
1063
  }
1064
}
1065
 
1066
/*!------------------------------------------------------------------------
1067
 * \fn     DecodeMotoDC(void)
1068
 * \brief  decode DC.x instruction
1069
 * ------------------------------------------------------------------------ */
1070
 
1071
void DecodeMotoDC(tSymbolSize OpSize, Boolean BigEndian)
1072
{
1073
  ShortInt SpaceFlag;
1074
  tStrComp *pArg, Arg;
1075
  LongInt z2, WSize, Rep = 0;
1076
  char *zp;
1077
  Boolean OK;
1078
  TempResult t;
1079
  tSymbolFlags Flags;
1080
  void (*EnterInt)(LargeWord, Boolean) = NULL;
1081
  void (*ConvertFloat)(Double, Byte*, Boolean) = NULL;
1082
  void (*EnterFloat)(Word*, Boolean) = NULL;
1083
  void (*Swap)(void*, int) = NULL;
1084
  IntType IntTypeEnum = UInt1;
1085
  FloatType FloatTypeEnum = Float32;
1086
  Boolean PadBeforeStart = Odd(EProgCounter()) && DoPadding && (OpSize != eSymbolSize8Bit);
1087
 
1088
  as_tempres_ini(&t);
1089
  if (*LabPart.str.p_str)
1090
    SetSymbolOrStructElemSize(&LabPart, OpSize);
1091
 
1092
  if (!ChkArgCnt(1, ArgCntMax))
1093
    LEAVE;
1094
 
1095
  if (OpSize < 0)
1096
    OpSize = eSymbolSize16Bit;
1097
 
1098
  WSize = GetWSize(OpSize);
1099
  switch (OpSize)
1100
  {
1101
    case eSymbolSize8Bit:
1102
      EnterInt = EnterByte;
1103
      IntTypeEnum = Int8;
1104
      break;
1105
    case eSymbolSize16Bit:
1106
      EnterInt = EnterWord;
1107
      IntTypeEnum = Int16;
1108
      break;
1109
    case eSymbolSize24Bit:
1110
      EnterInt = EnterPointer;
1111
      IntTypeEnum = Int24;
1112
      break;
1113
    case eSymbolSize32Bit:
1114
      EnterInt = EnterLWord;
1115
      IntTypeEnum = Int32;
1116
      break;
1117
    case eSymbolSize64Bit:
1118
      EnterInt = EnterQWord;
1119
#ifdef HAS64
1120
      IntTypeEnum = Int64;
1121
#else
1122
      IntTypeEnum = Int32;
1123
#endif
1124
      break;
1125
    case eSymbolSizeFloat16Bit:
1126
      ConvertFloat = Double_2_ieee2_wrap;
1127
      EnterFloat = EnterIEEE2;
1128
      FloatTypeEnum = Float16;
1129
      Swap = NULL;
1130
      break;
1131
    case eSymbolSizeFloat32Bit:
1132
      ConvertFloat = Double_2_ieee4;
1133
      EnterFloat = EnterIEEE4;
1134
      FloatTypeEnum = Float32;
1135
      Swap = DWSwap;
1136
      break;
1137
    case eSymbolSizeFloat64Bit:
1138
      ConvertFloat = Double_2_ieee8;
1139
      EnterFloat = EnterIEEE8;
1140
      FloatTypeEnum = Float64;
1141
      Swap = QWSwap;
1142
      break;
1143
 
1144
    /* NOTE: Double_2_ieee10() creates 10 bytes, but WSize is set to 12 (two
1145
       padding bytes in binary representation).  This means that WSwap() will
1146
       swap 12 instead of 10 bytes, which doesn't hurt, since TurnField is
1147
       large enough and the two (garbage) bytes at the end will not be used
1148
       by EnterIEEE10() anyway: */
1149
 
1150
    case eSymbolSizeFloat96Bit:
1151
      ConvertFloat = Double_2_ieee10;
1152
      EnterFloat = EnterIEEE10;
1153
      FloatTypeEnum = Float80;
1154
      Swap = TWSwap;
1155
      break;
1156
    case eSymbolSizeFloatDec96Bit:
1157
      ConvertFloat = ConvertMotoFloatDec;
1158
      EnterFloat = EnterMotoFloatDec;
1159
      FloatTypeEnum = FloatDec;
1160
      break;
1161
    default:
1162
      break;
1163
  }
1164
 
1165
  OK = True;
1166
  SpaceFlag = -1;
1167
 
1168
  forallargs (pArg, OK)
1169
  {
1170
    if (!*pArg->str.p_str)
1171
    {
1172
      OK = FALSE;
1173
      WrError(ErrNum_EmptyArgument);
1174
      break;
1175
    }
1176
 
1177
    OK = CutRep(&Arg, pArg, &Rep, &Flags);
1178
    if (!OK)
1179
      break;
1180
    if (mFirstPassUnknown(Flags))
1181
    {
1182
      OK = FALSE;
1183
      WrError(ErrNum_FirstPassCalc);
1184
      break;
1185
    }
1186
 
1187
    if (!strcmp(Arg.str.p_str, "?"))
1188
    {
1189
      if (SpaceFlag == 0)
1190
      {
1191
        WrError(ErrNum_MixDBDS);
1192
        OK = FALSE;
1193
      }
1194
      else
1195
      {
1196
        if (PadBeforeStart)
1197
        {
1198
          InsertPadding(1, True);
1199
          PadBeforeStart = False;
1200
        }
1201
 
1202
        SpaceFlag = 1;
1203
        CodeLen += (Rep * WSize);
1204
      }
1205
    }
1206
    else if (SpaceFlag == 1)
1207
    {
1208
      WrError(ErrNum_MixDBDS);
1209
      OK = FALSE;
1210
    }
1211
    else
1212
    {
1213
      SpaceFlag = 0;
1214
 
1215
      if (PadBeforeStart)
1216
      {
1217
        InsertPadding(1, False);
1218
        PadBeforeStart = False;
1219
      }
1220
 
1221
      EvalStrExpression(&Arg, &t);
1222
 
1223
      switch (t.Typ)
1224
      {
1225
        case TempInt:
1226
        ToInt:
1227
          if (!EnterInt)
1228
          {
1229
            if (ConvertFloat && EnterFloat)
1230
            {
1231
              TempResultToFloat(&t);
1232
              goto HandleFloat;
1233
            }
1234
            else
1235
            {
1236
              WrStrErrorPos(ErrNum_StringOrIntButFloat, pArg);
1237
              OK = False;
1238
            }
1239
          }
1240
          else if (!mFirstPassUnknownOrQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, IntTypeEnum))
1241
          {
1242
            WrError(ErrNum_OverRange);
1243
            OK = False;
1244
          }
1245
          else if (SetMaxCodeLen(CodeLen + (Rep * WSize)))
1246
          {
1247
            WrError(ErrNum_CodeOverflow);
1248
            OK = False;
1249
          }
1250
          else
1251
            for (z2 = 0; z2 < Rep; z2++)
1252
              EnterInt(t.Contents.Int, BigEndian);
1253
          break;
1254
        HandleFloat:
1255
        case TempFloat:
1256
          if (!ConvertFloat || !EnterFloat)
1257
          {
1258
            WrStrErrorPos(ErrNum_StringOrIntButFloat, pArg);
1259
            OK = False;
1260
          }
1261
          else if (!FloatRangeCheck(t.Contents.Float, FloatTypeEnum))
1262
          {
1263
            WrError(ErrNum_OverRange);
1264
            OK = False;
1265
          }
1266
          else if (SetMaxCodeLen(CodeLen + (Rep * WSize)))
1267
          {
1268
            WrError(ErrNum_CodeOverflow);
1269
            OK = False;
1270
          }
1271
          else
1272
          {
1273
            Word TurnField[8];
1274
 
1275
            ConvertFloat(t.Contents.Float, (Byte *) TurnField, HostBigEndian);
1276
            if (HostBigEndian && Swap)
1277
              Swap((void*) TurnField, WSize);
1278
            for (z2 = 0; z2 < Rep; z2++)
1279
              EnterFloat(TurnField, BigEndian);
1280
          }
1281
          break;
1282
        case TempString:
1283
          if (MultiCharToInt(&t, (WSize < 8) ? WSize : 8))
1284
            goto ToInt;
1285
          if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, &Arg)) { }
1286
          else if (!EnterInt)
1287
          {
1288
            if (ConvertFloat && EnterFloat)
1289
            {
1290
              if (SetMaxCodeLen(CodeLen + (Rep * WSize * t.Contents.str.len)))
1291
              {
1292
                WrError(ErrNum_CodeOverflow);
1293
                OK = False;
1294
              }
1295
              else
1296
              {
1297
                for (z2 = 0; z2 < Rep; z2++)
1298
                  for (zp = t.Contents.str.p_str; zp < t.Contents.str.p_str + t.Contents.str.len; zp++)
1299
                  {
1300
                    Word TurnField[8];
1301
 
1302
                    ConvertFloat((usint) (*zp & 0xff), (Byte *) TurnField, HostBigEndian);
1303
                    if (HostBigEndian && Swap)
1304
                      Swap((void*) TurnField, WSize);
1305
                    EnterFloat(TurnField, BigEndian);
1306
                  }
1307
              }
1308
            }
1309
            else
1310
            {
1311
              WrError(ErrNum_FloatButString);
1312
              OK = False;
1313
            }
1314
          }
1315
          else if (SetMaxCodeLen(CodeLen + Rep * t.Contents.str.len))
1316
          {
1317
            WrError(ErrNum_CodeOverflow);
1318
            OK = False;
1319
          }
1320
          else
1321
            for (z2 = 0; z2 < Rep; z2++)
1322
              for (zp = t.Contents.str.p_str; zp < t.Contents.str.p_str + t.Contents.str.len; EnterInt(((usint) *(zp++)) & 0xff, BigEndian));
1323
          break;
1324
        case TempNone:
1325
          OK = False;
1326
          break;
1327
        default:
1328
          assert(0);
1329
      }
1330
 
1331
    }
1332
  }
1333
 
1334
  /* purge results if an error occured */
1335
 
1336
  if (!OK) CodeLen = 0;
1337
 
1338
  /* just space reservation ? */
1339
 
1340
  else if (SpaceFlag == 1)
1341
    DontPrint = True;
1342
 
1343
func_exit:
1344
  as_tempres_free(&t);
1345
}
1346
 
1347
Boolean DecodeMoto16Pseudo(tSymbolSize OpSize, Boolean BigEndian)
1348
{
1349
  LongInt HVal;
1350
  Boolean ValOK;
1351
  tSymbolFlags Flags;
1352
  Boolean PadBeforeStart;
1353
 
1354
  if (OpSize < 0)
1355
    OpSize = eSymbolSize16Bit;
1356
 
1357
  PadBeforeStart = Odd(EProgCounter()) && DoPadding && (OpSize != eSymbolSize8Bit);
1358
  if (*OpPart.str.p_str != 'D')
1359
    return False;
1360
 
1361
  if (Memo("DC"))
1362
  {
1363
    DecodeMotoDC(OpSize, BigEndian);
1364
    return True;
1365
  }
1366
 
1367
  if (Memo("DS"))
1368
  {
1369
    Word WSize = GetWSize(OpSize);
1370
 
1371
    if (ChkArgCnt(1, 1))
1372
    {
1373
      HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &Flags);
1374
      if (mFirstPassUnknown(Flags))
1375
        WrError(ErrNum_FirstPassCalc);
1376
      if (ValOK && !mFirstPassUnknown(Flags))
1377
      {
1378
        Boolean OddSize = (eSymbolSize8Bit == OpSize) || (eSymbolSize24Bit == OpSize);
1379
 
1380
        if (PadBeforeStart)
1381
        {
1382
          InsertPadding(1, True);
1383
          PadBeforeStart = False;
1384
        }
1385
 
1386
        DontPrint = True;
1387
 
1388
        /* value of 0 means aligning the PC.  Doesn't make sense for bytes and 24 bit values */
1389
 
1390
        if ((HVal == 0) && !OddSize)
1391
        {
1392
          LongWord NewPC = EProgCounter() + WSize - 1;
1393
          NewPC -= NewPC % WSize;
1394
          CodeLen = NewPC - EProgCounter();
1395
          if (CodeLen == 0)
1396
          {
1397
            DontPrint = False;
1398
            if (WSize == 1)
1399
              WrError(ErrNum_NullResMem);
1400
          }
1401
        }
1402
        else
1403
          CodeLen = HVal * WSize;
1404
        if (DontPrint)
1405
          BookKeeping();
1406
      }
1407
    }
1408
    if (*LabPart.str.p_str)
1409
      SetSymbolOrStructElemSize(&LabPart, OpSize);
1410
    return True;
1411
  }
1412
 
1413
  return False;
1414
}
1415
 
1416
static Boolean DecodeMoto16AttrSizeCore(char SizeSpec, tSymbolSize *pResult, Boolean Allow24)
1417
{
1418
  switch (as_toupper(SizeSpec))
1419
  {
1420
    case 'B': *pResult = eSymbolSize8Bit; break;
1421
    case 'W': *pResult = eSymbolSize16Bit; break;
1422
    case 'L': *pResult = eSymbolSize32Bit; break;
1423
    case 'Q': *pResult = eSymbolSize64Bit; break;
1424
    case 'S': *pResult = eSymbolSizeFloat32Bit; break;
1425
    case 'D': *pResult = eSymbolSizeFloat64Bit; break;
1426
    case 'X': *pResult = eSymbolSizeFloat96Bit; break;
1427
    case 'C': *pResult = eSymbolSizeFloat16Bit; break;
1428
    case 'P': *pResult = Allow24 ? eSymbolSize24Bit : eSymbolSizeFloatDec96Bit; break;
1429
    case '\0': break;
1430
    default:
1431
      return False;
1432
  }
1433
  return True;
1434
}
1435
 
1436
/*!------------------------------------------------------------------------
1437
 * \fn     DecodeMoto16AttrSize(char SizeSpec, tSymbolSize *pResult, Boolean Allow24)
1438
 * \brief  decode Motorola-style operand size character
1439
 * \param  SizeSpec size specifier character
1440
 * \param  pResult returns result size
1441
 * \param  Allow24 allow 'p' as specifier for 24 Bits (S12Z-specific)
1442
 * \return True if decoded
1443
 * ------------------------------------------------------------------------ */
1444
 
1445
Boolean DecodeMoto16AttrSize(char SizeSpec, tSymbolSize *pResult, Boolean Allow24)
1446
{
1447
  if (!DecodeMoto16AttrSizeCore(SizeSpec, pResult, Allow24))
1448
  {
1449
    WrError(ErrNum_UndefAttr);
1450
    return False;
1451
  }
1452
  return True;
1453
}
1454
 
1455
Boolean DecodeMoto16AttrSizeStr(const struct sStrComp *pSizeSpec, tSymbolSize *pResult, Boolean Allow24)
1456
{
1457
  if ((strlen(pSizeSpec->str.p_str) > 1)
1458
   || !DecodeMoto16AttrSizeCore(*pSizeSpec->str.p_str, pResult, Allow24))
1459
  {
1460
    WrStrErrorPos(ErrNum_UndefAttr, pSizeSpec);
1461
    return False;
1462
  }
1463
  return True;
1464
}