Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* codez8000.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS-Portierung                                                             */
6
/*                                                                           */
7
/* Codegenerator Zilog Z8000                                                 */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
#include "stdinc.h"
12
#include <string.h>
13
#include <stdarg.h>
14
#include <ctype.h>
15
 
16
#include "cpulist.h"
17
#include "headids.h"
18
#include "strutil.h"
19
#include "intformat.h"
20
#include "bpemu.h"
21
#include "asmdef.h"
22
#include "asmsub.h"
23
#include "asmpars.h"
24
#include "asmallg.h"
25
#include "onoff_common.h"
26
#include "asmitree.h"
27
#include "asmstructs.h"
28
#include "codepseudo.h"
29
#include "codevars.h"
30
#include "intpseudo.h"
31
#include "operator.h"
32
 
33
#include "codez8000.h"
34
 
35
typedef enum
36
{
37
  eCoreNone = 0,
38
  eCoreZ8001 = 1,
39
  eCoreZ8003 = 2
40
} tCore;
41
 
42
typedef struct
43
{
44
  const char *pName;
45
  tCore Core;
46
  Boolean SuppSegmented;
47
} tCPUProps;
48
 
49
typedef enum eAdrMode
50
{
51
  eModNone = 0,
52
  eModReg = 1,
53
  eModIReg = 2,
54
  eModDirect = 3,
55
  eModIndexed = 4,
56
  eModBaseAddress = 5,
57
  eModBaseIndexed = 6,
58
  eModImm = 7,
59
  eModCtl = 8
60
} tAdrMode;
61
 
62
#define MModReg (1 << eModReg)
63
#define MModIReg (1 << eModIReg)
64
#define MModDirect (1 << eModDirect)
65
#define MModIndexed (1 << eModIndexed)
66
#define MModBaseAddress (1 << eModBaseAddress)
67
#define MModBaseIndexed (1 << eModBaseIndexed)
68
#define MModImm (1 << eModImm)
69
#define MModCtl (1 << eModCtl)
70
 
71
#define MModIO (1 << 15)
72
 
73
#define MModNoImm (MModReg | MModIReg | MModDirect | MModIndexed | MModBaseAddress | MModBaseIndexed)
74
#define MModAll (MModNoImm | MModImm)
75
 
76
#define eSymbolSize4Bit ((tSymbolSize)-2)
77
#define eSymbolSize3Bit ((tSymbolSize)-3)
78
 
79
typedef struct
80
{
81
  tAdrMode Mode;
82
  unsigned Cnt;
83
  Word Val, Vals[3];
84
} tAdrVals;
85
 
86
typedef struct
87
{
88
  Word Code;
89
  Boolean Privileged;
90
} FixedOrder;
91
 
92
typedef enum
93
{
94
  ePrivileged = 1 << 0,
95
  eSegMode = 1 << 1,
96
  eNonSegMode = 1 << 2
97
} tCtlFlags;
98
 
99
typedef struct
100
{
101
  const char *pName;
102
  Word Code;
103
  tCtlFlags Flags;
104
  tSymbolSize Size;
105
} tCtlReg;
106
 
107
typedef struct
108
{
109
  const char *pName;
110
  Word Code;
111
} tCondition;
112
 
113
/* Auto-optimization of LD #imm4,Rn -> LDK disabled for the moment,
114
   until we find a syntax to control it: */
115
 
116
#define OPT_LD_LDK 0
117
 
118
static const tCPUProps *pCurrCPUProps;
119
 
120
static FixedOrder *FixedOrders;
121
static tCtlReg *CtlRegs;
122
static tCondition *Conditions;
123
static int CtlRegCnt;
124
 
125
static tSymbolSize OpSize;
126
static ShortInt ImmOpSize;
127
static IntType MemIntType;
128
 
129
static LongInt AMDSyntax;
130
 
131
#ifdef __cplusplus
132
#include "codez8000.hpp"
133
#endif
134
 
135
/*--------------------------------------------------------------------------*/
136
/* Helper Functions */
137
 
138
/*!------------------------------------------------------------------------
139
 * \fn     CheckSup(Boolean Required)
140
 * \brief  check whether supervisor mode requirement and complain if violated
141
 * \param  Required is supervisor mode required?
142
 * \return False if violated
143
 * ------------------------------------------------------------------------ */
144
 
145
static Boolean CheckSup(Boolean Required)
146
{
147
  if (!SupAllowed && Required)
148
  {
149
    WrStrErrorPos(ErrNum_PrivOrder, &OpPart);
150
    return False;
151
  }
152
  return True;
153
}
154
 
155
/*!------------------------------------------------------------------------
156
 * \fn     Segmented(void)
157
 * \brief  operating in segmented mode?
158
 * \return True if yes
159
 * ------------------------------------------------------------------------ */
160
 
161
static Boolean Segmented(void)
162
{
163
  return pCurrCPUProps->SuppSegmented;
164
}
165
 
166
/*!------------------------------------------------------------------------
167
 * \fn     AddrRegSize(void)
168
 * \brief  return size of address register
169
 * \return 16 or 32 bit
170
 * ------------------------------------------------------------------------ */
171
 
172
static tSymbolSize AddrRegSize(void)
173
{
174
  return Segmented() ? eSymbolSize32Bit : eSymbolSize16Bit;
175
}
176
 
177
/*!------------------------------------------------------------------------
178
 * \fn     GetSegment(LongWord Address)
179
 * \brief  extract segment from (linear) address
180
 * \param  Address (linear) address
181
 * \return segment
182
 * ------------------------------------------------------------------------ */
183
 
184
static Word GetSegment(LongWord Address)
185
{
186
 return (Address >> 16) & 0x7f;
187
}
188
 
189
/*--------------------------------------------------------------------------*/
190
/* Register Handling */
191
 
192
/*!------------------------------------------------------------------------
193
 * \fn     DecodeRegCore(const char *pArg, Word *pValue, tSymbolSize *pSize)
194
 * \brief  check whether argument describes a CPU (general purpose) register
195
 * \param  pArg source argument
196
 * \param  pValue register number if yes
197
 * \param  pSize register size if yes
198
 * \return True if it is
199
 * ------------------------------------------------------------------------ */
200
 
201
static Boolean DecodeRegCore(const char *pArg, Word *pValue, tSymbolSize *pSize)
202
{
203
  Word Offset = 0, MaskVal, MaxVal;
204
 
205
  if (as_toupper(*pArg) != 'R')
206
    return False;
207
  pArg++;
208
 
209
  switch (as_toupper(*pArg))
210
  {
211
    case 'H':
212
      *pSize = eSymbolSize8Bit;
213
      MaskVal = 0; MaxVal = 7;
214
      pArg++;
215
      goto Num;
216
    case 'L':
217
      *pSize = eSymbolSize8Bit;
218
      Offset = 8;
219
      MaskVal = 0; MaxVal = 15;
220
      pArg++;
221
      goto Num;
222
    case 'R':
223
      *pSize = eSymbolSize32Bit;
224
      MaskVal = 1; MaxVal = 15;
225
      pArg++;
226
      goto Num;
227
    case 'Q':
228
      *pSize = eSymbolSize64Bit;
229
      MaskVal = 3; MaxVal = 15;
230
      pArg++;
231
      goto Num;
232
    default:
233
      *pSize = eSymbolSize16Bit;
234
      MaskVal = 0; MaxVal = 15;
235
      /* fall-thru */
236
    Num:
237
    {
238
      char *pEnd;
239
 
240
      *pValue = strtoul(pArg, &pEnd, 10) + Offset;
241
      return !*pEnd && (*pValue <= MaxVal) && !(*pValue & MaskVal);
242
    }
243
  }
244
}
245
 
246
/*!------------------------------------------------------------------------
247
 * \fn     DissectReg_Z8000(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
248
 * \brief  dissect register symbols - Z8000 variant
249
 * \param  pDest destination buffer
250
 * \param  DestSize destination buffer size
251
 * \param  Value numeric register value
252
 * \param  InpSize register size
253
 * ------------------------------------------------------------------------ */
254
 
