Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* code56k.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS-Portierung                                                             */
6
/*                                                                           */
7
/* AS-Codegeneratormodul fuer die DSP56K-Familie                             */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
#include "stdinc.h"
12
#include <string.h>
13
#include <ctype.h>
14
 
15
#include "strutil.h"
16
#include "chunks.h"
17
#include "errmsg.h"
18
#include "asmdef.h"
19
#include "asmsub.h"
20
#include "asmpars.h"
21
#include "asmitree.h"
22
#include "codepseudo.h"
23
#include "chartrans.h"
24
#include "codevars.h"
25
#include "onoff_common.h"
26
 
27
#include "code56k.h"
28
 
29
typedef struct
30
{
31
  LongWord Code;
32
  CPUVar MinCPU;
33
} FixedOrder;
34
 
35
typedef enum
36
{
37
  ParAB, ParABShl1, ParABShl2, ParXYAB, ParABXYnAB, ParABBA, ParXYnAB, ParMul, ParFixAB
38
} ParTyp;
39
typedef struct
40
{
41
  ParTyp Typ;
42
  Byte Code;
43
} ParOrder;
44
 
45
#define CondCount (sizeof(CondNames) / sizeof(*CondNames))
46
static const char CondNames[][3] =
47
{
48
  "CC", "GE", "NE", "PL", "NN", "EC", "LC", "GT", "CS", "LT", "EQ", "MI",
49
  "NR", "ES", "LS", "LE", "HS", "LO"
50
};
51
 
52
static const Byte MacTable[4][4] =
53
{
54
  { 0, 2, 5, 4 },
55
  { 2, 0xff, 6, 7 },
56
  { 5, 6, 1, 3 },
57
  { 4, 7, 3, 0xff }
58
};
59
 
60
static const Byte Mac4Table[4][4] =
61
{
62
  { 0, 13, 10, 4 },
63
  { 5, 1, 14, 11 },
64
  { 2, 6, 8, 15 },
65
  { 12, 3, 7, 9 }
66
};
67
 
68
static const Byte Mac2Table[4] =
69
{
70
  1, 3, 2, 0
71
};
72
 
73
enum
74
{
75
  ModNone = -1,
76
  ModImm = 0,
77
  ModAbs = 1,
78
  ModIReg = 2,
79
  ModPreDec = 3,
80
  ModPostDec = 4,
81
  ModPostInc = 5,
82
  ModIndex = 6,
83
  ModModDec = 7,
84
  ModModInc = 8,
85
  ModDisp = 9
86
};
87
 
88
#define MModImm (1 << ModImm)
89
#define MModAbs (1 << ModAbs)
90
#define MModIReg (1 << ModIReg)
91
#define MModPreDec (1 << ModPreDec)
92
#define MModPostDec (1 << ModPostDec)
93
#define MModPostInc (1 << ModPostInc)
94
#define MModIndex (1 << ModIndex)
95
#define MModModDec (1 << ModModDec)
96
#define MModModInc (1 << ModModInc)
97
#define MModDisp (1 << ModDisp)
98
 
99
#define MModNoExt (MModIReg | MModPreDec | MModPostDec | MModPostInc | MModIndex | MModModDec | MModModInc)
100
#define MModNoImm (MModAbs | MModNoExt)
101
#define MModAll (MModNoImm | MModImm)
102
 
103
#define SegLData SegBData /* SegYData + 1 */
104
 
105
#define MSegCode (1 << SegCode)
106
#define MSegXData (1 << SegXData)
107
#define MSegYData (1 << SegYData)
108
#define MSegLData (1 << SegLData)
109
 
110
typedef struct
111
{
112
  ShortInt Type;
113
  LongInt Mode, Val;
114
  Byte Seg, ShortMode;
115
  Boolean ForceImmLong;
116
  tSymbolFlags AbsSymFlags;
117
  int Cnt;
118
} tAdrResult;
119
 
120
static CPUVar CPU56000, CPU56002, CPU56300;
121
static IntType AdrInt;
122
static LargeInt MemLimit;
123
 
124
static tStrComp LeftComp, MidComp, RightComp, Left1Comp, Left2Comp, Right1Comp, Right2Comp;
125
 
126
static FixedOrder *FixedOrders;
127
static ParOrder *ParOrders;
128
 
129
/*----------------------------------------------------------------------------------------------*/
130
 
131
static void SplitArg(const tStrComp *pOrig, tStrComp *pLDest, tStrComp *pRDest)
132
{
133
  char *p;
134
 
135
  p = QuotPos(pOrig->str.p_str, ',');
136
  if (!p)
137
  {
138
    StrCompReset(pRDest);
139
    StrCompCopy(pLDest, pOrig);
140
  }
141
  else
142
    StrCompSplitCopy(pLDest, pRDest, pOrig, p);
143
}
144
 
145
static unsigned CutSize(const tStrComp *pArg, Byte *ShortMode)
146
{
147
  switch (*pArg->str.p_str)
148
  {
149
    case '>':
150
      *ShortMode = 2;
151
      return 1;
152
    case '<':
153
      *ShortMode = 1;
154
      return 1;
155
    default:
156
      *ShortMode = 0;
157
      return 0;
158
  }
159
}
160
 
161
static Boolean DecodeReg(char *Asc, LongInt *Erg)
162
{
163
#define RegCount (sizeof(RegNames) / sizeof(*RegNames))
164
  static const char RegNames[][3] =
165
  {
166
    "X0", "X1", "Y0", "Y1", "A0", "B0", "A2", "B2", "A1", "B1", "A", "B"
167
  };
168
  Word z;
169
 
170
  for (z = 0; z < RegCount; z++)
171
    if (!as_strcasecmp(Asc, RegNames[z]))
172
    {
173
      *Erg = z + 4;
174
      return True;
175
    }
176
  if ((strlen(Asc) == 2) && (Asc[1] >= '0') && (Asc[1] <= '7'))
177
    switch (as_toupper(*Asc))
178
    {
179
      case 'R':
180
        *Erg = 16 + Asc[1] - '0';
181
        return True;
182
      case 'N':
183
        *Erg = 24 + Asc[1] - '0';
184
        return True;
185
    }
186
  return False;
187
#undef RegCount
188
}
189
 
190
static Boolean DecodeALUReg(char *Asc, LongInt *Erg,
191
                            Boolean MayX, Boolean MayY, Boolean MayAcc)
192
{
193
  Boolean Result = False;
194
 
195
  if (!DecodeReg(Asc, Erg))
196
    return Result;
197
 
198
  switch (*Erg)
199
  {
200
    case 4:
201
    case 5:
202
      if (MayX)
203
      {
204
        Result = True;
205
        (*Erg) -= 4;
206
      }
207
      break;
208
    case 6:
209
    case 7:
210
      if (MayY)
211
      {
212
        Result = True;
213
        (*Erg) -= 6;
214
      }
215
      break;
216
    case 14:
217
    case 15:
218
      if (MayAcc)
219
      {
220
        Result = True;
221
        (*Erg) -= (MayX || MayY) ? 12 : 14;
222
      }
223
      break;
224
  }
225
 
226
  return Result;
227
}
228
 
229
static Boolean DecodeLReg(char *Asc, LongInt *Erg)
230
{
231
#define RegCount (sizeof(RegNames) / sizeof(*RegNames))
232
  static const char RegNames[][4] =
233
  {
234
    "A10", "B10", "X", "Y", "A", "B", "AB", "BA"
235
  };
236
  Word z;
237
 
238
  for (z = 0; z < RegCount; z++)
239
    if (!as_strcasecmp(Asc, RegNames[z]))
240
    {
241
      *Erg = z;
242
      return True;
243
    }
244
 
245
  return False;
246
#undef RegCount
247
}
248
 
249
static Boolean DecodeXYABReg(char *Asc, LongInt *Erg)
250
{
251
#define RegCount (sizeof(RegNames) / sizeof(*RegNames))
252
  static const char RegNames[][3] =
253
  {
254
    "B", "A", "X", "Y", "X0", "Y0", "X1", "Y1"
255
  };
256
  Word z;
257
 
258
  for (z = 0; z < RegCount; z++)
259
    if (!as_strcasecmp(Asc, RegNames[z]))
260
    {
261
      *Erg = z;
262
      return True;
263
    }
264
 
265
  return False;
266
#undef RegCount
267
}
268
 
269
static Boolean DecodeXYAB0Reg(char *Asc, LongInt *Erg)
270
{
271
#define RegCount (sizeof(RegNames) / sizeof(*RegNames))
272
  static const char RegNames[][3] =
273
  {
274
    "A0", "B0", "X0", "Y0", "X1", "Y1"
275
  };
276
  Word z;
277
 
278
  for (z = 0; z < RegCount; z++)
279
    if (!as_strcasecmp(Asc, RegNames[z]))
280
    {
281
      *Erg = z + 2;
282
      return True;
283
    }
284
 
285
  return False;
286
#undef RegCount
287
}
288
 
289
static Boolean DecodeXYAB1Reg(char *Asc, LongInt *Erg)
290
{
291
#define RegCount (sizeof(RegNames) / sizeof(*RegNames))
292
  static const char RegNames[][3] =
293
  {
294
    "A1", "B1", "X0", "Y0", "X1", "Y1"
295
  };
296
  Word z;
297
 
298
  for (z = 0; z < RegCount; z++)
299
    if (!as_strcasecmp(Asc, RegNames[z]))
300
    {
301
      *Erg = z + 2;
302
      return True;
303
    }
304
 
305
  return False;
306
#undef RegCount
307
}
308
 
309
static Boolean DecodePCReg(char *Asc, LongInt *Erg)
310
{
311
#define RegCount (sizeof(RegNames) / sizeof(*RegNames))
312
                                /** vvvv ab 56300 ? */
313
  static const char RegNames[][4] =
314
  {
315
    "SZ", "SR", "OMR", "SP", "SSH", "SSL", "LA", "LC"
316
  };
317
  Word z;
318
 
319
  for (z = 0; z < RegCount; z++)
320
    if (!as_strcasecmp(Asc, RegNames[z]))
321
    {
322
      (*Erg) = z;
323
      return True;
324
    }
325
 
326
  return False;
327
#undef RegCount
328
}
329
 
330
static Boolean DecodeAddReg(char *Asc, LongInt *Erg)
331
{
332
  if ((strlen(Asc) == 2) && (as_toupper(*Asc) == 'M') && (Asc[1] >= '0') && (Asc[1] <= '7'))
333
  {
334
    *Erg = Asc[1] - '0';
335
    return True;
336
  }
337
  /* >=56300 ? */
338
  if (!as_strcasecmp(Asc, "EP"))
339
  {
340
    *Erg = 0x0a;
341
    return True;
342
  }
343
  if (!as_strcasecmp(Asc, "VBA"))
344
  {
345
    *Erg = 0x10;
346
    return True;
347
  }
348
  if (!as_strcasecmp(Asc, "SC"))
349
  {
350
    *Erg = 0x11;
351
    return True;
352
  }
353
 
354
  return False;
355
}
356
 
357
static Boolean DecodeGeneralReg(char *Asc, LongInt *Erg)
358
{
359
  if (DecodeReg(Asc, Erg))
360
    return True;
361
  if (DecodePCReg(Asc, Erg))
362
  {
363
    (*Erg) += 0x38;
364
    return True;
365
  }
366
  if (DecodeAddReg(Asc, Erg))
367
  {
368
    (*Erg) += 0x20;
369
    return True;
370
  }
371
  return False;
372
}
373
 
374
static Boolean DecodeCtrlReg(char *Asc, LongInt *Erg)
375
{
376
  if (DecodeAddReg(Asc, Erg))
377
    return True;
378
  if (DecodePCReg(Asc, Erg))
379
  {
380
    (*Erg) += 0x18;
381
    return True;
382
  }
383
  return False;
384
}
385
 
386
static Boolean DecodeControlReg(char *Asc, LongInt *Erg)
387
{
388
  Boolean Result = True;
389
 
390
  if (!as_strcasecmp(Asc, "MR"))
391
    *Erg = 0;
392
  else if (!as_strcasecmp(Asc, "CCR"))
393
    *Erg = 1;
394
  else if ((!as_strcasecmp(Asc, "OMR")) || (!as_strcasecmp(Asc, "COM")))
395
    *Erg = 2;
396
  else if ((!as_strcasecmp(Asc, "EOM")) && (MomCPU >= CPU56000))
397
    *Erg = 3;
398
  else
399
    Result = False;
400
 
401
  return Result;
402
}
403
 
404
static void DecodeAdr(const tStrComp *pArg, Word Erl, Byte ErlSeg, tAdrResult *pResult)
405
{
406
  static const char ModMasks[ModModInc + 1][8] =
407
  {
408
    "","", "(Rx)", "-(Rx)", "(Rx)-", "(Rx)+", "(Rx+Nx)", "(Rx)-Nx", "(Rx)+Nx"
409
  };
410
  static const Byte ModCodes[ModModInc + 1] =
411
  {
412
    0, 0, 4, 7, 2, 3, 5, 0, 1
413
  };
414
#define Seg56KCount (sizeof(Seg56KNames) / sizeof(*Seg56KNames))
415
  static const char Seg56KNames[] =
416
  {
417
    'P', 'X', 'Y', 'L'
418
  };
419
  static Byte Seg56KVals[] =
420
  {
421
    SegCode, SegXData, SegYData, SegLData
422
  };
423
  int z, l, ArgLen;
424
  unsigned SegIndex, Offset;
425
  Boolean OK;
426
  tEvalResult EvalResult;
427
  Byte OrdVal;
428
  char *pp, *np, save;
429
  tStrComp Arg;
430
 
431
  pResult->Type = ModNone;
432
  pResult->Val = 0;
433
  pResult->Cnt = 0;
434
  pResult->AbsSymFlags = eSymbolFlag_None;
435
  pResult->ShortMode = 0;
436
  pResult->ForceImmLong = False;
437
 
438
  /* Adressierungsmodi vom 56300 abschneiden */
439
 
440
  if (MomCPU < CPU56300)
441
    Erl |= (~MModDisp);
442
 
443
  /* Defaultsegment herausfinden */
444
 
445
  if (ErlSeg & MSegXData)
446
    pResult->Seg = SegXData;
447
  else if (ErlSeg & MSegYData)
448
    pResult->Seg = SegYData;
449
  else if (ErlSeg & MSegCode)
450
    pResult->Seg = SegCode;
451
  else
452
    pResult->Seg = SegNone;
453
 
454
  /* Zielsegment vorgegeben ? */
455
 
456
  Offset = 0;
457
  for (SegIndex = 0; SegIndex < Seg56KCount; SegIndex++)
458
    if ((as_toupper(*pArg->str.p_str) == Seg56KNames[SegIndex]) && (pArg->str.p_str[1] == ':'))
459
    {
460
      pResult->Seg = Seg56KVals[SegIndex];
461
      Offset = 2;
462
    }
463
  StrCompRefRight(&Arg, pArg, Offset);
464
 
465
  /* Adressausdruecke abklopfen: dazu mit Referenzstring vergleichen */
466
 
467
  ArgLen = strlen(Arg.str.p_str);
468
  for (z = ModIReg; z <= ModModInc; z++)
469
    if (ArgLen == (int)strlen(ModMasks[z]))
470
    {
471
      pResult->Mode = 0xffff;
472
      for (l = 0; l <= ArgLen; l++)
473
        if (ModMasks[z][l] == 'x')
474
        {
475
          OrdVal = Arg.str.p_str[l] - '0';
476
          if (OrdVal > 7)
477
            break;
478
          else if (pResult->Mode == 0xffff)
479
            pResult->Mode = OrdVal;
480
          else if (pResult->Mode != OrdVal)
481
          {
482
            WrError(ErrNum_InvRegPair);
483
            goto chk;
484
          }
485
        }
486
        else if (ModMasks[z][l] != as_toupper(Arg.str.p_str[l]))
487
          break;
488
      if (l > ArgLen)
489
      {
490
        pResult->Type = z;
491
        pResult->Mode += ModCodes[z] << 3;
492
        goto chk;
493
      }
494
    }
495
 
496
  /* immediate ? */
497
 
498
  if (*Arg.str.p_str == '#')
499
  {
500
    if (Arg.str.p_str[1] == '>')
501
    {
502
      pResult->ForceImmLong = TRUE;
503
      pResult->Val = EvalStrIntExpressionOffs(&Arg, 2, Int24, &OK);
504
    }
505
    else
506
    {
507
      pResult->ForceImmLong = FALSE;
508
      pResult->Val = EvalStrIntExpressionOffs(&Arg, 1, Int24, &OK);
509
    }
510
    if (OK)
511
    {
512
      pResult->Type = ModImm; pResult->Cnt = 1; pResult->Mode = 0x34;
513
      goto chk;
514
    }
515
  }
516
 
517
  /* Register mit Displacement bei 56300 */
518
 
519
  if (IsIndirect(Arg.str.p_str))
520
  {
521
    tStrComp IArg;
522
 
523
    Arg.str.p_str[--ArgLen] = '\0'; Arg.Pos.Len--;
524
    StrCompRefRight(&IArg, &Arg, 1);
525
    pp = strchr(IArg.str.p_str, '+');
526
    np = strchr(IArg.str.p_str, '-');
527
    if ((!pp) || ((np) && (np < pp)))
528
      pp = np;
529
    if (pp)
530
    {
531
      save = *pp;
532
      *pp = '\0';
533
      if ((DecodeGeneralReg(IArg.str.p_str, &pResult->Mode)) && (pResult->Mode >= 16) && (pResult->Mode <= 23))
534
      {
535
        *pp = save;
536
        pResult->Mode -= 16;
537
        pResult->Val = EvalStrIntExpressionOffsWithResult(&IArg, pp - IArg.str.p_str, Int24, &EvalResult);
538
        if (EvalResult.OK)
539
        {
540
          if (mFirstPassUnknown(EvalResult.Flags))
541
            pResult->Val &= 63;
542
          pResult->Type = ModDisp;
543
        }
544
        goto chk;
545
      }
546
      *pp = save;
547
    }
548
  }
549
 
550
  /* dann absolut */
551
 
552
  Offset = CutSize(&Arg, &pResult->ShortMode);
553
  pResult->Val = EvalStrIntExpressionOffsWithResult(&Arg, Offset, AdrInt, &EvalResult);
554
  if (EvalResult.OK)
555
  {
556
    pResult->Type = ModAbs;
557
    pResult->AbsSymFlags = EvalResult.Flags;
558
    pResult->Mode = 0x30; pResult->Cnt = 1;
559
    if ((pResult->Seg & ((1 << SegCode) | (1 << SegXData) | (1 << SegYData))) != 0)
560
      ChkSpace(pResult->Seg, EvalResult.AddrSpaceMask);
561
    goto chk;
562
  }
563
 
564
chk:
565
  if ((pResult->Type != ModNone) && (!(Erl & (1 << pResult->Type))))
566
  {
567
    WrError(ErrNum_InvAddrMode);
568
    pResult->Cnt = 0;
569
    pResult->Type = ModNone;
570
  }
571
  if ((pResult->Seg != SegNone) && (!(ErlSeg & (1 << pResult->Seg))))
572
  {
573
    WrError(ErrNum_InvSegment);
574
    pResult->Cnt = 0;
575
    pResult->Type = ModNone;
576
  }
577
}
578
 
