Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

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