255
static void DissectReg_Z8000(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
256
{
257
  switch (InpSize)
258
  {
259
    case eSymbolSize8Bit:
260
      as_snprintf(pDest, DestSize, "R%c%u", "HL"[(Value >> 3) & 1], (unsigned)(Value & 7));
261
      break;
262
    case eSymbolSize16Bit:
263
      as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
264
      break;
265
    case eSymbolSize32Bit:
266
      as_snprintf(pDest, DestSize, "RR%u", (unsigned)Value);
267
      break;
268
    case eSymbolSize64Bit:
269
      as_snprintf(pDest, DestSize, "RQ%u", (unsigned)Value);
270
      break;
271
    default:
272
      as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
273
  }
274
}
275
 
276
/*!------------------------------------------------------------------------
277
 * \fn     ChkRegOverlap(Word FirstReg, int FirstSize, ...)
278
 * \brief  check for register overlap
279
 * \param  FirstReg first register #
280
 * \param  FirstSize first register size
281
 * \param  ... further num/size pairs
282
 * \return -1 if no overlap, otherwise index of first conflicting register
283
 * ------------------------------------------------------------------------ */
284
 
285
static int ChkRegOverlap(Word FirstReg, int FirstSize, ...)
286
{
287
  LongWord RegUse = 0, ThisUse;
288
  int Index = 0;
289
  va_list ap;
290
 
291
  va_start(ap, FirstSize);
292
  while (True)
293
  {
294
    switch (FirstSize)
295
    {
296
      case eSymbolSize8Bit:
297
        ThisUse = ((FirstReg & 8) ? 2ul : 1ul) << ((FirstReg & 7) * 2);
298
        break;
299
      case eSymbolSize16Bit:
300
        ThisUse = 3ul << (FirstReg * 2);
301
        break;
302
      case eSymbolSize32Bit:
303
        ThisUse = 15ul << (FirstReg * 2);
304
        break;
305
      default:
306
        va_end(ap);
307
        return Index;
308
    }
309
    if (RegUse & ThisUse)
310
    {
311
      va_end(ap);
312
      return Index;
313
    }
314
    RegUse |= ThisUse;
315
    Index++;
316
    FirstReg = va_arg(ap, unsigned);
317
    FirstSize = va_arg(ap, int);
318
    if (FirstSize == eSymbolSizeUnknown)
319
      break;
320
  }
321
  va_end(ap);
322
  return -1;
323
}
324
 
325
/*--------------------------------------------------------------------------*/
326
/* Address Parsing */
327
 
328
/*!------------------------------------------------------------------------
329
 * \fn     DecodeReg(const tStrComp *pArg, Word *pValue, tSymbolSize *pSize, tChkRegSize ChkRegSize, Boolean MustBeReg)
330
 * \brief  check whether argument is a CPU register or user-defined register alias
331
 * \param  pArg argument
332
 * \param  pValue resulting register # if yes
333
 * \param  pSize resulting register size if yes
334
 * \param  ChkReqSize optional check callback for register size
335
 * \param  MustBeReg expecting register or maybe not?
336
 * \return reg eval result
337
 * ------------------------------------------------------------------------ */
338
 
339
typedef Boolean (*tChkRegSize)(const tStrComp *pArg, tSymbolSize ActSize);
340
 
341
static Boolean ChkRegSize_Idx(const tStrComp *pArg, tSymbolSize ActSize)
342
{
343
  if (ActSize != eSymbolSize16Bit)
344
  {
345
    WrStrErrorPos(ErrNum_IndexRegMustBe16Bit, pArg);
346
    return False;
347
  }
348
  return True;
349
}
350
 
351
static Boolean ChkRegSize_8To32(const tStrComp *pArg, tSymbolSize ActSize)
352
{
353
  if (ActSize > eSymbolSize32Bit)
354
  {
355
    WrStrErrorPos(ErrNum_InvOpSize, pArg);
356
    return False;
357
  }
358
  return True;
359
}
360
 
361
static Boolean ChkRegSize_IOAddr(const tStrComp *pArg, tSymbolSize ActSize)
362
{
363
  if (ActSize != eSymbolSize16Bit)
364
  {
365
    WrStrErrorPos(ErrNum_IOAddrRegMustBe16Bit, pArg);
366
    return False;
367
  }
368
  return True;
369
}
370
 
371
static Boolean ChkRegSize_MemAddr(const tStrComp *pArg, tSymbolSize ActSize)
372
{
373
  if (Segmented())
374
  {
375
    if (ActSize != eSymbolSize32Bit)
376
    {
377
      WrStrErrorPos(ErrNum_SegAddrRegMustBe32Bit, pArg);
378
      return False;
379
    }
380
  }
381
  else
382
  {
383
    if (ActSize != eSymbolSize16Bit)
384
    {
385
      WrStrErrorPos(ErrNum_NonSegAddrRegMustBe16Bit, pArg);
386
      return False;
387
    }
388
  }
389
  return True;
390
}
391
 
392
static tRegEvalResult DecodeReg(const tStrComp *pArg, Word *pValue, tSymbolSize *pSize, tChkRegSize ChkRegSize, Boolean MustBeReg)
393
{
394
  tEvalResult EvalResult;
395
  tRegEvalResult RegEvalResult;
396
 
397
  if (DecodeRegCore(pArg->str.p_str, pValue, &EvalResult.DataSize))
398
    RegEvalResult = eIsReg;
399
  else
400
  {
401
    tRegDescr RegDescr;
402
 
403
    RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
404
    if (eIsReg == RegEvalResult)
405
      *pValue = RegDescr.Reg;
406
  }
407
 
408
  if ((RegEvalResult == eIsReg)
409
   && ChkRegSize
410
   && !ChkRegSize(pArg, EvalResult.DataSize))
411
    RegEvalResult = MustBeReg ? eIsNoReg : eRegAbort;
412
 
413
  if (pSize) *pSize = EvalResult.DataSize;
414
  return RegEvalResult;
415
}
416
 
417
/*!------------------------------------------------------------------------
418
 * \fn     ClearAdrVals(tAdrVals *pAdrVals)
419
 * \brief  clear address expression result buffer
420
 * \param  pAdrVals buffer to clear
421
 * ------------------------------------------------------------------------ */
422
 
423
static void ClearAdrVals(tAdrVals *pAdrVals)
424
{
425
  pAdrVals->Mode = eModNone;
426
  pAdrVals->Cnt = 0;
427
  pAdrVals->Val = 0;
428
}
429
 
430
/*!------------------------------------------------------------------------
431
 * \fn     SetOpSize(tSymbolSize Size, const tStrComp *pArg)
432
 * \brief  set (new) operand size of instruction
433
 * \param  Size size to set
434
 * \param  pArg source argument size was deduced from
435
 * \return True if no conflict
436
 * ------------------------------------------------------------------------ */
437
 
438
static Boolean SetOpSize(tSymbolSize Size, const tStrComp *pArg)
439
{
440
  if (OpSize == eSymbolSizeUnknown)
441
    OpSize = Size;
442
  else if ((Size != eSymbolSizeUnknown) && (Size != OpSize))
443
  {
444
    WrStrErrorPos(ErrNum_ConfOpSizes, pArg);
445
    return False;
446
  }
447
  return True;
448
}
449
 
450
/*!------------------------------------------------------------------------
451
 * \fn     GetImmIntType(tSymbolSize Size)
452
 * \brief  retrieve immediate int type fitting to operand size
453
 * \param  Size operand size
454
 * \return int type
455
 * ------------------------------------------------------------------------ */
456
 
457
static IntType GetImmIntType(tSymbolSize Size)
458
{
459
  switch ((int)Size)
460
  {
461
    case eSymbolSize3Bit:
462
      return UInt3;
463
    case eSymbolSize4Bit:
464
      return UInt4;
465
    case eSymbolSize8Bit:
466
      return Int8;
467
    case eSymbolSize16Bit:
468
      return Int16;
469
    case eSymbolSize32Bit:
470
      return Int32;
471
    default:
472
      return IntTypeCnt;
473
  }
474
}
475
 
476
/*!------------------------------------------------------------------------
477
 * \fn     DecodeAddrPartNum(const tStrComp *pArg, LongInt Disp, tEvalResult *pEvalResult, Boolean IsDirect, Boolean IsIO, Boolean *pForceShortt, Boolean *pIsDirect)
478
 * \brief  decode address part, for direct/immediate or indexed mode
479
 * \param  pArg source argument
480
 * \param  Disp displacement to add to value
481
 * \param  pAdrVals binary coding of addressing mode
482
 * \param  IsDirect force treatment as direct address mode
483
 * \param  IsIO I/O space instead of memory space
484
 * \param  pForceShort short coding required?
485
 * \param  pIsDirect classified as direct addressing?
486
 * \return True if success
487
 * ------------------------------------------------------------------------ */
488
 
489
typedef struct
490
{
491
  as_quoted_iterator_cb_data_t data;
492
  int nest;
493
  char *p_split_pos;
494
} split_cb_data_t;
495
 
496
static int split_cb(const char *p_pos, as_quoted_iterator_cb_data_t *p_cb_data)
497
{
498
  split_cb_data_t *p_data = (split_cb_data_t*)p_cb_data;
499
 
500
  switch (*p_pos)
501
  {
502
    case '(':
503
      p_data->nest++;
504
      break;
505
    case ')':
506
      p_data->nest--;
507
      break;
508
    case '>':
509
      if (!p_data->nest && (p_pos[1] == '>'))
510
        p_data->p_split_pos = (char*)p_pos;
511
      break;
512
    default:
513
      if (p_data->p_split_pos)
514
      {
515
        if (as_isspace(*p_pos)); /* delay decision to to next non-blank */
516
        else if (as_isalnum(*p_pos) || (*p_pos == '('))
517
          return -1; /* found */
518
        else
519
          p_data->p_split_pos = NULL;
520
      }
521
      break;
522
  }
523
  return 0;
524
}
525
 
526
static LongWord DecodeAddrPartNum(const tStrComp *pArg, LongInt Disp, tEvalResult *pEvalResult, Boolean IsDirect, Boolean IsIO, Boolean *pForceShort, Boolean *pIsDirect)
527
{
528
  tStrComp CopyComp;
529
  String Copy;
530
  Boolean HasSeg = False;
531
  LongWord Result, SegNum = 0;
532
  IntType ThisIntType;
533
 
534
  StrCompMkTemp(&CopyComp, Copy, sizeof(Copy));
535
  StrCompCopy(&CopyComp, pArg);
536
  *pForceShort = False;
537
 
538
  /* deal with |....| and <<seg>>offs only in segmented mode: */
539
 
540
  if (!IsIO && Segmented())
541
  {
542
    int Len = strlen(CopyComp.str.p_str);
543
 
544
    if ((Len >= 2) && (CopyComp.str.p_str[0] == '|') && (CopyComp.str.p_str[Len - 1] == '|'))
545
    {
546
      StrCompShorten(&CopyComp, 1);
547
      StrCompCutLeft(&CopyComp, 1);
548
      KillPrefBlanksStrComp(&CopyComp);
549
      KillPostBlanksStrComp(&CopyComp);
550
      *pForceShort = True;
551
      IsDirect = True;
552
      Len -= 2;
553
    }
554
    if (!strncmp(CopyComp.str.p_str, "<<", 2))
555
    {
556
      split_cb_data_t split_data;
557
 
558
      split_data.data.callback_before = False;
559
      split_data.data.qualify_quote = QualifyQuote;
560
      split_data.p_split_pos = NULL;
561
      split_data.nest = 0;
562
 
563
      as_iterate_str_quoted(CopyComp.str.p_str + 2, split_cb, &split_data.data);
564
 
565
      if (split_data.p_split_pos)
566
      {
567
        tStrComp SegArg;
568
 
569
        StrCompSplitRef(&SegArg, &CopyComp, &CopyComp, split_data.p_split_pos);
570
        StrCompIncRefLeft(&CopyComp, 1);
571
        SegNum = EvalStrIntExpressionOffsWithResult(&SegArg, 2, UInt7, pEvalResult);
572
        if (!pEvalResult->OK)
573
          return 0;
574
        HasSeg = True;
575
        IsDirect = True;
576
      }
577
    }
578
  }
579
 
580
  /* If we know it's direct, right away limit to the correct address range.  Otherwise, it might
581
     be immediate up to 32 bits: */
582
 
583
  if (IsDirect)
584
    ThisIntType = (IsIO || HasSeg) ? UInt16 : MemIntType;
585
  else
586
    ThisIntType = Int32;
587
  Result = EvalStrIntExpressionWithResult(&CopyComp, ThisIntType, pEvalResult) + Disp;
588
 
589
  /* For AMD syntax, treat as direct if no untyped constant */
590
 
591
  if (AMDSyntax && !IsDirect && pEvalResult->AddrSpaceMask)
592
    IsDirect = True;
593
 
594
  /* for forwards, truncate to allowed range */
595
 
596
  if (IsDirect)
597
    ThisIntType = (IsIO || HasSeg) ? UInt16 : MemIntType;
598
  else
599
    ThisIntType = GetImmIntType(OpSize);
600
  if (mFirstPassUnknown(pEvalResult->Flags) && (ThisIntType < IntTypeCnt))
601
    Result &= IntTypeDefs[(int)ThisIntType].Mask;
602
 
603
  if (IsDirect)
604
  {
605
    Result |= (SegNum << 16);
606
    if (pEvalResult->OK
607
     && !mFirstPassUnknownOrQuestionable(pEvalResult->Flags)
608
     && *pForceShort
609
     && (Result & 0x00ff00ul))
610
    {
611
      WrStrErrorPos(ErrNum_NoShortAddr, pArg);
612
      pEvalResult->OK = False;
613
    }
614
  }
615
  if (pIsDirect)
616
    *pIsDirect = IsDirect;
617
  return Result;
618
}
619
 
620
/*!------------------------------------------------------------------------
621
 * \fn     FillAbsAddr(tAdrVals *pAdrVals, LongWord Address, Boolean IsDirect, Boolean IsIO, Boolean ForceShort, Boolean *pIsDirect)
622
 * \brief  pack absolute addess into instruction extension word(s)
623
 * \param  pAdrVals destination buffer
624
 * \param  Address address to pack
625
 * \param  IsDirect force treatment as direct address mode
626
 * \param  IsIO I/O (16b) or memory (23/16b) address?
627
 * \param  ForceShort force short encoding
628
 * \param  pIsDirect classified as direct addressing?
629
 * ------------------------------------------------------------------------ */
630
 
631
static void FillAbsAddr(tAdrVals *pAdrVals, LongWord Address, Boolean IsIO, Boolean ForceShort)
632
{
633
  Word Offset = Address & 0xffff;
634
 
635
  if (Segmented() && !IsIO)
636
  {
637
    pAdrVals->Vals[pAdrVals->Cnt++] = (Address >> 8) & 0x7f00;
638
    if ((Offset <= 0xff) && ForceShort)
639
      pAdrVals->Vals[pAdrVals->Cnt - 1] |= Offset;
640
    else
641
    {
642
      pAdrVals->Vals[pAdrVals->Cnt - 1] |= 0x8000;
643
      pAdrVals->Vals[pAdrVals->Cnt++] = Offset;
644
    }
645
  }
646
  else
647
    pAdrVals->Vals[pAdrVals->Cnt++] = Offset;
648
}
649
 
650
/*!------------------------------------------------------------------------
651
 * \fn     FillImmVal(tAdrVals *pAdrVals, LongWord Value, tSymbolSize OpSize)
652
 * \brief  fill address values from immediate value
653
 * \param  pAdrVals dest buffer
654
 * \param  Value value to fill in
655
 * \param  OpSize used operand size
656
 * ------------------------------------------------------------------------ */
657
 
658
static void FillImmVal(tAdrVals *pAdrVals, LongWord Value, tSymbolSize OpSize)
659
{
660
  switch ((int)OpSize)
661
  {
662
    case eSymbolSize3Bit:
663
      pAdrVals->Val = Value & 7;
664
      break;
665
    case eSymbolSize4Bit:
666
      pAdrVals->Val = Value & 15;
667
      break;
668
    case eSymbolSize8Bit:
669
      pAdrVals->Vals[pAdrVals->Cnt++] = (Value & 0xff) | ((Value & 0xff) << 8);
670
      break;
671
    case eSymbolSize16Bit:
672
      pAdrVals->Vals[pAdrVals->Cnt++] = Value & 0xffff;
673
      break;
674
    case eSymbolSize32Bit:
675
      pAdrVals->Vals[pAdrVals->Cnt++] = (Value >> 16) & 0xffff;
676
      pAdrVals->Vals[pAdrVals->Cnt++] = Value & 0xffff;
677
      break;
678
    default:
679
      break;
680
  }
681
}
682
 
683
/*!------------------------------------------------------------------------
684
 * \fn     DecodeAddrPart(const tStrComp *pArg, LongInt Disp, tAdrVals *pAdrVals, Boolean IsDirect, Boolean IsIO, Boolean *pIsDirect)
685
 * \brief  decode address part, for direct/immediate or indexed mode
686
 * \param  pArg source argument
687
 * \param  Disp displacement to add to value
688
 * \param  pAdrVals binary coding of addressing mode
689
 * \param  IsDirect force treatment as direct address mode
690
 * \param  IsIO I/O space instead of memory space
691
 * \param  pIsDirect classified as direct addressing?
692
 * \return True if success
693
 * ------------------------------------------------------------------------ */
694
 
695
static Boolean DecodeAddrPart(const tStrComp *pArg, LongInt Disp, tAdrVals *pAdrVals, Boolean IsDirect, Boolean IsIO, Boolean *pIsDirect)
696
{
697
  LongWord Address;
698
  tEvalResult EvalResult;
699
  Boolean ForceLong;
700
 
701
  Address = DecodeAddrPartNum(pArg, Disp, &EvalResult, IsDirect, IsIO, &ForceLong, pIsDirect);
702
  if (EvalResult.OK)
703
  {
704
    ChkSpace(IsIO ? SegIO : SegCode, EvalResult.AddrSpaceMask);
705
    if (!pIsDirect || *pIsDirect)
706
      FillAbsAddr(pAdrVals, Address, IsIO, ForceLong);
707
    else
708
      FillImmVal(pAdrVals, Address, OpSize);
709
    return True;
710
  }
711
  else
712
    return False;
713
}
714
 
715
/*!------------------------------------------------------------------------
716
 * \fn     DecodeAdr(const tStrComp *pArg, unsigned ModeMask, tAdrVals *pAdrVals)
717
 * \brief  decode address expression
718
 * \param  pArg source argument
719
 * \param  ModeMask bit mask of allowed addressing modes
720
 * \param  pAdrVals binary coding of addressing mode
721
 * \return decoded mode
722
 * ------------------------------------------------------------------------ */
723
 
724
/* This is necessary to find the split position when a short address is used as
725
   base, i.e. |addr|(rn).  | is also the OR operator, and I don't want to get
726
   false positives on other targets on stuff like (...)|(...): */
727
 
728
static int ShortQualifier(const char *pArg, int NextNonBlankPos, int SplitPos)
729
{
730
  int FirstNonBlankPos;
731
 
732
  for (FirstNonBlankPos = 0; FirstNonBlankPos < NextNonBlankPos; FirstNonBlankPos++)
733
    if (!as_isspace(pArg[FirstNonBlankPos]))
734
      break;
735
  return ((FirstNonBlankPos < NextNonBlankPos) && (pArg[FirstNonBlankPos] == '|') && (pArg[NextNonBlankPos] == '|')) ? SplitPos : -1;
736
}
737
 
738
static tAdrMode DecodeAdr(const tStrComp *pArg, unsigned ModeMask, tAdrVals *pAdrVals)
739
{
740
  tSymbolSize ArgSize;
741
  int ArgLen, SplitPos, z;
742
  Boolean IsIO = !!(ModeMask & MModIO);
743
  tChkRegSize ChkRegSize_Addr = IsIO ? ChkRegSize_IOAddr : ChkRegSize_MemAddr, ChkRegSizeForIOIndir;
744
  Boolean IsDirect;
745
 
746
  ClearAdrVals(pAdrVals);
747
 
748
  /* immediate */
749
 
750
  if (*pArg->str.p_str == '#')
751
  {
752
    LongWord Result;
753
    Boolean OK;
754
 
755
    if (ImmOpSize == eSymbolSizeUnknown)
756
      ImmOpSize = OpSize;
757
    switch (ImmOpSize)
758
    {
759
      case eSymbolSize3Bit:
760
        pAdrVals->Val = EvalStrIntExpressionOffs(pArg, 1, UInt3, &OK);
761
        break;
762
      case eSymbolSize4Bit:
763
        pAdrVals->Val = EvalStrIntExpressionOffs(pArg, 1, UInt4, &OK);
764
        break;
765
      case eSymbolSize8Bit:
766
        Result = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
767
        if (OK)
768
          pAdrVals->Vals[pAdrVals->Cnt++] = (Result & 0xff) | ((Result & 0xff) << 8);
769
        break;
770
      case eSymbolSize16Bit:
771
        Result = EvalStrIntExpressionOffs(pArg, 1, Int16, &OK);
772
        if (OK)
773
          pAdrVals->Vals[pAdrVals->Cnt++] = Result & 0xffff;
774
        break;
775
      case eSymbolSize32Bit:
776
        Result = EvalStrIntExpressionOffs(pArg, 1, Int32, &OK);
777
        if (OK)
778
        {
779
          pAdrVals->Vals[pAdrVals->Cnt++] = (Result >> 16) & 0xffff;
780
          pAdrVals->Vals[pAdrVals->Cnt++] = Result & 0xffff;
781
        }
782
        break;
783
      default:
784
        WrStrErrorPos(ErrNum_UndefOpSizes, pArg);
785
        return pAdrVals->Mode;
786
    }
787
    if (OK)
788
    {
789
      /* Immediate: is the same coding as indirect, however with register field = 0.
790
         This why register 0 is not allowed for indirect mode.
791
         As an exception, immediate value is placed in pAdrVals->Val for bit number: */
792
 
793
      pAdrVals->Mode = eModImm;
794
      if (OpSize == eSymbolSizeUnknown)
795
        OpSize = (tSymbolSize)ImmOpSize;
796
    }
797
    goto chk;
798
  }
799
 
800
  /* Register (R): For AMD syntax, Rn is equivalent to Rn^ resp. @Rn, if I/O ports
801
     are addressed indirectly: */
802
 
803
  ChkRegSizeForIOIndir = (AMDSyntax && !(ModeMask & MModReg) && (ModeMask & MModIReg) && IsIO) ? ChkRegSize_Addr : NULL;
804
  switch (DecodeReg(pArg, &pAdrVals->Val, &ArgSize, ChkRegSizeForIOIndir, False))
805
  {
806
    case eRegAbort:
807
      return pAdrVals->Mode;
808
    case eIsReg:
809
    {
810
      if (ChkRegSizeForIOIndir)
811
        pAdrVals->Mode = eModIReg;
812
      else
813
      {
814
        if (!SetOpSize(ArgSize, pArg))
815
          return pAdrVals->Mode;
816
        pAdrVals->Mode = eModReg;
817
      }
818
      goto chk;
819
    }
820
    default:
821
      break;
822
  }
823
 
824
  /* control register */
825
 
826
  for (z = 0; z < CtlRegCnt; z++)
827
    if (!as_strcasecmp(pArg->str.p_str, CtlRegs[z].pName))
828
    {
829
      if (!(CtlRegs[z].Flags & (Segmented() ? eSegMode : eNonSegMode)))
830
      {
831
        WrStrErrorPos(ErrNum_InvCtrlReg, pArg);
832
        return pAdrVals->Mode;
833
      }
834
      if (!SetOpSize(CtlRegs[z].Size, pArg))
835
        return pAdrVals->Mode;
836
      if (!CheckSup(!!(CtlRegs[z].Flags & ePrivileged)))
837
        return pAdrVals->Mode;
838
      pAdrVals->Val = CtlRegs[z].Code;
839
      pAdrVals->Mode = eModCtl;
840
      goto chk;
841
    }
842
 
843
  /* Register indirect (IR): */
844
 
845
  if (*pArg->str.p_str == '@')
846
  {
847
    tStrComp RegComp;
848
 
849
    StrCompRefRight(&RegComp, pArg, 1);
850
    if (eIsReg == DecodeReg(&RegComp, &pAdrVals->Val, &ArgSize, ChkRegSize_Addr, True))
851
    {
852
      if (!pAdrVals->Val) WrStrErrorPos(ErrNum_InvAddrMode, &RegComp);
853
      else
854
        pAdrVals->Mode = eModIReg;
855
    }
856
    goto chk;
857
  }
858
  if (AMDSyntax
859
   && ((ArgLen = strlen(pArg->str.p_str)) > 1)
860
   && (pArg->str.p_str[ArgLen - 1] == '^'))
861
  {
862
    String Reg;
863
    tStrComp RegComp;
864
 
865
    StrCompMkTemp(&RegComp, Reg, sizeof(Reg));
866
    StrCompCopySub(&RegComp, pArg, 0, ArgLen - 1);
867
    switch (DecodeReg(&RegComp, &pAdrVals->Val, &ArgSize, ChkRegSize_Addr, False))
868
    {
869
      case eRegAbort:
870
        return pAdrVals->Mode;
871
      case eIsReg:
872
        if (!pAdrVals->Val) WrStrErrorPos(ErrNum_InvAddrMode, &RegComp);
873
        else
874
          pAdrVals->Mode = eModIReg;
875
        goto chk;
876
      default:
877
        break;
878
    }
879
  }
880
 
881
  /* Indexed, base... */
882
 
883
  SplitPos = FindDispBaseSplitWithQualifier(pArg->str.p_str, &ArgLen, ShortQualifier, "()");
884
  if (SplitPos > 0)
885
  {
886
    String OutStr, InStr;
887
    tStrComp OutArg, InArg;
888
 
889
    /* copy out base + index components */
890
 
891
    StrCompMkTemp(&OutArg, OutStr, sizeof(OutStr));
892
    StrCompMkTemp(&InArg, InStr, sizeof(InStr));
893
    StrCompCopySub(&OutArg, pArg, 0, SplitPos);
894
    KillPostBlanksStrComp(&OutArg);
895
    StrCompCopySub(&InArg, pArg, SplitPos + 1, ArgLen - SplitPos - 2);
896
    switch (DecodeReg(&OutArg, &pAdrVals->Val, &ArgSize, ChkRegSize_Addr, False))
897
    {
898
      case eIsReg: /* [R]Rx(...) */
899
        if (!pAdrVals->Val) WrStrErrorPos(ErrNum_InvAddrMode, &OutArg);
900
        else if (*InArg.str.p_str == '#')
901
        {
902
          Boolean OK;
903
 
904
          pAdrVals->Vals[pAdrVals->Cnt++] = EvalStrIntExpressionOffs(&InArg, 1, Int16, &OK);
905
          if (OK)
906
            pAdrVals->Mode = eModBaseAddress;
907
        }
908
        else if (DecodeReg(&InArg, &pAdrVals->Vals[pAdrVals->Cnt], &ArgSize, ChkRegSize_Idx, True) == eIsReg)
909
        {
910
          pAdrVals->Vals[pAdrVals->Cnt] <<= 8;
911
          pAdrVals->Cnt++;
912
          pAdrVals->Mode = eModBaseIndexed;
913
        }
914
        goto chk;
915
      case eIsNoReg: /* abs(...) */
916
      {
917
        switch (DecodeReg(&InArg, &pAdrVals->Val, &ArgSize, ChkRegSize_Idx, False))
918
        {
919
          case eIsReg: /* abs(Rx) */
920
            if (DecodeAddrPart(&OutArg, 0, pAdrVals, True, IsIO, NULL))
921
              pAdrVals->Mode = eModIndexed;
922
            break;
923
          case eIsNoReg: /* abs/imm(delta) -> direct/imm*/
924
          {
925
            Boolean OK;
926
            LongInt Disp = EvalStrIntExpression(&InArg, Int16, &OK);
927
 
928
            if (OK && DecodeAddrPart(&OutArg, Disp, pAdrVals, !AMDSyntax || !(ModeMask & MModImm), IsIO, &IsDirect))
929
              goto DirectOrImmediate;
930
            break;
931
          }
932
          default:
933
            return pAdrVals->Mode;
934
        }
935
        goto chk;
936
      }
937
      case eRegAbort:
938
        return pAdrVals->Mode;
939
    }
940
  }
941
 
942
  /* Absolute: is the same coding as indexed, however with index register field = 0.
943
     This is why register 0 is not allowed for indexed mode. */
944
 
945
  if (DecodeAddrPart(pArg, 0, pAdrVals, !AMDSyntax || !(ModeMask & MModImm), IsIO, &IsDirect))
946
  {
947
DirectOrImmediate:
948
    if (IsDirect)
949
    {
950
      pAdrVals->Val = 0;
951
      pAdrVals->Mode = eModDirect;
952
    }
953
    else
954
      pAdrVals->Mode = eModImm;
955
  }
956
 
957
chk:
958
  if ((pAdrVals->Mode != eModNone) & !((ModeMask >> pAdrVals->Mode) & 1))
959
  {
960
    WrStrErrorPos(ErrNum_InvAddrMode, pArg);
961
    ClearAdrVals(pAdrVals);
962
  }
963
  return pAdrVals->Mode;
964
}
965
 
966
/*--------------------------------------------------------------------------*/
967
/* Bit Symbol Handling */
968
 
969
/*
970
 * Compact representation of bits in symbol table:
971
 * bits 0...2/3: bit position
972
 * bits 3/4...25/26: address in memory space (7+16 bits)
973
 * bit  28: operand size (0/1 for 8/16 bits)
974
 * bit  29: force short address in segmented mode
975
 */
976
 
977
/*!------------------------------------------------------------------------
978
 * \fn     AssembleBitSymbol(Byte BitPos, tSymbolSize OpSize, LongWord Address, Boolean ForceShort)
979
 * \brief  build the compact internal representation of a bit symbol
980
 * \param  BitPos bit position in word
981
 * \param  OpSize operand size (8/16)
982
 * \param  Address memory address
983
 * \param  ForceShort force short address in segmented mode
984
 * \return compact representation
985
 * ------------------------------------------------------------------------ */
986
 
987
static LongWord AssembleBitSymbol(Byte BitPos, tSymbolSize OpSize, LongWord Address, Boolean ForceShort)
988
{
989
  LongWord CodeOpSize = (OpSize == eSymbolSize16Bit) ? 1 : 0;
990
  int AddrShift = CodeOpSize + 3;
991
 
992
  return BitPos
993
       | ((Address & 0x7fffff) << AddrShift)
994
       | (CodeOpSize << 28)
995
       | ((!!ForceShort) << 29);
996
}
997
 
998
/*!------------------------------------------------------------------------
999
 * \fn     EvalBitPosition(const char *pBitArg, Boolean *pOK, ShortInt OpSize)
1000
 * \brief  evaluate constant bit position, with bit range depending on operand size
1001
 * \param  pBitArg bit position argument
1002
 * \param  pOK returns True if OK
1003
 * \param  OpSize operand size (0,1,2 -> 8,16,32 bits)
1004
 * \return bit position as number
1005
 * ------------------------------------------------------------------------ */
1006
 
1007
static Byte EvalBitPosition(const tStrComp *pBitArg, Boolean *pOK, tSymbolSize OpSize)
1008
{
1009
  IntType Type;
1010
 
1011
  switch (OpSize)
1012
  {
1013
    case eSymbolSize8Bit:
1014
      Type = UInt3;
1015
      goto common;
1016
    case eSymbolSize16Bit:
1017
      Type = UInt4;
1018
      goto common;
1019
    default:
1020
      WrStrErrorPos(ErrNum_InvOpSize, pBitArg);
1021
      *pOK = False;
1022
      return 0;
1023
    common:
1024
      return EvalStrIntExpressionOffs(pBitArg, !!(*pBitArg->str.p_str == '#'), Type, pOK);
1025
  }
1026
}
1027
 
1028
/*!------------------------------------------------------------------------
1029
 * \fn     DecodeBitArg2(LongWord *pResult, const tStrComp *pMemArg, const tStrComp *pBitArg, tSymbolSize OpSize)
1030
 * \brief  encode a bit symbol, address & bit position separated
1031
 * \param  pResult resulting encoded bit
1032
 * \param  pMemArg register argument
1033
 * \param  pBitArg bit argument
1034
 * \param  OpSize register size (0/1 = 8/16 bit)
1035
 * \return True if success
1036
 * ------------------------------------------------------------------------ */
1037
 
1038
static Boolean DecodeBitArg2(LongWord *pResult, const tStrComp *pMemArg, const tStrComp *pBitArg, tSymbolSize OpSize)
1039
{
1040
  tEvalResult EvalResult;
1041
  LongWord Addr;
1042
  Byte BitPos;
1043
  Boolean ForceShort;
1044
 
1045
  BitPos = EvalBitPosition(pBitArg, &EvalResult.OK, OpSize);
1046
  if (!EvalResult.OK)
1047
    return False;
1048
 
1049
  Addr = DecodeAddrPartNum(pMemArg, 0, &EvalResult, True, False, &ForceShort, NULL);
1050
  if (!EvalResult.OK)
1051
    return False;
1052
 
1053
  *pResult = AssembleBitSymbol(BitPos, OpSize, Addr, ForceShort);
1054
 
1055
  return True;
1056
}
1057
 
1058
/*!------------------------------------------------------------------------
1059
 * \fn     DecodeBitArg(LongWord *pResult, int Start, int Stop, tSymbolSize OpSize)
1060
 * \brief  encode a bit symbol from instruction argument(s)
1061
 * \param  pResult resulting encoded bit
1062
 * \param  Start first argument
1063
 * \param  Stop last argument
1064
 * \param  OpSize register size (0/1 = 8/16 bit)
1065
 * \return True if success
1066
 * ------------------------------------------------------------------------ */
1067
 
1068
static Boolean DecodeBitArg(LongWord *pResult, int Start, int Stop, tSymbolSize OpSize)
1069
{
1070
  *pResult = 0;
1071
 
1072
  /* Just one argument -> parse as bit argument */
1073
 
1074
  if (Start == Stop)
1075
  {
1076
    tEvalResult EvalResult;
1077
 
1078
    *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], UInt32, &EvalResult);
1079
    if (EvalResult.OK)
1080
      ChkSpace(SegBData, EvalResult.AddrSpaceMask);
1081
    return EvalResult.OK;
1082
  }