579
static Boolean DecodeOpPair(const tStrComp *pLeft, const tStrComp *pRight, Byte WorkSeg,
580
                            LongInt *Dir, LongInt *Reg1, LongInt *Reg2, tAdrResult *pResult)
581
{
582
  Boolean Result = False;
583
 
584
  if (DecodeALUReg(pLeft->str.p_str, Reg1, WorkSeg == SegXData, WorkSeg == SegYData, True))
585
  {
586
    if (DecodeALUReg(pRight->str.p_str, Reg2, WorkSeg == SegXData, WorkSeg == SegYData, True))
587
    {
588
      *Dir = 2;
589
      pResult->Type = ModNone;
590
      pResult->Mode = 0;
591
      pResult->Cnt = 0;
592
      pResult->Val = 0;
593
      Result = True;
594
    }
595
    else
596
    {
597
      *Dir = 0;
598
      *Reg2 = -1;
599
      DecodeAdr(pRight, MModNoImm, 1 << WorkSeg, pResult);
600
      if (pResult->Type != ModNone)
601
        Result = True;
602
    }
603
  }
604
  else if (DecodeALUReg(pRight->str.p_str, Reg1, WorkSeg == SegXData, WorkSeg == SegYData, True))
605
  {
606
    *Dir = 1;
607
    *Reg2 = -1;
608
    DecodeAdr(pLeft, MModAll, 1 << WorkSeg, pResult);
609
    if (pResult->Type != ModNone)
610
      Result = True;
611
  }
612
 
613
  return Result;
614
}
615
 
616
static LongInt TurnXY(LongInt Inp)
617
{
618
  switch (Inp)
619
  {
620
    case 4:
621
    case 7:
622
      return Inp - 4;
623
    case 5:
624
    case 6:
625
      return 7 - Inp;
626
    default:  /* wird nie erreicht */
627
      return 0;
628
  }
629
}
630
 
631
static Boolean DecodeTFR(const tStrComp *pArg, LongInt *Erg)
632
{
633
  LongInt Part1, Part2;
634
 
635
  SplitArg(pArg, &LeftComp, &RightComp);
636
  if (!DecodeALUReg(RightComp.str.p_str, &Part2, False, False, True)) return False;
637
  if (!DecodeReg(LeftComp.str.p_str, &Part1)) return False;
638
  if ((Part1 < 4) || ((Part1 > 7) && (Part1 < 14)) || (Part1 > 15)) return False;
639
  if (Part1 > 13)
640
  {
641
    if (((Part1 ^ Part2) & 1) == 0) return False;
642
    else
643
      Part1 = 0;
644
  }
645
  else
646
    Part1 = TurnXY(Part1) + 4;
647
  *Erg = (Part1 << 1) + Part2;
648
  return True;
649
}
650
 
651
static Boolean DecodeRR(const tStrComp *pArg, LongInt *Erg)
652
{
653
  LongInt Part1, Part2;
654
 
655
  SplitArg(pArg, &LeftComp, &RightComp);
656
  if (!DecodeGeneralReg(RightComp.str.p_str, &Part2)) return False;
657
  if ((Part2 < 16) || (Part2 > 23)) return False;
658
  if (!DecodeGeneralReg(LeftComp.str.p_str, &Part1)) return False;
659
  if ((Part1 < 16) || (Part1 > 23)) return False;
660
  *Erg = (Part2 & 7) + ((Part1 & 7) << 8);
661
  return True;
662
}
663
 
664
static Boolean DecodeCondition(char *Asc, Word *Erg)
665
{
666
  Boolean Result;
667
 
668
  (*Erg) = 0;
669
  while ((*Erg < CondCount) && (as_strcasecmp(CondNames[*Erg], Asc)))
670
    (*Erg)++;
671
  if (*Erg == CondCount - 1)
672
    *Erg = 8;
673
  Result = (*Erg < CondCount);
674
  *Erg &= 15;
675
  return Result;
676
}
677
 
678
static Boolean DecodeMOVE_0(void)
679
{
680
  DAsmCode[0] = 0x200000;
681
  CodeLen = 1;
682
  return True;
683
}
684
 
685
static Boolean DecodeMOVE_1(int Start)
686
{
687
  LongInt RegErg, RegErg2, IsY, MixErg, l;
688
  char c;
689
  Word Condition;
690
  Boolean Result = False;
691
  Byte SegMask;
692
 
693
  if (!as_strncasecmp(ArgStr[Start].str.p_str, "IF", 2))
694
  {
695
    l = strlen(ArgStr[Start].str.p_str);
696
    if (!as_strcasecmp(ArgStr[Start].str.p_str + l - 2, ".U"))
697
    {
698
      RegErg = 0x1000;
699
      l -= 2;
700
    }
701
    else
702
      RegErg = 0;
703
    c = ArgStr[Start].str.p_str[l];
704
    ArgStr[Start].str.p_str[l] = '\0';
705
    if (DecodeCondition(ArgStr[Start].str.p_str + 2, &Condition))
706
    {
707
      if (ChkMinCPUExt(CPU56300, ErrNum_AddrModeNotSupported))
708
      {
709
        DAsmCode[0] = 0x202000 + (Condition << 8) + RegErg;
710
        CodeLen = 1;
711
        return True;
712
      }
713
    }
714
    ArgStr[Start].str.p_str[l] = c;
715
  }
716
 
717
  SplitArg(&ArgStr[Start], &LeftComp, &RightComp);
718
 
719
  /* 1. Register-Update */
720
 
721
  if (*RightComp.str.p_str == '\0')
722
  {
723
    tAdrResult AdrResult;
724
 
725
    DecodeAdr(&LeftComp, MModPostDec | MModPostInc | MModModDec | MModModInc, 0, &AdrResult);
726
    if (AdrResult.Type != ModNone)
727
    {
728
      Result = True;
729
      DAsmCode[0] = 0x204000 + (AdrResult.Mode << 8);
730
      CodeLen = 1;
731
    }
732
    return Result;
733
  }
734
 
735
  /* 2. Ziel ist Register */
736
 
737
  if (DecodeReg(RightComp.str.p_str, &RegErg))
738
  {
739
    tAdrResult AdrResult;
740
 
741
    AdrResult.Seg = SegNone;
742
    if (DecodeReg(LeftComp.str.p_str, &RegErg2))
743
    {
744
      Result = True;
745
      DAsmCode[0] = 0x200000 + (RegErg << 8) + (RegErg2 << 13);
746
      CodeLen = 1;
747
    }
748
    else
749
    {
750
      /* A und B gehen auch als L:..., in L-Zweig zwingen! */
751
 
752
      SegMask = MSegXData + MSegYData;
753
      if ((RegErg == 14) || (RegErg == 15))
754
        SegMask |= MSegLData;
755
      DecodeAdr(&LeftComp, MModAll | MModDisp, SegMask, &AdrResult);
756
      if (AdrResult.Seg != SegLData)
757
      {
758
        IsY = Ord(AdrResult.Seg == SegYData);
759
        MixErg = ((RegErg & 0x18) << 17) + (IsY << 19) + ((RegErg & 7) << 16);
760
        if (AdrResult.Type == ModDisp)
761
        {
762
          if ((AdrResult.Val < 63) && (AdrResult.Val > -64) && (RegErg <= 15))
763
          {
764
            DAsmCode[0] = 0x020090 + ((AdrResult.Val & 1) << 6) + ((AdrResult.Val & 0x7e) << 10)
765
                        + (AdrResult.Mode << 8) + (IsY << 5) + RegErg;
766
            CodeLen = 1;
767
          }
768
          else
769
          {
770
            DAsmCode[0] = 0x0a70c0 + (AdrResult.Mode << 8) + (IsY << 16) + RegErg;
771
            DAsmCode[1] = AdrResult.Val;
772
            CodeLen = 2;
773
          }
774
        }
775
        else if (!AdrResult.ForceImmLong && (AdrResult.Type == ModImm) && RangeCheck(AdrResult.Val, UInt8))
776
        {
777
          Result = True;
778
          DAsmCode[0] = 0x200000 + (RegErg << 16) + ((AdrResult.Val & 0xff) << 8);
779
          CodeLen = 1;
780
        }
781
        else if ((AdrResult.Type == ModAbs) && (AdrResult.Val <= 63) && (AdrResult.Val >= 0) && (AdrResult.ShortMode != 2))
782
        {
783
          Result = True;
784
          DAsmCode[0] = 0x408000 + MixErg + (AdrResult.Val << 8);
785
          CodeLen = 1;
786
        }
787
        else if (AdrResult.Type != ModNone)
788
        {
789
          Result = True;
790
          DAsmCode[0] = 0x40c000 + MixErg + (AdrResult.Mode << 8);
791
          DAsmCode[1] = AdrResult.Val;
792
          CodeLen = 1 + AdrResult.Cnt;
793
        }
794
      }
795
    }
796
    if (AdrResult.Seg != SegLData)
797
      return Result;
798
  }
799
 
800
  /* 3. Quelle ist Register */
801
 
802
  if (DecodeReg(LeftComp.str.p_str, &RegErg))
803
  {
804
    tAdrResult RightAdrResult;
805
 
806
    /* A und B gehen auch als L:..., in L-Zweig zwingen! */
807
    SegMask = MSegXData + MSegYData;
808
    if ((RegErg == 14) || (RegErg == 15))
809
      SegMask |= MSegLData;
810
    DecodeAdr(&RightComp, MModNoImm | MModDisp, SegMask, &RightAdrResult);
811
    if (RightAdrResult.Seg != SegLData)
812
    {
813
      IsY = Ord(RightAdrResult.Seg == SegYData);
814
      MixErg = ((RegErg & 0x18) << 17) + (IsY << 19) + ((RegErg & 7) << 16);
815
      if (RightAdrResult.Type == ModDisp)
816
      {
817
        if ((RightAdrResult.Val < 63) && (RightAdrResult.Val > -64) && (RegErg <= 15))
818
        {
819
          DAsmCode[0] = 0x020080 + ((RightAdrResult.Val & 1) << 6) + ((RightAdrResult.Val & 0x7e) << 10)
820
                      + (RightAdrResult.Mode << 8) + (IsY << 5) + RegErg;
821
          CodeLen = 1;
822
        }
823
        else
824
        {
825
          DAsmCode[0] = 0x0a7080 + (RightAdrResult.Mode << 8) + (IsY << 16) + RegErg;
826
          DAsmCode[1] = RightAdrResult.Val;
827
          CodeLen = 2;
828
        }
829
      }
830
      else if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val <= 63) && (RightAdrResult.Val >= 0) && (RightAdrResult.ShortMode != 2))
831
      {
832
        Result = True;
833
        DAsmCode[0] = 0x400000 + MixErg + (RightAdrResult.Val << 8);
834
        CodeLen = 1;
835
      }
836
      else if (RightAdrResult.Type != ModNone)
837
      {
838
        Result = True;
839
        DAsmCode[0] = 0x404000 + MixErg + (RightAdrResult.Mode << 8);
840
        DAsmCode[1] = RightAdrResult.Val;
841
        CodeLen = 1 + RightAdrResult.Cnt;
842
      }
843
      return Result;
844
    }
845
  }
846
 
847
  /* 4. Ziel ist langes Register */
848
 
849
  if (DecodeLReg(RightComp.str.p_str, &RegErg))
850
  {
851
    tAdrResult LeftAdrResult;
852
 
853
    DecodeAdr(&LeftComp, MModNoImm, MSegLData, &LeftAdrResult);
854
    MixErg = ((RegErg & 4) << 17) + ((RegErg & 3) << 16);
855
    if ((LeftAdrResult.Type == ModAbs) && (LeftAdrResult.Val <= 63) && (LeftAdrResult.Val >= 0) && (LeftAdrResult.ShortMode != 2))
856
    {
857
      Result = True;
858
      DAsmCode[0] = 0x408000 + MixErg + (LeftAdrResult.Val << 8);
859
      CodeLen = 1;
860
    }
861
    else
862
    {
863
      Result = True;
864
      DAsmCode[0] = 0x40c000 + MixErg + (LeftAdrResult.Mode << 8);
865
      DAsmCode[1] = LeftAdrResult.Val;
866
      CodeLen = 1 + LeftAdrResult.Cnt;
867
    }
868
    return Result;
869
  }
870
 
871
  /* 5. Quelle ist langes Register */
872
 
873
  if (DecodeLReg(LeftComp.str.p_str, &RegErg))