1083
 
1084
  /* register & bit position are given as separate arguments */
1085
 
1086
  else if (Stop == Start + 1)
1087
    return DecodeBitArg2(pResult, &ArgStr[Start], &ArgStr[Stop], OpSize);
1088
 
1089
  /* other # of arguments not allowed */
1090
 
1091
  else
1092
  {
1093
    WrError(ErrNum_WrongArgCnt);
1094
    return False;
1095
  }
1096
}
1097
 
1098
/*!------------------------------------------------------------------------
1099
 * \fn     DissectBitSymbol(LongWord BitSymbol, LongWord *pAddress, Byte *pBitPos, tSymbolSize *pOpSize, Boolean *pForceShort)
1100
 * \brief  transform compact represenation of bit symbol into components
1101
 * \param  BitSymbol compact storage
1102
 * \param  pAddress (I/O) register address
1103
 * \param  pBitPos (start) bit position
1104
 * \param  pOpSize returns register size (0/1 for 8/16 bits)
1105
 * \param  pForceShort returns force of short address in segmented mode
1106
 * \return constant True
1107
 * ------------------------------------------------------------------------ */
1108
 
1109
static Boolean DissectBitSymbol(LongWord BitSymbol, LongWord *pAddress, Byte *pBitPos, tSymbolSize *pOpSize, Boolean *pForceShort)
1110
{
1111
  *pForceShort = ((BitSymbol >> 29) & 1);
1112
  *pOpSize = (tSymbolSize)((BitSymbol >> 28) & 1);
1113
  switch (*pOpSize)
1114
  {
1115
    case eSymbolSize8Bit:
1116
      *pAddress = (BitSymbol >> 3) & 0x7ffffful;
1117
      *pBitPos = BitSymbol & 7;
1118
      break;
1119
    case eSymbolSize16Bit:
1120
      *pAddress = (BitSymbol >> 4) & 0x7ffffful;
1121
      *pBitPos = BitSymbol & 15;
1122
      break;
1123
    default:
1124
      break;
1125
  }
1126
  return True;
1127
}
1128
 
1129
/*!------------------------------------------------------------------------
1130
 * \fn     DissectBit_Z8000(char *pDest, size_t DestSize, LargeWord Inp)
1131
 * \brief  dissect compact storage of bit into readable form for listing
1132
 * \param  pDest destination for ASCII representation
1133
 * \param  DestSize destination buffer size
1134
 * \param  Inp compact storage
1135
 * ------------------------------------------------------------------------ */
1136
 
1137
static void DissectBit_Z8000(char *pDest, size_t DestSize, LargeWord Inp)
1138
{
1139
  Byte BitPos;
1140
  LongWord Address;
1141
  tSymbolSize OpSize;
1142
  Boolean ForceShort;
1143
  char Attribute;
1144
 
1145
  DissectBitSymbol(Inp, &Address, &BitPos, &OpSize, &ForceShort);
1146
  Attribute = "bw"[OpSize];
1147
  if (HexStartCharacter == 'A')
1148
    Attribute = as_toupper(Attribute);
1149
  as_snprintf(pDest, DestSize, "%s%~.*u%s%s(%c).%u",
1150
              ForceShort ? "|" : "",
1151
              ListRadixBase, (unsigned)Address, GetIntConstIntelSuffix(ListRadixBase),
1152
              ForceShort ? "|" : "",
1153
              Attribute, (unsigned)BitPos);
1154
}
1155
 
1156
/*!------------------------------------------------------------------------
1157
 * \fn     ExpandZ8000Bit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
1158
 * \brief  expands bit definition when a structure is instantiated
1159
 * \param  pVarName desired symbol name
1160
 * \param  pStructElem element definition
1161
 * \param  Base base address of instantiated structure
1162
 * ------------------------------------------------------------------------ */
1163
 
1164
static void ExpandZ8000Bit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
1165
{
1166
  LongWord Address = Base + pStructElem->Offset;
1167
 
1168
  if (pInnermostNamedStruct)
1169
  {
1170
    PStructElem pElem = CloneStructElem(pVarName, pStructElem);
1171
 
1172
    if (!pElem)
1173
      return;
1174
    pElem->Offset = Address;
1175
    AddStructElem(pInnermostNamedStruct->StructRec, pElem);
1176
  }
1177
  else
1178
  {
1179
    tSymbolSize OpSize = (pStructElem->OpSize == eSymbolSizeUnknown) ? eSymbolSize8Bit : pStructElem->OpSize;
1180
 
1181
    if (!ChkRange(Address, 0, 0x7fffff)
1182
     || !ChkRange(pStructElem->BitPos, 0, (8 << OpSize) - 1))
1183
      return;
1184
 
1185
    PushLocHandle(-1);
1186
    EnterIntSymbol(pVarName, AssembleBitSymbol(pStructElem->BitPos, OpSize, Address, False), SegBData, False);
1187
    PopLocHandle();
1188
    /* TODO: MakeUseList? */
1189
  }
1190
}
1191
 
1192
/*!------------------------------------------------------------------------
1193
 * \fn     SetOpSizeFromCode(Word Code)
1194
 * \brief  set operand size of instruction from insn name
1195
 * \param  Code contains size in MSB
1196
 * ------------------------------------------------------------------------ */
1197
 
1198
static Boolean SetOpSizeFromCode(Word Code)
1199
{
1200
  Byte Size = Hi(Code);
1201
 
1202
  return SetOpSize((Size == 0xff) ? eSymbolSizeUnknown : (tSymbolSize)Size, &OpPart);
1203
}
1204
 
1205
/*!------------------------------------------------------------------------
1206
 * \fn     AppendCode(Word Code)
1207
 * \brief  append instruction word
1208
 * \param  pVals code word to append
1209
 * ------------------------------------------------------------------------ */
1210
 
1211
static void AppendCode(Word Code)
1212
{
1213
  WAsmCode[CodeLen >> 1] = Code;
1214
  CodeLen += 2;
1215
}
1216
 
1217
/*!------------------------------------------------------------------------
1218
 * \fn     AppendAdrVals(const tAdrVals *pVals)
1219
 * \brief  append address argument(s)
1220
 * \param  pVals values to append
1221
 * ------------------------------------------------------------------------ */
1222
 
1223
static void AppendAdrVals(const tAdrVals *pVals)
1224
{
1225
  memcpy(&WAsmCode[CodeLen >> 1], pVals->Vals, pVals->Cnt << 1);
1226
  CodeLen += pVals->Cnt << 1;
1227
}
1228
 
1229
/*!------------------------------------------------------------------------
1230
 * \fn     DecodeCondition(const tStrComp *pArg, Word *pCondition)
1231
 * \brief  decode condition argument
1232
 * \param  pArg source argument (NULL for non-present condition)
1233
 * \param  pCondition result buffer
1234
 * \return True if found
1235
 * ------------------------------------------------------------------------ */
1236
 
1237
static Boolean DecodeCondition(const tStrComp *pArg, Word *pCondition)
1238
{
1239
  int z;
1240
 
1241
  for (z = 0; Conditions[z].pName; z++)
1242
    if (!as_strcasecmp(pArg ? pArg->str.p_str : "", Conditions[z].pName))
1243
    {
1244
      *pCondition = Conditions[z].Code;
1245
      return True;
1246
    }
1247
  WrStrErrorPos(ErrNum_UndefCond, pArg);
1248
  return False;
1249
}
1250
 
1251
/*!------------------------------------------------------------------------
1252
 * \fn     DecodeImm1_16(const tStrComp *pArg, tEvalResult *pEvalResult)
1253
 * \brief  decode immediate argument from 1..16 and return as 0..15
1254
 * \param  pArg source argument
1255
 * \param  pEvalResult evaluation result
1256
 * \return value
1257
 * ------------------------------------------------------------------------ */
1258
 
1259
static Word DecodeImm1_16(const tStrComp *pArg, tEvalResult *pEvalResult)
1260
{
1261
  Word Result;
1262
 
1263
  Result = EvalStrIntExpressionOffsWithResult(pArg, !!(*pArg->str.p_str == '#'), UInt5, pEvalResult);
1264
  if (pEvalResult->OK)
1265
  {
1266
    if (mFirstPassUnknownOrQuestionable(pEvalResult->Flags))
1267
      Result = 1;
1268
    else
1269
      pEvalResult->OK = ChkRange(Result, 1, 16);
1270
    Result--;
1271
  }
1272
  return Result;
1273
}
1274
 
1275
/*--------------------------------------------------------------------------*/
1276
/* Instruction Decoders */
1277
 
1278
/*!------------------------------------------------------------------------
1279
 * \fn     DecodeFixed(Word Index)
1280
 * \brief  decode instruction without arguments
1281
 * \param  Index machine code of instruction
1282
 * ------------------------------------------------------------------------ */
1283
 
1284
static void DecodeFixed(Word Index)
1285
{
1286
  const FixedOrder *pOrder = FixedOrders + Index;
1287
 
1288
  if (ChkArgCnt(0, 0)
1289
   && CheckSup(pOrder->Privileged))
1290
  {
1291
    CodeLen = 2;
1292
    WAsmCode[0] = pOrder->Code;
1293
  }
1294
}
1295
 
1296
/*!------------------------------------------------------------------------
1297
 * \fn     DecodeLD(Word Code)
1298
 * \brief  decode LD/LDB/LDL instruction
1299
 * \param  Code instruction type
1300
 * ------------------------------------------------------------------------ */
1301
 
1302
static void DecodeLD(Word Code)
1303
{
1304
  tAdrVals DestAdrVals;
1305
 
1306
  if (!SetOpSizeFromCode(Code)
1307
   || !ChkArgCnt(2, 2))
1308
    return;
1309
 
1310
  switch (DecodeAdr(&ArgStr[1], MModNoImm, &DestAdrVals))
1311
  {
1312
    case eModReg:
1313
    {
1314
      tAdrVals SrcAdrVals;
1315
 
1316
      switch (DecodeAdr(&ArgStr[2], MModAll, &SrcAdrVals))
1317
      {
1318
        case eModReg:
1319
          AppendCode(((OpSize == eSymbolSize32Bit) ? 0x9400 : (0xa000 | (OpSize << 8)))
1320
                   | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1321
          break;
1322
        case eModIReg:
1323
          AppendCode(((OpSize == eSymbolSize32Bit) ? 0x1400 : (0x2000 | (OpSize << 8)))
1324
                   | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1325
          break;
1326
        case eModDirect:
1327
        case eModIndexed:
1328
          AppendCode(((OpSize == eSymbolSize32Bit) ? 0x5400 : (0x6000 | (OpSize << 8)))
1329
                   | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1330
          AppendAdrVals(&SrcAdrVals);
1331
          break;
1332
        case eModBaseAddress:
1333
          AppendCode(((OpSize == eSymbolSize32Bit) ? 0x3500 : (0x3000 | (OpSize << 8)))
1334
                   | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1335
          AppendAdrVals(&SrcAdrVals);
1336
          break;
1337
        case eModBaseIndexed:
1338
          AppendCode(((OpSize == eSymbolSize32Bit) ? 0x7500 : (0x7000 | (OpSize << 8)))
1339
                   | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1340
          AppendAdrVals(&SrcAdrVals);
1341
          break;
1342
        case eModImm:
1343
          if (OpSize == eSymbolSize8Bit)
1344
            AppendCode(0xc000 | (DestAdrVals.Val << 8) | (SrcAdrVals.Vals[0] & 0xff));
1345
#if OPT_LD_LDK
1346
          else if ((OpSize == eSymbolSize16Bit) && (SrcAdrVals.Vals[0] < 16))
1347
            AppendCode(0xbd00 | (DestAdrVals.Val << 4) | (SrcAdrVals.Vals[0] & 0x0f));
1348
#endif
1349
          else
1350
          {
1351
            AppendCode(((OpSize == eSymbolSize32Bit) ? 0x1400 : (0x2000 | (OpSize << 8)))
1352
                     | DestAdrVals.Val);
1353
            AppendAdrVals(&SrcAdrVals);
1354
          }
1355
          break;
1356
        default:
1357
          break;
1358
      }
1359
      break;
1360
    }
1361
    case eModIReg:
1362
    {
1363
      tAdrVals SrcAdrVals;
1364
 
1365
      ImmOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
1366
      switch (DecodeAdr(&ArgStr[2], MModReg | MModImm, &SrcAdrVals))
1367
      {
1368
        case eModReg:
1369
          AppendCode(((OpSize == eSymbolSize32Bit) ? 0x1d00 : (0x2e00 | (OpSize << 8)))
1370
                   | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
1371
          break;
1372
        case eModImm:
1373
          if (OpSize > eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &OpPart);
1374
          else
1375
          {
1376
            AppendCode(0x0c05 | (OpSize << 8) | (DestAdrVals.Val << 4));
1377
            AppendAdrVals(&SrcAdrVals);
1378
          }
1379
          break;
1380
        default:
1381
          break;
1382
      }
1383
      break;
1384
    }
1385
    case eModDirect:
1386
    case eModIndexed:
1387
    {
1388
      tAdrVals SrcAdrVals;
1389
 
1390
      ImmOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
1391
      switch (DecodeAdr(&ArgStr[2], MModReg | MModImm, &SrcAdrVals))
1392
      {
1393
        case eModReg:
1394
          AppendCode(((OpSize == eSymbolSize32Bit) ? 0x5d00 : (0x6e00 | (OpSize << 8)))
1395
                   | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
1396
          AppendAdrVals(&DestAdrVals);
1397
          break;
1398
        case eModImm:
1399
          if (OpSize > eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &OpPart);
1400
          else
1401
          {
1402
            AppendCode(0x4c05 | (OpSize << 8) | (DestAdrVals.Val << 4));
1403
            AppendAdrVals(&DestAdrVals);
1404
            AppendAdrVals(&SrcAdrVals);
1405
          }
1406
          break;
1407
        default:
1408
          break;
1409
      }
1410
      break;
1411
    }
1412
    case eModBaseAddress:
1413
    {
1414
      tAdrVals SrcAdrVals;
1415
 
1416
      if (DecodeAdr(&ArgStr[2], MModReg, &SrcAdrVals) == eModReg)
1417
      {
1418
        AppendCode(((OpSize == eSymbolSize32Bit) ? 0x3700 : (0x3200 | (OpSize << 8)))
1419
                 | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
1420
        AppendAdrVals(&DestAdrVals);
1421
      }
1422
      break;
1423
    }
1424
    case eModBaseIndexed:
1425
    {
1426
      tAdrVals SrcAdrVals;
1427
 
1428
      if (DecodeAdr(&ArgStr[2], MModReg, &SrcAdrVals) == eModReg)
1429
      {
1430
        AppendCode(((OpSize == eSymbolSize32Bit) ? 0x7700 : (0x7200 | (OpSize << 8)))
1431
                 | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
1432
        AppendAdrVals(&DestAdrVals);
1433
      }
1434
      break;
1435
    }
1436
    default:
1437
      break;
1438
  }
1439
}
1440
 
1441
/*!------------------------------------------------------------------------
1442
 * \fn     DecodeLDA(Word Code)
1443
 * \brief  decode LDA instruction
1444
 * ------------------------------------------------------------------------ */
1445
 
1446
static void DecodeLDA(Word Code)
1447
{
1448
  tAdrVals DestAdrVals, SrcAdrVals;
1449
 
1450
  UNUSED(Code);
1451
 
1452
  SetOpSize(AddrRegSize(), &OpPart);
1453
  if (ChkArgCnt(2, 2)
1454
   && DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals))
1455
    switch (DecodeAdr(&ArgStr[2], MModDirect | MModIndexed | MModBaseAddress | MModBaseIndexed, &SrcAdrVals))
1456
    {
1457
      case eModDirect:
1458
      case eModIndexed:
1459
        AppendCode(0x7600 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1460
        AppendAdrVals(&SrcAdrVals);
1461
        break;
1462
      case eModBaseAddress:
1463
        AppendCode(0x3400 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1464
        AppendAdrVals(&SrcAdrVals);
1465
        break;
1466
      case eModBaseIndexed:
1467
        AppendCode(0x7400 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1468
        AppendAdrVals(&SrcAdrVals);
1469
        break;
1470
      default:
1471
        break;
1472
    }
1473
}
1474
 
1475
/*!------------------------------------------------------------------------
1476
 * \fn     DecodeLDAR(Word Code)
1477
 * \brief  decode LDAR instruction
1478
 * ------------------------------------------------------------------------ */
1479
 
1480
static void DecodeLDAR(Word Code)
1481
{
1482
  tAdrVals DestAdrVals;
1483
 
1484
  SetOpSize(AddrRegSize(), &OpPart);
1485
  if (ChkArgCnt(2, 2)
1486
   && DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals))
1487
  {
1488
    tEvalResult EvalResult;
1489
    LongWord Addr = EvalStrIntExpressionWithResult(&ArgStr[2], MemIntType, &EvalResult);
1490
    if (EvalResult.OK)
1491
    {
1492
      Word Delta;
1493
 
1494
      if (!mFirstPassUnknownOrQuestionable(EvalResult.Flags) && (GetSegment(Addr) != GetSegment(EProgCounter())))
1495
        WrStrErrorPos(ErrNum_InAccSegment, &ArgStr[2]);
1496
 
1497
      Delta = (Addr & 0xffff) - ((EProgCounter() + 4) & 0xffff);
1498
      AppendCode(Code | DestAdrVals.Val);
1499
      AppendCode(Delta);
1500
    }
1501
  }
1502
}
1503
 
1504
/*!------------------------------------------------------------------------
1505
 * \fn     DecodeLDCTL(Word Code)
1506
 * \brief  decode LDCTL(B) instruction
1507
 * ------------------------------------------------------------------------ */
1508
 
1509
static void DecodeLDCTL(Word Code)
1510
{
1511
  tAdrVals DestAdrVals;
1512
 
1513
  UNUSED(Code);
1514
  if (SetOpSizeFromCode(Code)
1515
   && ChkArgCnt(2, 2)
1516
   && CheckSup(True))
1517
    switch (DecodeAdr(&ArgStr[1], MModReg | MModCtl, &DestAdrVals))
1518
    {
1519
      case eModReg:
1520
      {
1521
        tAdrVals SrcAdrVals;
1522
 
1523
        if (DecodeAdr(&ArgStr[2], MModCtl, &SrcAdrVals))
1524
          AppendCode((OpSize ? 0x7d00 : 0x8c00) | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
1525
        break;
1526
      }
1527
      case eModCtl:
1528
      {
1529
        tAdrVals SrcAdrVals;
1530
 
1531
        if (DecodeAdr(&ArgStr[2], MModReg, &SrcAdrVals))
1532
          AppendCode((OpSize ? 0x7d08 : 0x8c08) | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1533
        break;
1534
      }
1535
      default:
1536
        break;
1537
    }
1538
}
1539
 
1540
/*!------------------------------------------------------------------------
1541
 * \fn     DecodeLDR(Word Code)
1542
 * \brief  decode LDR[L|B]
1543
 * \param  Code machine code
1544
 * ------------------------------------------------------------------------ */
1545
 
1546
static void DecodeLDR(Word Code)
1547
{
1548
  Word Reg;
1549
  tSymbolSize RegSize;
1550
  int RegArgIndex = 1;
1551
 
1552
  if (SetOpSizeFromCode(Code)
1553
   && ChkArgCnt(2, 2))
1554
  switch (DecodeReg(&ArgStr[RegArgIndex], &Reg, &RegSize, ChkRegSize_8To32, False))
1555
  {
1556
    case eIsNoReg:
1557
      RegArgIndex = 2;
1558
      if (DecodeReg(&ArgStr[RegArgIndex], &Reg, &RegSize, ChkRegSize_8To32, True) != eIsReg)
1559
        return;
1560
      Code |= 2;
1561
      /* fall-thru */
1562
    case eIsReg:
1563
    {
1564
      tEvalResult EvalResult;
1565
      LongWord Addr;
1566
 
1567
      if (!SetOpSize(RegSize, &ArgStr[RegArgIndex]))
1568
        return;
1569
      if (OpSize > eSymbolSize32Bit)
1570
      {
1571
        WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[RegArgIndex]);
1572
        return;
1573
      }
1574
 
1575
      Addr = EvalStrIntExpressionWithResult(&ArgStr[3 - RegArgIndex], MemIntType, &EvalResult);
1576
      if (EvalResult.OK)
1577
      {
1578
        Word Delta;
1579
 
1580
        if (!mFirstPassUnknownOrQuestionable(EvalResult.Flags) && (GetSegment(Addr) != GetSegment(EProgCounter())))
1581
          WrStrErrorPos(ErrNum_InAccSegment, &ArgStr[2]);
1582
 
1583
        Delta = (Addr & 0xffff) - ((EProgCounter() + 4) & 0xffff);
1584
        AppendCode(((Lo(Code) | ((OpSize == eSymbolSize32Bit) ? 0x5 : OpSize)) << 8) | Reg);
1585
        AppendCode(Delta);
1586
      }
1587
      break;
1588
    }
1589
    case eRegAbort:
1590
      break;
1591
  }
1592
}
1593
 
1594
/*!------------------------------------------------------------------------
1595
 * \fn     DecodeADD(Word Code)
1596
 * \brief  decode ADD/ADDB/ADDL instruction
1597
 * \param  Code instruction type
1598
 * ------------------------------------------------------------------------ */
1599
 
1600
static void DecodeADD(Word Code)
1601
{
1602
  tAdrVals DestAdrVals;
1603
 
1604
  if (!SetOpSizeFromCode(Code)
1605
   || !ChkArgCnt(2, 2))
1606
    return;
1607
 
1608
  if (DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals) == eModReg)
1609
  {
1610
    tAdrVals SrcAdrVals;
1611
 
1612
    switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | MModIReg | MModDirect | MModIndexed, &SrcAdrVals))
1613
    {
1614
      case eModReg:
1615
        AppendCode(((OpSize == eSymbolSize32Bit) ? 0x9600 : (0x8000 | (OpSize << 8)))
1616
                 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1617
        break;
1618
      case eModIReg:
1619
      case eModImm:
1620
        AppendCode(((OpSize == eSymbolSize32Bit) ? 0x1600 : (0x0000 | (OpSize << 8)))
1621
                 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1622
        AppendAdrVals(&SrcAdrVals);
1623
        break;
1624
      case eModDirect:
1625
      case eModIndexed:
1626
        AppendCode(((OpSize == eSymbolSize32Bit) ? 0x5600 : (0x4000 | (OpSize << 8)))
1627
                 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1628
        AppendAdrVals(&SrcAdrVals);
1629
        break;
1630
      default:
1631
        break;
1632
    }
1633
  }
1634
}
1635
 
1636
/*!------------------------------------------------------------------------
1637
 * \fn     DecodeSUB(Word Code)
1638
 * \brief  decode SUB/SUBB/SUBL instruction
1639
 * \param  Code instruction type
1640
 * ------------------------------------------------------------------------ */
1641
 
1642
static void DecodeSUB(Word Code)
1643
{
1644
  tAdrVals DestAdrVals;
1645
 
1646
  if (!SetOpSizeFromCode(Code)
1647
   || !ChkArgCnt(2, 2))
1648
    return;
1649
 
1650
  if (DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals) == eModReg)
1651
  {
1652
    tAdrVals SrcAdrVals;
1653
 
1654
    switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | MModIReg | MModDirect | MModIndexed, &SrcAdrVals))
1655
    {
1656
      case eModReg:
1657
        AppendCode(((OpSize == eSymbolSize32Bit) ? 0x9200 : (0x8200 | (OpSize << 8)))
1658
                 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1659
        break;
1660
      case eModIReg:
1661
      case eModImm:
1662
        AppendCode(((OpSize == eSymbolSize32Bit) ? 0x1200 : (0x0200 | (OpSize << 8)))
1663
                 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1664
        AppendAdrVals(&SrcAdrVals);
1665
        break;
1666
      case eModDirect:
1667
      case eModIndexed:
1668
        AppendCode(((OpSize == eSymbolSize32Bit) ? 0x5200 : (0x4200 | (OpSize << 8)))
1669
                 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1670
        AppendAdrVals(&SrcAdrVals);
1671
        break;
1672
      default:
1673
        break;
1674
    }
1675
  }
1676
}
1677
 
1678
/*!------------------------------------------------------------------------
1679
 * \fn     DecodeCP(Word Code)
1680
 * \brief  decode CP/CPB/CPL instruction
1681
 * \param  Code instruction type
1682
 * ------------------------------------------------------------------------ */
1683
 
1684
static void DecodeCP(Word Code)
1685
{
1686
  tAdrVals DestAdrVals;
1687
 
1688
  if (!SetOpSizeFromCode(Code)
1689
   || !ChkArgCnt(2, 2))
1690
    return;
1691
 
1692
  switch (DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModDirect | MModIndexed, &DestAdrVals))
1693
  {
1694
    case eModReg:
1695
    {
1696
      tAdrVals SrcAdrVals;
1697
 
1698
      switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | MModIReg | MModDirect | MModIndexed, &SrcAdrVals))
1699
      {
1700
        case eModReg:
1701
          AppendCode(((OpSize == eSymbolSize32Bit) ? 0x9000 : (0x8a00 | (OpSize << 8)))
1702
                   | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1703
          break;
1704
        case eModIReg:
1705
        case eModImm:
1706
          AppendCode(((OpSize == eSymbolSize32Bit) ? 0x1000 : (0x0a00 | (OpSize << 8)))
1707
                   | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1708
          AppendAdrVals(&SrcAdrVals);
1709
          break;
1710
        case eModDirect:
1711
        case eModIndexed:
1712
          AppendCode(((OpSize == eSymbolSize32Bit) ? 0x5000 : (0x4a00 | (OpSize << 8)))
1713
                   | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1714
          AppendAdrVals(&SrcAdrVals);
1715
          break;
1716
        default:
1717
          break;
1718
      }
1719
      break;
1720
    }
1721
    case eModIReg:
1722
    {
1723
      tAdrVals SrcAdrVals;
1724
 
1725
      ImmOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
1726
      if (OpSize == eSymbolSize32Bit) WrStrErrorPos(ErrNum_InvOpSize, &OpPart);
1727
      else if (eModImm == DecodeAdr(&ArgStr[2], MModImm, &SrcAdrVals))
1728
      {
1729
        AppendCode(0x0c01 | (DestAdrVals.Val << 4)  | (OpSize << 8));
1730
        AppendAdrVals(&SrcAdrVals);
1731
      }
1732
      break;
1733
    }
1734
    case eModDirect:
1735
    case eModIndexed:
1736
    {
1737
      tAdrVals SrcAdrVals;
1738
 
1739
      ImmOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
1740
      if (OpSize == eSymbolSize32Bit) WrStrErrorPos(ErrNum_InvOpSize, &OpPart);
1741
      else if (eModImm == DecodeAdr(&ArgStr[2], MModImm, &SrcAdrVals))
1742
      {
1743
        AppendCode(0x4c01 | (DestAdrVals.Val << 4)  | (OpSize << 8));
1744
        AppendAdrVals(&DestAdrVals);
1745
        AppendAdrVals(&SrcAdrVals);
1746
      }
1747
      break;
1748
    }
1749
    default:
1750
      break;
1751
  }
1752
}
1753
 
1754
/*!------------------------------------------------------------------------
1755
 * \fn     DecodeADC_SBC(Word Code)
1756
 * \brief  decode ADC/SBC instructions
1757
 * \param  Code instruction type
1758
 * ------------------------------------------------------------------------ */
1759
 
1760
static void DecodeADC_SBC(Word Code)
1761
{
1762
  tAdrVals DestAdrVals, SrcAdrVals;
1763
 
1764
  if (!SetOpSizeFromCode(Code)
1765
   || !ChkArgCnt(2, 2))
1766
    return;
1767
 
1768
  if ((DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals) == eModReg)
1769
   && (DecodeAdr(&ArgStr[2], MModReg, &SrcAdrVals) == eModReg))
1770
  {
1771
    if (OpSize > eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
1772
    else
1773
      AppendCode(0x8000 | (((Code & 0xfe) | OpSize) << 8)
1774
               | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1775
  }
1776
}
1777
 
1778
/*!------------------------------------------------------------------------
1779
 * \fn     DecodeAND_OR_XOR(Word Code)
1780
 * \brief  decode AND/OR/XOR instructions
1781
 * \param  Code instruction type
1782
 * ------------------------------------------------------------------------ */
1783
 
1784
static void DecodeAND_OR_XOR(Word Code)
1785
{
1786
  tAdrVals DestAdrVals;
1787
 
1788
  if (!SetOpSizeFromCode(Code)
1789
   || !ChkArgCnt(2, 2))
1790
    return;
1791
 
1792
  if (DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals) == eModReg)
1793
  {
1794
    tAdrVals SrcAdrVals;
1795
 
1796
    if (OpSize > eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
1797
    else switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | MModIReg | MModDirect | MModIndexed, &SrcAdrVals))
1798
    {
1799
      case eModReg:
1800
        AppendCode(0x8000 | (((Code & 0xfe) | OpSize) << 8)
1801
                 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1802
        break;
1803
      case eModIReg:
1804
      case eModImm:
1805
        AppendCode(0x0000 | (((Code & 0xfe) | OpSize) << 8)
1806
                 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1807
        AppendAdrVals(&SrcAdrVals);
1808
        break;
1809
      case eModDirect:
1810
      case eModIndexed:
1811
        AppendCode(0x4000 | (((Code & 0xfe) | OpSize) << 8)
1812
                 | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
1813
        AppendAdrVals(&SrcAdrVals);
1814
        break;
1815
      default:
1816
        break;
1817
    }
1818
  }
1819
}
1820
 
1821
/*!------------------------------------------------------------------------
1822
 * \fn     DecodeINC_DEC(Word Code)
1823
 * \brief  decode increment/decrement instructions
1824
 * \param  Code instruction type
1825
 * ------------------------------------------------------------------------ */
1826
 
1827
static void DecodeINC_DEC(Word Code)
1828
{
1829
  tAdrVals AdrVals;
1830
 
1831
  if (SetOpSizeFromCode(Code)
1832
   && ChkArgCnt(1, 2)
1833
   && DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModDirect | MModIndexed, &AdrVals))
1834
  {
1835
    if (OpSize == eSymbolSizeUnknown)
1836
      OpSize = eSymbolSize16Bit;
1837
    if (OpSize > eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
1838
    else
1839
    {
1840
      tEvalResult EvalResult;
1841
      Word ImmVal = 0;
1842
 
1843
      if (2 == ArgCnt)
1844
        ImmVal = DecodeImm1_16(&ArgStr[2], &EvalResult);
1845
      else
1846
        EvalResult.OK = True;
1847
 
1848
      if (EvalResult.OK)
1849
        switch (AdrVals.Mode)
1850
        {
1851
          case eModReg:
1852
            AppendCode(0x8000 | ((Code | OpSize) << 8) | (AdrVals.Val << 4) | ImmVal);
1853
            break;
1854
          case eModIReg:
1855
            AppendCode(0x0000 | ((Code | OpSize) << 8) | (AdrVals.Val << 4) | ImmVal);
1856
            break;
1857
          case eModDirect:
1858
          case eModIndexed:
1859
            AppendCode(0x4000 | ((Code | OpSize) << 8) | (AdrVals.Val << 4) | ImmVal);
1860
            AppendAdrVals(&AdrVals);
1861
            break;
1862
          default:
1863
            break;
1864
        }
1865
    }
1866
  }
1867
}
1868
 
1869
/*!------------------------------------------------------------------------
1870
 * \fn     DecodeBitOp(Word Code)
1871
 * \brief  decode bit set/reset/test instructions
1872
 * \param  Code instruction type
1873
 * ------------------------------------------------------------------------ */
1874
 
1875
static void DecodeBitOp(Word Code)
1876
{
1877
  tAdrVals DestAdrVals, SrcAdrVals;
1878
  tSymbolSize DestOpSize;
1879
 
1880
  if (!SetOpSizeFromCode(Code))
1881
    return;
1882
 
1883
  switch (ArgCnt)
1884
  {
1885
    case 1:
1886
    {
1887
      LongWord PacketBit;
1888
 
1889
      if (DecodeBitArg(&PacketBit, 1, 1, OpSize))
1890
      {
1891
        LongWord Address;
1892
        Byte BitPos;
1893
        Boolean ForceShort;
1894
 
1895
        if (DissectBitSymbol(PacketBit, &Address, &BitPos, &DestOpSize, &ForceShort)
1896
         && SetOpSize(DestOpSize, &ArgStr[1]))
1897
        {
1898
          ClearAdrVals(&SrcAdrVals);
1899
          SrcAdrVals.Val = BitPos;
1900
          ClearAdrVals(&DestAdrVals);
1901
          FillAbsAddr(&DestAdrVals, Address, False, ForceShort);
1902
          goto Abs2Imm; /* yeah! */
1903
        }
1904
      }
1905
      break;
1906
    }
1907
    case 2:
1908
      if (DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModDirect | MModIndexed, &DestAdrVals))
1909
      {
1910
        DestOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
1911
 
1912
        switch (DestOpSize)
1913
        {
1914
          case eSymbolSize8Bit:
1915
            ImmOpSize = eSymbolSize3Bit; break;
1916
          case eSymbolSize16Bit:
1917
            ImmOpSize = eSymbolSize4Bit; break;
1918
          default:
1919
            WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]); return;
1920
        }
1921
        OpSize = eSymbolSizeUnknown;
1922
 
1923
        switch (DecodeAdr(&ArgStr[2], MModReg | MModImm, &SrcAdrVals))
1924
        {
1925
          case eModImm:
1926
            switch (DestAdrVals.Mode)
1927
            {
1928
              case eModReg:
1929
                AppendCode(0x8000 | (((Code & 0xfe) | DestOpSize) << 8)
1930
                         | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
1931
                break;
1932
              case eModIReg:
1933
                AppendCode(0x0000 | (((Code & 0xfe) | DestOpSize) << 8)
1934
                         | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
1935
                break;
1936
              case eModDirect:
1937
              case eModIndexed:
1938
              Abs2Imm:
1939
                AppendCode(0x4000 | (((Code & 0xfe) | DestOpSize) << 8)
1940
                         | (DestAdrVals.Val << 4) | SrcAdrVals.Val);
1941
                AppendAdrVals(&DestAdrVals);
1942
                break;
1943
              default:
1944
                break;
1945
            }
1946
            break;
1947
          case eModReg:
1948
            switch (DestAdrVals.Mode)
1949
            {
1950
              case eModReg:
1951
                if (OpSize != eSymbolSize16Bit) WrStrErrorPos (ErrNum_InvOpSize, &ArgStr[2]);
1952
                else
1953
                {
1954
                  AppendCode(0x0000 | (((Code & 0xfe) | DestOpSize) << 8) | SrcAdrVals.Val);
1955
                  AppendCode(DestAdrVals.Val << 8);
1956
                }
1957
                break;
1958
              case eModNone:
1959
                break;
1960
              default:
1961
                WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
1962
            }
1963
            break;
1964
          default:
1965
            break;
1966
        }
1967
      }
1968
      break;
1969
    default:
1970
      (void)ChkArgCnt(1, 2);
1971
  }
1972
}
1973
 
1974
/*!------------------------------------------------------------------------
1975
 * \fn     DecodeCALL_JP(Word Code)
1976
 * \brief  decode jump/call instructions
1977
 * \param  instruction code
1978
 * ------------------------------------------------------------------------ */
1979
 
1980
static void DecodeCALL_JP(Word Code)
1981
{
1982
  tAdrVals AdrVals;
1983
  Boolean IsCALL = Code & 1;
1984
 
1985
  if (ChkArgCnt(1, 2 - IsCALL))
1986
  {
1987
    Word Condition;
1988
 
1989
    if (IsCALL)
1990
      Condition = 0;
1991
    else if (!DecodeCondition((ArgCnt == 2) ? &ArgStr[1] : NULL, &Condition))
1992
      return;
1993
 
1994
    switch (DecodeAdr(&ArgStr[ArgCnt], MModIReg | MModDirect | MModIndexed, &AdrVals))
1995
    {
1996
      case eModIReg:
1997
        AppendCode(0x0000 | (Code << 8) | (AdrVals.Val << 4) | Condition);
1998
        break;
1999
      case eModDirect:
2000
      case eModIndexed:
2001
        AppendCode(0x4000 | (Code << 8) | (AdrVals.Val << 4) | Condition);
2002
        AppendAdrVals(&AdrVals);
2003
        break;
2004
      default:
2005
        break;
2006
    }
2007
  }
2008
}
2009
 
2010
/*!------------------------------------------------------------------------
2011
 * \fn     DecodeBranch(Word CodeWord MaxDist, Boolean Inverse, const tStrComp *pArg)
2012
 * \brief  relative branch core decode
2013
 * \param  Code instruction code (upper bits)
2014
 * \param  MaxDist maximum positive distance (in bytes, e.g. even value)
2015
 * \param  Inverse Displacement is subtraced and not added by CPU
2016
 * \param  pArg source argument
2017
 * ------------------------------------------------------------------------ */
2018
 
2019
static void DecodeBranch(Word Code, Word MaxDist, Boolean Inverse, const tStrComp *pArg)
2020
{
2021
  tEvalResult EvalResult;
2022
  LongWord Addr = EvalStrIntExpressionWithResult(pArg, MemIntType, &EvalResult);
2023
 
2024
  if (EvalResult.OK)
2025
  {
2026
    Word Delta;
2027
 
2028
    /* considering wraparound in segment makes things a bit more complicated: */
2029
 
2030
    if (!mFirstPassUnknownOrQuestionable(EvalResult.Flags) && (GetSegment(Addr) != GetSegment(EProgCounter())))
2031
      WrStrErrorPos(ErrNum_InAccSegment, pArg);
2032
 
2033
    Delta = (Addr & 0xffff) - ((EProgCounter() + 2) & 0xffff);
2034
    if (Inverse)
2035
      Delta = (~Delta) + 1;
2036
    if ((Delta & 1) && !mFirstPassUnknownOrQuestionable(EvalResult.Flags)) WrStrErrorPos(ErrNum_AddrMustBeEven, pArg);
2037
    else if ((Delta > MaxDist) && (Delta < (0xfffe - MaxDist)) && !mFirstPassUnknownOrQuestionable(EvalResult.Flags)) WrStrErrorPos(ErrNum_JmpDistTooBig, pArg);
2038
    else
2039
      AppendCode(Code | ((Delta >> 1) & (MaxDist + 1)));
2040
  }
2041
}
2042
 
2043
/*!------------------------------------------------------------------------
2044
 * \fn     DecodeCALR(Word Code)
2045
 * \brief  decode CALR instruction
2046
 * \param  Code instruction code (upper bits)
2047
 * ------------------------------------------------------------------------ */
2048
 
2049
static void DecodeCALR(Word Code)
2050
{
2051
  if (ChkArgCnt(1, 1))
2052
    DecodeBranch(Code, 4094, True, &ArgStr[1]);
2053
}
2054
 
2055
/*!------------------------------------------------------------------------
2056
 * \fn     DecodeJR(Word Code)
2057
 * \brief  decode JR instruction
2058
 * \param  Code instruction code (upper bits)
2059
 * ------------------------------------------------------------------------ */
2060
 
2061
static void DecodeJR(Word Code)
2062
{
2063
  Word Condition;
2064
 
2065
  if (ChkArgCnt(1, 2)
2066
   && DecodeCondition(ArgCnt == 2 ? &ArgStr[1] : NULL, &Condition))
2067
    DecodeBranch(Code | (Condition << 8), 254, False, &ArgStr[ArgCnt]);
2068
}
2069
 
2070
/*!------------------------------------------------------------------------
2071
 * \fn     DecodeDJNZ(Word Code)
2072
 * \brief  decode DJNZ instructions
2073
 * \param  size spec
2074
 * ------------------------------------------------------------------------ */
2075
 
2076
static void DecodeDJNZ(Word Code)
2077
{
2078
  tAdrVals AdrVals;
2079
 
2080
  if (SetOpSizeFromCode(Code)
2081
   && ChkArgCnt(2, 2)
2082
   && DecodeAdr(&ArgStr[1], MModReg, &AdrVals))
2083
  {
2084
    if (OpSize > eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
2085
    else
2086
    {
2087
      tEvalResult EvalResult;
2088
      LongWord Addr = EvalStrIntExpressionWithResult(&ArgStr[2], MemIntType, &EvalResult);
2089
 
2090
      if (EvalResult.OK)
2091
      {
2092
        Word Delta;
2093
 
2094
        /* considering wraparound in segment makes things a bit more complicated: */
2095
 
2096
        if (!mFirstPassUnknownOrQuestionable(EvalResult.Flags) && (GetSegment(Addr) != GetSegment(EProgCounter())))
2097
          WrStrErrorPos(ErrNum_InAccSegment, &ArgStr[2]);
2098
 
2099
        Delta = (Addr & 0xffff) - ((EProgCounter() + 2) & 0xffff);
2100
        if ((Delta & 1) && !mFirstPassUnknownOrQuestionable(EvalResult.Flags)) WrStrErrorPos(ErrNum_AddrMustBeEven, &ArgStr[2]);
2101
        else if ((Delta > 0) && (Delta < 0xff02) && !mFirstPassUnknownOrQuestionable(EvalResult.Flags)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[2]);
2102
        else
2103
        {
2104
          Delta = (0x10000lu - Delta) >> 1;
2105
          AppendCode(0xf000 | (AdrVals.Val << 8) | (OpSize << 7) | (Delta & 0x7f));
2106
        }
2107
      }
2108
    }
2109
  }
2110
}
2111
 
2112
/*!------------------------------------------------------------------------
2113
 * \fn     DecodeCLR_COM_NEG_TSET(Word Code)
2114
 * \brief  decode CLR/COM/NEG/TSET instructions
2115
 * \param  Code machine code + size spec
2116
 * ------------------------------------------------------------------------ */
2117
 
2118
static void DecodeCLR_COM_NEG_TSET(Word Code)
2119
{
2120
  tAdrVals AdrVals;
2121
 
2122
  if (SetOpSizeFromCode(Code)
2123
   && ChkArgCnt(1,1)
2124
   && DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModDirect | MModIndexed, &AdrVals))
2125
  {
2126
    if (OpSize == eSymbolSizeUnknown)
2127
      OpSize = eSymbolSize16Bit;
2128
    if (OpSize > eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
2129
    else
2130
    {
2131
      Code = ((Code >> 4) & 0x0f) | (((Code & 0x0e) | OpSize) << 8);
2132
      switch (AdrVals.Mode)
2133
      {
2134
        case eModReg:
2135
          AppendCode(0x8000 | Code | (AdrVals.Val << 4));
2136
          break;
2137
        case eModIReg:
2138
          AppendCode(0x0000 | Code | (AdrVals.Val << 4));
2139
          break;
2140
        case eModDirect:
2141
        case eModIndexed:
2142
          AppendCode(0x4000 | Code | (AdrVals.Val << 4));
2143
          AppendAdrVals(&AdrVals);
2144
          break;
2145
        default:
2146
          break;
2147
      }
2148
    }
2149
  }
2150
}
2151
 
2152
/*!------------------------------------------------------------------------
2153
 * \fn     DecodeTEST(Word Code)
2154
 * \brief  decode TEST instruction
2155
 * \param  Code machine code + size spec
2156
 * ------------------------------------------------------------------------ */
2157
 
2158
static void DecodeTEST(Word Code)
2159
{
2160
  tAdrVals AdrVals;
2161
 
2162
  if (SetOpSizeFromCode(Code)
2163
   && ChkArgCnt(1, 1)
2164
   && DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModDirect | MModIndexed, &AdrVals))
2165
  {
2166
    if (OpSize == eSymbolSizeUnknown)
2167
      OpSize = eSymbolSize16Bit;
2168
    if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
2169
    else
2170
    {
2171
      Code = (Lo(Code) | ((OpSize == eSymbolSize32Bit) ? 0x10 : OpSize)) << 8 | ((OpSize == eSymbolSize32Bit) ? 8 : 4);
2172
      switch (AdrVals.Mode)
2173
      {
2174
        case eModReg:
2175
          AppendCode(0x8000 | Code | (AdrVals.Val << 4));
2176
          break;
2177
        case eModIReg:
2178
          AppendCode(0x0000 | Code | (AdrVals.Val << 4));
2179
          break;
2180
        case eModDirect:
2181
        case eModIndexed:
2182
          AppendCode(0x4000 | Code | (AdrVals.Val << 4));
2183
          AppendAdrVals(&AdrVals);
2184
          break;
2185
        default:
2186
          break;
2187
      }
2188
    }
2189
  }
2190
}
2191
 
2192
/*!------------------------------------------------------------------------
2193
 * \fn     DecodeEX(Word Code)
2194
 * \brief  decode EX instruction
2195
 * \param  Code machine code + size spec
2196
 * ------------------------------------------------------------------------ */
2197
 
2198
static void DecodeEX(Word Code)
2199
{
2200
  tAdrVals SrcAdrVals, DestAdrVals;
2201
 
2202
  if (SetOpSizeFromCode(Code)
2203
   && ChkArgCnt(2, 2)
2204
   && DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModDirect | MModIndexed, &DestAdrVals)
2205
   && DecodeAdr(&ArgStr[2], MModReg | ((DestAdrVals.Mode == eModReg) ? (MModIReg | MModDirect | MModIndexed) : 0), &SrcAdrVals))
2206
  {
2207
    if (OpSize == eSymbolSizeUnknown)
2208
      OpSize = eSymbolSize16Bit;
2209
    if (OpSize > eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
2210
    else
2211
    {
2212
      if (DestAdrVals.Mode != eModReg)
2213
      {
2214
        tAdrVals Swap;
2215
        Swap = SrcAdrVals;
2216
        SrcAdrVals = DestAdrVals;
2217
        DestAdrVals = Swap;
2218
      }
2219
      Code = (Lo(Code) | OpSize) << 8;
2220
      switch (SrcAdrVals.Mode)
2221
      {
2222
        case eModReg:
2223
          AppendCode(0x8000 | Code | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
2224
          break;
2225
        case eModIReg:
2226
          AppendCode(0x0000 | Code | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
2227
          break;
2228
        case eModDirect:
2229
        case eModIndexed:
2230
          AppendCode(0x4000 | Code | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
2231
          AppendAdrVals(&SrcAdrVals);
2232
          break;
2233
        default:
2234
          break;
2235
      }
2236
    }
2237
  }
2238
}
2239
 
2240
/*!------------------------------------------------------------------------
2241
 * \fn     DecodeEXTS(Word Code)
2242
 * \brief  decode EXTS instruction
2243
 * \param  Code machine code + size spec
2244
 * ------------------------------------------------------------------------ */
2245
 
2246
static void DecodeEXTS(Word Code)
2247
{
2248
  if (SetOpSizeFromCode(Code)
2249
   && ChkArgCnt(1, 1))
2250
  {
2251
    tAdrVals AdrVals;
2252
 
2253
    if (OpSize != eSymbolSizeUnknown)
2254
      OpSize++;
2255
    if (DecodeAdr(&ArgStr[1], MModReg, &AdrVals))
2256
    {
2257
      Code = (Lo(Code) << 8) | 0x8000 | (AdrVals.Val << 4);
2258
      switch (OpSize)
2259
      {
2260
        case eSymbolSize16Bit:
2261
          AppendCode(Code | 0x0000);
2262
          break;
2263
        case eSymbolSize32Bit:
2264
          AppendCode(Code | 0x000a);
2265
          break;
2266
        case eSymbolSize64Bit:
2267
          AppendCode(Code | 0x0007);
2268
          break;
2269
        default:
2270
          WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
2271
      }
2272
    }
2273
  }
2274
}
2275
 
2276
/*!------------------------------------------------------------------------
2277
 * \fn     DecodeMULT_DIV(Word Code)
2278
 * \brief  decode multiply/divide instructions
2279
 * \param  Code instruction code
2280
 * ------------------------------------------------------------------------ */
2281
 
2282
static void DecodeMULT_DIV(Word Code)
2283
{
2284
  if (SetOpSizeFromCode(Code)
2285
   && ChkArgCnt(2, 2))
2286
  {
2287
    tAdrVals DestAdrVals;
2288
 
2289
    if (OpSize != eSymbolSizeUnknown)
2290
      OpSize++;
2291
    if (DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals) == eModReg)
2292
    {
2293
      tAdrVals SrcAdrVals;
2294
 
2295
      if ((OpSize < eSymbolSize32Bit) || (OpSize > eSymbolSize64Bit))
2296
      {
2297
        WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
2298
        return;
2299
      }
2300
 
2301
      OpSize--;
2302
      switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | MModIReg | MModDirect | MModIndexed, &SrcAdrVals))
2303
      {
2304
        case eModReg:
2305
          AppendCode(0x8000 | ((Code | (OpSize & 1)) << 8) | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
2306
          break;
2307
        case eModImm:
2308
        case eModIReg:
2309
          AppendCode(0x0000 | ((Code | (OpSize & 1)) << 8) | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
2310
          AppendAdrVals(&SrcAdrVals);
2311
          break;
2312
        case eModDirect:
2313
        case eModIndexed:
2314
          AppendCode(0x4000 | ((Code | (OpSize & 1)) << 8) | (SrcAdrVals.Val << 4) | DestAdrVals.Val);
2315
          AppendAdrVals(&SrcAdrVals);
2316
          break;
2317
        default:
2318
          break;
2319
      }
2320
    }
2321
  }
2322
}
2323
 
2324
/*!------------------------------------------------------------------------
2325
 * \fn     DecodeDAB(Word Code)
2326
 * \brief  decode DAB instruction
2327
 * \param  Code instruction code
2328
 * ------------------------------------------------------------------------ */
2329
 
2330
static void DecodeDAB(Word Code)
2331
{
2332
  tAdrVals AdrVals;
2333
 
2334
  SetOpSize(eSymbolSize8Bit, &OpPart);
2335
  if (ChkArgCnt(1,1) && DecodeAdr(&ArgStr[1], MModReg, &AdrVals))
2336
    AppendCode(Code | (AdrVals.Val << 4));
2337
}
2338
 
2339
/*!------------------------------------------------------------------------
2340
 * \fn     DecodeFLG(Word Code)
2341
 * \brief  decode flag set/reset/complement instructions
2342
 * \param  machine code
2343
 * ------------------------------------------------------------------------ */
2344
 
2345
static void DecodeFLG(Word Code)
2346
{
2347
  if (ChkArgCnt(1, ArgCntMax))
2348
  {
2349
    int z;
2350
    Word Num;
2351
    static const char FlagNames[] = "PSZCV";
2352
 
2353
    for (z = 1; z <= ArgCnt; z++)
2354
    {
2355
      if (!as_strcasecmp(ArgStr[z].str.p_str, "P/V"))
2356
        Num = 1 << 0;
2357
      else if (!as_strcasecmp(ArgStr[z].str.p_str, "ZR"))
2358
        Num = 1 << 2;
2359
      else if (!as_strcasecmp(ArgStr[z].str.p_str, "CY"))
2360
        Num = 1 << 3;
2361
      else if (1 == strlen(ArgStr[z].str.p_str))
2362
      {
2363
        const char *pPos = strchr(FlagNames, as_toupper(*ArgStr[z].str.p_str));
2364
        Num = pPos ? (1 << ((pPos - FlagNames) % 4)) : 0;
2365
      }
2366
      else
2367
        Num = 0;
2368
 
2369
      if (!Num)
2370
      {
2371
        WrStrErrorPos(ErrNum_UnknownFlag, &ArgStr[z]);
2372
        return;
2373
      }
2374
      else if (Code & (Num << 4))
2375
      {
2376
        WrStrErrorPos(ErrNum_DuplicateFlag, &ArgStr[z]);
2377
        return;
2378
      }
2379
      else
2380
        Code |= Num << 4;
2381
    }
2382
    AppendCode(Code);
2383
  }
2384
}
2385
 
2386
/*!------------------------------------------------------------------------
2387
 * \fn     DecodeDI_EI(Word Code)
2388
 * \brief  decode interrupt enable/disable instructions
2389
 * \param  Code machine code
2390
 * ------------------------------------------------------------------------ */
2391
 
2392
static void DecodeDI_EI(Word Code)
2393
{
2394
  if (ChkArgCnt(1, ArgCntMax)
2395
   && CheckSup(True))
2396
  {
2397
    int z;
2398
    Word Num;
2399
 
2400
    Code |= 3;
2401
    for (z = 1; z <= ArgCnt; z++)
2402
    {
2403
      if (!as_strcasecmp(ArgStr[z].str.p_str, "VI"))
2404
        Num = 1 << 1;
2405
      else if (!as_strcasecmp(ArgStr[z].str.p_str, "NVI"))
2406
        Num = 1 << 0;
2407
      else
2408
        Num = 0;
2409
 
2410
      if (!Num)
2411
      {
2412
        WrStrErrorPos(ErrNum_UnknownInt, &ArgStr[z]);
2413
        return;
2414
      }
2415
      else if (!(Code & Num))
2416
      {
2417
        WrStrErrorPos(ErrNum_DuplicateInt, &ArgStr[z]);
2418
        return;
2419
      }
2420
      else
2421
        Code &= ~Num;
2422
    }
2423
    AppendCode(Code);
2424
  }
2425
}
2426
 
2427
/*!------------------------------------------------------------------------
2428
 * \fn     DecodeIN_SIN_OUT_SOUT(Word Code)
2429
 * \brief  decode IN/SIN/OUT/SOUT
2430
 * \param  Code machine code
2431
 * ------------------------------------------------------------------------ */
2432
 
2433
static void DecodeIN_SIN_OUT_SOUT(Word Code)
2434
{
2435
  tAdrVals RegAdrVals;
2436
  Word IsOUT = Code & 2,
2437
       IsSpecial = Code & 1;
2438
  const tStrComp *pRegArg = IsOUT ? &ArgStr[2] : &ArgStr[1],
2439
                 *pIOArg  = IsOUT ? &ArgStr[1] : &ArgStr[2];
2440
 
2441
  if (SetOpSizeFromCode(Code)
2442
   && ChkArgCnt(2, 2)
2443
   && CheckSup(True)
2444
   && DecodeAdr(pRegArg, MModReg, &RegAdrVals))
2445
  {
2446
    tAdrVals IOAdrVals;
2447
 
2448
    if (OpSize > eSymbolSize16Bit)
2449
    {
2450
      WrStrErrorPos(ErrNum_InvOpSize, pRegArg);
2451
      return;
2452
    }
2453
    switch (DecodeAdr(pIOArg, MModIO | MModDirect | (IsSpecial ? 0 : MModIReg), &IOAdrVals))
2454
    {
2455
      case eModIReg:
2456
        AppendCode(0x3c00 | (IsOUT << 8) | (OpSize << 8) | (IOAdrVals.Val << 4) | RegAdrVals.Val);
2457
        break;
2458
      case eModDirect:
2459
        AppendCode(0x3a04 | (OpSize << 8) | (RegAdrVals.Val << 4) | Lo(Code));
2460
        AppendAdrVals(&IOAdrVals);
2461
        break;
2462
      default:
2463
        break;
2464
    }
2465
  }
2466
}
2467
 
2468
/*!------------------------------------------------------------------------
2469
 * \fn     DecodeCPRep(Word Code)
2470
 * \brief  decode CP[S](I/D)[R][D] instructions
2471
 * \param  Code instruction code
2472
 * ------------------------------------------------------------------------ */
2473
 
2474
static void DecodeCPRep(Word Code)
2475
{
2476
  tAdrVals DestAdrVals, SrcAdrVals, CntAdrVals;
2477
  Word Condition;
2478
  tAdrMode DestMode = (Code & 0x02) ? eModIReg : eModReg;
2479
 
2480
  if (!SetOpSizeFromCode(Code)
2481
   || !ChkArgCnt(3, 4)
2482
   || !DecodeCondition((ArgCnt == 4) ? &ArgStr[4] : NULL, &Condition))
2483
    return;
2484
 
2485
  if ((DecodeAdr(&ArgStr[1], 1 << DestMode, &DestAdrVals) == DestMode)
2486
   && (DecodeAdr(&ArgStr[2], MModIReg, &SrcAdrVals) == eModIReg))
2487
  {
2488
    tSymbolSize SaveOpSize;
2489
 
2490
    if (OpSize == eSymbolSizeUnknown)
2491
      OpSize = eSymbolSize16Bit;
2492
     SaveOpSize = OpSize;
2493
    OpSize = eSymbolSize16Bit;
2494
    if (DecodeAdr(&ArgStr[3], MModReg, &CntAdrVals) == eModReg)
2495
    {
2496
      if (SaveOpSize == eSymbolSize32Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
2497
      else
2498
      {
2499
        int Index =
2500
          ChkRegOverlap((unsigned)DestAdrVals.Val, ((DestMode == eModIReg) ? AddrRegSize() : SaveOpSize),
2501
                        (unsigned)SrcAdrVals.Val, (int)AddrRegSize(),
2502
                        (unsigned)CntAdrVals.Val, (int)eSymbolSize16Bit,
2503
                        0, eSymbolSizeUnknown);
2504
 
2505
        if (Index >= 0)
2506
          WrStrErrorPos(ErrNum_OverlapReg, &ArgStr[Index + 1]);
2507
        AppendCode(0xba00 | (SaveOpSize << 8) | (SrcAdrVals.Val << 4) | Lo(Code));
2508
        AppendCode((CntAdrVals.Val << 8) | (DestAdrVals.Val << 4) | Condition);
2509
      }
2510
    }
2511
  }
2512
}
2513
 
2514
/*!------------------------------------------------------------------------
2515
 * \fn     DecodeINOUTRep(Word Code)
2516
 * \brief  decode string I/O instructions
2517
 * \param  Code instruction machine code
2518
 * ------------------------------------------------------------------------ */
2519
 
2520
static void DecodeINOUTRep(Word Code)
2521
{
2522
  tAdrVals DestAdrVals, SrcAdrVals;
2523
  Word IsOUT = Code & 0x20;
2524
 
2525
  if (!SetOpSizeFromCode(Code)
2526
   || !CheckSup(True)
2527
   || !ChkArgCnt(3, 3))
2528
    return;
2529
 
2530
  if (DecodeAdr(&ArgStr[1], MModIReg | (IsOUT ? MModIO : 0), &DestAdrVals)
2531
   && DecodeAdr(&ArgStr[2], MModIReg | (IsOUT ? 0 : MModIO), &SrcAdrVals))
2532
  {
2533
    tAdrVals CntAdrVals;
2534
    tSymbolSize SaveOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
2535
 
2536
    OpSize = eSymbolSize16Bit;
2537
    if (DecodeAdr(&ArgStr[3], MModReg, &CntAdrVals))
2538
    {
2539
      AppendCode(0x3a00 | (SaveOpSize << 8) | (SrcAdrVals.Val << 4) | ((Code >> 4) & 15));
2540
      AppendCode((CntAdrVals.Val << 8) | (DestAdrVals.Val << 4) | (Code & 15));
2541
    }
2542
  }
2543
}
2544
 
2545
/*!------------------------------------------------------------------------
2546
 * \fn     DecodeLDRep(Word Code)
2547
 * \brief  decode string copy instructions
2548
 * \param  Code instruction machine code
2549
 * ------------------------------------------------------------------------ */
2550
 
2551
static void DecodeLDRep(Word Code)
2552
{
2553
  tAdrVals DestAdrVals, SrcAdrVals;
2554
 
2555
  if (!SetOpSizeFromCode(Code)
2556
   || !ChkArgCnt(3, 3))
2557
    return;
2558
 
2559
  if (DecodeAdr(&ArgStr[1], MModIReg, &DestAdrVals)
2560
   && DecodeAdr(&ArgStr[2], MModIReg, &SrcAdrVals))
2561
  {
2562
    tAdrVals CntAdrVals;
2563
    tSymbolSize SaveOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
2564
 
2565
    OpSize = eSymbolSize16Bit;
2566
    if (DecodeAdr(&ArgStr[3], MModReg, &CntAdrVals))
2567
    {
2568
      AppendCode(0xba00 | (SaveOpSize << 8) | (SrcAdrVals.Val << 4) | ((Code >> 4) & 15));
2569
      AppendCode((CntAdrVals.Val << 8) | (DestAdrVals.Val << 4) | (Code & 15));
2570
    }
2571
  }
2572
}
2573
 
2574
/*!------------------------------------------------------------------------
2575
 * \fn     DecodeTRRep(Word Code)
2576
 * \brief  decode string translate instructions
2577
 * \param  Code instruction machine code
2578
 * ------------------------------------------------------------------------ */
2579
 
2580
static void DecodeTRRep(Word Code)
2581
{
2582
  tAdrVals DestAdrVals, SrcAdrVals, CntAdrVals;
2583
 
2584
  /* op size only applies to counter reg */
2585
 
2586
  OpSize = eSymbolSize16Bit;
2587
  if (ChkArgCnt(3, 3)
2588
   && DecodeAdr(&ArgStr[1], MModIReg, &DestAdrVals)
2589
   && DecodeAdr(&ArgStr[2], MModIReg, &SrcAdrVals)
2590
   && DecodeAdr(&ArgStr[3], MModReg, &CntAdrVals))
2591
  {
2592
    Boolean OK = True;
2593
    int Index;
2594
 
2595
    /* R0/R1 in non-seg mode or RR0 in seg mode must not be used as src/dest.
2596
       R1 should not be used as counter.
2597
       This is only spelled out for TRDB, but due to the implicit usage of RH1
2598
       in all translate instructions, this restriction effectively applies to
2599
       them all.
2600
       Since (R)R0 is anyway not allowed for indirect addressing, this reduces
2601
       to check fo R1: */
2602
 
2603
    if (!Segmented() && (DestAdrVals.Val == 1))
2604
    {
2605
      WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
2606
      OK = False;
2607
    }
2608
    if (!Segmented() && (SrcAdrVals.Val == 1))
2609
    {
2610
      WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
2611
      OK = False;
2612
    }
2613
    if (CntAdrVals.Val == 1)
2614
    {
2615
      WrStrErrorPos(ErrNum_InvReg, &ArgStr[3]);
2616
      OK = False;
2617
    }
2618
 
2619
    Index = ChkRegOverlap((unsigned)DestAdrVals.Val, AddrRegSize(),
2620
                          (unsigned)SrcAdrVals.Val, (int)AddrRegSize(),
2621
                          (unsigned)CntAdrVals.Val, (int)eSymbolSize16Bit,
2622
                          0, eSymbolSizeUnknown);
2623
    if (Index >= 0)
2624
      WrStrErrorPos(ErrNum_OverlapReg, &ArgStr[Index + 1]);
2625
 
2626
    if (OK)
2627
    {
2628
      AppendCode(0xb800 | (DestAdrVals.Val << 4) | ((Code >> 4) & 15));
2629
      AppendCode((CntAdrVals.Val << 8) | (SrcAdrVals.Val << 4) | (Code & 15));
2630
    }
2631
  }
2632
}
2633
 
2634
/*!------------------------------------------------------------------------
2635
 * \fn     DecodeLDK(Word Code)
2636
 * \brief  decode LDK instruction
2637
 * \param  Code machine code
2638
 * ------------------------------------------------------------------------ */
2639
 
2640
static void DecodeLDK(Word Code)
2641
{
2642
  tAdrVals DestAdrVals;
2643
 
2644
  if (ChkArgCnt(2, 2)
2645
   && DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals))
2646
  {
2647
    Word Value;
2648
    Boolean OK;
2649
 
2650
    if (OpSize != eSymbolSize16Bit)
2651
    {
2652
      WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
2653
      return;
2654
    }
2655
    Value = EvalStrIntExpressionOffs(&ArgStr[2], !!(*ArgStr[2].str.p_str == '#'), UInt4, &OK);
2656
    if (OK)
2657
      AppendCode(Code | (DestAdrVals.Val << 4) | Value);
2658
  }
2659
}
2660
 
2661
/*!------------------------------------------------------------------------
2662
 * \fn     DecodeLDM(Word Code)
2663
 * \brief  decode LDM instruction
2664
 * \param  Code machine code
2665
 * ------------------------------------------------------------------------ */
2666
 
2667
static void DecodeLDM(Word Code)
2668
{
2669
  Word Count;
2670
  tEvalResult EvalResult;
2671
  tAdrVals RegAdrVals, MemAdrVals;
2672
  int RegArgIndex;
2673
 
2674
  if (!ChkArgCnt(3, 3))
2675
    return;
2676
 
2677
  Count = DecodeImm1_16(&ArgStr[3], &EvalResult);
2678
  if (!EvalResult.OK)
2679
    return;
2680
 
2681
  switch (DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModDirect | MModIndexed, &RegAdrVals))
2682
  {
2683
    case eModReg:
2684
      RegArgIndex = 1;
2685
      if (!DecodeAdr(&ArgStr[2], MModIReg | MModDirect | MModIndexed, &MemAdrVals))
2686
        return;
2687
      goto common;
2688
    case eModIReg:
2689
    case eModDirect:
2690
    case eModIndexed:
2691
      MemAdrVals = RegAdrVals;
2692
      Code |= 0x0008;
2693
      if (!DecodeAdr(&ArgStr[2], MModReg, &RegAdrVals))
2694
        return;
2695
      RegArgIndex = 2;
2696
      /* fall-thru */
2697
    common:
2698
      if (OpSize != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[RegArgIndex]);
2699
      else
2700
      {
2701
        if (RegAdrVals.Val + Count >= 16) WrStrErrorPos(ErrNum_RegNumWraparound, &ArgStr[3]);
2702
        switch (MemAdrVals.Mode)
2703
        {
2704
          case eModIReg:
2705
            AppendCode(Code | (MemAdrVals.Val << 4));
2706
            AppendCode((RegAdrVals.Val << 8) | Count);
2707
            break;
2708
          case eModDirect:
2709
          case eModIndexed:
2710
            AppendCode(Code | 0x4000 | (MemAdrVals.Val << 4));
2711
            AppendCode((RegAdrVals.Val << 8) | Count);
2712
            AppendAdrVals(&MemAdrVals);
2713
            break;
2714
          default:
2715
            break;
2716
        }
2717
      }
2718
      break;
2719
    default:
2720
      break;
2721
  }
2722
}
2723
 
2724
/*!------------------------------------------------------------------------
2725
 * \fn     DecodeLDPS(Word Code)
2726
 * \brief  decode LDPS instruction
2727
 * \param  Code machine code
2728
 * ------------------------------------------------------------------------ */
2729
 
2730
static void DecodeLDPS(Word Code)
2731
{
2732
  tAdrVals AdrVals;
2733
 
2734
  if (ChkArgCnt(1, 1)
2735
   && CheckSup(True))
2736
    switch (DecodeAdr(&ArgStr[1], MModIReg | MModDirect | MModIndexed, &AdrVals))
2737
    {
2738
      case eModIReg:
2739
        AppendCode(Code | 0x0000 | (AdrVals.Val << 4));
2740
        break;
2741
      case eModDirect:
2742
      case eModIndexed:
2743
        AppendCode(Code | 0x4000 | (AdrVals.Val << 4));
2744
        AppendAdrVals(&AdrVals);
2745
        break;
2746
      default:
2747
        break;
2748
    }
2749
}
2750
 
2751
/*!------------------------------------------------------------------------
2752
 * \fn     DecodeMREQ(Word Code)
2753
 * \brief  decode MREQ instruction
2754
 * \param  Code instruction code
2755
 * ------------------------------------------------------------------------ */
2756
 
2757
static void DecodeMREQ(Word Code)
2758
{
2759
  tAdrVals AdrVals;
2760
 
2761
  SetOpSize(eSymbolSize16Bit, &OpPart);
2762
  if (ChkArgCnt(1, 1)
2763
   && CheckSup(True)
2764
   && DecodeAdr(&ArgStr[1], MModReg, &AdrVals))
2765
    AppendCode(Code | (AdrVals.Val << 4));
2766
}
2767
 
2768
/*!------------------------------------------------------------------------
2769
 * \fn     DecodePUSH_POP(Word Code)
2770
 * \brief  decode PUSH(L)/POP(L)
2771
 * \param  Code machine code & size
2772
 * ------------------------------------------------------------------------ */
2773
 
2774
static void DecodePUSH_POP(Word Code)
2775
{
2776
  tAdrVals RegAdrVals;
2777
  Word IsPOP = Code & 0x04;
2778
  int OpArg = !IsPOP + 1, RegArg = 3 - OpArg;
2779
 
2780
  if (SetOpSizeFromCode(Code)
2781
   && ChkArgCnt(2, 2)
2782
   && DecodeAdr(&ArgStr[RegArg], MModIReg, &RegAdrVals))
2783
  {
2784
    tAdrVals OpAdrVals;
2785
 
2786
    ImmOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
2787
    if (DecodeAdr(&ArgStr[OpArg], MModReg | MModIReg | MModDirect | MModIndexed | (IsPOP ? 0 : MModImm), &OpAdrVals))
2788
    {
2789
      int Index;
2790
 
2791
      if (OpSize == eSymbolSizeUnknown)
2792
        OpSize = eSymbolSize16Bit;
2793
      if ((OpSize < eSymbolSize16Bit) || (OpSize > eSymbolSize32Bit))
2794
      {
2795
        WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[OpArg]);
2796
        return;
2797
      }
2798
      switch (OpAdrVals.Mode)
2799
      {
2800
        case eModReg:
2801
          Index = ChkRegOverlap((unsigned)OpAdrVals.Val, OpSize,
2802
                                (unsigned)RegAdrVals.Val, (int)AddrRegSize(),
2803
                                0, eSymbolSizeUnknown);
2804
          break;
2805
        case eModIReg:
2806
          Index = ChkRegOverlap((unsigned)OpAdrVals.Val, AddrRegSize(),
2807
                                (unsigned)RegAdrVals.Val, (int)AddrRegSize(),
2808
                                0, eSymbolSizeUnknown);
2809
          break;
2810
        case eModIndexed:
2811
          Index = ChkRegOverlap((unsigned)OpAdrVals.Val, eSymbolSize16Bit,
2812
                                (unsigned)RegAdrVals.Val, (int)AddrRegSize(),
2813
                                0, eSymbolSizeUnknown);
2814
          break;
2815
        default:
2816
          Index = -1;
2817
          break;
2818
      }
2819
      if (Index >= 0)
2820
        WrStrErrorPos(ErrNum_OverlapReg, &ArgStr[Index ? RegArg : OpArg]);
2821
      Code = Lo(Code) | ((OpSize == eSymbolSize16Bit) ? 2 : 0);
2822
      switch (OpAdrVals.Mode)
2823
      {
2824
        case eModImm:
2825
          if (OpSize != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &OpPart);
2826
          else
2827
          {
2828
            AppendCode(0x0d09 | (RegAdrVals.Val << 4));
2829
            AppendAdrVals(&OpAdrVals);
2830
          }
2831
          break;
2832
        case eModReg:
2833
          AppendCode(0x8000 | (Code << 8) | (RegAdrVals.Val << 4) | OpAdrVals.Val);
2834
          break;
2835
        case eModIReg:
2836
          AppendCode(0x0000 | (Code << 8) | (RegAdrVals.Val << 4) | OpAdrVals.Val);
2837
          break;
2838
        case eModDirect:
2839
        case eModIndexed:
2840
          AppendCode(0x4000 | (Code << 8) | (RegAdrVals.Val << 4) | OpAdrVals.Val);
2841
          AppendAdrVals(&OpAdrVals);
2842
          break;
2843
        default:
2844
          break;
2845
      }
2846
    }
2847
  }
2848
}
2849
 
2850
/*!------------------------------------------------------------------------
2851
 * \fn     DecodeRET(Word Code)
2852
 * \brief  decode RET instruction
2853
 * \param  Code machine code
2854
 * ------------------------------------------------------------------------ */
2855
 
2856
static void DecodeRET(Word Code)
2857
{
2858
  Word Condition;
2859
 
2860
  if (ChkArgCnt(0, 1)
2861
   && DecodeCondition((ArgCnt >= 1) ? &ArgStr[1] : NULL, &Condition))
2862
    AppendCode(Code | Condition);
2863
}
2864
 
2865
/*!------------------------------------------------------------------------
2866
 * \fn     DecodeRotate(Word Code)
2867
 * \brief  handle rotate instructions
2868
 * \param  Code machine code
2869
 * ------------------------------------------------------------------------ */
2870
 
2871
static void DecodeRotate(Word Code)
2872
{
2873
  tAdrVals RegAdrVals;
2874
 
2875
  if (ChkArgCnt(1, 2)
2876
   && SetOpSizeFromCode(Code)
2877
   && DecodeAdr(&ArgStr[1], MModReg, &RegAdrVals))
2878
  {
2879
    Word Count = 1;
2880
    tEvalResult EvalResult;
2881
 
2882
    if (OpSize > eSymbolSize16Bit)
2883
    {
2884
      WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
2885
      return;
2886
    }
2887
    if (ArgCnt >= 2)
2888
    {
2889
      Count = EvalStrIntExpressionOffsWithResult(&ArgStr[2], !!(*ArgStr[2].str.p_str == '#'), UInt2, &EvalResult);
2890
      if (EvalResult.OK && mFirstPassUnknownOrQuestionable(EvalResult.Flags))
2891
        Count = 1;
2892
    }
2893
    if (ChkRange(Count, 1, 2))
2894
      AppendCode(0xb200 | (OpSize << 8) | (RegAdrVals.Val << 4) | Lo(Code) | ((Count - 1) << 1));
2895
  }
2896
}
2897
 
2898
/*!------------------------------------------------------------------------
2899
 * \fn     DecodeRotateDigit(Word Code)
2900
 * \brief  decode nibble-wide rotates
2901
 * \param  Code machine code
2902
 * ------------------------------------------------------------------------ */
2903
 
2904
static void DecodeRotateDigit(Word Code)
2905
{
2906
  tAdrVals LinkAdrVals, SrcAdrVals;
2907
 
2908
  SetOpSize(eSymbolSize8Bit, &OpPart);
2909
  if (ChkArgCnt(2, 2)
2910
   && DecodeAdr(&ArgStr[1], MModReg, &LinkAdrVals)
2911
   && DecodeAdr(&ArgStr[2], MModReg, &SrcAdrVals))
2912
    AppendCode(Code | (SrcAdrVals.Val << 4) | LinkAdrVals.Val);
2913
}
2914
 
2915
/*!------------------------------------------------------------------------
2916
 * \fn     DecodeSC(Word Code)
2917
 * \brief  decode SC instruction
2918
 * \param  Code machine code
2919
 * ------------------------------------------------------------------------ */
2920
 
2921
static void DecodeSC(Word Code)
2922
{
2923
  if (ChkArgCnt(1, 1))
2924
  {
2925
    Boolean OK;
2926
    Word Arg = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), Int8, &OK);
2927
 
2928
    if (OK)
2929
      AppendCode(Code | (Arg & 0xff));
2930
  }
2931
}
2932
 
2933
/*!------------------------------------------------------------------------
2934
 * \fn     DecodeSD(Word Code)
2935
 * \brief  decode dynamic shifts
2936
 * \param  Code machine code
2937
 * ------------------------------------------------------------------------ */
2938
 
2939
static void DecodeSD(Word Code)
2940
{
2941
  tAdrVals DestAdrVals;
2942
 
2943
  if (ChkArgCnt(2, 2)
2944
   && SetOpSizeFromCode(Code)
2945
   && DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals))
2946
  {
2947
    tAdrVals SrcAdrVals;
2948
    tSymbolSize SaveOpSize = (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize;
2949
 
2950
    if (SaveOpSize > eSymbolSize32Bit)
2951
    {
2952
      WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
2953
      return;
2954
    }
2955
    OpSize = eSymbolSize16Bit;
2956
    if (DecodeAdr(&ArgStr[2], MModReg, &SrcAdrVals))
2957
    {
2958
      AppendCode(0xb200 | (((SaveOpSize == eSymbolSize32Bit) ? 1 : SaveOpSize) << 8) | (DestAdrVals.Val << 4) | Lo(Code) | (SaveOpSize == eSymbolSize32Bit ? 4 : 0));
2959
      AppendCode(SrcAdrVals.Val << 8);
2960
    }
2961
  }
2962
}
2963
 
2964
/*!------------------------------------------------------------------------
2965
 * \fn     DecodeShift(Word Code)
2966
 * \brief  decode statuc shifts
2967
 * \param  Code machine code
2968
 * ------------------------------------------------------------------------ */
2969
 
2970
static void DecodeShift(Word Code)
2971
{
2972
  tAdrVals DestAdrVals;
2973
 
2974
  if (ChkArgCnt(1, 2)
2975
   && SetOpSizeFromCode(Code)
2976
   && DecodeAdr(&ArgStr[1], MModReg, &DestAdrVals))
2977
  {
2978
    Word Count;
2979
    Word Negate = Code & 0x80;
2980
 
2981
    if (OpSize == eSymbolSizeUnknown)
2982
      OpSize = eSymbolSize16Bit;
2983
    if (OpSize > eSymbolSize32Bit)
2984
    {
2985
      WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
2986
      return;
2987
    }
2988
 
2989
    if (ArgCnt >= 2)
2990
    {
2991
      tEvalResult EvalResult;
2992
 
2993
      Count = EvalStrIntExpressionOffsWithResult(&ArgStr[2], !!(*ArgStr[2].str.p_str == '#'), (OpSize == eSymbolSize32Bit) ? UInt6 : (OpSize == eSymbolSize16Bit) ? UInt5 : UInt4, &EvalResult);
2994
      if (mFirstPassUnknownOrQuestionable(EvalResult.Flags))
2995
        Count = 1;
2996
      if (!ChkRange(Count, Negate ? 1 : 0, 8 << OpSize))
2997
        return;
2998
    }
2999
    else
3000
      Count = 1;
3001
 
3002
    if (Negate)
3003
    {
3004
      Code ^= Negate;
3005
      Count = 0x10000ul - Count;
3006
      if (OpSize == eSymbolSize8Bit)
3007
        Count &= 0xff;
3008
    }
3009
    AppendCode(0xb200 | (((OpSize == eSymbolSize32Bit) ? 1 : OpSize) << 8) | (DestAdrVals.Val << 4) | Lo(Code) | (OpSize == eSymbolSize32Bit ? 4 : 0));
3010
    AppendCode(Count);
3011
  }
3012
}
3013
 
3014
/*!------------------------------------------------------------------------
3015
 * \fn     DecodeTCC(Word Code)
3016
 * \brief  decode TCC instruction
3017
 * \param  Code machine code
3018
 * ------------------------------------------------------------------------ */
3019
 
3020
static void DecodeTCC(Word Code)
3021
{
3022
  Word Condition;
3023
  tAdrVals DestAdrVals;
3024
 
3025
  if (ChkArgCnt(1, 2)
3026
   && SetOpSizeFromCode(Code)
3027
   && DecodeCondition((ArgCnt == 2) ? &ArgStr[1] : NULL, &Condition)
3028
   && DecodeAdr(&ArgStr[ArgCnt], MModReg, &DestAdrVals))
3029
  {
3030
    if (OpSize > eSymbolSize16Bit)
3031
    {
3032
      WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[2]);
3033
      return;
3034
    }
3035
    AppendCode(0xae00 | (OpSize << 8) | (DestAdrVals.Val << 4) | Condition);
3036
  }
3037
}
3038
 
3039
/*!------------------------------------------------------------------------
3040
 * \fn     DecodePORT(Word Code)
3041
 * \brief  decode PORT instruction
3042
 * ------------------------------------------------------------------------ */
3043
 
3044
static void DecodePORT(Word Code)
3045
{
3046
  UNUSED(Code);
3047
  CodeEquate(SegIO, 0, SegLimits[SegIO]);
3048
}
3049
 
3050
/*!------------------------------------------------------------------------
3051
 * \fn     DecodeDEFBIT(Word Code)
3052
 * \brief  decode DEFBIT(B) instructions
3053
 * \param  Code machine code
3054
 * ------------------------------------------------------------------------ */
3055
 
3056
static void DecodeDEFBIT(Word Code)
3057
{
3058
  LongWord BitSpec;
3059
 
3060
  OpSize = (tSymbolSize)Code;
3061
 
3062
  /* if in structure definition, add special element to structure */
3063
 
3064
  if (ActPC == StructSeg)
3065
  {
3066
    Boolean OK;
3067
    Byte BitPos;
3068
    PStructElem pElement;
3069
 
3070
    if (!ChkArgCnt(2, 2))
3071
      return;
3072
    BitPos = EvalBitPosition(&ArgStr[2], &OK, OpSize);
3073
    if (!OK)
3074
      return;
3075
    pElement = CreateStructElem(&LabPart);
3076
    if (!pElement)
3077
      return;
3078
    pElement->pRefElemName = as_strdup(ArgStr[1].str.p_str);
3079
    pElement->OpSize = OpSize;
3080
    pElement->BitPos = BitPos;
3081
    pElement->ExpandFnc = ExpandZ8000Bit;
3082
    AddStructElem(pInnermostNamedStruct->StructRec, pElement);
3083
  }
3084
  else
3085
  {
3086
    if (DecodeBitArg(&BitSpec, 1, ArgCnt, OpSize))
3087
    {
3088
      *ListLine = '=';
3089
      DissectBit_Z8000(ListLine + 1, STRINGSIZE - 3, BitSpec);
3090
      PushLocHandle(-1);
3091
      EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
3092
      PopLocHandle();
3093
      /* TODO: MakeUseList? */
3094
    }
3095
  }
3096
}
3097
 
3098
/*--------------------------------------------------------------------------*/
3099
/* Instruction Table Buildup/Teardown */
3100
 
3101
/*!------------------------------------------------------------------------
3102
 * \fn     InitFields(void)
3103
 * \brief  Set up hash table
3104
 * ------------------------------------------------------------------------ */
3105
 
3106
static void AddFixed(const char *NName, Word Code, Boolean Privileged)
3107
{
3108
  order_array_rsv_end(FixedOrders, FixedOrder);
3109
  FixedOrders[InstrZ].Code = Code;
3110
  FixedOrders[InstrZ].Privileged = Privileged;
3111
  AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
3112
}
3113
 
3114
static void AddCtl(const char *pName, Word Code, tCtlFlags Flags, tSymbolSize Size)
3115
{
3116
  order_array_rsv_end(CtlRegs, tCtlReg);
3117
  CtlRegs[InstrZ  ].pName = pName;
3118
  CtlRegs[InstrZ  ].Code  = Code;
3119
  CtlRegs[InstrZ  ].Flags = Flags;
3120
  CtlRegs[InstrZ++].Size  = Size;
3121
}
3122
 
3123
static void AddCondition(const char *pName, Word Code)
3124
{
3125
  order_array_rsv_end(Conditions, tCondition);
3126
  Conditions[InstrZ].pName = pName;
3127
  Conditions[InstrZ++].Code = Code;
3128
}
3129
 
3130
static void AddSizeInstTable(const char *pName, unsigned SizeMask, Word Code, InstProc Proc)
3131
{
3132
  char Name[20];
3133
 
3134
  AddInstTable(InstTable, pName, Code | 0xff00, Proc);
3135
  if (SizeMask & (1 << eSymbolSize8Bit))
3136
  {
3137
    as_snprintf(Name, sizeof(Name), "%sB", pName);
3138
    AddInstTable(InstTable, Name, Code | (eSymbolSize8Bit << 8), Proc);
3139
  }
3140
  if (SizeMask & (1 << eSymbolSize32Bit))
3141
  {
3142
    as_snprintf(Name, sizeof(Name), "%sL", pName);
3143
    AddInstTable(InstTable, Name, Code | (eSymbolSize32Bit << 8), Proc);
3144
  }
3145
}
3146
 
3147
static void InitFields(void)
3148
{
3149
  InstTable = CreateInstTable(302);
3150
  SetDynamicInstTable(InstTable);
3151
 
3152
  add_null_pseudo(InstTable);
3153
 
3154
  InstrZ = 0;
3155
  AddFixed("HALT" , 0x7a00 , True );
3156
  AddFixed("IRET" , 0x7b00 , True );
3157
  AddFixed("MBIT" , 0x7b0a , True );
3158
  AddFixed("MRES" , 0x7b09 , True );
3159
  AddFixed("MSET" , 0x7b08 , True );
3160
  AddFixed("NOP"  , NOPCode, False);
3161
 
3162
  InstrZ = 0;
3163
  AddCtl("FCW"     , 2, ePrivileged | eSegMode | eNonSegMode , eSymbolSize16Bit);
3164
  AddCtl("REFRESH" , 3, ePrivileged | eSegMode | eNonSegMode , eSymbolSize16Bit);
3165
  AddCtl("PSAPSEG" , 4, ePrivileged | eSegMode               , eSymbolSize16Bit);
3166
  AddCtl("PSAPOFF" , 5, ePrivileged | eSegMode | eNonSegMode , eSymbolSize16Bit);
3167
  AddCtl("PSAP"    , 5, ePrivileged            | eNonSegMode , eSymbolSize16Bit);
3168
  AddCtl("NSPSEG"  , 6, ePrivileged | eSegMode               , eSymbolSize16Bit);
3169
  AddCtl("NSPOFF"  , 7, ePrivileged | eSegMode | eNonSegMode , eSymbolSize16Bit);
3170
  AddCtl("NSP"     , 7, ePrivileged            | eNonSegMode , eSymbolSize16Bit);
3171
  AddCtl("FLAGS"   , 1,               eSegMode | eNonSegMode , eSymbolSize8Bit );
3172
  CtlRegCnt = InstrZ;
3173
 
3174
  InstrZ = 0;
3175
  AddCondition(""   , 0x08);
3176
  AddCondition("F"  , 0x00);
3177
  AddCondition("LT" , 0x01);
3178
  AddCondition("LE" , 0x02);
3179
  AddCondition("ULE", 0x03);
3180
  AddCondition("PE" , 0x04);
3181
  AddCondition("MI" , 0x05);
3182
  AddCondition("Z"  , 0x06);
3183
  AddCondition("ULT", 0x07);
3184
  AddCondition("GE" , 0x09);
3185
  AddCondition("GT" , 0x0a);
3186
  AddCondition("UGT", 0x0b);
3187
  AddCondition("PO" , 0x0c);
3188
  AddCondition("PL" , 0x0d);
3189
  AddCondition("NZ" , 0x0e);
3190
  AddCondition("UGE", 0x0f);
3191
  AddCondition("OV" , 0x04);
3192
  AddCondition("EQ" , 0x06);
3193
  AddCondition("C"  , 0x07);
3194
  AddCondition("NOV", 0x0c);
3195
  AddCondition("NE" , 0x0e);
3196
  AddCondition("NC" , 0x0f);
3197
 
3198
  /* non-Zilog conditions */
3199
 
3200
  AddCondition("ZR" , 0x06);
3201
  AddCondition("CY" , 0x07);
3202
  AddCondition("LLE", 0x03);
3203
  AddCondition("LLT", 0x07);
3204
  AddCondition("LGT", 0x0b);
3205
  AddCondition("LGE", 0x0f);
3206
  AddCondition(NULL , 0);
3207
 
3208
 
3209
  AddSizeInstTable("LD"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0, DecodeLD);
3210
  AddInstTable(InstTable, "LDA" , 0, DecodeLDA);
3211
  AddInstTable(InstTable, "LDAR", 0x3400, DecodeLDAR);
3212
  AddInstTable(InstTable, "LDK" , 0xbd00, DecodeLDK);
3213
  AddInstTable(InstTable, "LDM" , 0x1c01, DecodeLDM);
3214
  AddInstTable(InstTable, "LDPS", 0x3900, DecodeLDPS);
3215
  AddSizeInstTable("LDR", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x30, DecodeLDR);
3216
  AddSizeInstTable("LDCTL", 1 << eSymbolSize8Bit, 0x00, DecodeLDCTL);
3217
  AddSizeInstTable("ADD" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0, DecodeADD);
3218
  AddSizeInstTable("SUB" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0, DecodeSUB);
3219
  AddSizeInstTable("CP"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0, DecodeCP);
3220
  AddSizeInstTable("ADC" , 1 << eSymbolSize8Bit, 0x34, DecodeADC_SBC);
3221
  AddSizeInstTable("SBC" , 1 << eSymbolSize8Bit, 0x36, DecodeADC_SBC);
3222
  AddSizeInstTable("AND" , 1 << eSymbolSize8Bit, 0x06, DecodeAND_OR_XOR);
3223
  AddSizeInstTable("OR"  , 1 << eSymbolSize8Bit, 0x04, DecodeAND_OR_XOR);
3224
  AddSizeInstTable("XOR" , 1 << eSymbolSize8Bit, 0x08, DecodeAND_OR_XOR);
3225
  AddSizeInstTable("INC" , 1 << eSymbolSize8Bit, 0x28, DecodeINC_DEC);
3226
  AddSizeInstTable("DEC" , 1 << eSymbolSize8Bit, 0x2a, DecodeINC_DEC);
3227
  AddSizeInstTable("BIT" , 1 << eSymbolSize8Bit, 0x26, DecodeBitOp);
3228
  AddSizeInstTable("DIV" , 1 << eSymbolSize32Bit, 0x1a, DecodeMULT_DIV);
3229
  AddSizeInstTable("MULT", 1 << eSymbolSize32Bit, 0x18, DecodeMULT_DIV);
3230
  AddSizeInstTable("RES" , 1 << eSymbolSize8Bit, 0x22, DecodeBitOp);
3231
  AddSizeInstTable("SET" , 1 << eSymbolSize8Bit, 0x24, DecodeBitOp);
3232
  AddInstTable(InstTable, "CALL", 0x1f, DecodeCALL_JP);
3233
  AddInstTable(InstTable, "JP"  , 0x1e, DecodeCALL_JP);
3234
  AddInstTable(InstTable, "CALR", 0xd000, DecodeCALR);
3235
  AddInstTable(InstTable, "JR"  , 0xe000, DecodeJR);
3236
  AddInstTable(InstTable, "DJNZ" , 0xff00, DecodeDJNZ);
3237
  AddInstTable(InstTable, "DBJNZ", eSymbolSize8Bit << 8, DecodeDJNZ);
3238
  AddInstTable(InstTable, "RET", 0x9e00, DecodeRET);
3239
  AddSizeInstTable("CLR" , 1 << eSymbolSize8Bit, 0x8c, DecodeCLR_COM_NEG_TSET);
3240
  AddSizeInstTable("COM" , 1 << eSymbolSize8Bit, 0x0c, DecodeCLR_COM_NEG_TSET);
3241
  AddSizeInstTable("NEG" , 1 << eSymbolSize8Bit, 0x2c, DecodeCLR_COM_NEG_TSET);
3242
  AddSizeInstTable("TSET", 1 << eSymbolSize8Bit, 0x6c, DecodeCLR_COM_NEG_TSET);
3243
  AddSizeInstTable("TEST", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x0c, DecodeTEST);
3244
  AddSizeInstTable("EX", 1 << eSymbolSize8Bit, 0x2c, DecodeEX);
3245
  AddSizeInstTable("EXTS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x31, DecodeEXTS);
3246
  AddInstTable(InstTable, "DAB", 0xb000, DecodeDAB);
3247
  AddInstTable(InstTable, "COMFLG", 0x8d05, DecodeFLG);
3248
  AddInstTable(InstTable, "SETFLG", 0x8d01, DecodeFLG);
3249
  AddInstTable(InstTable, "RESFLG", 0x8d03, DecodeFLG);
3250
  AddInstTable(InstTable, "DI", 0x7c00, DecodeDI_EI);
3251
  AddInstTable(InstTable, "EI", 0x7c04, DecodeDI_EI);
3252
  AddInstTable(InstTable, "MREQ", 0x7b0d, DecodeMREQ);
3253
  AddSizeInstTable("IN"  , 1 << eSymbolSize8Bit, 0x00, DecodeIN_SIN_OUT_SOUT);
3254
  AddSizeInstTable("SIN" , 1 << eSymbolSize8Bit, 0x01, DecodeIN_SIN_OUT_SOUT);
3255
  AddSizeInstTable("OUT" , 1 << eSymbolSize8Bit, 0x02, DecodeIN_SIN_OUT_SOUT);
3256
  AddSizeInstTable("SOUT", 1 << eSymbolSize8Bit, 0x03, DecodeIN_SIN_OUT_SOUT);
3257
  AddSizeInstTable("CPD"  , 1 << eSymbolSize8Bit, 0x08, DecodeCPRep);
3258
  AddSizeInstTable("CPDR" , 1 << eSymbolSize8Bit, 0x0c, DecodeCPRep);
3259
  AddSizeInstTable("CPI"  , 1 << eSymbolSize8Bit, 0x00, DecodeCPRep);
3260
  AddSizeInstTable("CPIR" , 1 << eSymbolSize8Bit, 0x04, DecodeCPRep);
3261
  AddSizeInstTable("CPSD" , 1 << eSymbolSize8Bit, 0x0a, DecodeCPRep);
3262
  AddSizeInstTable("CPSDR", 1 << eSymbolSize8Bit, 0x0e, DecodeCPRep);
3263
  AddSizeInstTable("CPSI" , 1 << eSymbolSize8Bit, 0x02, DecodeCPRep);
3264
  AddSizeInstTable("CPSIR", 1 << eSymbolSize8Bit, 0x06, DecodeCPRep);
3265
  AddSizeInstTable("IND"  , 1 << eSymbolSize8Bit, 0x88, DecodeINOUTRep);
3266
  AddSizeInstTable("INDR" , 1 << eSymbolSize8Bit, 0x80, DecodeINOUTRep);
3267
  AddSizeInstTable("SIND" , 1 << eSymbolSize8Bit, 0x98, DecodeINOUTRep);
3268
  AddSizeInstTable("SINDR", 1 << eSymbolSize8Bit, 0x90, DecodeINOUTRep);
3269
  AddSizeInstTable("INI"  , 1 << eSymbolSize8Bit, 0x08, DecodeINOUTRep);
3270
  AddSizeInstTable("INIR" , 1 << eSymbolSize8Bit, 0x00, DecodeINOUTRep);
3271
  AddSizeInstTable("SINI" , 1 << eSymbolSize8Bit, 0x18, DecodeINOUTRep);
3272
  AddSizeInstTable("SINIR", 1 << eSymbolSize8Bit, 0x10, DecodeINOUTRep);
3273
  AddSizeInstTable("OUTD" , 1 << eSymbolSize8Bit, 0xa8, DecodeINOUTRep);
3274
  AddSizeInstTable("OTDR" , 1 << eSymbolSize8Bit, 0xa0, DecodeINOUTRep);
3275
  AddSizeInstTable("SOUTD", 1 << eSymbolSize8Bit, 0xb8, DecodeINOUTRep);
3276
  AddSizeInstTable("SOTDR", 1 << eSymbolSize8Bit, 0xb0, DecodeINOUTRep);
3277
  AddSizeInstTable("OUTI" , 1 << eSymbolSize8Bit, 0x28, DecodeINOUTRep);
3278
  AddSizeInstTable("OTIR" , 1 << eSymbolSize8Bit, 0x20, DecodeINOUTRep);
3279
  AddSizeInstTable("SOUTI", 1 << eSymbolSize8Bit, 0x38, DecodeINOUTRep);
3280
  AddSizeInstTable("SOTIR", 1 << eSymbolSize8Bit, 0x30, DecodeINOUTRep);
3281
  AddSizeInstTable("LDD"  , 1 << eSymbolSize8Bit, 0x98, DecodeLDRep);
3282
  AddSizeInstTable("LDDR" , 1 << eSymbolSize8Bit, 0x90, DecodeLDRep);
3283
  AddSizeInstTable("LDI"  , 1 << eSymbolSize8Bit, 0x18, DecodeLDRep);
3284
  AddSizeInstTable("LDIR" , 1 << eSymbolSize8Bit, 0x10, DecodeLDRep);
3285
  AddInstTable(InstTable, "TRDB"  , 0x80, DecodeTRRep);
3286
  AddInstTable(InstTable, "TRDRB" , 0xc0, DecodeTRRep);
3287
  AddInstTable(InstTable, "TRIB"  , 0x00, DecodeTRRep);
3288
  AddInstTable(InstTable, "TRIRB" , 0x40, DecodeTRRep);
3289
  AddInstTable(InstTable, "TRTDB" , 0xa0, DecodeTRRep);
3290
  AddInstTable(InstTable, "TRTDRB", 0xee, DecodeTRRep);
3291
  AddInstTable(InstTable, "TRTIB" , 0x20, DecodeTRRep);
3292
  AddInstTable(InstTable, "TRTIRB", 0x6e, DecodeTRRep);
3293
  AddSizeInstTable("POP"  , 1 << eSymbolSize32Bit, 0x15, DecodePUSH_POP);
3294
  AddSizeInstTable("PUSH" , 1 << eSymbolSize32Bit, 0x11, DecodePUSH_POP);
3295
  AddSizeInstTable("RL"   , 1 << eSymbolSize8Bit, 0x00, DecodeRotate);
3296
  AddSizeInstTable("RLC"  , 1 << eSymbolSize8Bit, 0x08, DecodeRotate);
3297
  AddSizeInstTable("RR"   , 1 << eSymbolSize8Bit, 0x04, DecodeRotate);
3298
  AddSizeInstTable("RRC"  , 1 << eSymbolSize8Bit, 0x0c, DecodeRotate);
3299
  AddInstTable(InstTable, "RLDB" , 0xbe00, DecodeRotateDigit);
3300
  AddInstTable(InstTable, "RRDB" , 0xbc00, DecodeRotateDigit);
3301
  AddSizeInstTable("SDA", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x0b, DecodeSD);
3302
  AddSizeInstTable("SDL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x03, DecodeSD);
3303
  AddSizeInstTable("SLA", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x09, DecodeShift);
3304
  AddSizeInstTable("SLL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x01, DecodeShift);
3305
  AddSizeInstTable("SRA", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x89, DecodeShift);
3306
  AddSizeInstTable("SRL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize32Bit), 0x81, DecodeShift);
3307
  AddInstTable(InstTable, "SC", 0x7f00, DecodeSC);
3308
  AddSizeInstTable("TCC", 1 << eSymbolSize8Bit, 0x00, DecodeTCC);
3309
 
3310
  AddInstTable(InstTable, "PORT", 0, DecodePORT);
3311
  AddInstTable(InstTable, "REG" , 0, CodeREG);
3312
  AddInstTable(InstTable, "DEFBIT" , eSymbolSize16Bit, DecodeDEFBIT);
3313
  AddInstTable(InstTable, "DEFBITB", eSymbolSize8Bit , DecodeDEFBIT);
3314
 
3315
  AddIntelPseudo(InstTable, eIntPseudoFlag_BigEndian);
3316
}
3317
 
3318
/*!------------------------------------------------------------------------
3319
 * \fn     DeinitFields(void)
3320
 * \brief  Tear down hash table
3321
 * ------------------------------------------------------------------------ */
3322
 
3323
static void DeinitFields(void)
3324
{
3325
  order_array_free(CtlRegs);
3326
  order_array_free(FixedOrders);
3327
  order_array_free(Conditions);
3328
 
3329
  DestroyInstTable(InstTable);
3330
}
3331
 
3332
/*---------------------------------------------------------------------*/
3333
 
3334
/*!------------------------------------------------------------------------
3335
 * \fn     MakeCode_Z8000(void)
3336
 * \brief  encode machine instruction
3337
 * ------------------------------------------------------------------------ */
3338
 
3339
static void MakeCode_Z8000(void)
3340
{
3341
  ImmOpSize = OpSize = eSymbolSizeUnknown;
3342
 
3343
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
3344
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
3345
}
3346
 
3347
/*!------------------------------------------------------------------------
3348
 * \fn     InternSymbol_Z8000(char *pArg, TempResult *pResult)
3349
 * \brief  handle built-in symbols on Z8000
3350
 * \param  pArg source argument
3351
 * \param  pResult result buffer
3352
 * ------------------------------------------------------------------------ */
3353
 
3354
static void InternSymbol_Z8000(char *pArg, TempResult *pResult)
3355
{
3356
  Word Reg;
3357
  tSymbolSize Size;
3358
 
3359
  if (DecodeRegCore(pArg, &Reg, &Size))
3360
  {
3361
    pResult->Typ = TempReg;
3362
    pResult->DataSize = Size;
3363
    pResult->Contents.RegDescr.Reg = Reg;
3364
    pResult->Contents.RegDescr.Dissect = DissectReg_Z8000;
3365
    pResult->Contents.RegDescr.compare = NULL;
3366
  }
3367
}
3368
 
3369
/*!------------------------------------------------------------------------
3370
 * \fn     IsDef_Z8000(void)
3371
 * \brief  check whether insn makes own use of label
3372
 * \return True if yes
3373
 * ------------------------------------------------------------------------ */
3374
 
3375
static Boolean IsDef_Z8000(void)
3376
{
3377
  return Memo("REG")
3378
      || Memo("PORT")
3379
      || Memo("DEFBIT")
3380
      || Memo("DEFBITB");
3381
}
3382
 
3383
/*!------------------------------------------------------------------------
3384
 * \fn     PotOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
3385
 * \brief  special ^ operator for AMD syntax
3386
 * \param  pErg operator result
3387
 * \param  pRVal input argument
3388
 * ------------------------------------------------------------------------ */
3389
 
3390
static Boolean PotMonadicOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
3391
{
3392
  UNUSED(pLVal);
3393
  if (!pRVal)
3394
    return False;
3395
 
3396
  /* If in front of a label, takes the address as an 'untyped' value.  This
3397
     will instruct the address decoder to use immediate instead of direct
3398
     addressing: */
3399
 
3400
  if (pRVal->AddrSpaceMask)
3401
    pErg->AddrSpaceMask = 0;
3402
 
3403
  /* Vice-versa, for a constant, this makes an address of it: */
3404
 
3405
  else
3406
    pErg->AddrSpaceMask |= (1 << SegCode);
3407
 
3408
  /* clone remainder as-is */
3409
 
3410
  pErg->Typ = pRVal->Typ;
3411
  pErg->Contents = pRVal->Contents;
3412
  pErg->Flags |= (pLVal->Flags & eSymbolFlags_Promotable);
3413
  if (pErg->DataSize == eSymbolSizeUnknown) pErg->DataSize = pLVal->DataSize;
3414
  return True;
3415
}
3416
 
3417
static const as_operator_t z8000_operators[] =
3418
{
3419
  { "^" ,1 , e_op_monadic, 8, { TempInt | (TempInt << 4), 0, 0, 0 }, PotMonadicOp},
3420
  {NULL, 0 , e_op_monadic,  0, { 0, 0, 0, 0, 0 }, NULL}
3421
};
3422
 
3423
/*!------------------------------------------------------------------------
3424
 * \fn     SwitchTo_Z8000(void *pUser)
3425
 * \brief  prepare to assemble code for this target
3426
 * \param  pUser CPU properties
3427
 * ------------------------------------------------------------------------ */
3428
 
3429
static Boolean TrueFnc(void)
3430
{
3431
  return True;
3432
}
3433
 
3434
static void SwitchTo_Z8000(void *pUser)
3435
{
3436
  const TFamilyDescr *pDescr = FindFamilyByName("Z8000");
3437
 
3438
  TurnWords = True;
3439
  SetIntConstMode(eIntConstModeIntel);
3440
 
3441
  pCurrCPUProps = (const tCPUProps*)pUser;
3442
 
3443
  PCSymbol = "$"; HeaderID = pDescr->Id;
3444
  NOPCode = 0x8d07;
3445
  DivideChars = ","; HasAttrs = False;
3446
 
3447
  ValidSegs = (1 << SegCode) | (1 << SegIO);
3448
  Grans[SegCode] = 1; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
3449
  SegLimits[SegCode] = pCurrCPUProps->SuppSegmented ? 0x7fffff : 0xffff;
3450
  Grans[SegIO] = 1; ListGrans[SegIO] = 1; SegInits[SegIO] = 0;
3451
  SegLimits[SegIO] = 0xffff;
3452
  MemIntType = Segmented() ? UInt23 : UInt16;
3453
 
3454
  MakeCode = MakeCode_Z8000;
3455
  IsDef = IsDef_Z8000;
3456
  DissectReg = DissectReg_Z8000;
3457
  DissectBit = DissectBit_Z8000;
3458
  InternSymbol = InternSymbol_Z8000;
3459
  SwitchFrom = DeinitFields;
3460
  InitFields();
3461
  SetIsOccupiedFnc = TrueFnc;
3462
  if (AMDSyntax)
3463
    target_operators = z8000_operators;
3464
  onoff_supmode_add();
3465
}
3466
 
3467
/*!------------------------------------------------------------------------
3468
 * \fn     codez8000_init(void)
3469
 * \brief  register target to AS
3470
 * ------------------------------------------------------------------------ */
3471
 
3472
static const tCPUProps CPUProps[] =
3473
{
3474
  { "Z8001" , eCoreZ8001   , True  },
3475
  { "Z8002" , eCoreZ8001   , False },
3476
  { "Z8003" , eCoreZ8003   , True  },
3477
  { "Z8004" , eCoreZ8003   , False },
3478
  { NULL    , eCoreNone    , False }
3479
};
3480
 
3481
void codez8000_init(void)
3482
{
3483
  const tCPUProps *pRun;
3484
  static const tCPUArg Z8000Args[] =
3485
  {
3486
    { "AMDSYNTAX", 0, 1, 0, &AMDSyntax },
3487
    { NULL       , 0, 0, 0, NULL       }
3488
  };
3489
 
3490
  for (pRun = CPUProps; pRun->pName; pRun++)
3491
    (void)AddCPUUserWithArgs(pRun->pName, SwitchTo_Z8000, (void*)pRun, NULL, Z8000Args);
3492
}