874
  {
875
    tAdrResult RightAdrResult;
876
 
877
    DecodeAdr(&RightComp, MModNoImm, MSegLData, &RightAdrResult);
878
    MixErg = ((RegErg & 4) << 17) + ((RegErg & 3) << 16);
879
    if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val <= 63) && (RightAdrResult.Val >= 0) && (RightAdrResult.ShortMode != 2))
880
    {
881
      Result = True;
882
      DAsmCode[0] = 0x400000 + MixErg + (RightAdrResult.Val << 8);
883
      CodeLen = 1;
884
    }
885
    else
886
    {
887
      Result = True;
888
      DAsmCode[0] = 0x404000 + MixErg + (RightAdrResult.Mode << 8);
889
      DAsmCode[1] = RightAdrResult.Val;
890
      CodeLen = 1 + RightAdrResult.Cnt;
891
    }
892
    return Result;
893
  }
894
 
895
  WrError(ErrNum_InvAddrMode);
896
  return Result;
897
}
898
 
899
static Boolean DecodeMOVE_2(int Start)
900
{
901
  LongInt RegErg, Reg1L, Reg1R, Reg2L, Reg2R, Dir1, Dir2;
902
  tAdrResult AdrResult1, AdrResult2;
903
  Boolean Result = False;
904
 
905
  SplitArg(&ArgStr[Start], &Left1Comp, &Right1Comp);
906
  SplitArg(&ArgStr[Start + 1], &Left2Comp, &Right2Comp);
907
 
908
  /* 1. Spezialfall X auf rechter Seite ? */
909
 
910
  if (!as_strcasecmp(Left2Comp.str.p_str, "X0"))
911
  {
912
    if (!DecodeALUReg(Right2Comp.str.p_str, &RegErg, False, False, True)) WrError(ErrNum_InvAddrMode);
913
    else if (strcmp(Left1Comp.str.p_str, Right2Comp.str.p_str)) WrError(ErrNum_InvAddrMode);
914
    else
915
    {
916
      DecodeAdr(&Right1Comp, MModNoImm, MSegXData, &AdrResult1);
917
      if (AdrResult1.Type != ModNone)
918
      {
919
        CodeLen = 1 + AdrResult1.Cnt;
920
        DAsmCode[0] = 0x080000 + (RegErg << 16) + (AdrResult1.Mode << 8);
921
        DAsmCode[1] = AdrResult1.Val;
922
        Result = True;
923
      }
924
    }
925
    return Result;
926
  }
927
 
928
  /* 2. Spezialfall Y auf linker Seite ? */
929
 
930
  if (!as_strcasecmp(Left1Comp.str.p_str, "Y0"))
931
  {
932
    if (!DecodeALUReg(Right1Comp.str.p_str, &RegErg, False, False, True)) WrError(ErrNum_InvAddrMode);
933
    else if (strcmp(Left2Comp.str.p_str, Right1Comp.str.p_str)) WrError(ErrNum_InvAddrMode);
934
    else
935
    {
936
      DecodeAdr(&Right2Comp, MModNoImm, MSegYData, &AdrResult2);
937
      if (AdrResult2.Type != ModNone)
938
      {
939
        CodeLen = 1 + AdrResult2.Cnt;
940
        DAsmCode[0] = 0x088000 + (RegErg << 16) + (AdrResult2.Mode << 8);
941
        DAsmCode[1] = AdrResult2.Val;
942
        Result = True;
943
      }
944
    }
945
    return Result;
946
  }
947
 
948
  /* der Rest..... */
949
 
950
  if ((DecodeOpPair(&Left1Comp, &Right1Comp, SegXData, &Dir1, &Reg1L, &Reg1R, &AdrResult1))
951
   && (DecodeOpPair(&Left2Comp, &Right2Comp, SegYData, &Dir2, &Reg2L, &Reg2R, &AdrResult2)))
952
  {
953
    if ((Reg1R == -1) && (Reg2R == -1))
954
    {
955
      if ((AdrResult1.Mode >> 3 < 1) || (AdrResult1.Mode >> 3 > 4) || (AdrResult2.Mode >> 3 < 1) || (AdrResult2.Mode >> 3 > 4)) WrError(ErrNum_InvAddrMode);
956
      else if (((AdrResult1.Mode ^ AdrResult2.Mode) & 4) == 0) WrError(ErrNum_InvRegPair);
957
      else
958
      {
959
        DAsmCode[0] = 0x800000 + (Dir2 << 22) + (Dir1 << 15)
960
                    + (Reg1L << 18) + (Reg2L << 16) + ((AdrResult1.Mode & 0x1f) << 8)
961
                    + ((AdrResult2.Mode & 3) << 13) + ((AdrResult2.Mode & 24) << 17);
962
        CodeLen = 1;
963
        Result = True;
964
      }
965
    }
966
    else if (Reg1R == -1)
967
    {
968
      if ((Reg2L < 2) || (Reg2R > 1)) WrError(ErrNum_InvAddrMode);
969
      else
970
      {
971
        DAsmCode[0] = 0x100000 + (Reg1L << 18) + ((Reg2L - 2) << 17) + (Reg2R << 16)
972
                    + (Dir1 << 15) + (AdrResult1.Mode << 8);
973
        DAsmCode[1] = AdrResult1.Val;
974
        CodeLen = 1 + AdrResult1.Cnt;
975
        Result = True;
976
      }
977
    }
978
    else if (Reg2R == -1)
979
    {
980
      if ((Reg1L < 2) || (Reg1R > 1)) WrError(ErrNum_InvAddrMode);
981
      else
982
      {
983
        DAsmCode[0] = 0x104000 + (Reg2L << 16) + ((Reg1L - 2) << 19) + (Reg1R << 18)
984
                    + (Dir2 << 15) + (AdrResult2.Mode << 8);
985
        DAsmCode[1] = AdrResult2.Val;
986
        CodeLen = 1 + AdrResult2.Cnt;
987
        Result = True;
988
      }
989
    }
990
    else
991
      WrError(ErrNum_InvAddrMode);
992
    return Result;
993
  }
994
 
995
  WrError(ErrNum_InvAddrMode);
996
  return Result;
997
}
998
 
999
static Boolean DecodeMOVE(int Start)
1000
{
1001
  switch (ArgCnt - Start + 1)
1002
  {
1003
    case 0:
1004
      return DecodeMOVE_0();
1005
    case 1:
1006
      return DecodeMOVE_1(Start);
1007
    case 2:
1008
      return DecodeMOVE_2(Start);
1009
    default:
1010
      (void)ChkArgCnt(0, 2);
1011
      return False;
1012
  }
1013
}
1014
 
1015
static tErrorNum ErrCode;
1016
static const tStrComp *pErrComp;
1017
 
1018
static void SetError(tErrorNum Code)
1019
{
1020
  ErrCode = Code; pErrComp = NULL;
1021
}
1022
 
1023
static void SetXError(tErrorNum Code, const tStrComp *pNewErrComp)
1024
{
1025
  ErrCode = Code; pErrComp = pNewErrComp;
1026
}
1027
 
1028
static void PrError(void)
1029
{
1030
  if (pErrComp) WrStrErrorPos(ErrCode, pErrComp);
1031
  else if (ErrCode != 0) WrError(ErrCode);
1032
}
1033
 
1034
/*----------------------------------------------------------------------------------------------*/
1035
 
1036
static void DecodeSFR(Word space)
1037
{
1038
  CodeEquate((as_addrspace_t)space, 0, MemLimit);
1039
}
1040
 
1041
static void DecodeDS(Word Code)
1042
{
1043
  UNUSED(Code);
1044
 
1045
  if (ChkArgCnt(1, 1))
1046
  {
1047
    Boolean OK;
1048
    tSymbolFlags Flags;
1049
    Word AdrWord = EvalStrIntExpressionWithFlags(&ArgStr[1], AdrInt, &OK, &Flags);
1050
 
1051
    if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
1052
    if (OK && !mFirstPassUnknown(Flags))
1053
    {
1054
      if (!AdrWord) WrError(ErrNum_NullResMem);
1055
      CodeLen = AdrWord; DontPrint = True;
1056
      BookKeeping();
1057
    }
1058
  }
1059
}
1060
 
1061
static void DecodeDC(Word Code)
1062
{
1063
  TempResult t;
1064
 
1065
  UNUSED(Code);
1066
 
1067
  as_tempres_ini(&t);
1068
  if (ChkArgCnt(1, ArgCntMax))
1069
  {
1070
    Boolean OK = True;
1071
    tStrComp *pArg;
1072
 
1073
    forallargs(pArg, OK)
1074
    {
1075
      EvalStrExpression(pArg, &t);
1076
      switch (t.Typ)
1077
      {
1078
        case TempString:
1079
          if (MultiCharToInt(&t, 3))
1080
            goto ToInt;
1081
 
1082
          if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pArg))
1083
            OK = False;
1084
          else
1085
            OK = !string_2_dasm_code(&t.Contents.str, Packing ? 3 : 1, True);
1086
          break;
1087
        ToInt:
1088
        case TempInt:
1089
          if (mFirstPassUnknown(t.Flags)) t.Contents.Int &= 0xffffff;
1090
          if (!(OK = RangeCheck(t.Contents.Int, Int24))) WrStrErrorPos(ErrNum_OverRange, pArg);
1091
          else
1092
            DAsmCode[CodeLen++] = t.Contents.Int & 0xffffff;
1093
          break;
1094
        case TempFloat:
1095
          WrStrErrorPos(ErrNum_StringOrIntButFloat, pArg);
1096
          /* fall-through */
1097
        default:
1098
          OK = False;
1099
      }
1100
    }
1101
    if (!OK) CodeLen = 0;
1102
  }
1103
  as_tempres_free(&t);
1104
}
1105
 
1106
/* ohne Argument */
1107
 
1108
static void DecodeFixed(Word Index)
1109
{
1110
  const FixedOrder *pOrder = FixedOrders + Index;
1111
 
1112
  if (!ChkArgCnt(0, 0));
1113
  else if (ChkMinCPU(pOrder->MinCPU))
1114
  {
1115
    CodeLen = 1;
1116
    DAsmCode[0] = pOrder->Code;
1117
  }
1118
}
1119
 
1120
/* ALU */
1121
 
1122
static void DecodePar(Word Index)
1123
{
1124
  const ParOrder *pOrder = ParOrders + Index;
1125
  Boolean OK, DontAdd, is_cmpm = (pOrder->Code == 0x07);
1126
  tSymbolFlags Flags;
1127
  tStrComp LeftRegComp;
1128
  LargeInt LAddVal;
1129
  LongInt AddVal, h = 0, Reg1, Reg2, Reg3;
1130
 
1131
  if (DecodeMOVE(2))
1132
  {
1133
    SetError((tErrorNum)0);
1134
    DontAdd = False;
1135
    switch (pOrder->Typ)
1136
    {
1137
      case ParAB:
1138
        if (!DecodeALUReg(ArgStr[1].str.p_str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &ArgStr[1]);
1139
        else
1140
          h = Reg1 << 3;
1141
        break;
1142
      case ParFixAB:
1143
        if (as_strcasecmp(ArgStr[1].str.p_str, "A,B")) SetError(ErrNum_InvRegPair);
1144
        else
1145
          h = 0;
1146
        break;
1147
      case ParABShl1:
1148
        if (!strchr(ArgStr[1].str.p_str, ','))
1149
        {
1150
          if (!DecodeALUReg(ArgStr[1].str.p_str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &ArgStr[1]);
1151
          else
1152
            h = Reg1 << 3;
1153
        }
1154
        else if (ArgCnt != 1) SetError(ErrNum_ParNotPossible);
1155
        else if (MomCPU < CPU56300) SetError(ErrNum_InstructionNotSupported);
1156
        else
1157
        {
1158
          SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1159
          if (!strchr(RightComp.str.p_str, ','))
1160
            StrCompCopy(&MidComp, &RightComp);
1161
          else
1162
            SplitArg(&RightComp, &MidComp, &RightComp);
1163
          if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
1164
          else if (!DecodeALUReg(MidComp.str.p_str, &Reg2, False, False, True)) SetXError(ErrNum_InvReg, &MidComp);
1165
          else if (*LeftComp.str.p_str == '#')
1166
          {
1167
            AddVal = EvalStrIntExpressionOffs(&LeftComp, 1, UInt6, &OK);
1168
            if (OK)
1169
            {
1170
              DAsmCode[0] = 0x0c1c00 + ((pOrder->Code & 0x10) << 4) + (Reg2 << 7)
1171
                          + (AddVal << 1) + Reg1;
1172
              CodeLen = 1;
1173
              DontAdd = True;
1174
            }
1175
          }
1176
          else if (!DecodeXYAB1Reg(LeftComp.str.p_str, &Reg3)) SetXError(ErrNum_InvReg, &LeftComp);
1177
          else
1178
          {
1179
            DAsmCode[0] = 0x0c1e60 - ((pOrder->Code & 0x10) << 2) + (Reg2 << 4)
1180
                        + (Reg3 << 1) + Reg1;
1181
            CodeLen = 1;
1182
            DontAdd = True;
1183
          }
1184
        }
1185
        break;
1186
      case ParABShl2:
1187
        if (!strchr(ArgStr[1].str.p_str, ','))
1188
        {
1189
          if (!DecodeALUReg(ArgStr[1].str.p_str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &ArgStr[1]);
1190
          else
1191
            h = Reg1 << 3;
1192
        }
1193
        else if (ArgCnt != 1) SetError(ErrNum_ParNotPossible);
1194
        else if (MomCPU < CPU56300) SetError(ErrNum_InstructionNotSupported);
1195
        else
1196
        {
1197
          SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1198
          if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
1199
          else if (*LeftComp.str.p_str == '#')
1200
          {
1201
            AddVal = EvalStrIntExpressionOffs(&LeftComp, 1, UInt5, &OK);
1202
            if (OK)
1203
            {
1204
              DAsmCode[0] = 0x0c1e80 + ((0x33 - pOrder->Code) << 2)
1205
                          + (AddVal << 1) + Reg1;
1206
              CodeLen = 1;
1207
              DontAdd = True;
1208
            }
1209
          }
1210
          else if (!DecodeXYAB1Reg(LeftComp.str.p_str, &Reg3)) SetXError(ErrNum_InvReg, &LeftComp);
1211
          else
1212
          {
1213
            DAsmCode[0] = 0x0c1e10 + ((0x33 - pOrder->Code) << 1)
1214
                        + (Reg3 << 1) + Reg1;
1215
            CodeLen = 1;
1216
            DontAdd = True;
1217
          }
1218
        }
1219
        break;
1220
      case ParXYAB:
1221
        SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1222
        if (!DecodeALUReg(RightComp.str.p_str, &Reg2, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
1223
        else if (!DecodeLReg(LeftComp.str.p_str, &Reg1)) SetXError(ErrNum_InvReg, &LeftComp);
1224
        else if ((Reg1 < 2) || (Reg1 > 3)) SetXError(ErrNum_InvReg, &LeftComp);
1225
        else
1226
           h = (Reg2 << 3) + ((Reg1 - 2) << 4);
1227
        break;
1228
      case ParABXYnAB:
1229
        SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1230
        if (!DecodeALUReg(RightComp.str.p_str, &Reg2, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
1231
        else if (*LeftComp.str.p_str == '#')
1232
        {
1233
          if (is_cmpm) SetError(ErrNum_InvAddrMode);
1234
          else if (MomCPU < CPU56300) SetError(ErrNum_InstructionNotSupported);
1235
          else if (ArgCnt != 1) SetError(ErrNum_ParNotPossible);
1236
          else
1237
          {
1238
            AddVal = EvalStrIntExpressionOffs(&LeftComp, 1, Int24, &OK);
1239
            if (!OK) SetError((tErrorNum)-1);
1240
            else if ((AddVal >= 0) && (AddVal <= 63))
1241
            {
1242
              DAsmCode[0] = 0x014000 + (AddVal << 8);
1243
              h = 0x80 + (Reg2 << 3);
1244
            }
1245
            else
1246
            {
1247
              DAsmCode[0] = 0x014000; h = 0xc0 + (Reg2 << 3);
1248
              DAsmCode[1] = AddVal & 0xffffff; CodeLen = 2;
1249
            }
1250
          }
1251
        }
1252
        else
1253
        {
1254
          if (!DecodeXYABReg(LeftComp.str.p_str, &Reg1)) SetXError(ErrNum_InvReg, &LeftComp);
1255
          else if ((Reg1 ^ Reg2) == 1) SetError(ErrNum_InvRegPair);
1256
          else if (is_cmpm && ((Reg1 & 6) == 2)) SetXError(ErrNum_InvReg, &LeftComp);
1257
          else
1258
          {
1259
            if (Reg1 < 2)
1260
              Reg1 = !is_cmpm;
1261
            h = (Reg2 << 3) + (Reg1 << 4);
1262
          }
1263
        }
1264
        break;
1265
      case ParABBA:
1266
        if  (!as_strcasecmp(ArgStr[1].str.p_str, "B,A"))
1267
          h = 0;
1268
        else if (!as_strcasecmp(ArgStr[1].str.p_str, "A,B"))
1269
          h = 8;
1270
        else
1271
          SetXError(ErrNum_InvRegPair, &ArgStr[1]);
1272
        break;
1273
      case ParXYnAB:
1274
        SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1275
        if (!DecodeALUReg(RightComp.str.p_str, &Reg2, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
1276
        else if (*LeftComp.str.p_str == '#')
1277
        {
1278
          if (MomCPU < CPU56300) SetError(ErrNum_InstructionNotSupported);
1279
          else if (ArgCnt != 1) SetError(ErrNum_ParNotPossible);
1280
          else
1281
          {
1282
            AddVal = EvalStrIntExpressionOffs(&LeftComp, 1, Int24, &OK);
1283
            if (!OK) SetError((tErrorNum)-1);
1284
            else if ((AddVal >= 0) && (AddVal <= 63))
1285
            {
1286
              DAsmCode[0] = 0x014080 + (AddVal << 8) + (Reg2 << 3) + (pOrder->Code & 7);
1287
              CodeLen = 1;
1288
              DontAdd = True;
1289
            }
1290
            else
1291
            {
1292
              DAsmCode[0] = 0x0140c0 + (Reg2 << 3) + (pOrder->Code & 7);
1293
              DAsmCode[1] = AddVal & 0xffffff;
1294
              CodeLen = 2;
1295
              DontAdd = True;
1296
            }
1297
          }
1298
        }
1299
        else
1300
        {
1301
          if (!DecodeReg(LeftComp.str.p_str, &Reg1)) SetXError(ErrNum_InvReg, &LeftComp);
1302
          else if ((Reg1 < 4) || (Reg1 > 7)) SetXError(ErrNum_InvReg, &LeftComp);
1303
          else
1304
            h = (Reg2 << 3) + (TurnXY(Reg1) << 4);
1305
        }
1306
        break;
1307
      case ParMul:
1308
        SplitArg(&ArgStr[1], &LeftComp, &MidComp);
1309
        SplitArg(&MidComp, &MidComp, &RightComp);
1310
        h = 0;
1311
        if (*LeftComp.str.p_str == '-')
1312
        {
1313
          StrCompRefRight(&LeftRegComp, &LeftComp, 1);
1314
          h += 4;
1315
        }
1316
        else if (*LeftComp.str.p_str == '+')
1317
          StrCompRefRight(&LeftRegComp, &LeftComp, 1);
1318
        else
1319
          StrCompRefRight(&LeftRegComp, &LeftComp, 0);
1320
        if (!DecodeALUReg(RightComp.str.p_str, &Reg3, False, False, True)) SetXError(ErrNum_InvReg, &RightComp);
1321
        else if (!DecodeReg(LeftRegComp.str.p_str, &Reg1)) SetXError(ErrNum_InvReg, &LeftRegComp);
1322
        else if ((Reg1 < 4) || (Reg1 > 7)) SetXError(ErrNum_InvReg, &LeftRegComp);
1323
        else if (*MidComp.str.p_str == '#')
1324
        {
1325
          if (!ChkArgCnt(1, 1));
1326
          else if (ChkMinCPU(CPU56300))
1327
          {
1328
            AddVal = EvalStrIntExpressionOffsWithFlags(&MidComp, 1, UInt24, &OK, &Flags);
1329
            if (mFirstPassUnknown(Flags))
1330
              AddVal = 1;
1331
            if ((!(SingleBit(AddVal, &LAddVal))) || (LAddVal > 22)) WrError(ErrNum_NotOneBit);
1332
            else
1333
            {
1334
              LAddVal = 23 - LAddVal;
1335
              DAsmCode[0] = 0x010040 + (LAddVal << 8) + (Mac2Table[Reg1 & 3] << 4)
1336
                          + (Reg3 << 3);
1337
              CodeLen = 1;
1338
            }
1339
          }
1340
        }
1341
 
1342
        else if (!DecodeReg(MidComp.str.p_str, &Reg2)) SetXError(ErrNum_InvReg, &MidComp);
1343
        else if ((Reg2 < 4) || (Reg2 > 7)) SetXError(ErrNum_InvReg, &MidComp);
1344
        else if (MacTable[Reg1 - 4][Reg2 - 4] == 0xff) SetError(ErrNum_InvRegPair);
1345
        else
1346
          h += (Reg3 << 3) + (MacTable[Reg1 - 4][Reg2 - 4] << 4);
1347
        break;
1348
    }
1349
    if (ErrCode == 0)
1350
    {
1351
      if (!DontAdd)
1352
        DAsmCode[0] += pOrder->Code + h;
1353
    }
1354
    else
1355
    {
1356
      if (ErrCode > 0)
1357
        PrError();
1358
      CodeLen = 0;
1359
    }
1360
  }
1361
}
1362
 
1363
static void DecodeDIV(Word Code)
1364
{
1365
  UNUSED(Code);
1366
 
1367
  if (ChkArgCnt(1, 1))
1368
  {
1369
    LongInt Reg2, Reg1;
1370
 
1371
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1372
    if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
1373
    else if (!DecodeALUReg(RightComp.str.p_str, &Reg2, False, False, True)) WrError(ErrNum_InvAddrMode);
1374
    else if (!DecodeReg(LeftComp.str.p_str, &Reg1)) WrError(ErrNum_InvAddrMode);
1375
    else if ((Reg1 < 4) || (Reg1 > 7)) WrError(ErrNum_InvAddrMode);
1376
    else
1377
    {
1378
      CodeLen = 1;
1379
      DAsmCode[0] = 0x018040 + (Reg2 << 3) + (TurnXY(Reg1) << 4);
1380
    }
1381
  }
1382
}
1383
 
1384
static void DecodeImmMac(Word Code)
1385
{
1386
  tStrComp LeftArg;
1387
  Boolean OK;
1388
  LongInt h = 0, Reg1, Reg2;
1389
 
1390
  if (!ChkArgCnt(1, 1));
1391
  else if (ChkMinCPU(CPU56300))
1392
  {
1393
    SplitArg(&ArgStr[1], &LeftComp, &MidComp);
1394
    SplitArg(&MidComp, &MidComp, &RightComp);
1395
    h = 0;
1396
    StrCompRefRight(&LeftArg, &LeftComp, 0);
1397
    switch (*LeftComp.str.p_str)
1398
    {
1399
      case '-':
1400
        h = 4;
1401
        /* fall-through */
1402
      case '+':
1403
        StrCompRefRight(&LeftArg, &LeftComp, 1);
1404
    }
1405
    if ((*MidComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
1406
    else if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1407
    else if (!DecodeXYABReg(MidComp.str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1408
    else if ((Reg2 < 4) || (Reg2 > 7)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1409
    else if (*LeftArg.str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
1410
    else
1411
    {
1412
      DAsmCode[1] = EvalStrIntExpressionOffs(&LeftArg, 1, Int24, &OK);
1413
      if (OK)
1414
      {
1415
        DAsmCode[0] = 0x0141c0 + Code + h + (Reg1 << 3) + ((Reg2 & 3) << 4);
1416
        CodeLen = 2;
1417
      }
1418
    }
1419
  }
1420
}
1421
 
1422
static void DecodeDMAC(Word Code)
1423
{
1424
  if (!ChkArgCnt(1, 1));
1425
  else if (ChkMinCPU(CPU56300))
1426
  {
1427
    LongInt Reg1, Reg2, Reg3;
1428
    tStrComp LeftReg;
1429
 
1430
    SplitArg(&ArgStr[1], &LeftComp, &MidComp);
1431
    SplitArg(&MidComp, &MidComp, &RightComp);
1432
    if (*LeftComp.str.p_str == '-')
1433
    {
1434
      StrCompRefRight(&LeftReg, &LeftComp, 1);
1435
      Code += 16;
1436
    }
1437
    else if (*LeftComp.str.p_str == '+')
1438
      StrCompRefRight(&LeftReg, &LeftComp, 1);
1439
    else
1440
      StrCompRefRight(&LeftReg, &LeftComp, 0);
1441
    if ((*MidComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
1442
    else if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1443
    else if (!DecodeXYAB1Reg(MidComp.str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1444
    else if (Reg2 < 4) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1445
    else if (!DecodeXYAB1Reg(LeftReg.str.p_str, &Reg3)) WrStrErrorPos(ErrNum_InvReg, &LeftReg);
1446
    else if (Reg3 < 4) WrStrErrorPos(ErrNum_InvReg, &LeftReg);
1447
    else
1448
    {
1449
      DAsmCode[0] = 0x012480 + Code + (Reg1 << 5) + Mac4Table[Reg3 - 4][Reg2 - 4];
1450
      CodeLen = 1;
1451
    }
1452
  }
1453
}
1454
 
1455
static void DecodeMAC_MPY(Word Code)
1456
{
1457
  if (!ChkArgCnt(1, 1));
1458
  else if (ChkMinCPU(CPU56300))
1459
  {
1460
    tStrComp LeftReg;
1461
    LongInt Reg1, Reg2, Reg3;
1462
 
1463
    SplitArg(&ArgStr[1], &LeftComp, &MidComp);
1464
    SplitArg(&MidComp, &MidComp, &RightComp);
1465
    if (*LeftComp.str.p_str == '-')
1466
    {
1467
      StrCompRefRight(&LeftReg, &LeftComp, 1);
1468
      Code += 16;
1469
    }
1470
    else if (*LeftComp.str.p_str == '+')
1471
      StrCompRefRight(&LeftReg, &LeftComp, 1);
1472
    else
1473
      StrCompRefRight(&LeftReg, &LeftComp, 0);
1474
    if ((*MidComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
1475
    else if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1476
    else if (!DecodeXYAB1Reg(MidComp.str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1477
    else if (Reg2 < 4) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1478
    else if (!DecodeXYAB1Reg(LeftReg.str.p_str, &Reg3)) WrStrErrorPos(ErrNum_InvReg, &LeftReg);
1479
    else if (Reg3 < 4) WrStrErrorPos(ErrNum_InvReg, &LeftReg);
1480
    else
1481
    {
1482
      DAsmCode[0] = 0x012680 + Code + (Reg1 << 5) + Mac4Table[Reg3 - 4][Reg2 - 4];
1483
      CodeLen = 1;
1484
    }
1485
  }
1486
}
1487
 
1488
static void DecodeINC_DEC(Word Code)
1489
{
1490
  LongInt Reg1;
1491
 
1492
  if (!ChkArgCnt(1, 1));
1493
  else if (!ChkMinCPU(CPU56002));
1494
  else if (!DecodeALUReg(ArgStr[1].str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
1495
  else
1496
  {
1497
    DAsmCode[0] = (LongWord)Code + Reg1;
1498
    CodeLen = 1;
1499
  }
1500
}
1501
 
1502
static void DecodeANDI_ORI(Word Code)
1503
{
1504
  LongInt Reg1, h = 0;
1505
  Boolean OK;
1506
 
1507
  if (ChkArgCnt(1, 1))
1508
  {
1509
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1510
    if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
1511
    else if (!DecodeControlReg(RightComp.str.p_str, &Reg1)) WrStrErrorPos(ErrNum_InvAddrMode, &RightComp);
1512
    else if (*LeftComp.str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
1513
    else
1514
    {
1515
      h = EvalStrIntExpressionOffs(&LeftComp, 1, Int8, &OK);
1516
      if (OK)
1517
      {
1518
        CodeLen = 1;
1519
        DAsmCode[0] = (LongWord)Code + ((h & 0xff) << 8) + Reg1;
1520
      }
1521
    }
1522
  }
1523
}
1524
 
1525
static void DecodeNORM(Word Code)
1526
{
1527
  LongInt Reg1, Reg2;
1528
 
1529
  UNUSED(Code);
1530
 
1531
  if (ChkArgCnt(1, 1))
1532
  {
1533
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1534
    if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
1535
    else if (!DecodeALUReg(RightComp.str.p_str, &Reg2, False, False, True)) WrError(ErrNum_InvAddrMode);
1536
    else if (!DecodeReg(LeftComp.str.p_str, &Reg1)) WrError(ErrNum_InvAddrMode);
1537
    else if ((Reg1 < 16) || (Reg1 > 23)) WrError(ErrNum_InvAddrMode);
1538
    else
1539
    {
1540
      CodeLen = 1;
1541
      DAsmCode[0] = 0x01d815 + ((Reg1 & 7) << 8) + (Reg2 << 3);
1542
    }
1543
  }
1544
}
1545
 
1546
static void DecodeNORMF(Word Code)
1547
{
1548
  LongInt Reg1, Reg2;
1549
 
1550
  UNUSED(Code);
1551
 
1552
  if (ChkArgCnt(1, 1))
1553
  {
1554
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1555
    if (*RightComp.str.p_str == '\0') WrError(ErrNum_CannotSplitArg);
1556
    else if (!DecodeALUReg(RightComp.str.p_str, &Reg2, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1557
    else if (!DecodeXYAB1Reg(LeftComp.str.p_str, &Reg1)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
1558
    else
1559
    {
1560
      CodeLen = 1;
1561
      DAsmCode[0] = 0x0c1e20 + Reg2 + (Reg1 << 1);
1562
    }
1563
  }
1564
}
1565
 
1566
static void DecodeBit(Word Code)
1567
{
1568
  LongInt Reg1, Reg2, Reg3, h = 0;
1569
  Boolean OK;
1570
  tSymbolFlags Flags;
1571
 
1572
  if (ChkArgCnt(1, 1))
1573
  {
1574
    Reg2 = ((Code & 1) << 5) + (((LongInt) Code >> 1) << 16);
1575
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1576
    if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
1577
    else if (*LeftComp.str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
1578
    else
1579
    {
1580
      h = EvalStrIntExpressionOffsWithFlags(&LeftComp, 1, Int8, &OK, &Flags);
1581
      if (mFirstPassUnknown(Flags)) h &= 15;
1582
      if (OK)
1583
      {
1584
        if ((h < 0) || (h > 23)) WrError(ErrNum_OverRange);
1585
        else if (DecodeGeneralReg(RightComp.str.p_str, &Reg1))
1586
        {
1587
          CodeLen = 1;
1588
          DAsmCode[0] = 0x0ac040 + h + (Reg1 << 8) + Reg2;
1589
        }
1590
        else
1591
        {
1592
          tAdrResult RightAdrResult;
1593
 
1594
          DecodeAdr(&RightComp, MModNoImm, MSegXData + MSegYData, &RightAdrResult);
1595
          Reg3 = Ord(RightAdrResult.Seg == SegYData) << 6;
1596
          if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val <= 63) && (RightAdrResult.Val >= 0) && (RightAdrResult.ShortMode != 2))
1597
          {
1598
            CodeLen = 1;
1599
            DAsmCode[0] = 0x0a0000 + h + (RightAdrResult.Val << 8) + Reg3 + Reg2;
1600
          }
1601
          else if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val >= MemLimit - 0x3f) && (RightAdrResult.Val <= MemLimit) && (RightAdrResult.ShortMode != 2))
1602
          {
1603
            CodeLen = 1;
1604
            DAsmCode[0] = 0x0a8000 + h + ((RightAdrResult.Val & 0x3f) << 8) + Reg3 + Reg2;
1605
          }
1606
          else if ((RightAdrResult.Type == ModAbs) && (MomCPU >= CPU56300) && (RightAdrResult.Val >= MemLimit - 0x7f) && (RightAdrResult.Val <= MemLimit - 0x40) && (RightAdrResult.ShortMode != 2))
1607
          {
1608
            Reg2 = ((Code & 1) << 5) + (((LongInt) Code >> 1) << 14);
1609
            CodeLen = 1;
1610
            DAsmCode[0] = 0x010000 + h + ((RightAdrResult.Val & 0x3f) << 8) + Reg3 + Reg2;
1611
          }
1612
          else if (RightAdrResult.Type != ModNone)
1613
          {
1614
            CodeLen = 1 + RightAdrResult.Cnt;
1615
            DAsmCode[0] = 0x0a4000 + h + (RightAdrResult.Mode << 8) + Reg3 + Reg2;
1616
            DAsmCode[1] = RightAdrResult.Val;
1617
          }
1618
        }
1619
      }
1620
    }
1621
  }
1622
}
1623
 
1624
static void DecodeEXTRACT_EXTRACTU(Word Code)
1625
{
1626
  LongInt Reg1, Reg2, Reg3;
1627
  Boolean OK;
1628
 
1629
  if (ChkArgCnt(1, 1)
1630
   && ChkMinCPU(CPU56300))
1631
  {
1632
    SplitArg(&ArgStr[1], &LeftComp, &MidComp);
1633
    SplitArg(&MidComp, &MidComp, &RightComp);
1634
    if ((*MidComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
1635
    else if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1636
    else if (!DecodeALUReg(MidComp.str.p_str, &Reg2, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1637
    else if (*LeftComp.str.p_str == '#')
1638
    {
1639
      DAsmCode[1] = EvalStrIntExpressionOffs(&LeftComp, 1, Int24, &OK);
1640
      if (OK)
1641
      {
1642
        DAsmCode[0] = 0x0c1800 + Code + Reg1 + (Reg2 << 4);
1643
        CodeLen = 2;
1644
      }
1645
    }
1646
    else if (!DecodeXYAB1Reg(LeftComp.str.p_str, &Reg3)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
1647
    else
1648
    {
1649
      DAsmCode[0] = 0x0c1a00 + Code + Reg1 + (Reg2 << 4) + (Reg3 << 1);
1650
      CodeLen = 1;
1651
    }
1652
  }
1653
}
1654
 
1655
static void DecodeINSERT(Word Code)
1656
{
1657
  LongInt Reg1, Reg2, Reg3;
1658
  Boolean OK;
1659
 
1660
  UNUSED(Code);
1661
 
1662
  if (ChkArgCnt(1, 1)
1663
   && ChkMinCPU(CPU56300))
1664
  {
1665
    SplitArg(&ArgStr[1], &LeftComp, &MidComp);
1666
    SplitArg(&MidComp, &MidComp, &RightComp);
1667
    if ((*MidComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
1668
    else if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1669
    else if (!DecodeXYAB0Reg(MidComp.str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &MidComp);
1670
    else if (*LeftComp.str.p_str == '#')
1671
    {
1672
      DAsmCode[1] = EvalStrIntExpressionOffs(&LeftComp, 1, Int24, &OK);
1673
      if (OK)
1674
      {
1675
        DAsmCode[0] = 0x0c1900 + Reg1 + (Reg2 << 4);
1676
        CodeLen = 2;
1677
      }
1678
    }
1679
    else if (!DecodeXYAB1Reg(LeftComp.str.p_str, &Reg3)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
1680
    else
1681
    {
1682
      DAsmCode[0] = 0x0c1b00 + Reg1 + (Reg2 << 4) + (Reg3 << 1);
1683
      CodeLen = 1;
1684
    }
1685
  }
1686
}
1687
 
1688
static void DecodeMERGE(Word Code)
1689
{
1690
  LongInt Reg1, Reg2;
1691
 
1692
  UNUSED(Code);
1693
 
1694
  if (ChkArgCnt(1, 1)
1695
   && ChkMinCPU(CPU56300))
1696
  {
1697
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1698
    if (*RightComp.str.p_str == '\0') WrError(ErrNum_CannotSplitArg);
1699
    else if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1700
    else if (!DecodeXYAB1Reg(LeftComp.str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
1701
    else
1702
    {
1703
      DAsmCode[0] = 0x0c1b80 + Reg1 + (Reg2 << 1);
1704
      CodeLen = 1;
1705
    }
1706
  }
1707
}
1708
 
1709
static void DecodeCLB(Word Code)
1710
{
1711
  LongInt Reg1, Reg2;
1712
 
1713
  UNUSED(Code);
1714
 
1715
  if (ChkArgCnt(1, 1)
1716
   && ChkMinCPU(CPU56300))
1717
  {
1718
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1719
    if (*RightComp.str.p_str == '\0') WrError(ErrNum_CannotSplitArg);
1720
    else if (!DecodeALUReg(LeftComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
1721
    else if (!DecodeALUReg(RightComp.str.p_str, &Reg2, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1722
    else
1723
    {
1724
      DAsmCode[0] = 0x0c1e00 + Reg2 + (Reg1 << 1);
1725
      CodeLen = 1;
1726
    }
1727
  }
1728
}
1729
 
1730
static void DecodeCMPU(Word Code)
1731
{
1732
  LongInt Reg1, Reg2;
1733
 
1734
  UNUSED(Code);
1735
 
1736
  if (ChkArgCnt(1, 1)
1737
   && ChkMinCPU(CPU56300))
1738
  {
1739
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1740
    if (*RightComp.str.p_str == '\0') WrError(ErrNum_CannotSplitArg);
1741
    else if (!DecodeALUReg(RightComp.str.p_str, &Reg1, False, False, True)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1742
    else if (!DecodeXYABReg(LeftComp.str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
1743
    else if ((Reg1 ^ Reg2) == 1) WrError(ErrNum_InvRegPair);
1744
    else if ((Reg2 & 6) == 2) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
1745
    else
1746
    {
1747
      if (Reg2 < 2)
1748
        Reg2 = 0;
1749
      DAsmCode[0] = 0x0c1ff0 + (Reg2 << 1) + Reg1;
1750
      CodeLen = 1;
1751
    }
1752
  }
1753
}
1754
 
1755
/* Datentransfer */
1756
 
1757
static void DecodePlainMOVE(Word Code)
1758
{
1759
  UNUSED(Code);
1760
 
1761
  DecodeMOVE(1);
1762
}
1763
 
1764
static void DecodeMOVEC(Word Code)
1765
{
1766
  LongInt Reg1, Reg2, Reg3;
1767
 
1768
  UNUSED(Code);
1769
 
1770
  if (ChkArgCnt(1, 1))
1771
  {
1772
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1773
    if (*RightComp.str.p_str == '\0') WrError(ErrNum_CannotSplitArg);
1774
    else if (DecodeCtrlReg(LeftComp.str.p_str, &Reg1))
1775
    {
1776
      if (DecodeGeneralReg(RightComp.str.p_str, &Reg2))
1777
      {
1778
        DAsmCode[0] = 0x0440a0 + (Reg2 << 8) + Reg1;
1779
        CodeLen = 1;
1780
      }
1781
      else
1782
      {
1783
        tAdrResult RightAdrResult;
1784
 
1785
        DecodeAdr(&RightComp, MModNoImm, MSegXData + MSegYData, &RightAdrResult);
1786
        Reg3 = (Ord(RightAdrResult.Seg == SegYData)) << 6;
1787
        if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val <= 63) && (RightAdrResult.ShortMode != 2))
1788
        {
1789
          DAsmCode[0] = 0x050020 + (RightAdrResult.Val << 8) + Reg3 + Reg1;
1790
          CodeLen = 1;
1791
        }
1792
        else
1793
        {
1794
          DAsmCode[0] = 0x054020 + (RightAdrResult.Mode << 8) + Reg3 + Reg1;
1795
          DAsmCode[1] = RightAdrResult.Val; CodeLen = 1 + RightAdrResult.Cnt;
1796
        }
1797
      }
1798
    }
1799
    else if (!DecodeCtrlReg(RightComp.str.p_str, &Reg1)) WrStrErrorPos(ErrNum_InvCtrlReg, &RightComp);
1800
    else
1801
    {
1802
      if (DecodeGeneralReg(LeftComp.str.p_str, &Reg2))
1803
      {
1804
        DAsmCode[0] = 0x04c0a0 + (Reg2 << 8) + Reg1;
1805
        CodeLen = 1;
1806
      }
1807
      else
1808
      {
1809
        tAdrResult LeftAdrResult;
1810
 
1811
        DecodeAdr(&LeftComp, MModAll, MSegXData + MSegYData, &LeftAdrResult);
1812
        Reg3 = (Ord(LeftAdrResult.Seg == SegYData)) << 6;
1813
        if ((LeftAdrResult.Type == ModAbs) && (LeftAdrResult.Val <= 63) && (LeftAdrResult.ShortMode != 2))
1814
        {
1815
          DAsmCode[0] = 0x058020 + (LeftAdrResult.Val << 8) + Reg3 + Reg1;
1816
          CodeLen = 1;
1817
        }
1818
        else if (!LeftAdrResult.ForceImmLong && (LeftAdrResult.Type == ModImm) && (LeftAdrResult.Val <= 255))
1819
        {
1820
          DAsmCode[0] = 0x0500a0 + (LeftAdrResult.Val << 8) + Reg1;
1821
          CodeLen = 1;
1822
        }
1823
        else
1824
        {
1825
          DAsmCode[0] = 0x05c020 + (LeftAdrResult.Mode << 8) + Reg3 + Reg1;
1826
          DAsmCode[1] = LeftAdrResult.Val; CodeLen = 1 + LeftAdrResult.Cnt;
1827
        }
1828
      }
1829
    }
1830
  }
1831
}
1832
 
1833
static void DecodeMOVEM(Word Code)
1834
{
1835
  LongInt Reg1, Reg2;
1836
 
1837
  UNUSED(Code);
1838
 
1839
  if (ChkArgCnt(1, 1))
1840
  {
1841
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1842
    if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
1843
    else if (DecodeGeneralReg(LeftComp.str.p_str, &Reg1))
1844
    {
1845
      tAdrResult RightAdrResult;
1846
 
1847
      DecodeAdr(&RightComp, MModNoImm, MSegCode, &RightAdrResult);
1848
      if ((RightAdrResult.Type == ModAbs) && (RightAdrResult.Val >= 0) && (RightAdrResult.Val <= 63) && (RightAdrResult.ShortMode != 2))
1849
      {
1850
        CodeLen = 1;
1851
        DAsmCode[0] = 0x070000 + Reg1 + (RightAdrResult.Val << 8);
1852
      }
1853
      else if (RightAdrResult.Type != ModNone)
1854
      {
1855
        CodeLen = 1 + RightAdrResult.Cnt;
1856
        DAsmCode[1] = RightAdrResult.Val;
1857
        DAsmCode[0] = 0x074080 + Reg1 + (RightAdrResult.Mode << 8);
1858
      }
1859
    }
1860
    else if (!DecodeGeneralReg(RightComp.str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
1861
    else
1862
    {
1863
      tAdrResult LeftAdrResult;
1864
 
1865
      DecodeAdr(&LeftComp, MModNoImm, MSegCode, &LeftAdrResult);
1866
      if ((LeftAdrResult.Type == ModAbs) && (LeftAdrResult.Val >= 0) && (LeftAdrResult.Val <= 63) && (LeftAdrResult.ShortMode != 2))
1867
      {
1868
        CodeLen = 1;
1869
        DAsmCode[0] = 0x078000 + Reg2 + (LeftAdrResult.Val << 8);
1870
      }
1871
      else if (LeftAdrResult.Type != ModNone)
1872
      {
1873
        CodeLen = 1 + LeftAdrResult.Cnt;
1874
        DAsmCode[1] = LeftAdrResult.Val;
1875
        DAsmCode[0] = 0x07c080 + Reg2 + (LeftAdrResult.Mode << 8);
1876
      }
1877
    }
1878
  }
1879
}
1880
 
1881
static void DecodeMOVEP(Word Code)
1882
{
1883
  LongInt Reg1, Reg2;
1884
 
1885
  UNUSED(Code);
1886
 
1887
  if (ChkArgCnt(1, 1))
1888
  {
1889
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
1890
    if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
1891
    else if (DecodeGeneralReg(LeftComp.str.p_str, &Reg1))
1892
    {
1893
      tAdrResult RightAdrResult;
1894
 
1895
      DecodeAdr(&RightComp, MModAbs, MSegXData + MSegYData, &RightAdrResult);
1896
      if (RightAdrResult.Type != ModNone)
1897
      {
1898
        if ((RightAdrResult.Val <= MemLimit) && (RightAdrResult.Val >= MemLimit - 0x3f))
1899
        {
1900
          CodeLen = 1;
1901
          DAsmCode[0] = 0x08c000 + (Ord(RightAdrResult.Seg == SegYData) << 16)
1902
                      + (RightAdrResult.Val & 0x3f) + (Reg1 << 8);
1903
        }
1904
        else if ((MomCPU >= CPU56300) && (RightAdrResult.Val <= MemLimit - 0x40) && (RightAdrResult.Val >= MemLimit - 0x7f))
1905
        {
1906
          CodeLen = 1;
1907
          DAsmCode[0] = 0x04c000 + (Ord(RightAdrResult.Seg == SegYData) << 5)
1908
                      + (Ord(RightAdrResult.Seg == SegXData) << 7)
1909
                      + (RightAdrResult.Val & 0x1f) + ((RightAdrResult.Val & 0x20) << 1) + (Reg1 << 8);
1910
        }
1911
        else
1912
          WrError(ErrNum_UnderRange);
1913
      }
1914
    }
1915
    else if (DecodeGeneralReg(RightComp.str.p_str, &Reg2))
1916
    {
1917
      tAdrResult LeftAdrResult;
1918
 
1919
      DecodeAdr(&LeftComp, MModAbs, MSegXData + MSegYData, &LeftAdrResult);
1920
      if (LeftAdrResult.Type != ModNone)
1921
      {
1922
        if ((LeftAdrResult.Val <= MemLimit) && (LeftAdrResult.Val >= MemLimit - 0x3f))
1923
        {
1924
          CodeLen = 1;
1925
          DAsmCode[0] = 0x084000 + (Ord(LeftAdrResult.Seg == SegYData) << 16)
1926
                      + (LeftAdrResult.Val & 0x3f) + (Reg2 << 8);
1927
        }
1928
        else if ((MomCPU >= CPU56300) && (LeftAdrResult.Val <= MemLimit - 0x40) && (LeftAdrResult.Val >= MemLimit - 0x7f))
1929
        {
1930
          CodeLen = 1;
1931
          DAsmCode[0] = 0x044000 + (Ord(LeftAdrResult.Seg == SegYData) << 5)
1932
                      + (Ord(LeftAdrResult.Seg == SegXData) << 7)
1933
                      + (LeftAdrResult.Val & 0x1f) + ((LeftAdrResult.Val & 0x20) << 1) + (Reg2 << 8);
1934
        }
1935
        else
1936
          WrError(ErrNum_UnderRange);
1937
      }
1938
    }
1939
    else
1940
    {
1941
      tAdrResult LeftAdrResult;
1942
 
1943
      DecodeAdr(&LeftComp, MModAll, MSegXData + MSegYData + MSegCode, &LeftAdrResult);
1944
      if ((LeftAdrResult.Type == ModAbs) && (LeftAdrResult.Seg != SegCode) && (LeftAdrResult.Val >= MemLimit - 0x3f) && (LeftAdrResult.Val <= MemLimit))
1945
      {
1946
        LongInt HVal = LeftAdrResult.Val & 0x3f, HSeg = LeftAdrResult.Seg;
1947
        tAdrResult RightAdrResult;
1948
 
1949
        DecodeAdr(&RightComp, MModNoImm, MSegXData + MSegYData + MSegCode, &RightAdrResult);
1950
        if (RightAdrResult.Type != ModNone)
1951
        {
1952
          if (RightAdrResult.Seg == SegCode)
1953
          {
1954
            CodeLen = 1 + RightAdrResult.Cnt;
1955
            DAsmCode[1] = RightAdrResult.Val;
1956
            DAsmCode[0] = 0x084040 + HVal + (RightAdrResult.Mode << 8)
1957
                        + (Ord(HSeg == SegYData) << 16);
1958
          }
1959
          else
1960
          {
1961
            CodeLen = 1 + RightAdrResult.Cnt;
1962
            DAsmCode[1] = RightAdrResult.Val;
1963
            DAsmCode[0] = 0x084080 + HVal + (RightAdrResult.Mode << 8)
1964
                        + (Ord(HSeg == SegYData) << 16)
1965
                        + (Ord(RightAdrResult.Seg == SegYData) << 6);
1966
          }
1967
        }
1968
      }
1969
      else if ((LeftAdrResult.Type == ModAbs) && (MomCPU >= CPU56300) && (LeftAdrResult.Seg != SegCode) && (LeftAdrResult.Val >= MemLimit - 0x7f) && (LeftAdrResult.Val <= MemLimit - 0x40) && (LeftAdrResult.ShortMode != 2))
1970
      {
1971
        LongInt HVal = LeftAdrResult.Val & 0x3f, HSeg = LeftAdrResult.Seg;
1972
        tAdrResult RightAdrResult;
1973
 
1974
        DecodeAdr(&RightComp, MModNoImm, MSegXData + MSegYData + MSegCode, &RightAdrResult);
1975
        if (RightAdrResult.Type != ModNone)
1976
        {
1977
          if (RightAdrResult.Seg == SegCode)
1978
          {
1979
            CodeLen = 1 + RightAdrResult.Cnt;
1980
            DAsmCode[1] = RightAdrResult.Val;
1981
            DAsmCode[0] = 0x008000 + HVal + (RightAdrResult.Mode << 8)
1982
                        + (Ord(HSeg == SegYData) << 6);
1983
          }
1984
          else
1985
          {
1986
            CodeLen = 1 + RightAdrResult.Cnt;
1987
            DAsmCode[1] = RightAdrResult.Val;
1988
            DAsmCode[0] = 0x070000 + HVal + (RightAdrResult.Mode << 8)
1989
                        + (Ord(HSeg == SegYData) << 7)
1990
                        + (Ord(HSeg == SegXData) << 14)
1991
                        + (Ord(RightAdrResult.Seg == SegYData) << 6);
1992
          }
1993
        }
1994
      }
1995
      else if (LeftAdrResult.Type != ModNone)
1996
      {
1997
        LongInt HVal = LeftAdrResult.Val,
1998
                HCnt = LeftAdrResult.Cnt,
1999
                HMode = LeftAdrResult.Mode,
2000
                HSeg = LeftAdrResult.Seg;
2001
        tAdrResult RightAdrResult;
2002
 
2003
        DecodeAdr(&RightComp, MModAbs, MSegXData + MSegYData, &RightAdrResult);
2004
        if (RightAdrResult.Type != ModNone)
2005
        {
2006
          if ((RightAdrResult.Val >= MemLimit - 0x3f) && (RightAdrResult.Val <= MemLimit))
2007
          {
2008
            if (HSeg == SegCode)
2009
            {
2010
              CodeLen = 1 + HCnt;
2011
              DAsmCode[1] = HVal;
2012
              DAsmCode[0] = 0x08c040 + (RightAdrResult.Val & 0x3f) + (HMode << 8)
2013
                          + (Ord(RightAdrResult.Seg == SegYData) << 16);
2014
            }
2015
            else
2016
            {
2017
              CodeLen = 1 + HCnt;
2018
              DAsmCode[1] = HVal;
2019
              DAsmCode[0] = 0x08c080 + (((Word)RightAdrResult.Val) & 0x3f) + (HMode << 8)
2020
                          + (Ord(RightAdrResult.Seg == SegYData) << 16)
2021
                          + (Ord(HSeg == SegYData) << 6);
2022
            }
2023
          }
2024
          else if ((MomCPU >= CPU56300) && (RightAdrResult.Val >= MemLimit - 0x7f) && (RightAdrResult.Val <= MemLimit - 0x40))
2025
          {
2026
            if (HSeg == SegCode)
2027
            {
2028
              CodeLen = 1 + HCnt;
2029
              DAsmCode[1] = HVal;
2030
              DAsmCode[0] = 0x00c000 + (RightAdrResult.Val & 0x3f) + (HMode << 8)
2031
                          + (Ord(RightAdrResult.Seg == SegYData) << 6);
2032
            }
2033
            else
2034
            {
2035
              CodeLen = 1 + HCnt;
2036
              DAsmCode[1] = HVal;
2037
              DAsmCode[0] = 0x078000 + (((Word)RightAdrResult.Val) & 0x3f) + (HMode << 8)
2038
                          + (Ord(RightAdrResult.Seg == SegYData) << 7)
2039
                          + (Ord(RightAdrResult.Seg == SegXData) << 14)
2040
                          + (Ord(HSeg == SegYData) << 6);
2041
            }
2042
          }
2043
          else
2044
            WrError(ErrNum_UnderRange);
2045
        }
2046
      }
2047
    }
2048
  }
2049
}
2050
 
2051
static void DecodePlainTFR(Word Code)
2052
{
2053
  LongInt Reg1;
2054
 
2055
  UNUSED(Code);
2056
 
2057
  if (ChkArgCnt(1, ArgCntMax))
2058
  if (DecodeMOVE(2))
2059
  {
2060
    if (DecodeTFR(&ArgStr[1], &Reg1))
2061
    {
2062
      DAsmCode[0] += 0x01 + (Reg1 << 3);
2063
    }
2064
    else
2065
    {
2066
      WrError(ErrNum_InvAddrMode);
2067
      CodeLen = 0;
2068
    }
2069
  }
2070
}
2071
 
2072
static void DecodeTcc(Word Condition)
2073
{
2074
  LongInt Reg1, Reg2;
2075
 
2076
  if (!ChkArgCnt(1, 2));
2077
  else if (DecodeTFR(&ArgStr[1], &Reg1))
2078
  {
2079
    if (ArgCnt == 1)
2080
    {
2081
      CodeLen = 1;
2082
      DAsmCode[0] = 0x020000 + (Condition << 12) + (Reg1 << 3);
2083
    }
2084
    else if (!DecodeRR(&ArgStr[2], &Reg2)) WrError(ErrNum_InvAddrMode);
2085
    else
2086
    {
2087
      CodeLen = 1;
2088
      DAsmCode[0] = 0x030000 + (Condition << 12) + (Reg1 << 3) + Reg2;
2089
    }
2090
  }
2091
  else if (!ChkArgCnt(1, 1));
2092
  else if (!DecodeRR(&ArgStr[1], &Reg1)) WrError(ErrNum_InvAddrMode);
2093
  else
2094
  {
2095
    DAsmCode[0] = 0x020800 + (Condition << 12) + Reg1;
2096
    CodeLen = 1;
2097
  }
2098
}
2099
 
2100
static void DecodeBitBr(Word Code)
2101
{
2102
  LongInt Reg1, Reg3, h = 0, h2, AddVal;
2103
  Boolean OK;
2104
  tSymbolFlags Flags;
2105
 
2106
  if (ChkArgCnt(1, 1)
2107
   && ChkMinCPU(CPU56300))
2108
  {
2109
    h = (Code & 1) << 5;
2110
    h2 = (((LongInt) Code) & 2) << 15;
2111
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
2112
    SplitArg(&RightComp, &MidComp, &RightComp);
2113
    if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0') || (*MidComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
2114
    else if (*LeftComp.str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
2115
    else
2116
    {
2117
      AddVal = EvalStrIntExpressionOffsWithFlags(&LeftComp, 1, Int8, &OK, &Flags);
2118
      if (mFirstPassUnknown(Flags)) AddVal &= 15;
2119
      if (OK)
2120
      {
2121
        if ((AddVal < 0) || (AddVal > 23)) WrError(ErrNum_OverRange);
2122
        else if (DecodeGeneralReg(MidComp.str.p_str, &Reg1))
2123
        {
2124
          CodeLen = 1;
2125
          DAsmCode[0] = 0x0cc080 + AddVal + (Reg1 << 8) + h + h2;
2126
        }
2127
        else
2128
        {
2129
          tAdrResult AdrResult;
2130
 
2131
          DecodeAdr(&MidComp, MModNoImm, MSegXData + MSegYData, &AdrResult);
2132
          Reg3 = Ord(AdrResult.Seg == SegYData) << 6;
2133
          if ((AdrResult.Type == ModAbs) && (mFirstPassUnknown(AdrResult.AbsSymFlags))) AdrResult.Val &= 0x3f;
2134
          if ((AdrResult.Type == ModAbs) && (AdrResult.Val <= 63) && (AdrResult.Val >= 0) && (AdrResult.ShortMode != 2))
2135
          {
2136
            CodeLen = 1;
2137
            DAsmCode[0] = 0x0c8080 + AddVal + (AdrResult.Val << 8) + Reg3 + h + h2;
2138
          }
2139
          else if ((AdrResult.Type == ModAbs) && (AdrResult.Val >= MemLimit - 0x3f) && (AdrResult.Val <= MemLimit))
2140
          {
2141
            CodeLen = 1;
2142
            DAsmCode[0] = 0x0cc000 + AddVal + ((AdrResult.Val & 0x3f) << 8) + Reg3 + h + h2;
2143
          }
2144
          else if ((AdrResult.Type == ModAbs) && (AdrResult.Val >= MemLimit - 0x7f) && (AdrResult.Val <= MemLimit - 0x40))
2145
          {
2146
            CodeLen = 1;
2147
            DAsmCode[0] = 0x048000 + AddVal + ((AdrResult.Val & 0x3f) << 8) + Reg3 + h + (h2 >> 9);
2148
          }
2149
          else if (AdrResult.Type == ModAbs) WrError(ErrNum_InvAddrMode);
2150
          else if (AdrResult.Type != ModNone)
2151
          {
2152
            CodeLen = 1;
2153
            DAsmCode[0] = 0x0c8000 + AddVal + (AdrResult.Mode << 8) + Reg3 + h + h2;
2154
          }
2155
        }
2156
      }
2157
    }
2158
    if (CodeLen == 1)
2159
    {
2160
      LongInt Dist = EvalStrIntExpression(&RightComp, AdrInt, &OK) - EProgCounter();
2161
 
2162
      if (OK)
2163
      {
2164
        DAsmCode[1] = Dist & 0xffffff;
2165
        CodeLen = 2;
2166
      }
2167
      else
2168
        CodeLen = 0;
2169
    }
2170
  }
2171
}
2172
 
2173
static void DecodeBRA_BSR(Word Code)
2174
{
2175
  LongInt Reg1, Dist;
2176
  Byte Size;
2177
  Boolean OK;
2178
  tSymbolFlags Flags;
2179
 
2180
  if (ChkArgCnt(1, 1)
2181
   && ChkMinCPU(CPU56300)
2182
   && DecodeReg(ArgStr[1].str.p_str, &Reg1))
2183
  {
2184
    if ((Reg1 < 16) || (Reg1 > 23)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
2185
    else
2186
    {
2187
      Reg1 -= 16;
2188
      DAsmCode[0] = 0x0d1880 + (Reg1 << 8) + Code;
2189
      CodeLen = 1;
2190
    }
2191
  }
2192
  else
2193
  {
2194
    unsigned Offset = CutSize(&ArgStr[1], &Size);
2195
 
2196
    Dist = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], Offset, AdrInt, &OK, &Flags) - EProgCounter();
2197
    if (Size == 0)
2198
      Size = ((Dist> - 256) && (Dist < 255)) ? 1 : 2;
2199
    switch (Size)
2200
    {
2201
      case 1:
2202
        if (!mSymbolQuestionable(Flags) && ((Dist < -256) || (Dist > 255))) WrError(ErrNum_JmpDistTooBig);
2203
        else
2204
        {
2205
          Dist &= 0x1ff;
2206
          DAsmCode[0] = 0x050800 + (Code << 4) + ((Dist & 0x1e0) << 1) + (Dist & 0x1f);
2207
          CodeLen = 1;
2208
        }
2209
        break;
2210
      case 2:
2211
        DAsmCode[0] = 0x0d1080 + Code;
2212
        DAsmCode[1] = Dist & 0xffffff;
2213
        CodeLen = 2;
2214
        break;
2215
    }
2216
  }
2217
}
2218
 
2219
static void DecodeBcc(Word Condition)
2220
{
2221
  LongInt Dist, Reg1;
2222
  Boolean OK;
2223
  tSymbolFlags Flags;
2224
  Byte Size;
2225
 
2226
  if (ChkArgCnt(1, 1)
2227
   && ChkMinCPU(CPU56300)
2228
   && DecodeReg(ArgStr[1].str.p_str, &Reg1))
2229
  {
2230
    if ((Reg1 < 16) || (Reg1 > 23)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
2231
    else
2232
    {
2233
      Reg1 -= 16;
2234
      DAsmCode[0] = 0x0d1840 + (Reg1 << 8) + Condition;
2235
      CodeLen = 1;
2236
    }
2237
  }
2238
  else
2239
  {
2240
    unsigned Offset = CutSize(&ArgStr[1], &Size);
2241
 
2242
    Dist = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], Offset, AdrInt, &OK, &Flags) - EProgCounter();
2243
    if (Size == 0)
2244
      Size = ((Dist > -256) && (Dist < 255)) ? 1 : 2;
2245
    switch (Size)
2246
    {
2247
      case 1:
2248
        if (!mSymbolQuestionable(Flags) && ((Dist < -256) || (Dist > 255))) WrError(ErrNum_JmpDistTooBig);
2249
        else
2250
        {
2251
          Dist &= 0x1ff;
2252
          DAsmCode[0] = 0x050400 + (Condition << 12) + ((Dist & 0x1e0) << 1) + (Dist & 0x1f);
2253
          CodeLen = 1;
2254
        }
2255
        break;
2256
      case 2:
2257
        DAsmCode[0] = 0x0d1040 + Condition;
2258
        DAsmCode[1] = Dist & 0xffffff;
2259
        CodeLen = 2;
2260
        break;
2261
    }
2262
  }
2263
}
2264
 
2265
static void DecodeBScc(Word Condition)
2266
{
2267
  LongInt Reg1, Dist;
2268
  Byte Size;
2269
  Boolean OK;
2270
  tSymbolFlags Flags;
2271
 
2272
  if (ChkArgCnt(1, 1)
2273
   && ChkMinCPU(CPU56300)
2274
   && DecodeReg(ArgStr[1].str.p_str, &Reg1))
2275
  {
2276
    if ((Reg1 < 16) || (Reg1 > 23)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
2277
    else
2278
    {
2279
      Reg1 -= 16;
2280
      DAsmCode[0] = 0x0d1800 + (Reg1 << 8) + Condition;
2281
      CodeLen = 1;
2282
    }
2283
  }
2284
  else
2285
  {
2286
    unsigned Offset;
2287
 
2288
    Offset = CutSize(&ArgStr[1], &Size);
2289
    Dist = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], Offset, AdrInt, &OK, &Flags) - EProgCounter();
2290
    if (Size == 0)
2291
      Size = ((Dist > -256) && (Dist < 255)) ? 1 : 2;
2292
    switch (Size)
2293
    {
2294
      case 1:
2295
        if (!mSymbolQuestionable(Flags) && ((Dist < -256) || (Dist > 255))) WrError(ErrNum_JmpDistTooBig);
2296
        else
2297
        {
2298
          Dist &= 0x1ff;
2299
          DAsmCode[0] = 0x050000 + (Condition << 12) + ((Dist & 0x1e0) << 1) + (Dist & 0x1f);
2300
          CodeLen = 1;
2301
        }
2302
        break;
2303
      case 2:
2304
        DAsmCode[0] = 0x0d1000 + Condition;
2305
        DAsmCode[1] = Dist & 0xffffff;
2306
        CodeLen = 2;
2307
        break;
2308
    }
2309
  }
2310
}
2311
 
2312
static void DecodeLUA_LEA(Word Code)
2313
{
2314
  LongInt Reg1;
2315
 
2316
  UNUSED(Code);
2317
 
2318
  if (ChkArgCnt(1, 1))
2319
  {
2320
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
2321
    if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
2322
    else if (!DecodeReg(RightComp.str.p_str, &Reg1)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
2323
    else if (Reg1 > 31) WrStrErrorPos(ErrNum_InvReg, &RightComp);
2324
    else
2325
    {
2326
      tAdrResult AdrResult;
2327
 
2328
      DecodeAdr(&LeftComp, MModModInc | MModModDec | MModPostInc | MModPostDec | MModDisp, MSegXData, &AdrResult);
2329
      if (AdrResult.Type == ModDisp)
2330
      {
2331
        if (ChkRange(AdrResult.Val, -64, 63))
2332
        {
2333
          AdrResult.Val &= 0x7f;
2334
          DAsmCode[0] = 0x040000 + (Reg1 - 16) + (AdrResult.Mode << 8)
2335
                      + ((AdrResult.Val & 0x0f) << 4)
2336
                      + ((AdrResult.Val & 0x70) << 7);
2337
           CodeLen = 1;
2338
        }
2339
      }
2340
      else if (AdrResult.Type != ModNone)
2341
      {
2342
        CodeLen = 1;
2343
        DAsmCode[0] = 0x044000 + (AdrResult.Mode << 8) + Reg1;
2344
      }
2345
    }
2346
  }
2347
}
2348
 
2349
static void DecodeLRA(Word Code)
2350
{
2351
  LongInt Reg1, Reg2;
2352
  Boolean OK;
2353
 
2354
  UNUSED(Code);
2355
 
2356
  if (ChkArgCnt(1, 1)
2357
   && ChkMinCPU(CPU56300))
2358
  {
2359
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
2360
    if (*RightComp.str.p_str == '\0') WrError(ErrNum_CannotSplitArg);
2361
    else if (!DecodeGeneralReg(RightComp.str.p_str, &Reg1)) WrStrErrorPos(ErrNum_InvReg, &RightComp);
2362
    else if (Reg1 > 0x1f) WrStrErrorPos(ErrNum_InvReg, &RightComp);
2363
    else if (DecodeGeneralReg(LeftComp.str.p_str, &Reg2))
2364
    {
2365
      if ((Reg2 < 16) || (Reg2 > 23)) WrStrErrorPos(ErrNum_InvReg, &LeftComp);
2366
      else
2367
      {
2368
        DAsmCode[0] = 0x04c000 + ((Reg2 & 7) << 8) + Reg1;
2369
        CodeLen = 1;
2370
      }
2371
    }
2372
    else
2373
    {
2374
      DAsmCode[1] = EvalStrIntExpression(&LeftComp, AdrInt, &OK) - EProgCounter();
2375
      if (OK)
2376
      {
2377
        DAsmCode[0] = 0x044040 + Reg1;
2378
        CodeLen = 2;
2379
      }
2380
    }
2381
  }
2382
}
2383
 
2384
static void DecodePLOCK(Word Code)
2385
{
2386
  UNUSED(Code);
2387
 
2388
  if (ChkArgCnt(1, 1)
2389
   && ChkMinCPU(CPU56300))
2390
  {
2391
    tAdrResult AdrResult;
2392
 
2393
    DecodeAdr(&ArgStr[1], MModNoImm, MSegCode, &AdrResult);
2394
    if (AdrResult.Type != ModNone)
2395
    {
2396
      DAsmCode[0] = 0x0ac081 + (AdrResult.Mode << 8); DAsmCode[1] = AdrResult.Val;
2397
      CodeLen = 2;
2398
    }
2399
  }
2400
}
2401
 
2402
static void DecodePLOCKR_PUNLOCKR(Word Code)
2403
{
2404
  if (ChkArgCnt(1, 1)
2405
   && ChkMinCPU(CPU56300))
2406
  {
2407
    Boolean OK;
2408
 
2409
    DAsmCode[1] = (EvalStrIntExpression(&ArgStr[1],  AdrInt,  &OK) - EProgCounter()) & 0xffffff;
2410
    if (OK)
2411
    {
2412
      DAsmCode[0] = Code;
2413
      CodeLen = 2;
2414
    }
2415
  }
2416
}
2417
 
2418
/* Spruenge */
2419
 
2420
static void DecodeJMP_JSR(Word Code)
2421
{
2422
  if (ChkArgCnt(1, 1))
2423
  {
2424
    LongWord AddVal = (LongWord)Code << 16;
2425
    tAdrResult AdrResult;
2426
 
2427
    DecodeAdr(&ArgStr[1], MModNoImm, MSegCode, &AdrResult);
2428
    if (AdrResult.Type == ModAbs)
2429
     if (((AdrResult.Val & 0xfff000) == 0) && (AdrResult.ShortMode != 2))
2430
     {
2431
       CodeLen = 1;
2432
       DAsmCode[0] = 0x0c0000 + AddVal + (AdrResult.Val & 0xfff);
2433
     }
2434
     else
2435
     {
2436
       CodeLen = 2;
2437
       DAsmCode[0] = 0x0af080 + AddVal;
2438
       DAsmCode[1] = AdrResult.Val;
2439
     }
2440
    else if (AdrResult.Type != ModNone)
2441
    {
2442
      CodeLen = 1;
2443
      DAsmCode[0] = 0x0ac080 + AddVal + (AdrResult.Mode << 8);
2444
    }
2445
  }
2446
}
2447
 
2448
static void DecodeJcc(Word Condition)
2449
{
2450
  if (ChkArgCnt(1, 1))
2451
  {
2452
    tAdrResult AdrResult;
2453
 
2454
    DecodeAdr(&ArgStr[1], MModNoImm, MSegCode, &AdrResult);
2455
    if (AdrResult.Type == ModAbs)
2456
    {
2457
      if (((AdrResult.Val & 0xfff000) == 0) && (AdrResult.ShortMode != 2))
2458
      {
2459
        CodeLen = 1;
2460
        DAsmCode[0] = 0x0e0000 + (Condition << 12) + (AdrResult.Val & 0xfff);
2461
      }
2462
      else
2463
      {
2464
        CodeLen = 2;
2465
        DAsmCode[0] = 0x0af0a0 + Condition;
2466
        DAsmCode[1] = AdrResult.Val;
2467
      }
2468
    }
2469
    else if (AdrResult.Type != ModNone)
2470
    {
2471
      CodeLen = 1;
2472
      DAsmCode[0] = 0x0ac0a0 + Condition + (AdrResult.Mode << 8);
2473
    }
2474
  }
2475
}
2476
 
2477
static void DecodeJScc(Word Condition)
2478
{
2479
  if (ChkArgCnt(1, 1))
2480
  {
2481
    tAdrResult AdrResult;
2482
 
2483
    DecodeAdr(&ArgStr[1], MModNoImm, MSegCode, &AdrResult);
2484
    if (AdrResult.Type == ModAbs)
2485
    {
2486
      if (((AdrResult.Val & 0xfff000) == 0) && (AdrResult.ShortMode != 2))
2487
      {
2488
        CodeLen = 1;
2489
        DAsmCode[0] = 0x0f0000 + (Condition << 12) + (AdrResult.Val & 0xfff);
2490
      }
2491
      else
2492
      {
2493
        CodeLen = 2;
2494
        DAsmCode[0] = 0x0bf0a0 + Condition;
2495
        DAsmCode[1] = AdrResult.Val;
2496
      }
2497
    }
2498
    else if (AdrResult.Type != ModNone)
2499
    {
2500
      CodeLen = 1;
2501
      DAsmCode[0] = 0x0bc0a0 + Condition + (AdrResult.Mode << 8);
2502
    }
2503
  }
2504
}
2505
 
2506
static void DecodeBitJmp(Word Code)
2507
{
2508
  Boolean OK;
2509
  tSymbolFlags Flags;
2510
  LongInt h, Reg1, Reg2, Reg3;
2511
 
2512
  if (ChkArgCnt(1, 1))
2513
  {
2514
    SplitArg(&ArgStr[1], &LeftComp, &MidComp);
2515
    SplitArg(&MidComp, &MidComp, &RightComp);
2516
    if ((*LeftComp.str.p_str == '\0') || (*MidComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
2517
    else if (*LeftComp.str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
2518
    else
2519
    {
2520
      DAsmCode[1] = EvalStrIntExpression(&RightComp, AdrInt, &OK);
2521
      if (OK)
2522
      {
2523
        h = EvalStrIntExpressionOffsWithFlags(&LeftComp, 1, Int8, &OK, &Flags);
2524
        if (mFirstPassUnknown(Flags))
2525
          h &= 15;
2526
        if (OK)
2527
        {
2528
          if ((h < 0) || (h > 23)) WrError(ErrNum_OverRange);
2529
          else
2530
          {
2531
            Reg2 = ((Code & 1) << 5) + (((LongInt)(Code >> 1)) << 16);
2532
            if (DecodeGeneralReg(MidComp.str.p_str, &Reg1))
2533
            {
2534
              CodeLen = 2;
2535
              DAsmCode[0] = 0x0ac000 + h + Reg2 + (Reg1 << 8);
2536
            }
2537
            else
2538
            {
2539
              tAdrResult AdrResult;
2540
 
2541
              DecodeAdr(&MidComp, MModNoImm, MSegXData + MSegYData, &AdrResult);
2542
              Reg3 = Ord(AdrResult.Seg == SegYData) << 6;
2543
              if (AdrResult.Type == ModAbs)
2544
              {
2545
                if ((AdrResult.Val >= 0) && (AdrResult.Val <= 63))
2546
                {
2547
                  CodeLen = 2;
2548
                  DAsmCode[0] = 0x0a0080 + h + Reg2 + Reg3 + (AdrResult.Val << 8);
2549
                }
2550
                else if ((AdrResult.Val >= MemLimit - 0x3f) && (AdrResult.Val <= MemLimit))
2551
                {
2552
                  CodeLen = 2;
2553
                  DAsmCode[0] = 0x0a8080 + h + Reg2 + Reg3 + ((AdrResult.Val & 0x3f) << 8);
2554
                }
2555
                else if ((MomCPU >= CPU56300) && (AdrResult.Val >= MemLimit - 0x7f) && (AdrResult.Val <= MemLimit - 0x40))
2556
                {
2557
                  CodeLen = 2;
2558
                  Reg2 = ((Code & 1) << 5) + (((LongInt)(Code >> 1)) << 14);
2559
                  DAsmCode[0] = 0x018080 + h + Reg2 + Reg3 + ((AdrResult.Val & 0x3f) << 8);
2560
                }
2561
                else WrError(ErrNum_OverRange);
2562
              }
2563
              else if (AdrResult.Type != ModNone)
2564
              {
2565
                CodeLen = 2;
2566
                DAsmCode[0] = 0x0a4080 + h + Reg2 + Reg3 + (AdrResult.Mode << 8);
2567
              }
2568
            }
2569
          }
2570
        }
2571
      }
2572
    }
2573
  }
2574
}
2575
 
2576
static void DecodeDO_DOR(Word Code)
2577
{
2578
  if (ChkArgCnt(1, 1))
2579
  {
2580
    SplitArg(&ArgStr[1], &LeftComp, &RightComp);
2581
    if ((*LeftComp.str.p_str == '\0') || (*RightComp.str.p_str == '\0')) WrError(ErrNum_CannotSplitArg);
2582
    else
2583
    {
2584
      LongInt Reg1;
2585
      tEvalResult EvalResult;
2586
 
2587
      DAsmCode[1] = EvalStrIntExpressionWithResult(&RightComp, AdrInt, &EvalResult) - 1;
2588
      if (EvalResult.OK)
2589
      {
2590
        ChkSpace(SegCode, EvalResult.AddrSpaceMask);
2591
        if (!as_strcasecmp(LeftComp.str.p_str, "FOREVER"))
2592
        {
2593
          if (ChkMinCPU(CPU56300))
2594
          {
2595
            DAsmCode[0] = 0x000203 - Code;
2596
            CodeLen = 2;
2597
          }
2598
        }
2599
        else if (DecodeGeneralReg(LeftComp.str.p_str, &Reg1))
2600
        {
2601
          if (Reg1 == 0x3c) WrXError(ErrNum_InvReg, LeftComp.str.p_str); /* kein SSH!! */
2602
          else
2603
          {
2604
            CodeLen = 2;
2605
            DAsmCode[0] = 0x06c000 + (Reg1 << 8) + (Code << 4);
2606
          }
2607
        }
2608
        else if (*LeftComp.str.p_str == '#')
2609
        {
2610
          Reg1 = EvalStrIntExpressionOffsWithResult(&LeftComp, 1, UInt12, &EvalResult);
2611
          if (EvalResult.OK)
2612
          {
2613
            CodeLen = 2;
2614
            DAsmCode[0] = 0x060080 + (Reg1 >> 8) + ((Reg1 & 0xff) << 8) + (Code << 4);
2615
          }
2616
        }
2617
        else
2618
        {
2619
          tAdrResult AdrResult;
2620
 
2621
          DecodeAdr(&LeftComp, MModNoImm, MSegXData + MSegYData, &AdrResult);
2622
          if (AdrResult.Type == ModAbs)
2623
           if ((AdrResult.Val < 0) || (AdrResult.Val > 63)) WrError(ErrNum_OverRange);
2624
           else
2625
           {
2626
             CodeLen = 2;
2627
             DAsmCode[0] = 0x060000 + (AdrResult.Val << 8) + (Ord(AdrResult.Seg == SegYData) << 6) + (Code << 4);
2628
           }
2629
          else
2630
          {
2631
            CodeLen = 2;
2632
            DAsmCode[0] = 0x064000 + (AdrResult.Mode << 8) + (Ord(AdrResult.Seg == SegYData) << 6) + (Code << 4);
2633
          }
2634
        }
2635
      }
2636
    }
2637
  }
2638
}
2639
 
2640
static void DecodeBRKcc(Word Condition)
2641
{
2642
  if (ChkArgCnt(0, 0)
2643
   && ChkMinCPU(CPU56300))
2644
  {
2645
    DAsmCode[0] = 0x00000210 + Condition;
2646
    CodeLen = 1;
2647
  }
2648
}
2649
 
2650
static void DecodeTRAPcc(Word Condition)
2651
{
2652
  if (ChkArgCnt(0, 0)
2653
   && ChkMinCPU(CPU56300))
2654
  {
2655
    DAsmCode[0] = 0x000010 + Condition;
2656
    CodeLen = 1;
2657
  }
2658
}
2659
 
2660
static void DecodeDEBUGcc(Word Condition)
2661
{
2662
  if (ChkArgCnt(0, 0)
2663
   && ChkMinCPU(CPU56300))
2664
  {
2665
    DAsmCode[0] = 0x00000300 + Condition;
2666
    CodeLen = 1;
2667
  }
2668
}
2669
 
2670
static void DecodeREP(Word Code)
2671
{
2672
  LongInt Reg1;
2673
 
2674
  UNUSED(Code);
2675
 
2676
  if (!ChkArgCnt(1, 1));
2677
  else if (DecodeGeneralReg(ArgStr[1].str.p_str, &Reg1))
2678
  {
2679
    CodeLen = 1;
2680
    DAsmCode[0] = 0x06c020 + (Reg1 << 8);
2681
  }
2682
  else
2683
  {
2684
    tAdrResult AdrResult;
2685
 
2686
    DecodeAdr(&ArgStr[1], MModAll, MSegXData + MSegYData, &AdrResult);
2687
    if (AdrResult.Type == ModImm)
2688
    {
2689
      if ((AdrResult.Val < 0) || (AdrResult.Val > 0xfff)) WrError(ErrNum_OverRange);
2690
      else
2691
      {
2692
        CodeLen = 1;
2693
        DAsmCode[0] = 0x0600a0 + (AdrResult.Val >> 8) + ((AdrResult.Val & 0xff) << 8);
2694
      }
2695
    }
2696
    else if (AdrResult.Type == ModAbs)
2697
    {
2698
      if ((AdrResult.Val < 0) || (AdrResult.Val > 63)) WrError(ErrNum_OverRange);
2699
      else
2700
      {
2701
        CodeLen = 1;
2702
        DAsmCode[0] = 0x060020 + (AdrResult.Val << 8) + (Ord(AdrResult.Seg == SegYData) << 6);
2703
      }
2704
    }
2705
    else
2706
    {
2707
      CodeLen = 1 + AdrResult.Cnt;
2708
      DAsmCode[1] = AdrResult.Val;
2709
      DAsmCode[0] = 0x064020 + (AdrResult.Mode << 8) + (Ord(AdrResult.Seg == SegYData) << 6);
2710
    }
2711
  }
2712
}
2713
 
2714
/*----------------------------------------------------------------------------------------------*/
2715
 
2716
static void AddFixed(const char *Name, LongWord Code, CPUVar NMin)
2717
{
2718
  order_array_rsv_end(FixedOrders, FixedOrder);
2719
  FixedOrders[InstrZ].Code = Code;
2720
  FixedOrders[InstrZ].MinCPU = NMin;
2721
  AddInstTable(InstTable, Name, InstrZ++, DecodeFixed);
2722
}
2723
 
2724
static void AddPar(const char *Name, ParTyp Typ, LongWord Code)
2725
{
2726
  order_array_rsv_end(ParOrders, ParOrder);
2727
  ParOrders[InstrZ].Typ = Typ;
2728
  ParOrders[InstrZ].Code = Code;
2729
  AddInstTable(InstTable, Name, InstrZ++, DecodePar);
2730
}
2731
 
2732
static void AddMix(const char *pName, Word Code, InstProc Proc, unsigned Mask)
2733
{
2734
  char TmpName[30];
2735
 
2736
  if (Mask & 1)
2737
  {
2738
    as_snprintf(TmpName, sizeof(TmpName), "%sSS", pName);
2739
    AddInstTable(InstTable, TmpName, Code + 0x0000, Proc);
2740
  }
2741
  if (Mask & 2)
2742
  {
2743
    as_snprintf(TmpName, sizeof(TmpName), "%sSU", pName);
2744
    AddInstTable(InstTable, TmpName, Code + 0x0100, Proc);
2745
  }
2746
  if (Mask & 4)
2747
  {
2748
    as_snprintf(TmpName, sizeof(TmpName), "%sUU", pName);
2749
    AddInstTable(InstTable, TmpName, Code + 0x0140, Proc);
2750
  }
2751
}
2752
 
2753
static void AddCondition(const char *pName, InstProc Proc)
2754
{
2755
  unsigned z;
2756
  char TmpName[30];
2757
  Word Code;
2758
 
2759
  for (z = 0; z < CondCount; z++)
2760
  {
2761
    as_snprintf(TmpName, sizeof(TmpName), "%s%s", pName, CondNames[z]);
2762
    Code = (z == CondCount - 1) ? 8 : z & 15;
2763
    AddInstTable(InstTable, TmpName, Code, Proc);
2764
  }
2765
}
2766
 
2767
static void InitFields(void)
2768
{
2769
  InstTable = CreateInstTable(307);
2770
  SetDynamicInstTable(InstTable);
2771
 
2772
  add_null_pseudo(InstTable);
2773
 
2774
  AddInstTable(InstTable, "DIV", 0, DecodeDIV);
2775
  AddInstTable(InstTable, "INC", 0x0008, DecodeINC_DEC);
2776
  AddInstTable(InstTable, "DEC", 0x000a, DecodeINC_DEC);
2777
  AddInstTable(InstTable, "ANDI", 0x00b8, DecodeANDI_ORI);
2778
  AddInstTable(InstTable, "ORI", 0x00f8, DecodeANDI_ORI);
2779
  AddInstTable(InstTable, "NORM", 0, DecodeNORM);
2780
  AddInstTable(InstTable, "NORMF", 0, DecodeNORMF);
2781
  AddInstTable(InstTable, "EXTRACT", 0, DecodeEXTRACT_EXTRACTU);
2782
  AddInstTable(InstTable, "EXTRACTU", 128, DecodeEXTRACT_EXTRACTU);
2783
  AddInstTable(InstTable, "INSERT", 0, DecodeINSERT);
2784
  AddInstTable(InstTable, "MERGE", 0, DecodeMERGE);
2785
  AddInstTable(InstTable, "CLB", 0, DecodeCLB);
2786
  AddInstTable(InstTable, "CMPU", 0, DecodeCMPU);
2787
  AddInstTable(InstTable, "MOVE", 0, DecodePlainMOVE);
2788
  AddInstTable(InstTable, "MOVEC", 0, DecodeMOVEC);
2789
  AddInstTable(InstTable, "MOVEM", 0, DecodeMOVEM);
2790
  AddInstTable(InstTable, "MOVEP", 0, DecodeMOVEP);
2791
  AddInstTable(InstTable, "TFR", 0, DecodePlainTFR);
2792
  AddInstTable(InstTable, "BRA", 0x40, DecodeBRA_BSR);
2793
  AddInstTable(InstTable, "BSR", 0x00, DecodeBRA_BSR);
2794
  AddInstTable(InstTable, "LUA", 0, DecodeLUA_LEA);
2795
  AddInstTable(InstTable, "LEA", 0, DecodeLUA_LEA);
2796
  AddInstTable(InstTable, "LRA", 0, DecodeLRA);
2797
  AddInstTable(InstTable, "PLOCK", 0, DecodePLOCK);
2798
  AddInstTable(InstTable, "PLOCKR", 0x00000e, DecodePLOCKR_PUNLOCKR);
2799
  AddInstTable(InstTable, "PUNLOCKR", 0x00000f, DecodePLOCKR_PUNLOCKR);
2800
  AddInstTable(InstTable, "JMP", 0, DecodeJMP_JSR);
2801
  AddInstTable(InstTable, "JSR", 1, DecodeJMP_JSR);
2802
  AddInstTable(InstTable, "DO", 0, DecodeDO_DOR);
2803
  AddInstTable(InstTable, "DOR", 1, DecodeDO_DOR);
2804
  AddInstTable(InstTable, "REP", 0, DecodeREP);
2805
 
2806
  InstrZ = 0;
2807
  AddFixed("NOP"    , 0x000000, CPU56000);
2808
  AddFixed("ENDDO"  , 0x00008c, CPU56000);
2809
  AddFixed("ILLEGAL", 0x000005, CPU56000);
2810
  AddFixed("RESET"  , 0x000084, CPU56000);
2811
  AddFixed("RTI"    , 0x000004, CPU56000);
2812
  AddFixed("RTS"    , 0x00000c, CPU56000);
2813
  AddFixed("STOP"   , 0x000087, CPU56000);
2814
  AddFixed("SWI"    , 0x000006, CPU56000);
2815
  AddFixed("WAIT"   , 0x000086, CPU56000);
2816
  AddFixed("DEBUG"  , 0x000200, CPU56300);
2817
  AddFixed("PFLUSH" , 0x000003, CPU56300);
2818
  AddFixed("PFLUSHUN",0x000001, CPU56300);
2819
  AddFixed("PFREE"  , 0x000002, CPU56300);
2820
  AddFixed("TRAP"   , 0x000006, CPU56300);
2821
 
2822
  InstrZ = 0;
2823
  AddPar("ABS" , ParAB,     0x26);
2824
  AddPar("ASL" , ParABShl1, 0x32);
2825
  AddPar("ASR" , ParABShl1, 0x22);
2826
  AddPar("CLR" , ParAB,     0x13);
2827
  AddPar("LSL" , ParABShl2, 0x33);
2828
  AddPar("LSR" , ParABShl2, 0x23);
2829
  AddPar("NEG" , ParAB,     0x36);
2830
  AddPar("NOT" , ParAB,     0x17);
2831
  AddPar("RND" , ParAB,     0x11);
2832
  AddPar("ROL" , ParAB,     0x37);
2833
  AddPar("ROR" , ParAB,     0x27);
2834
  AddPar("TST" , ParAB,     0x03);
2835
  AddPar("ADC" , ParXYAB,   0x21);
2836
  AddPar("SBC" , ParXYAB,   0x25);
2837
  AddPar("ADD" , ParABXYnAB,0x00);
2838
  AddPar("CMP" , ParABXYnAB,0x05);
2839
  AddPar("CMPM", ParABXYnAB,0x07);
2840
  AddPar("SUB" , ParABXYnAB,0x04);
2841
  AddPar("ADDL", ParABBA,   0x12);
2842
  AddPar("ADDR", ParABBA,   0x02);
2843
  AddPar("SUBL", ParABBA,   0x16);
2844
  AddPar("SUBR", ParABBA,   0x06);
2845
  AddPar("AND" , ParXYnAB,  0x46);
2846
  AddPar("EOR" , ParXYnAB,  0x43);
2847
  AddPar("OR"  , ParXYnAB,  0x42);
2848
  AddPar("MAC" , ParMul,    0x82);
2849
  AddPar("MACR", ParMul,    0x83);
2850
  AddPar("MPY" , ParMul,    0x80);
2851
  AddPar("MPYR", ParMul,    0x81);
2852
  AddPar("MAX" , ParFixAB,  0x1d);
2853
  AddPar("MAXM", ParFixAB,  0x15);
2854
 
2855
  InstrZ = 0;
2856
  AddInstTable(InstTable, "MPYI", InstrZ++, DecodeImmMac);
2857
  AddInstTable(InstTable, "MPYRI", InstrZ++, DecodeImmMac);
2858
  AddInstTable(InstTable, "MACI", InstrZ++, DecodeImmMac);
2859
  AddInstTable(InstTable, "MACRI", InstrZ++, DecodeImmMac);
2860
 
2861
  InstrZ = 0;
2862
  AddInstTable(InstTable, "BCLR", InstrZ++, DecodeBit);
2863
  AddInstTable(InstTable, "BSET", InstrZ++, DecodeBit);
2864
  AddInstTable(InstTable, "BCHG", InstrZ++, DecodeBit);
2865
  AddInstTable(InstTable, "BTST", InstrZ++, DecodeBit);
2866
 
2867
  InstrZ = 0;
2868
  AddInstTable(InstTable, "BRCLR", InstrZ++, DecodeBitBr);
2869
  AddInstTable(InstTable, "BRSET", InstrZ++, DecodeBitBr);
2870
  AddInstTable(InstTable, "BSCLR", InstrZ++, DecodeBitBr);
2871
  AddInstTable(InstTable, "BSSET", InstrZ++, DecodeBitBr);
2872
 
2873
  InstrZ = 0;
2874
  AddInstTable(InstTable, "JCLR", InstrZ++, DecodeBitJmp);
2875
  AddInstTable(InstTable, "JSET", InstrZ++, DecodeBitJmp);
2876
  AddInstTable(InstTable, "JSCLR", InstrZ++, DecodeBitJmp);
2877
  AddInstTable(InstTable, "JSSET", InstrZ++, DecodeBitJmp);
2878
 
2879
  AddMix("DMAC", 0, DecodeDMAC, 7);
2880
  AddMix("MAC", 0xff00, DecodeMAC_MPY, 6);
2881
  AddMix("MPY", 0, DecodeMAC_MPY, 6);
2882
 
2883
  AddCondition("T", DecodeTcc);
2884
  AddCondition("B", DecodeBcc);
2885
  AddCondition("BS", DecodeBScc);
2886
  AddCondition("J", DecodeJcc);
2887
  AddCondition("JS", DecodeJScc);
2888
  AddCondition("BRK", DecodeBRKcc);
2889
  AddCondition("TRAP", DecodeTRAPcc);
2890
  AddCondition("DEBUG", DecodeDEBUGcc);
2891
 
2892
  AddInstTable(InstTable, "XSFR", SegXData, DecodeSFR);
2893
  AddInstTable(InstTable, "YSFR", SegYData, DecodeSFR);
2894
  AddInstTable(InstTable, "DS", 0, DecodeDS);
2895
  AddInstTable(InstTable, "DC", 0, DecodeDC);
2896
 
2897
  StrCompAlloc(&LeftComp, STRINGSIZE);
2898
  StrCompAlloc(&MidComp, STRINGSIZE);
2899
  StrCompAlloc(&RightComp, STRINGSIZE);
2900
  StrCompAlloc(&Left1Comp, STRINGSIZE);
2901
  StrCompAlloc(&Left2Comp, STRINGSIZE);
2902
  StrCompAlloc(&Right1Comp, STRINGSIZE);
2903
  StrCompAlloc(&Right2Comp, STRINGSIZE);
2904
}
2905
 
2906
static void DeinitFields(void)
2907
{
2908
  DestroyInstTable(InstTable);
2909
  order_array_free(FixedOrders);
2910
  order_array_free(ParOrders);
2911
 
2912
  StrCompFree(&LeftComp);
2913
  StrCompFree(&MidComp);
2914
  StrCompFree(&RightComp);
2915
  StrCompFree(&Left1Comp);
2916
  StrCompFree(&Left2Comp);
2917
  StrCompFree(&Right1Comp);
2918
  StrCompFree(&Right2Comp);
2919
}
2920
 
2921
static void MakeCode_56K(void)
2922
{
2923
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
2924
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2925
}
2926
 
2927
static Boolean IsDef_56K(void)
2928
{
2929
  return ((Memo("XSFR")) || (Memo("YSFR")));
2930
}
2931
 
2932
static void SwitchFrom_56K(void)
2933
{
2934
  DeinitFields();
2935
}
2936
 
2937
static void SwitchTo_56K(void)
2938
{
2939
  TurnWords = True;
2940
  SetIntConstMode(eIntConstModeMoto);
2941
 
2942
  PCSymbol = "*";
2943
  HeaderID = 0x09;
2944
  NOPCode = 0x000000;
2945
  DivideChars = " \t";
2946
  HasAttrs = False;
2947
 
2948
  if (MomCPU == CPU56300)
2949
  {
2950
    AdrInt = UInt24;
2951
    MemLimit = 0xffffffl;
2952
  }
2953
  else
2954
  {
2955
    AdrInt = UInt16;
2956
    MemLimit = 0xffff;
2957
  }
2958
 
2959
  ValidSegs = (1 << SegCode) | (1 << SegXData) | (1 << SegYData);
2960
  Grans[SegCode ] = 4; ListGrans[SegCode ] = 4; SegInits[SegCode ] = 0;
2961
  SegLimits[SegCode ]  =  MemLimit;
2962
  Grans[SegXData] = 4; ListGrans[SegXData] = 4; SegInits[SegXData] = 0;
2963
  SegLimits[SegXData]  =  MemLimit;
2964
  Grans[SegYData] = 4; ListGrans[SegYData] = 4; SegInits[SegYData] = 0;
2965
  SegLimits[SegYData] = MemLimit;
2966
 
2967
  onoff_packing_add(True);
2968
 
2969
  MakeCode = MakeCode_56K;
2970
  IsDef = IsDef_56K;
2971
  SwitchFrom = SwitchFrom_56K;
2972
  InitFields();
2973
}
2974
 
2975
void code56k_init(void)
2976
{
2977
  CPU56000 = AddCPU("56000", SwitchTo_56K);
2978
  CPU56002 = AddCPU("56002", SwitchTo_56K);
2979
  CPU56300 = AddCPU("56300", SwitchTo_56K);
2980
}