Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* code166.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS-Portierung                                                             */
6
/*                                                                           */
7
/* AS-Codegenerator Siemens 80C16x                                           */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
#include "stdinc.h"
12
#include <string.h>
13
#include <ctype.h>
14
 
15
#include "nls.h"
16
#include "strutil.h"
17
#include "bpemu.h"
18
#include "asmdef.h"
19
#include "asmsub.h"
20
#include "asmpars.h"
21
#include "asmitree.h"
22
#include "asmcode.h"
23
#include "asmallg.h"
24
#include "codepseudo.h"
25
#include "intpseudo.h"
26
#include "codevars.h"
27
#include "errmsg.h"
28
 
29
#include "code166.h"
30
 
31
typedef struct
32
{
33
  CPUVar MinCPU;
34
  Word Code1, Code2;
35
} BaseOrder;
36
 
37
typedef struct
38
{
39
  const char *Name;
40
  Byte Code;
41
} Condition;
42
 
43
#define COND_CODE_TRUE 0x0
44
 
45
#define DPPCount 4
46
static const char RegNames[6][5] = { "DPP0", "DPP1", "DPP2", "DPP3", "CP", "SP" };
47
 
48
static CPUVar CPU80C166, CPU80C167, CPU80C167CS;
49
 
50
static BaseOrder *FixedOrders;
51
static Condition *Conditions;
52
static int TrueCond;
53
 
54
static LongInt DPPAssumes[DPPCount];
55
static IntType MemInt, MemInt2;
56
static tSymbolSize OpSize;
57
 
58
static Boolean DPPChanged[DPPCount], N_DPPChanged[DPPCount];
59
static Boolean SPChanged, CPChanged, N_SPChanged, N_CPChanged;
60
 
61
static ShortInt ExtCounter;
62
static enum
63
{
64
  MemModeStd,       /* normal */
65
  MemModeNoCheck,   /* EXTS Rn */
66
  MemModeZeroPage,  /* EXTP Rn */
67
  MemModeFixedBank, /* EXTS nn */
68
  MemModeFixedPage  /* EXTP nn */
69
} MemMode;
70
static Word MemPage;
71
static Boolean ExtSFRs;
72
 
73
#define ASSUME166Count 4
74
static ASSUMERec ASSUME166s[ASSUME166Count] =
75
{
76
  { "DPP0", DPPAssumes + 0, 0, 15, -1, NULL },
77
  { "DPP1", DPPAssumes + 1, 0, 15, -1, NULL },
78
  { "DPP2", DPPAssumes + 2, 0, 15, -1, NULL },
79
  { "DPP3", DPPAssumes + 3, 0, 15, -1, NULL }
80
};
81
 
82
/*-------------------------------------------------------------------------*/
83
 
84
enum
85
{
86
  ModNone = -1,
87
  ModReg = 0,
88
  ModImm = 1,
89
  ModIReg = 2,
90
  ModPreDec = 3,
91
  ModPostInc = 4,
92
  ModIndex = 5,
93
  ModAbs = 6,
94
  ModMReg = 7,
95
  ModLAbs = 8
96
};
97
 
98
typedef enum
99
{
100
  eForceNone = 0,
101
  eForceShort = 1,
102
  eForceLong = 2
103
} tForceSize;
104
 
105
#define MModReg (1 << ModReg)
106
#define MModImm (1 << ModImm)
107
#define MModIReg (1 << ModIReg)
108
#define MModPreDec (1 << ModPreDec)
109
#define MModPostInc (1 << ModPostInc)
110
#define MModIndex (1 << ModIndex)
111
#define MModAbs (1 << ModAbs)
112
#define MModMReg (1 << ModMReg)
113
#define MModLAbs (1 << ModLAbs)
114
 
115
#define M_InCode (1 << 14)
116
#define M_Dest (1 << 13)
117
 
118
typedef struct
119
{
120
  Byte Mode;
121
  Byte Vals[2];
122
  ShortInt Type;
123
  tSymbolFlags SymFlags;
124
  tForceSize ForceSize;
125
  int Cnt;
126
} tAdrResult;
127
 
128
/*!------------------------------------------------------------------------
129
 * \fn     IsRegCore(const char *pArg, tRegInt *pValue, tSymbolSize *pSize)
130
 * \brief  check whether argument describes a CPU (general purpose) register
131
 * \param  pArg argument
132
 * \param  pValue resulting register # if yes
133
 * \param  pSize resulting register size if yes
134
 * \return true if yes
135
 * ------------------------------------------------------------------------ */
136
 
137
static Boolean IsRegCore(const char *pArg, tRegInt *pValue, tSymbolSize *pSize)
138
{
139
  int l = strlen(pArg);
140
  Boolean OK;
141
 
142
  if ((l < 2) || (as_toupper(*pArg) != 'R'))
143
    return False;
144
  else if ((l > 2) && (as_toupper(pArg[1]) == 'L'))
145
  {
146
    *pValue = ConstLongInt(pArg + 2, &OK, 10) << 1;
147
    *pSize = eSymbolSize8Bit;
148
    return (OK && (*pValue <= 15));
149
  }
150
  else if ((l > 2) && (as_toupper(pArg[1]) == 'H'))
151
  {
152
    *pValue = (ConstLongInt(pArg + 2, &OK, 10) << 1) + 1;
153
    *pSize = eSymbolSize8Bit;
154
    return (OK && (*pValue <= 15));
155
  }
156
  else
157
  {
158
    *pValue = ConstLongInt(pArg + 1, &OK, 10);
159
    *pSize = eSymbolSize16Bit;
160
    return (OK && (*pValue <= 15));
161
  }
162
}
163
 
164
/*!------------------------------------------------------------------------
165
 * \fn     DissectReg_166(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
166
 * \brief  dissect register symbols - C16x variant
167
 * \param  pDest destination buffer
168
 * \param  DestSize destination buffer size
169
 * \param  Value numeric register value
170
 * \param  InpSize register size
171
 * ------------------------------------------------------------------------ */
172
 
173
static void DissectReg_166(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
174
{
175
  switch (InpSize)
176
  {
177
    case eSymbolSize8Bit:
178
      as_snprintf(pDest, DestSize, "R%c%u", Value & 1 ? 'H' : 'L', (unsigned)(Value >> 1));
179
      break;
180
    case eSymbolSize16Bit:
181
      as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
182
      break;
183
    default:
184
      as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
185
  }
186
}
187
 
188
/*!------------------------------------------------------------------------
189
 * \fn     IsReg(const tStrComp *pArg, Byte *pValue, tSymbolSize *pSize, tSymbolSize ReqSize, Boolean MustBeReg)
190
 * \brief  check whether argument is a CPU register or user-defined register alias
191
 * \param  pArg argument
192
 * \param  pValue resulting register # if yes
193
 * \param  pSize resulting register size if yes
194
 * \param  ReqSize requested register size
195
 * \param  MustBeReg expecting register or maybe not?
196
 * \return reg eval result
197
 * ------------------------------------------------------------------------ */
198
 
199
/* NOTE: If requester register size is 8 bits, R0..R15 is allowed as
200
   alias for R0L,R0H,R1L,...,R7H: */
201
 
202
static Boolean ChkRegSize(tSymbolSize ReqSize, tSymbolSize ActSize)
203
{
204
  return (ReqSize == eSymbolSizeUnknown)
205
      || (ReqSize == ActSize)
206
      || ((ReqSize == eSymbolSize8Bit) && (ActSize == eSymbolSize16Bit));
207
}
208
 
209
static tRegEvalResult IsReg(const tStrComp *pArg, Byte *pValue, tSymbolSize *pSize, tSymbolSize ReqSize, Boolean MustBeReg)
210
{
211
  tRegDescr RegDescr;
212
  tEvalResult EvalResult;
213
  tRegEvalResult RegEvalResult;
214
 
215
  if (IsRegCore(pArg->str.p_str, &RegDescr.Reg, &EvalResult.DataSize))
216
    RegEvalResult = eIsReg;
217
  else
218
    RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
219
 
220
  if (RegEvalResult == eIsReg)
221
  {
222
    if (!ChkRegSize(ReqSize, EvalResult.DataSize))
223
    {
224
      WrStrErrorPos(ErrNum_InvOpSize, pArg);
225
      RegEvalResult = MustBeReg ? eIsNoReg : eRegAbort;
226
    }
227
  }
228
 
229
  *pValue = RegDescr.Reg;
230
  if (pSize) *pSize = EvalResult.DataSize;
231
  return RegEvalResult;
232
}
233
 
234
static tRegEvalResult IsRegM1(const tStrComp *pArg, Byte *pValue, tSymbolSize ReqSize, Boolean MustBeReg)
235
{
236
  if (*pArg->str.p_str)
237
  {
238
    int l;
239
    char tmp = pArg->str.p_str[l = (strlen(pArg->str.p_str) - 1)];
240
    tRegEvalResult b;
241
 
242
    pArg->str.p_str[l] = '\0';
243
    b = IsReg(pArg, pValue, NULL, ReqSize, MustBeReg);
244
    pArg->str.p_str[l] = tmp;
245
    return b;
246
  }
247
  else
248
    return eIsNoReg;
249
}
250
 
251
static tRegEvalResult IsRegP1(const tStrComp *pArg, Byte *pValue, tSymbolSize ReqSize, Boolean MustBeReg)
252
{
253
  tStrComp Arg;
254
 
255
  StrCompRefRight(&Arg, pArg, 1);
256
  return IsReg(&Arg, pValue, NULL, ReqSize, MustBeReg);
257
}
258
 
259
static LongInt SFRStart(void)
260
{
261
  return (ExtSFRs) ? 0xf000 : 0xfe00;
262
}
263
 
264
static LongInt SFREnd(void)
265
{
266
  return (ExtSFRs) ? 0xf1de : 0xffde;
267
}
268
 
269
static Boolean CalcPage(LongInt *Adr, Boolean DoAnyway)
270
{
271
  int z;
272
  Word Bank;
273
 
274
  switch (MemMode)
275
  {
276
    case MemModeStd:
277
      z = 0;
278
      while ((z <= 3) && (((*Adr) >> 14) != DPPAssumes[z]))
279
        z++;
280
      if (z > 3)
281
      {
282
        WrError(ErrNum_InAccPage);
283
        (*Adr) &= 0xffff;
284
        return DoAnyway;
285
      }
286
      else
287
      {
288
        *Adr = ((*Adr) & 0x3fff) + (z << 14);
289
        if (DPPChanged[z])
290
          WrXError(ErrNum_Pipeline, RegNames[z]);
291
        return True;
292
      }
293
    case MemModeZeroPage:
294
      (*Adr) &= 0x3fff;
295
      return True;
296
    case MemModeFixedPage:
297
      Bank = (*Adr) >> 14;
298
      (*Adr) &= 0x3fff;
299
      if (Bank != MemPage)
300
      {
301
        WrError(ErrNum_InAccPage);
302
        return (DoAnyway);
303
      }
304
      else
305
        return True;
306
    case MemModeNoCheck:
307
      (*Adr) &= 0xffff;
308
      return True;
309
    case MemModeFixedBank:
310
      Bank = (*Adr) >> 16; (*Adr) &= 0xffff;
311
      if (Bank != MemPage)
312
      {
313
        WrError(ErrNum_InAccPage);
314
        return (DoAnyway);
315
      }
316
      else
317
        return True;
318
    default:
319
      return False;
320
  }
321
}
322
 
323
static void DecideAbsolute(LongInt DispAcc, Word Mask, tAdrResult *pResult)
324
{
325
#define DPPAdr 0xfe00
326
#define SPAdr 0xfe12
327
#define CPAdr 0xfe10
328
 
329
  int z;
330
 
331
  if (Mask & M_InCode)
332
  {
333
    if ((HiWord(EProgCounter()) == HiWord(DispAcc)) && (Mask & MModAbs))
334
    {
335
      pResult->Type = ModAbs;
336
      pResult->Cnt = 2;
337
      pResult->Vals[0] = Lo(DispAcc);
338
      pResult->Vals[1] = Hi(DispAcc);
339
    }
340
    else
341
    {
342
      pResult->Type = ModLAbs;
343
      pResult->Cnt = 2;
344
      pResult->Mode = DispAcc >> 16;
345
      pResult->Vals[0] = Lo(DispAcc);
346
      pResult->Vals[1] = Hi(DispAcc);
347
    }
348
  }
349
  else if (((Mask & MModMReg) != 0) && (DispAcc >= SFRStart()) && (DispAcc <= SFREnd()) && (!(DispAcc & 1)))
350
  {
351
    pResult->Type = ModMReg;
352
    pResult->Cnt = 1;
353
    pResult->Vals[0] = (DispAcc - SFRStart()) >> 1;
354
  }
355
  else switch (MemMode)
356
  {
357
    case MemModeStd:
358
      z = 0;
359
      while ((z <= 3) && ((DispAcc >> 14) != DPPAssumes[z]))
360
        z++;
361
      if (z > 3)
362
      {
363
        WrError(ErrNum_InAccPage);
364
        z = (DispAcc >> 14) & 3;
365
      }
366
      pResult->Type = ModAbs;
367
      pResult->Cnt = 2;
368
      pResult->Vals[0] = Lo(DispAcc);
369
      pResult->Vals[1] = (Hi(DispAcc) & 0x3f) + (z << 6);
370
      if (DPPChanged[z])
371
        WrXError(ErrNum_Pipeline, RegNames[z]);
372
      break;
373
    case MemModeZeroPage:
374
      pResult->Type = ModAbs;
375
      pResult->Cnt = 2;
376
      pResult->Vals[0] = Lo(DispAcc);
377
      pResult->Vals[1] = Hi(DispAcc) & 0x3f;
378
      break;
379
    case MemModeFixedPage:
380
      if ((DispAcc >> 14) != MemPage)
381
        WrError(ErrNum_InAccPage);
382
      pResult->Type = ModAbs;
383
      pResult->Cnt = 2;
384
      pResult->Vals[0] = Lo(DispAcc);
385
      pResult->Vals[1] = Hi(DispAcc) & 0x3f;
386
      break;
387
    case MemModeNoCheck:
388
      pResult->Type = ModAbs;
389
      pResult->Cnt = 2;
390
      pResult->Vals[0] = Lo(DispAcc);
391
      pResult->Vals[1] = Hi(DispAcc);
392
      break;
393
    case MemModeFixedBank:
394
      if ((DispAcc >> 16) != MemPage)
395
        WrError(ErrNum_InAccPage);
396
      pResult->Type = ModAbs;
397
      pResult->Cnt = 2;
398
      pResult->Vals[0] = Lo(DispAcc);
399
      pResult->Vals[1] = Hi(DispAcc);
400
      break;
401
  }
402
 
403
  if ((pResult->Type != ModNone) && (Mask & M_Dest))
404
  {
405
    switch ((Word)DispAcc)
406
    {
407
      case SPAdr    : N_SPChanged = True; break;
408
      case CPAdr    : N_CPChanged = True; break;
409
      case DPPAdr   :
410
      case DPPAdr + 1 : N_DPPChanged[0] = True; break;
411
      case DPPAdr + 2 :
412
      case DPPAdr + 3 : N_DPPChanged[1] = True; break;
413
      case DPPAdr + 4 :
414
      case DPPAdr + 5 : N_DPPChanged[2] = True; break;
415
      case DPPAdr + 6 :
416
      case DPPAdr + 7 : N_DPPChanged[3] = True; break;
417
    }
418
  }
419
}
420
 
421
static int SplitForceSize(const char *pArg, tForceSize *pForceSize)
422
{
423
  switch (*pArg)
424
  {
425
    case '>': *pForceSize = eForceLong; return 1;
426
    case '<': *pForceSize = eForceShort; return 1;
427
    default: return 0;
428
  }
429
}
430
 
431
typedef struct
432
{
433
  as_eval_cb_data_t cb_data;
434
  tAdrResult *p_result;
435
} s166_eval_cb_data_t;
436
 
437
DECLARE_AS_EVAL_CB(s166_eval_cb)
438
{
439
  s166_eval_cb_data_t *p_s166_eval_cb_data = (s166_eval_cb_data_t*)p_data;
440
  Byte reg;
441
 
442
  switch (IsReg(p_arg, &reg, NULL, eSymbolSize16Bit, False))
443
  {
444
    case eIsNoReg:
445
      return e_eval_none;
446
    case eIsReg:
447
      if ((p_s166_eval_cb_data->p_result->Mode != 0xff)
448
       || !as_eval_cb_data_stack_plain_add(p_data->p_stack))
449
      {
450
        WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
451
        return e_eval_fail;
452
      }
453
      p_s166_eval_cb_data->p_result->Mode = reg;
454
      as_tempres_set_int(p_res, 0);
455
      return e_eval_ok;
456
    default:
457
      return e_eval_fail;
458
  }
459
}
460
 
461
static ShortInt DecodeAdr(const tStrComp *pArg, Word Mask, tAdrResult *pResult)
462
{
463
  LongInt HDisp, DispAcc;
464
  Boolean OK;
465
  int Offs;
466
  tRegEvalResult RegEvalResult;
467
 
468
  pResult->Type = ModNone;
469
  pResult->Cnt = 0;
470
  pResult->ForceSize = eForceNone;
471
 
472
  /* immediate ? */
473
 
474
  if (*pArg->str.p_str == '#')
475
  {
476
    Offs = SplitForceSize(pArg->str.p_str + 1, &pResult->ForceSize);
477
    switch (OpSize)
478
    {
479
      case eSymbolSize8Bit:
480
        pResult->Vals[0] = EvalStrIntExpressionOffsWithFlags(pArg, 1 + Offs, Int8, &OK, &pResult->SymFlags);
481
        pResult->Vals[1] = 0;
482
        break;
483
      case eSymbolSize16Bit:
484
        HDisp = EvalStrIntExpressionOffsWithFlags(pArg, 1 + Offs, Int16, &OK, &pResult->SymFlags);
485
        pResult->Vals[0] = Lo(HDisp);
486
        pResult->Vals[1] = Hi(HDisp);
487
        break;
488
      default:
489
        OK = False;
490
        break;
491
    }
492
    if (OK)
493
    {
494
      pResult->Type = ModImm;
495
      AdrCnt = OpSize + 1;
496
    }
497
  }
498
 
499
  /* Register ? */
500
 
501
  else if ((RegEvalResult = IsReg(pArg, &pResult->Mode, NULL, OpSize, False)) != eIsNoReg)
502
  {
503
    if (RegEvalResult == eRegAbort)
504
      return pResult->Type;
505
    if ((Mask & MModReg) != 0)
506
      pResult->Type = ModReg;
507
    else
508
    {
509
      pResult->Type = ModMReg;
510
      pResult->Vals[0] = 0xf0 + pResult->Mode;
511
      AdrCnt = 1;
512
    }
513
    if (CPChanged)
514
      WrXError(ErrNum_Pipeline, RegNames[4]);
515
  }
516
 
517
  /* indirekt ? */
518
 
519
  else if ((*pArg->str.p_str == '[') && (pArg->str.p_str[strlen(pArg->str.p_str) - 1] == ']'))
520
  {
521
    tStrComp Arg;
522
    int ArgLen;
523
 
524
    StrCompRefRight(&Arg, pArg, 1);
525
    StrCompShorten(&Arg, 1);
526
    KillPrefBlanksStrCompRef(&Arg);
527
    KillPostBlanksStrComp(&Arg);
528
    ArgLen = strlen(Arg.str.p_str);
529
 
530
    /* Predekrement ? */
531
 
532
    if ((ArgLen > 2) && (*Arg.str.p_str == '-') && ((RegEvalResult = IsRegP1(&Arg, &pResult->Mode, eSymbolSize16Bit, False)) != eIsNoReg))
533
    {
534
      if (eRegAbort == RegEvalResult)
535
        return pResult->Type;
536
      pResult->Type = ModPreDec;
537
    }
538
 
539
    /* Postinkrement ? */
540
 
541
    else if ((ArgLen > 2) && (Arg.str.p_str[ArgLen - 1] == '+') && ((RegEvalResult = IsRegM1(&Arg, &pResult->Mode, eSymbolSize16Bit, False)) != eIsNoReg))
542
    {
543
      if (eRegAbort == RegEvalResult)
544
        return pResult->Type;
545
      pResult->Type = ModPostInc;
546
    }
547
 
548
    /* indiziert ? */
549
 
550
    else
551
    {
552
      s166_eval_cb_data_t s166_eval_cb_data;
553
      tEvalResult eval_result;
554
 
555
      as_eval_cb_data_ini(&s166_eval_cb_data.cb_data, s166_eval_cb);
556
      pResult->Mode = 0xff;
557
      s166_eval_cb_data.p_result = pResult;
558
      DispAcc = EvalStrIntExprWithResultAndCallback(&Arg, Int16, &eval_result, &s166_eval_cb_data.cb_data);
559
      if (!eval_result.OK)
560
        return pResult->Type;
561
 
562
      if (pResult->Mode == 0xff)
563
        DecideAbsolute(DispAcc, Mask, pResult);
564
      else if (DispAcc == 0)
565
        pResult->Type = ModIReg;
566
      else if (DispAcc > 0xffff)
567
        WrError(ErrNum_OverRange);
568
      else if (DispAcc < -0x8000l)
569
        WrError(ErrNum_UnderRange);
570
      else
571
      {
572
        pResult->Vals[0] = Lo(DispAcc);
573
        pResult->Vals[1] = Hi(DispAcc);
574
        pResult->Type = ModIndex;
575
        pResult->Cnt = 2;
576
      }
577
    }
578
  }
579
  else
580
  {
581
    int Offset = SplitForceSize(pArg->str.p_str, &pResult->ForceSize);
582
 
583
    DispAcc = EvalStrIntExpressionOffsWithFlags(pArg, Offset, MemInt, &OK, &pResult->SymFlags);
584
    if (OK)
585
      DecideAbsolute(DispAcc, Mask, pResult);
586
  }
587
 
588
  if ((pResult->Type != ModNone) && (!((1 << pResult->Type) & Mask)))
589
  {
590
    WrError(ErrNum_InvAddrMode);
591
    pResult->Type = ModNone;
592
    pResult->Cnt = 0;
593
  }
594
  return pResult->Type;
595
}
596
 
597
static Boolean DecodeCondition(const char *Name, Byte *p_cond_code)
598
{
599
  int z;
600
 
601
  for (z = 0; Conditions[z].Name; z++)
602
    if (!as_strcasecmp(Conditions[z].Name, Name))
603
    {
604
      *p_cond_code = Conditions[z].Code;
605
      return True;
606
    }
607
  return False;
608
}
609
 
610
static Boolean DecodeBitAddr(const tStrComp *pArg, Word *Adr, Byte *Bit, Boolean MayBeOut)
611
{
612
  char *p;
613
  Word LAdr;
614
  Byte Reg;
615
  Boolean OK;
616
 
617
  p = QuotPos(pArg->str.p_str, '.');
618
  if (!p)
619
  {
620
    LAdr = EvalStrIntExpression(pArg, UInt16, &OK) & 0x1fff;
621
    if (OK)
622
    {
623
      if ((!MayBeOut) && ((LAdr >> 12) != Ord(ExtSFRs)))
624
      {
625
        WrError(ErrNum_InAccReg);
626
        return False;
627
      }
628
      *Adr = LAdr >> 4;
629
      *Bit = LAdr & 15;
630
      if (!MayBeOut)
631
        *Adr = Lo(*Adr);
632
      return True;
633
    }
634
    else return False;
635
  }
636
  else if (p == pArg->str.p_str)
637
  {
638
    WrError(ErrNum_InvAddrMode);
639
    return False;
640
  }
641
  else
642
  {
643
    tStrComp AddrComp, BitComp;
644
 
645
    StrCompSplitRef(&AddrComp, &BitComp, pArg, p);
646
 
647
    switch (IsReg(&AddrComp, &Reg, NULL, eSymbolSize16Bit, False))
648
    {
649
      case eIsReg:
650
        *Adr = 0xf0 + Reg;
651
        break;
652
      case eRegAbort:
653
        return False;
654
      case eIsNoReg:
655
      {
656
        tSymbolFlags Flags;
657
 
658
        LAdr = EvalStrIntExpressionWithFlags(&AddrComp, UInt16, &OK, &Flags);
659
        if (!OK)
660
          return False;
661
        if (mFirstPassUnknown(Flags))
662
          LAdr = 0xfd00;
663
 
664
        /* full addresses must be even, since bitfields in memory are 16 bit: */
665
 
666
        if ((LAdr > 0xff) && (LAdr & 1))
667
        {
668
          WrStrErrorPos(ErrNum_NotAligned, &AddrComp);
669
          return False;
670
        }
671
 
672
        /* coded bit address: */
673
 
674
        if (LAdr <= 0xff)
675
          *Adr = LAdr;
676
 
677
        /* 1st RAM bank: */
678
 
679
        else if ((LAdr >= 0xfd00) && (LAdr <= 0xfdfe))
680
          *Adr = (LAdr - 0xfd00)/2;
681
 
682
        /* SFR space: */
683
 
684
        else if ((LAdr >= 0xff00) && (LAdr <= 0xffde))
685
        {
686
          if ((ExtSFRs) && (!MayBeOut))
687
          {
688
            WrStrErrorPos(ErrNum_InAccReg, &AddrComp);
689
            return False;
690
          }
691
          *Adr = 0x80 + ((LAdr - 0xff00) / 2);
692
        }
693
 
694
        /* extended SFR space: */
695
 
696
        else if ((LAdr >= 0xf100) && (LAdr <= 0xf1de))
697
        {
698
          if ((!ExtSFRs) && (!MayBeOut))
699
          {
700
            WrStrErrorPos(ErrNum_InAccReg, &AddrComp);
701
            return False;
702
          }
703
          *Adr = 0x80 + ((LAdr - 0xf100) / 2);
704
          if (MayBeOut)
705
            (*Adr) += 0x100;
706
        }
707
        else
708
        {
709
          WrStrErrorPos(ErrNum_OverRange, &AddrComp);
710
          return False;
711
        }
712
      }
713
    }
714
 
715
    *Bit = EvalStrIntExpression(&BitComp, UInt4, &OK);
716
    return OK;
717
  }
718
}
719
 
720
static Word WordVal(const tAdrResult *pResult)
721
{
722
  return pResult->Vals[0] + (((Word)pResult->Vals[1]) << 8);
723
}
724
 
725
static Boolean DecodePref(const tStrComp *pArg, Byte *Erg)
726
{
727
  Boolean OK;
728
  tSymbolFlags Flags;
729
 
730
  if (*pArg->str.p_str != '#')
731
  {
732
    WrError(ErrNum_InvAddrMode);
733
    return False;
734
  }
735
  *Erg = EvalStrIntExpressionOffsWithFlags(pArg, 1, UInt3, &OK, &Flags);
736
  if (mFirstPassUnknown(Flags))
737
    *Erg = 1;
738
  if (!OK)
739
    return False;
740
  if (*Erg < 1)
741
    WrError(ErrNum_UnderRange);
742
  else if (*Erg > 4)
743
    WrError(ErrNum_OverRange);
744
  else
745
  {
746
    (*Erg)--;
747
    return True;
748
  }
749
  return False;
750
}
751
 
752
/*-------------------------------------------------------------------------*/
753
 
754
static void DecodeFixed(Word Index)
755
{
756
  const BaseOrder *pOrder = FixedOrders + Index;
757
 
758
  if (ChkArgCnt(0, 0))
759
  {
760
    CodeLen = 2;
761
    BAsmCode[0] = Lo(pOrder->Code1);
762
    BAsmCode[1] = Hi(pOrder->Code1);
763
    if (pOrder->Code2 != 0)
764
    {
765
      CodeLen = 4;
766
      BAsmCode[2] = Lo(pOrder->Code2);
767
      BAsmCode[3] = Hi(pOrder->Code2);
768
      if ((!strncmp(OpPart.str.p_str, "RET", 3)) && (SPChanged))
769
        WrXError(ErrNum_Pipeline, RegNames[5]);
770
    }
771
  }
772
}
773
 
774
static void DecodeMOV(Word Code)
775
{
776
  LongInt AdrLong;
777
 
778
  OpSize = (tSymbolSize)Hi(Code);
779
  Code = 1 - OpSize;
780
 
781
  if (ChkArgCnt(2, 2))
782
  {
783
    tAdrResult DestResult;
784
 
785
    switch (DecodeAdr(&ArgStr[1], MModReg | MModMReg | MModIReg | MModPreDec | MModPostInc | MModIndex | MModAbs | M_Dest, &DestResult))
786
    {
787
      case ModReg:
788
      {
789
        tAdrResult SrcResult;
790
 
791
        switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | MModIReg | MModPostInc | MModIndex | MModAbs, &SrcResult))
792
        {
793
          case ModReg:
794
            CodeLen = 2;
795
             BAsmCode[0] = 0xf0 + Code;
796
            BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
797
            break;
798
          case ModImm:
799
          {
800
            Boolean IsShort = WordVal(&SrcResult) <= 15;
801
 
802
            if (!SrcResult.ForceSize)
803
              SrcResult.ForceSize = IsShort ? eForceShort : eForceLong;
804
            if (SrcResult.ForceSize == eForceShort)
805
            {
806
              if (!IsShort && !mSymbolQuestionable(SrcResult.SymFlags)) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
807
              else
808
              {
809
                CodeLen = 2;
810
                BAsmCode[0] = 0xe0 + Code;
811
                BAsmCode[1] = (WordVal(&SrcResult) << 4) + DestResult.Mode;
812
              }
813
            }
814
            else
815
            {
816
              CodeLen = 4;
817
              BAsmCode[0] = 0xe6 + Code;
818
              BAsmCode[1] = DestResult.Mode + 0xf0;
819
              memcpy(BAsmCode + 2, SrcResult.Vals, 2);
820
            }
821
            break;
822
          }
823
          case ModIReg:
824
            CodeLen = 2;
825
            BAsmCode[0] = 0xa8 + Code;
826
            BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
827
            break;
828
          case ModPostInc:
829
            CodeLen = 2;
830
            BAsmCode[0] = 0x98 + Code;
831
            BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
832
            break;
833
          case ModIndex:
834
            CodeLen = 2 + SrcResult.Cnt;
835
            BAsmCode[0] = 0xd4 + (Code << 5);
836
            BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
837
            memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt);
838
            break;
839
          case ModAbs:
840
            CodeLen = 2 + SrcResult.Cnt;
841
            BAsmCode[0] = 0xf2 + Code;
842
            BAsmCode[1] = 0xf0 + DestResult.Mode;
843
            memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt);
844
            break;
845
        }
846
        break;
847
      }
848
      case ModMReg:
849
      {
850
        tAdrResult SrcResult;
851
 
852
        BAsmCode[1] = DestResult.Vals[0];
853
        switch (DecodeAdr(&ArgStr[2], MModImm | MModMReg | ((DPPAssumes[3] == 3) ? MModIReg : 0) | MModAbs, &SrcResult))
854
        {
855
          case ModImm:
856
            CodeLen = 4;
857
            BAsmCode[0] = 0xe6 + Code;
858
            memcpy(BAsmCode + 2, SrcResult.Vals, 2);
859
            break;
860
          case ModMReg: /* BAsmCode[1] sicher absolut darstellbar, da Rn vorher */
861
                        /* abgefangen wird! */
862
            BAsmCode[0] = 0xf6 + Code;
863
            AdrLong = SFRStart() + (((Word)BAsmCode[1]) << 1);
864
            CalcPage(&AdrLong, True);
865
            BAsmCode[2] = Lo(AdrLong);
866
            BAsmCode[3] = Hi(AdrLong);
867
            BAsmCode[1] = SrcResult.Vals[0];
868
            CodeLen = 4;
869
            break;
870
          case ModIReg:
871
            CodeLen = 4; BAsmCode[0] = 0x94 + (Code << 5);
872
            BAsmCode[2] = BAsmCode[1] << 1;
873
            BAsmCode[3] = 0xfe + (BAsmCode[1] >> 7); /* ANSI :-0 */
874
            BAsmCode[1] = SrcResult.Mode;
875
            break;
876
          case ModAbs:
877
            CodeLen = 2 + SrcResult.Cnt;
878
            BAsmCode[0] = 0xf2 + Code;
879
            memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt);
880
            break;
881
        }
882
        break;
883
      }
884
      case ModIReg:
885
      {
886
        tAdrResult SrcResult;
887
 
888
        switch (DecodeAdr(&ArgStr[2], MModReg | MModIReg | MModPostInc | MModAbs, &SrcResult))
889
        {
890
          case ModReg:
891
            CodeLen = 2;
892
            BAsmCode[0] = 0xb8 + Code;
893
            BAsmCode[1] = DestResult.Mode + (SrcResult.Mode << 4);
894
            break;
895
          case ModIReg:
896
            CodeLen = 2;
897
           BAsmCode[0] = 0xc8 + Code;
898
            BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
899
            break;
900
          case ModPostInc:
901
            CodeLen = 2;
902
            BAsmCode[0] = 0xe8 + Code;
903
            BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
904
            break;
905
          case ModAbs:
906
            CodeLen = 2 + SrcResult.Cnt;
907
            BAsmCode[0] = 0x84 + (Code << 5);
908
            BAsmCode[1] = DestResult.Mode;
909
            memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt);
910
            break;
911
        }
912
        break;
913
      }
914
      case ModPreDec:
915
      {
916
        tAdrResult SrcResult;
917
 
918
        switch (DecodeAdr(&ArgStr[2], MModReg, &SrcResult))
919
        {
920
          case ModReg:
921
            CodeLen = 2;
922
            BAsmCode[0] = 0x88 + Code;
923
            BAsmCode[1] = DestResult.Mode + (SrcResult.Mode << 4);
924
            break;
925
        }
926
        break;
927
      }
928
      case ModPostInc:
929
      {
930
        tAdrResult SrcResult;
931
 
932
        switch (DecodeAdr(&ArgStr[2], MModIReg, &SrcResult))
933
        {
934
          case ModIReg:
935
            CodeLen = 2;
936
            BAsmCode[0] = 0xd8 + Code;
937
            BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
938
            break;
939
        }
940
        break;
941
      }
942
      case ModIndex:
943
      {
944
        tAdrResult SrcResult;
945
 
946
        BAsmCode[1] = DestResult.Mode;
947
        memcpy(BAsmCode + 2, DestResult.Vals, DestResult.Cnt);
948
        switch (DecodeAdr(&ArgStr[2], MModReg, &SrcResult))
949
        {
950
          case ModReg:
951
            BAsmCode[0] = 0xc4 + (Code << 5);
952
            CodeLen = 4;
953
            BAsmCode[1] += SrcResult.Mode << 4;
954
            break;
955
        }
956
        break;
957
      }
958
      case ModAbs:
959
      {
960
        tAdrResult SrcResult;
961
 
962
        memcpy(BAsmCode + 2, DestResult.Vals, DestResult.Cnt);
963
        switch (DecodeAdr(&ArgStr[2], MModIReg | MModMReg, &SrcResult))
964
        {
965
          case ModIReg:
966
            CodeLen = 4;
967
            BAsmCode[0] = 0x94 + (Code << 5);
968
            BAsmCode[1] = SrcResult.Mode;
969
            break;
970
          case ModMReg:
971
            CodeLen = 4;
972
            BAsmCode[0] = 0xf6 + Code;
973
            BAsmCode[1] = SrcResult.Vals[0];
974
            break;
975
        }
976
        break;
977
      }
978
    }
979
  }
980
}
981
 
982
static void DecodeMOVBS_MOVBZ(Word Code)
983
{
984
  LongInt AdrLong;
985
 
986
  if (ChkArgCnt(2, 2))
987
  {
988
    tAdrResult DestResult;
989
 
990
    OpSize = eSymbolSize16Bit;
991
    switch (DecodeAdr(&ArgStr[1], MModReg | MModMReg | MModAbs | M_Dest, &DestResult))
992
    {
993
      case ModReg:
994
      {
995
        tAdrResult SrcResult;
996
 
997
        OpSize = eSymbolSize8Bit;
998
        switch (DecodeAdr(&ArgStr[2], MModReg | MModAbs, &SrcResult))
999
        {
1000
          case ModReg:
1001
            CodeLen = 2;
1002
            BAsmCode[0] = 0xc0 + Code;
1003
            BAsmCode[1] = DestResult.Mode + (SrcResult.Mode << 4);
1004
            break;
1005
          case ModAbs:
1006
            CodeLen = 4;
1007
            BAsmCode[0] = 0xc2 + Code;
1008
            BAsmCode[1] = 0xf0 + DestResult.Mode;
1009
            memcpy(BAsmCode + 2, SrcResult.Vals, 2);
1010
            break;
1011
        }
1012
        break;
1013
      }
1014
      case ModMReg:
1015
      {
1016
        tAdrResult SrcResult;
1017
 
1018
        BAsmCode[1] = DestResult.Vals[0];
1019
        OpSize = eSymbolSize8Bit;
1020
        switch (DecodeAdr(&ArgStr[2], MModAbs | MModMReg, &SrcResult))
1021
        {
1022
          case ModMReg: /* BAsmCode[1] sicher absolut darstellbar, da Rn vorher */
1023
                        /* abgefangen wird! */
1024
            BAsmCode[0] = 0xc5 + Code;
1025
            AdrLong = SFRStart() + (((Word)BAsmCode[1]) << 1);
1026
            CalcPage(&AdrLong, True);
1027
            BAsmCode[2] = Lo(AdrLong);
1028
            BAsmCode[3] = Hi(AdrLong);
1029
            BAsmCode[1] = SrcResult.Vals[0];
1030
            CodeLen = 4;
1031
            break;
1032
          case ModAbs:
1033
            CodeLen = 2 + SrcResult.Cnt;
1034
            BAsmCode[0] = 0xc2 + Code;
1035
            memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt);
1036
            break;
1037
        }
1038
        break;
1039
      }
1040
      case ModAbs:
1041
      {
1042
        tAdrResult SrcResult;
1043
 
1044
        OpSize = eSymbolSize8Bit;
1045
        memcpy(BAsmCode + 2, DestResult.Vals, DestResult.Cnt);
1046
        switch (DecodeAdr(&ArgStr[2], MModMReg, &SrcResult))
1047
        {
1048
          case ModMReg:
1049
            CodeLen = 4;
1050
            BAsmCode[0] = 0xc5 + Code;
1051
            BAsmCode[1] = SrcResult.Vals[0];
1052
            break;
1053
        }
1054
        break;
1055
      }
1056
    }
1057
  }
1058
}
1059
 
1060
static void DecodePUSH_POP(Word Code)
1061
{
1062
  if (ChkArgCnt(1, 1))
1063
  {
1064
    tAdrResult Result;
1065
 
1066
    switch (DecodeAdr(&ArgStr[1], MModMReg | ((Code & 0x10) ? M_Dest : 0), &Result))
1067
    {
1068
      case ModMReg:
1069
        CodeLen = 2;
1070
        BAsmCode[0] = Code;
1071
        BAsmCode[1] = Result.Vals[0];
1072
        if (SPChanged) WrXError(ErrNum_Pipeline, RegNames[5]);
1073
        break;
1074
    }
1075
  }
1076
}
1077
 
1078
static void DecodeSCXT(Word Code)
1079
{
1080
  UNUSED(Code);
1081
 
1082
  if (ChkArgCnt(2, 2))
1083
  {
1084
    tAdrResult Result;
1085
 
1086
    switch (DecodeAdr(&ArgStr[1], MModMReg | M_Dest, &Result))
1087
    {
1088
      case ModMReg:
1089
        BAsmCode[1] = Result.Vals[0];
1090
        if (DecodeAdr(&ArgStr[2], MModAbs | MModImm, &Result) != ModNone)
1091
        {
1092
          CodeLen = 4; BAsmCode[0] = 0xc6 + (Ord(Result.Type == ModAbs) << 4);
1093
          memcpy(BAsmCode + 2, Result.Vals, 2);
1094
        }
1095
        break;
1096
    }
1097
  }
1098
}
1099
 
1100
static void DecodeALU2(Word Code)
1101
{
1102
  LongInt AdrLong;
1103
 
1104
  OpSize = (tSymbolSize)Hi(Code);
1105
  Code = (1 - OpSize) + (Lo(Code)  << 4);
1106
 
1107
  if (ChkArgCnt(2, 2))
1108
  {
1109
    tAdrResult DestResult;
1110
 
1111
    switch (DecodeAdr(&ArgStr[1], MModReg | MModMReg | MModAbs | M_Dest, &DestResult))
1112
    {
1113
      case ModReg:
1114
      {
1115
        tAdrResult SrcResult;
1116
 
1117
        switch (DecodeAdr(&ArgStr[2], MModReg | MModIReg | MModPostInc | MModAbs | MModImm, &SrcResult))
1118
        {
1119
          case ModReg:
1120
            CodeLen = 2;
1121
            BAsmCode[0] = Code;
1122
            BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
1123
            break;
1124
          case ModIReg:
1125
            if (SrcResult.Mode > 3) WrError(ErrNum_InvAddrMode);
1126
            else
1127
            {
1128
              CodeLen = 2;
1129
              BAsmCode[0] = 0x08 + Code;
1130
              BAsmCode[1] = (DestResult.Mode << 4) + 8 + SrcResult.Mode;
1131
            }
1132
            break;
1133
          case ModPostInc:
1134
            if (SrcResult.Mode > 3) WrError(ErrNum_InvAddrMode);
1135
            else
1136
            {
1137
              CodeLen = 2;
1138
              BAsmCode[0] = 0x08 + Code;
1139
              BAsmCode[1] = (DestResult.Mode << 4) + 12 + SrcResult.Mode;
1140
            }
1141
            break;
1142
          case ModAbs:
1143
            CodeLen = 4;
1144
            BAsmCode[0] = 0x02 + Code;
1145
            BAsmCode[1] = 0xf0 + DestResult.Mode;
1146
            memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt);
1147
            break;
1148
          case ModImm:
1149
          {
1150
            Boolean IsShort = WordVal(&SrcResult) <= 7;
1151
 
1152
            if (!SrcResult.ForceSize)
1153
              SrcResult.ForceSize = IsShort ? eForceShort : eForceLong;
1154
            if (SrcResult.ForceSize == eForceShort)
1155
            {
1156
              if (!IsShort && !mSymbolQuestionable(SrcResult.SymFlags)) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
1157
              else
1158
              {
1159
                CodeLen = 2;
1160
                BAsmCode[0] = 0x08 + Code;
1161
                BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Vals[0];
1162
              }
1163
            }
1164
            else
1165
            {
1166
              CodeLen = 4;
1167
              BAsmCode[0] = 0x06 + Code;
1168
              BAsmCode[1] = 0xf0 + DestResult.Mode;
1169
              memcpy(BAsmCode + 2, SrcResult.Vals, 2);
1170
            }
1171
            break;
1172
          }
1173
        }
1174
        break;
1175
      }
1176
      case ModMReg:
1177
      {
1178
        tAdrResult SrcResult;
1179
 
1180
        BAsmCode[1] = DestResult.Vals[0];
1181
        switch (DecodeAdr(&ArgStr[2], MModAbs | MModMReg | MModImm, &SrcResult))
1182
        {
1183
          case ModAbs:
1184
            CodeLen = 4;
1185
            BAsmCode[0] = 0x02 + Code;
1186
            memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt);
1187
            break;
1188
          case ModMReg: /* BAsmCode[1] sicher absolut darstellbar, da Rn vorher */
1189
                        /* abgefangen wird! */
1190
            BAsmCode[0] = 0x04 + Code;
1191
            AdrLong = SFRStart() + (((Word)BAsmCode[1]) << 1);
1192
            CalcPage(&AdrLong, True);
1193
            BAsmCode[2] = Lo(AdrLong);
1194
            BAsmCode[3] = Hi(AdrLong);
1195
            BAsmCode[1] = SrcResult.Vals[0];
1196
            CodeLen = 4;
1197
            break;
1198
          case ModImm:
1199
            CodeLen = 4;
1200
            BAsmCode[0] = 0x06 + Code;
1201
            memcpy(BAsmCode + 2, SrcResult.Vals, 2);
1202
            break;
1203
        }
1204
        break;
1205
      }
1206
      case ModAbs:
1207
      {
1208
        tAdrResult SrcResult;
1209
 
1210
        memcpy(BAsmCode + 2, DestResult.Vals, DestResult.Cnt);
1211
        switch (DecodeAdr(&ArgStr[2], MModMReg, &SrcResult))
1212
        {
1213
          case ModMReg:
1214
            CodeLen = 4;
1215
            BAsmCode[0] = 0x04 + Code;
1216
            BAsmCode[1] = SrcResult.Vals[0];
1217
            break;
1218
        }
1219
        break;
1220
      }
1221
    }
1222
  }
1223
}
1224
 
1225
static void DecodeCPL_NEG(Word Code)
1226
{
1227
  OpSize = (tSymbolSize)Hi(Code);
1228
 
1229
  Code = Lo(Code) + ((1 - OpSize) << 5);
1230
  if (ChkArgCnt(1, 1))
1231
  {
1232
    tAdrResult Result;
1233
 
1234
    if (DecodeAdr(&ArgStr[1], MModReg | M_Dest, &Result) == ModReg)
1235
    {
1236
      CodeLen = 2;
1237
      BAsmCode[0] = Code;
1238
      BAsmCode[1] = Result.Mode << 4;
1239
    }
1240
  }
1241
}
1242
 
1243
static void DecodeDiv(Word Code)
1244
{
1245
  if (ChkArgCnt(1, 1))
1246
  {
1247
    tAdrResult Result;
1248
 
1249
    if (DecodeAdr(&ArgStr[1], MModReg, &Result) == ModReg)
1250
    {
1251
      CodeLen = 2;
1252
      BAsmCode[0] = 0x4b + (Code << 4);
1253
      BAsmCode[1] = Result.Mode * 0x11;
1254
    }
1255
  }
1256
}
1257
 
1258
static void DecodeLoop(Word Code)
1259
{
1260
  if (ChkArgCnt(2, 2))
1261
  {
1262
    tAdrResult Result;
1263
 
1264
    if (DecodeAdr(&ArgStr[1], MModReg | M_Dest, &Result) == ModReg)
1265
    {
1266
      BAsmCode[1] = Result.Mode;
1267
      switch (DecodeAdr(&ArgStr[2], MModAbs | MModImm, &Result))
1268
      {
1269
        case ModAbs:
1270
          CodeLen = 4;
1271
          BAsmCode[0] = Code + 2;
1272
          BAsmCode[1] += 0xf0;
1273
          memcpy(BAsmCode + 2, Result.Vals, 2);
1274
          break;
1275
        case ModImm:
1276
        {
1277
          Boolean IsShort = WordVal(&Result) < 16;
1278
 
1279
          if (!Result.ForceSize)
1280
            Result.ForceSize = IsShort ? eForceShort : eForceLong;
1281
          if (Result.ForceSize == eForceShort)
1282
          {
1283
            if (!IsShort && !mSymbolQuestionable(Result.SymFlags)) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
1284
            else
1285
            {
1286
              CodeLen = 2;
1287
              BAsmCode[0] = Code;
1288
              BAsmCode[1] += (WordVal(&Result) << 4);
1289
            }
1290
          }
1291
          else
1292
          {
1293
            CodeLen = 4;
1294
            BAsmCode[0] = Code + 6;
1295
            BAsmCode[1] += 0xf0;
1296
            memcpy(BAsmCode + 2, Result.Vals, 2);
1297
          }
1298
          break;
1299
        }
1300
      }
1301
    }
1302
  }
1303
}
1304
 
1305
static void DecodeMul(Word Code)
1306
{
1307
  if (ChkArgCnt(2, 2))
1308
  {
1309
    tAdrResult DestResult;
1310
 
1311
    switch (DecodeAdr(&ArgStr[1], MModReg, &DestResult))
1312
    {
1313
      case ModReg:
1314
      {
1315
        tAdrResult SrcResult;
1316
 
1317
        switch (DecodeAdr(&ArgStr[2], MModReg, &SrcResult))
1318
        {
1319
          case ModReg:
1320
            CodeLen = 2;
1321
            BAsmCode[0] = 0x0b + (Code << 4);
1322
            BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
1323
            break;
1324
        }
1325
        break;
1326
      }
1327
    }
1328
  }
1329
}
1330
 
1331
static void DecodeShift(Word Code)
1332
{
1333
  if (ChkArgCnt(2, 2))
1334
  {
1335
    tAdrResult DestResult;
1336
 
1337
    OpSize = eSymbolSize16Bit;
1338
    switch (DecodeAdr(&ArgStr[1], MModReg | M_Dest, &DestResult))
1339
    {
1340
      case ModReg:
1341
      {
1342
        tAdrResult SrcResult;
1343
 
1344
        switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | M_Dest, &SrcResult))
1345
        {
1346
          case ModReg:
1347
            BAsmCode[0] = Code;
1348
            BAsmCode[1] = SrcResult.Mode + (DestResult.Mode << 4);
1349
            CodeLen = 2;
1350
            break;
1351
          case ModImm:
1352
            if ((WordVal(&SrcResult) > 15) && !mSymbolQuestionable(SrcResult.SymFlags)) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
1353
            else
1354
            {
1355
              BAsmCode[0] = Code + 0x10;
1356
              BAsmCode[1] = (WordVal(&SrcResult) << 4) + DestResult.Mode;
1357
              CodeLen = 2;
1358
            }
1359
            break;
1360
        }
1361
        break;
1362
      }
1363
    }
1364
  }
1365
}
1366
 
1367
static void DecodeBit2(Word Code)
1368
{
1369
  Byte BOfs1, BOfs2;
1370
  Word BAdr1, BAdr2;
1371
 
1372
  if (ChkArgCnt(2, 2)
1373
   && DecodeBitAddr(&ArgStr[1], &BAdr1, &BOfs1, False)
1374
   && DecodeBitAddr(&ArgStr[2], &BAdr2, &BOfs2, False))
1375
  {
1376
    CodeLen = 4;
1377
    BAsmCode[0] = Code;
1378
    BAsmCode[1] = BAdr2;
1379
    BAsmCode[2] = BAdr1;
1380
    BAsmCode[3] = (BOfs2 << 4) + BOfs1;
1381
  }
1382
}
1383
 
1384
static void DecodeBCLR_BSET(Word Code)
1385
{
1386
  Byte BOfs;
1387
  Word BAdr;
1388
 
1389
  if (ChkArgCnt(1, 1)
1390
   && DecodeBitAddr(&ArgStr[1], &BAdr, &BOfs, False))
1391
  {
1392
    CodeLen = 2;
1393
    BAsmCode[0] = (BOfs << 4) + Code;
1394
    BAsmCode[1] = BAdr;
1395
  }
1396
}
1397
 
1398
static void DecodeBFLDH_BFLDL(Word Code)
1399
{
1400
  Byte BOfs;
1401
  Word BAdr;
1402
 
1403
  if (ChkArgCnt(3, 3))
1404
  {
1405
    strmaxcat(ArgStr[1].str.p_str, ".0", STRINGSIZE);
1406
    if (DecodeBitAddr(&ArgStr[1], &BAdr, &BOfs, False))
1407
    {
1408
      tAdrResult Result;
1409
 
1410
      OpSize = eSymbolSize8Bit;
1411
      BAsmCode[1] = BAdr;
1412
      if (DecodeAdr(&ArgStr[2], MModImm, &Result) == ModImm)
1413
      {
1414
        BAsmCode[2] = Result.Vals[0];
1415
        if (DecodeAdr(&ArgStr[3], MModImm, &Result) == ModImm)
1416
        {
1417
          BAsmCode[3] = Result.Vals[0];
1418
          CodeLen = 4;
1419
          BAsmCode[0] = Code;
1420
          if (Code & 0x10)
1421
          {
1422
            BAdr = BAsmCode[2];
1423
            BAsmCode[2] = BAsmCode[3];
1424
            BAsmCode[3] = BAdr;
1425
          }
1426
        }
1427
      }
1428
    }
1429
  }
1430
}
1431
 
1432
static void DecodeJMP(Word Code)
1433
{
1434
  UNUSED(Code);
1435
 
1436
  if (ChkArgCnt(1, 2))
1437
  {
1438
    Byte cond_code;
1439
    tAdrResult Result;
1440
 
1441
    if (ArgCnt == 1)
1442
      cond_code = TrueCond;
1443
    else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code))
1444
    {
1445
      WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1446
      return;
1447
    }
1448
 
1449
    switch (DecodeAdr(&ArgStr[ArgCnt], MModAbs | MModLAbs | MModIReg | M_InCode, &Result))
1450
    {
1451
      case ModLAbs:
1452
        if (cond_code != COND_CODE_TRUE) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1453
        else
1454
        {
1455
          CodeLen = 2 + Result.Cnt;
1456
          BAsmCode[0] = 0xfa;
1457
          BAsmCode[1] = Result.Mode;
1458
          memcpy(BAsmCode + 2, Result.Vals, Result.Cnt);
1459
        }
1460
        break;
1461
      case ModAbs:
1462
      {
1463
        LongInt AdrDist = WordVal(&Result) - (EProgCounter() + 2);
1464
        Boolean IsShort = (AdrDist <= 254) && (AdrDist >= -256) && ((AdrDist & 1) == 0);
1465
 
1466
        if (!Result.ForceSize)
1467
          Result.ForceSize = IsShort ? eForceShort : eForceLong;
1468
        if (Result.ForceSize == eForceShort)
1469
        {
1470
          if (!IsShort && !mSymbolQuestionable(Result.SymFlags)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[ArgCnt]);
1471
          else
1472
          {
1473
            CodeLen = 2;
1474
            BAsmCode[0] = 0x0d + (cond_code << 4);
1475
            BAsmCode[1] = (AdrDist / 2) & 0xff;
1476
          }
1477
        }
1478
        else
1479
        {
1480
          CodeLen = 2 + Result.Cnt;
1481
          BAsmCode[0] = 0xea;
1482
          BAsmCode[1] = cond_code << 4;
1483
          memcpy(BAsmCode + 2, Result.Vals, Result.Cnt);
1484
        }
1485
        break;
1486
      }
1487
      case ModIReg:
1488
        CodeLen = 2; BAsmCode[0] = 0x9c;
1489
        BAsmCode[1] = (cond_code << 4) + Result.Mode;
1490
        break;
1491
    }
1492
  }
1493
}
1494
 
1495
static void DecodeCALL(Word Code)
1496
{
1497
  UNUSED(Code);
1498
 
1499
  if (ChkArgCnt(1, 2))
1500
  {
1501
    Byte cond_code;
1502
    tAdrResult Result;
1503
 
1504
    if (ArgCnt == 1)
1505
      cond_code = COND_CODE_TRUE;
1506
    else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code))
1507
    {
1508
      WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1509
      return;
1510
    }
1511
 
1512
    switch (DecodeAdr(&ArgStr[ArgCnt], MModAbs | MModLAbs | MModIReg | M_InCode, &Result))
1513
    {
1514
      case ModLAbs:
1515
        if (cond_code != COND_CODE_TRUE) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1516
        else
1517
        {
1518
          CodeLen = 2 + Result.Cnt;
1519
          BAsmCode[0] = 0xda;
1520
          BAsmCode[1] = Result.Mode;
1521
          memcpy(BAsmCode + 2, Result.Vals, Result.Cnt);
1522
        }
1523
        break;
1524
      case ModAbs:
1525
      {
1526
        LongInt AdrLong = WordVal(&Result) - (EProgCounter() + 2);
1527
        Boolean IsShort = (AdrLong <= 254) && (AdrLong >= -256) && ((AdrLong & 1) == 0);
1528
 
1529
        if (!Result.ForceSize && (cond_code == COND_CODE_TRUE))
1530
          Result.ForceSize = IsShort ? eForceShort : eForceLong;
1531
        if (Result.ForceSize == eForceShort)
1532
        {
1533
          if (!IsShort && !mSymbolQuestionable(Result.SymFlags)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[ArgCnt]);
1534
          else
1535
          {
1536
            CodeLen = 2;
1537
            BAsmCode[0] = 0xbb;
1538
            BAsmCode[1] = (AdrLong / 2) & 0xff;
1539
          }
1540
        }
1541
        else
1542
        {
1543
          CodeLen = 2 + Result.Cnt;
1544
          BAsmCode[0] = 0xca;
1545
          BAsmCode[1] = 0x00 + (cond_code << 4);
1546
          memcpy(BAsmCode + 2, Result.Vals, Result.Cnt);
1547
        }
1548
        break;
1549
      }
1550
      case ModIReg:
1551
        CodeLen = 2;
1552
        BAsmCode[0] = 0xab;
1553
        BAsmCode[1] = (cond_code << 4) + Result.Mode;
1554
        break;
1555
    }
1556
  }
1557
}
1558
 
1559
static void DecodeJMPR(Word Code)
1560
{
1561
  UNUSED(Code);
1562
 
1563
  if (ChkArgCnt(1, 2))
1564
  {
1565
    Byte cond_code;
1566
    Boolean OK;
1567
    tSymbolFlags Flags;
1568
    LongInt AdrLong;
1569
 
1570
    if (ArgCnt == 1)
1571
      cond_code = COND_CODE_TRUE;
1572
    else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code))
1573
    {
1574
      WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1575
      return;
1576
    }
1577
 
1578
    AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], MemInt, &OK, &Flags) - (EProgCounter() + 2);
1579
    if (OK)
1580
    {
1581
      if (AdrLong & 1) WrError(ErrNum_DistIsOdd);
1582
      else if (!mSymbolQuestionable(Flags) && ((AdrLong > 254) || (AdrLong < -256))) WrError(ErrNum_JmpDistTooBig);
1583
      else
1584
      {
1585
        CodeLen = 2;
1586
        BAsmCode[0] = 0x0d + (cond_code << 4);
1587
        BAsmCode[1] = (AdrLong / 2) & 0xff;
1588
      }
1589
    }
1590
  }
1591
}
1592
 
1593
static void DecodeCALLR(Word Code)
1594
{
1595
  UNUSED(Code);
1596
 
1597
  if (ChkArgCnt(1, 1))
1598
  {
1599
    Boolean OK;
1600
    tSymbolFlags Flags;
1601
    LongInt AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], MemInt, &OK, &Flags) - (EProgCounter() + 2);
1602
    if (OK)
1603
    {
1604
      if (AdrLong & 1) WrError(ErrNum_DistIsOdd);
1605
      else if (!mSymbolQuestionable(Flags) && ((AdrLong > 254) || (AdrLong < -256))) WrError(ErrNum_JmpDistTooBig);
1606
      else
1607
      {
1608
        CodeLen = 2;
1609
        BAsmCode[0] = 0xbb;
1610
        BAsmCode[1] = (AdrLong / 2) & 0xff;
1611
      }
1612
    }
1613
  }
1614
}
1615
 
1616
static void DecodeJMPA_CALLA(Word Code)
1617
{
1618
  if (ChkArgCnt(1, 2))
1619
  {
1620
    Byte cond_code;
1621
    Boolean OK;
1622
    LongInt AdrLong;
1623
    tSymbolFlags Flags;
1624
 
1625
    if (ArgCnt == 1)
1626
      cond_code = COND_CODE_TRUE;
1627
    else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code))
1628
    {
1629
      WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1630
      return;
1631
    }
1632
 
1633
    AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], MemInt, &OK, &Flags);
1634
    if (OK && ChkSamePage(AdrLong, EProgCounter(), 16, Flags))
1635
    {
1636
      CodeLen = 4;
1637
      BAsmCode[0] = Code;
1638
      BAsmCode[1] = 0x00 + (cond_code << 4);
1639
      BAsmCode[2] = Lo(AdrLong);
1640
      BAsmCode[3] = Hi(AdrLong);
1641
    }
1642
  }
1643
}
1644
 
1645
static void DecodeJMPS_CALLS(Word Code)
1646
{
1647
  if (ChkArgCnt(1, 2))
1648
  {
1649
    Boolean OK;
1650
    Word AdrWord;
1651
    Byte AdrBank;
1652
    LongInt AdrLong;
1653
 
1654
    if (ArgCnt == 1)
1655
    {
1656
      AdrLong = EvalStrIntExpression(&ArgStr[1], MemInt, &OK);
1657
      AdrWord = AdrLong & 0xffff;
1658
      AdrBank = AdrLong >> 16;
1659
    }
1660
    else
1661
    {
1662
      AdrWord = EvalStrIntExpression(&ArgStr[2], UInt16, &OK);
1663
      AdrBank = OK ? EvalStrIntExpression(&ArgStr[1], MemInt2, &OK) : 0;
1664
    }
1665
    if (OK)
1666
    {
1667
      CodeLen = 4;
1668
      BAsmCode[0] = Code;
1669
      BAsmCode[1] = AdrBank;
1670
      BAsmCode[2] = Lo(AdrWord);
1671
      BAsmCode[3] = Hi(AdrWord);
1672
    }
1673
  }
1674
}
1675
 
1676
static void DecodeJMPI_CALLI(Word Code)
1677
{
1678
  if (ChkArgCnt(1, 2))
1679
  {
1680
    Byte cond_code;
1681
    tAdrResult Result;
1682
 
1683
    if (ArgCnt == 1)
1684
      cond_code = COND_CODE_TRUE;
1685
    else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code))
1686
    {
1687
      WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1688
      return;
1689
    }
1690
 
1691
    switch (DecodeAdr(&ArgStr[ArgCnt], MModIReg | M_InCode, &Result))
1692
    {
1693
      case ModIReg:
1694
        CodeLen = 2;
1695
        BAsmCode[0] = Code;
1696
        BAsmCode[1] = Result.Mode + (cond_code << 4);
1697
        break;
1698
    }
1699
  }
1700
}
1701
 
1702
static void DecodeBJmp(Word Code)
1703
{
1704
  Byte BOfs;
1705
  Word BAdr;
1706
 
1707
  if (ChkArgCnt(2, 2)
1708
   && DecodeBitAddr(&ArgStr[1], &BAdr, &BOfs, False))
1709
  {
1710
    Boolean OK;
1711
    tSymbolFlags Flags;
1712
    LongInt AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[2], MemInt, &OK, &Flags) - (EProgCounter() + 4);
1713
    if (OK)
1714
    {
1715
      if (AdrLong & 1) WrError(ErrNum_DistIsOdd);
1716
      else if (!mSymbolQuestionable(Flags) && ((AdrLong < -256) || (AdrLong > 254))) WrError(ErrNum_JmpDistTooBig);
1717
      else
1718
      {
1719
        CodeLen = 4; BAsmCode[0] = 0x8a + (Code << 4);
1720
        BAsmCode[1] = BAdr;
1721
        BAsmCode[2] = (AdrLong / 2) & 0xff;
1722
        BAsmCode[3] = BOfs << 4;
1723
      }
1724
    }
1725
  }
1726
}
1727
 
1728
static void DecodePCALL(Word Code)
1729
{
1730
  UNUSED(Code);
1731
 
1732
  if (ChkArgCnt(2, 2))
1733
  {
1734
    tAdrResult Result;
1735
 
1736
    switch (DecodeAdr(&ArgStr[1], MModMReg, &Result))
1737
    {
1738
      case ModMReg:
1739
        BAsmCode[1] = Result.Vals[0];
1740
        switch (DecodeAdr(&ArgStr[2], MModAbs | M_InCode, &Result))
1741
        {
1742
          case ModAbs:
1743
            CodeLen = 4;
1744
            BAsmCode[0] = 0xe2;
1745
            memcpy(BAsmCode + 2, Result.Vals, 2);
1746
            break;
1747
        }
1748
        break;
1749
    }
1750
  }
1751
}
1752
 
1753
static void DecodeRETP(Word Code)
1754
{
1755
  UNUSED(Code);
1756
 
1757
  if (ChkArgCnt(1, 1))
1758
  {
1759
    tAdrResult Result;
1760
 
1761
    switch (DecodeAdr(&ArgStr[1], MModMReg, &Result))
1762
    {
1763
      case ModMReg:
1764
        BAsmCode[1] = Result.Vals[0];
1765
        BAsmCode[0] = 0xeb;
1766
        CodeLen = 2;
1767
        if (SPChanged)
1768
          WrXError(ErrNum_Pipeline, RegNames[5]);
1769
        break;
1770
    }
1771
  }
1772
}
1773
 
1774
static void DecodeTRAP(Word Code)
1775
{
1776
  UNUSED(Code);
1777
 
1778
  if (!ChkArgCnt(1, 1));
1779
  else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode);
1780
  else
1781
  {
1782
    Boolean OK;
1783
 
1784
    BAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt7, &OK) << 1;
1785
    if (OK)
1786
    {
1787
      BAsmCode[0] = 0x9b;
1788
      CodeLen = 2;
1789
    }
1790
  }
1791
}
1792
 
1793
static void DecodeATOMIC(Word Code)
1794
{
1795
  Byte HReg;
1796
 
1797
  UNUSED(Code);
1798
 
1799
  if (ChkArgCnt(1, 1)
1800
   && ChkMinCPU(CPU80C167)
1801
   && DecodePref(&ArgStr[1], &HReg))
1802
  {
1803
    CodeLen = 2;
1804
    BAsmCode[0] = 0xd1;
1805
    BAsmCode[1] = HReg << 4;
1806
  }
1807
}
1808
 
1809
static void DecodeEXTR(Word Code)
1810
{
1811
  Byte HReg;
1812
 
1813
  UNUSED(Code);
1814
 
1815
  if (ChkArgCnt(1, 1)
1816
   && ChkMinCPU(CPU80C167)
1817
   && DecodePref(&ArgStr[1], &HReg))
1818
  {
1819
    CodeLen = 2;
1820
    BAsmCode[0] = 0xd1;
1821
    BAsmCode[1] = 0x80 + (HReg << 4);
1822
    ExtCounter = HReg + 1;
1823
    ExtSFRs = True;
1824
  }
1825
}
1826
 
1827
static void DecodeEXTP_EXTPR(Word Code)
1828
{
1829
  Byte HReg;
1830
 
1831
  if (ChkArgCnt(2, 2)
1832
   && ChkMinCPU(CPU80C167)
1833
   && DecodePref(&ArgStr[2], &HReg))
1834
  {
1835
    tAdrResult Result;
1836
 
1837
    switch (DecodeAdr(&ArgStr[1], MModReg | MModImm, &Result))
1838
    {
1839
      case ModReg:
1840
        CodeLen = 2;
1841
        BAsmCode[0] = 0xdc;
1842
        BAsmCode[1] = Code + 0x40 + (HReg << 4) + Result.Mode;
1843
        ExtCounter = HReg + 1;
1844
        MemMode = MemModeZeroPage;
1845
        break;
1846
      case ModImm:
1847
        CodeLen = 4;
1848
        BAsmCode[0] = 0xd7;
1849
        BAsmCode[1] = Code + 0x40 + (HReg << 4);
1850
        BAsmCode[2] = WordVal(&Result) & 0xff;
1851
        BAsmCode[3] = (WordVal(&Result) >> 8) & 3;
1852
        ExtCounter = HReg + 1;
1853
        MemMode = MemModeFixedPage;
1854
        MemPage = WordVal(&Result) & 0x3ff;
1855
        break;
1856
    }
1857
  }
1858
}
1859
 
1860
static void DecodeEXTS_EXTSR(Word Code)
1861
{
1862
  Byte HReg;
1863
 
1864
  OpSize = eSymbolSize8Bit;
1865
  if (ChkArgCnt(2, 2)
1866
   && ChkMinCPU(CPU80C167)
1867
   && DecodePref(&ArgStr[2], &HReg))
1868
  {
1869
    tAdrResult Result;
1870
 
1871
    switch (DecodeAdr(&ArgStr[1], MModReg | MModImm, &Result))
1872
    {
1873
      case ModReg:
1874
        CodeLen = 2;
1875
        BAsmCode[0] = 0xdc;
1876
        BAsmCode[1] = Code + 0x00 + (HReg << 4) + Result.Mode;
1877
        ExtCounter = HReg + 1;
1878
        MemMode = MemModeNoCheck;
1879
        break;
1880
      case ModImm:
1881
        CodeLen = 4;
1882
        BAsmCode[0] = 0xd7;
1883
        BAsmCode[1] = Code + 0x00 + (HReg << 4);
1884
        BAsmCode[2] = Result.Vals[0];
1885
        BAsmCode[3] = 0;
1886
        ExtCounter = HReg + 1;
1887
        MemMode = MemModeFixedBank;
1888
        MemPage = Result.Vals[0];
1889
        break;
1890
    }
1891
  }
1892
}
1893
 
1894
static void DecodeBIT(Word Code)
1895
{
1896
  Word Adr;
1897
  Byte Bit;
1898
 
1899
  UNUSED(Code);
1900
 
1901
 if (ChkArgCnt(1, 1)
1902
  && DecodeBitAddr(&ArgStr[1], &Adr, &Bit, True))
1903
 {
1904
   PushLocHandle(-1);
1905
   EnterIntSymbol(&LabPart, (Adr << 4) + Bit, SegNone, False);
1906
   PopLocHandle();
1907
   as_snprintf(ListLine, STRINGSIZE, "=%02xH.%1x", (unsigned)Adr, (unsigned)Bit);
1908
 }
1909
}
1910
 
1911
/*!------------------------------------------------------------------------
1912
 * \fn     update_prefixes(Word index)
1913
 * \brief  necessary operations prior to assembling machine instructions
1914
 * ------------------------------------------------------------------------ */
1915
 
1916
static void update_prefixes(Word index)
1917
{
1918
  int z;
1919
 
1920
  UNUSED(index);
1921
 
1922
  /* Pipeline-Flags weiterschalten */
1923
 
1924
  SPChanged = N_SPChanged; N_SPChanged = False;
1925
  CPChanged = N_CPChanged; N_CPChanged = False;
1926
  for (z = 0; z < DPPCount; z++)
1927
  {
1928
    DPPChanged[z] = N_DPPChanged[z];
1929
    N_DPPChanged[z] = False;
1930
  }
1931
 
1932
  /* Praefixe herunterzaehlen */
1933
 
1934
  if (ExtCounter >= 0)
1935
   if (--ExtCounter < 0)
1936
   {
1937
     MemMode = MemModeStd;
1938
     ExtSFRs = False;
1939
   }
1940
}
1941
 
1942
/*-------------------------------------------------------------------------*/
1943
 
1944
static void AddBInstTable(const char *NName, Word NCode, InstProc Proc)
1945
{
1946
  char BName[30];
1947
 
1948
  AddInstTable(InstTable, NName, NCode | (eSymbolSize16Bit << 8), Proc);
1949
  as_snprintf(BName, sizeof(BName), "%sB", NName);
1950
  AddInstTable(InstTable, BName, NCode | (eSymbolSize8Bit << 8), Proc);
1951
}
1952
 
1953
static void AddFixed(const char *NName, CPUVar NMin, Word NCode1, Word NCode2)
1954
{
1955
  order_array_rsv_end(FixedOrders, BaseOrder);
1956
  FixedOrders[InstrZ].MinCPU = NMin;
1957
  FixedOrders[InstrZ].Code1 = NCode1;
1958
  FixedOrders[InstrZ].Code2 = NCode2;
1959
  AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
1960
}
1961
 
1962
static void AddShift(const char *NName, Byte NCode)
1963
{
1964
  AddInstTable(InstTable, NName, NCode, DecodeShift);
1965
}
1966
 
1967
static void AddBit2(const char *NName, Byte NCode)
1968
{
1969
  AddInstTable(InstTable, NName, NCode, DecodeBit2);
1970
}
1971
 
1972
static void AddLoop(const char *NName, Byte NCode)
1973
{
1974
  AddInstTable(InstTable, NName, NCode, DecodeLoop);
1975
}
1976
 
1977
static void AddCondition(const char *NName, Byte NCode)
1978
{
1979
  order_array_rsv_end(Conditions, Condition);
1980
  Conditions[InstrZ].Name = NName;
1981
  Conditions[InstrZ++].Code = NCode;
1982
}
1983
 
1984
static void InitFields(void)
1985
{
1986
  InstTable = CreateInstTable(201);
1987
  SetDynamicInstTable(InstTable);
1988
 
1989
  add_null_pseudo(InstTable);
1990
 
1991
  inst_table_set_prefix_proc(InstTable, update_prefixes, 0);
1992
 
1993
  AddBInstTable("MOV", 0, DecodeMOV);
1994
  AddInstTable(InstTable, "MOVBS", 0x10, DecodeMOVBS_MOVBZ);
1995
  AddInstTable(InstTable, "MOVBZ", 0x00, DecodeMOVBS_MOVBZ);
1996
  AddInstTable(InstTable, "PUSH", 0xec, DecodePUSH_POP);
1997
  AddInstTable(InstTable, "POP", 0xfc, DecodePUSH_POP);
1998
  AddInstTable(InstTable, "SCXT", 0, DecodeSCXT);
1999
  AddBInstTable("CPL", 0x91, DecodeCPL_NEG);
2000
  AddBInstTable("NEG", 0x81, DecodeCPL_NEG);
2001
  AddInstTable(InstTable, "BCLR", 0x0e, DecodeBCLR_BSET);
2002
  AddInstTable(InstTable, "BSET", 0x0f, DecodeBCLR_BSET);
2003
  AddInstTable(InstTable, "BFLDL", 0x0a, DecodeBFLDH_BFLDL);
2004
  AddInstTable(InstTable, "BFLDH", 0x1a, DecodeBFLDH_BFLDL);
2005
  AddInstTable(InstTable, "JMP", 0, DecodeJMP);
2006
  AddInstTable(InstTable, "CALL", 0, DecodeCALL);
2007
  AddInstTable(InstTable, "JMPR", 0, DecodeJMPR);
2008
  AddInstTable(InstTable, "CALLR", 0, DecodeCALLR);
2009
  AddInstTable(InstTable, "JMPA", 0xea, DecodeJMPA_CALLA);
2010
  AddInstTable(InstTable, "CALLA", 0xca, DecodeJMPA_CALLA);
2011
  AddInstTable(InstTable, "JMPS", 0xfa, DecodeJMPS_CALLS);
2012
  AddInstTable(InstTable, "CALLS", 0xda, DecodeJMPS_CALLS);
2013
  AddInstTable(InstTable, "JMPI", 0x9c, DecodeJMPI_CALLI);
2014
  AddInstTable(InstTable, "CALLI", 0xab, DecodeJMPI_CALLI);
2015
  AddInstTable(InstTable, "PCALL", 0, DecodePCALL);
2016
  AddInstTable(InstTable, "RETP", 0, DecodeRETP);
2017
  AddInstTable(InstTable, "TRAP", 0, DecodeTRAP);
2018
  AddInstTable(InstTable, "ATOMIC", 0, DecodeATOMIC);
2019
  AddInstTable(InstTable, "EXTR", 0, DecodeEXTR);
2020
  AddInstTable(InstTable, "EXTP", 0x00, DecodeEXTP_EXTPR);
2021
  AddInstTable(InstTable, "EXTPR", 0x80, DecodeEXTP_EXTPR);
2022
  AddInstTable(InstTable, "EXTS", 0x00, DecodeEXTS_EXTSR);
2023
  AddInstTable(InstTable, "EXTSR", 0x80, DecodeEXTS_EXTSR);
2024
 
2025
  InstrZ = 0;
2026
  AddFixed("DISWDT", CPU80C166, 0x5aa5, 0xa5a5);
2027
  AddFixed("EINIT" , CPU80C166, 0x4ab5, 0xb5b5);
2028
  AddFixed("IDLE"  , CPU80C166, 0x7887, 0x8787);
2029
  AddFixed("NOP"   , CPU80C166, 0x00cc, 0x0000);
2030
  AddFixed("PWRDN" , CPU80C166, 0x6897, 0x9797);
2031
  AddFixed("RET"   , CPU80C166, 0x00cb, 0x0000);
2032
  AddFixed("RETI"  , CPU80C166, 0x88fb, 0x0000);
2033
  AddFixed("RETS"  , CPU80C166, 0x00db, 0x0000);
2034
  AddFixed("SRST"  , CPU80C166, 0x48b7, 0xb7b7);
2035
  AddFixed("SRVWDT", CPU80C166, 0x58a7, 0xa7a7);
2036
 
2037
  InstrZ = 0;
2038
  AddCondition("UC" , COND_CODE_TRUE); AddCondition("Z"  , 0x2);
2039
  AddCondition("NZ" , 0x3); AddCondition("V"  , 0x4);
2040
  AddCondition("NV" , 0x5); AddCondition("N"  , 0x6);
2041
  AddCondition("NN" , 0x7); AddCondition("C"  , 0x8);
2042
  AddCondition("NC" , 0x9); AddCondition("EQ" , 0x2);
2043
  AddCondition("NE" , 0x3); AddCondition("ULT", 0x8);
2044
  AddCondition("ULE", 0xf); AddCondition("UGE", 0x9);
2045
  AddCondition("UGT", 0xe); AddCondition("SLT", 0xc);
2046
  AddCondition("SLE", 0xb); AddCondition("SGE", 0xd);
2047
  AddCondition("SGT", 0xa); AddCondition("NET", 0x1);
2048
  AddCondition(NULL, 0);
2049
 
2050
  InstrZ = 0;
2051
  AddBInstTable("ADD" , InstrZ++, DecodeALU2);
2052
  AddBInstTable("ADDC", InstrZ++, DecodeALU2);
2053
  AddBInstTable("SUB" , InstrZ++, DecodeALU2);
2054
  AddBInstTable("SUBC", InstrZ++, DecodeALU2);
2055
  AddBInstTable("CMP" , InstrZ++, DecodeALU2);
2056
  AddBInstTable("XOR" , InstrZ++, DecodeALU2);
2057
  AddBInstTable("AND" , InstrZ++, DecodeALU2);
2058
  AddBInstTable("OR"  , InstrZ++, DecodeALU2);
2059
 
2060
  AddShift("ASHR", 0xac); AddShift("ROL" , 0x0c);
2061
  AddShift("ROR" , 0x2c); AddShift("SHL" , 0x4c);
2062
  AddShift("SHR" , 0x6c);
2063
 
2064
  AddBit2("BAND", 0x6a); AddBit2("BCMP" , 0x2a);
2065
  AddBit2("BMOV", 0x4a); AddBit2("BMOVN", 0x3a);
2066
  AddBit2("BOR" , 0x5a); AddBit2("BXOR" , 0x7a);
2067
 
2068
  AddLoop("CMPD1", 0xa0); AddLoop("CMPD2", 0xb0);
2069
  AddLoop("CMPI1", 0x80); AddLoop("CMPI2", 0x90);
2070
 
2071
  InstrZ = 0;
2072
  AddInstTable(InstTable, "DIV"  , InstrZ++, DecodeDiv);
2073
  AddInstTable(InstTable, "DIVU" , InstrZ++, DecodeDiv);
2074
  AddInstTable(InstTable, "DIVL" , InstrZ++, DecodeDiv);
2075
  AddInstTable(InstTable, "DIVLU", InstrZ++, DecodeDiv);
2076
 
2077
  InstrZ = 0;
2078
  AddInstTable(InstTable, "JB"   , InstrZ++, DecodeBJmp);
2079
  AddInstTable(InstTable, "JNB"  , InstrZ++, DecodeBJmp);
2080
  AddInstTable(InstTable, "JBC"  , InstrZ++, DecodeBJmp);
2081
  AddInstTable(InstTable, "JNBS" , InstrZ++, DecodeBJmp);
2082
 
2083
  InstrZ = 0;
2084
  AddInstTable(InstTable, "MUL"  , InstrZ++, DecodeMul);
2085
  AddInstTable(InstTable, "MULU" , InstrZ++, DecodeMul);
2086
  AddInstTable(InstTable, "PRIOR", InstrZ++, DecodeMul);
2087
 
2088
  inst_table_set_prefix_proc(InstTable, NULL, 0);
2089
 
2090
  AddInstTable(InstTable, "BIT" , 0, DecodeBIT);
2091
  AddInstTable(InstTable, "REG" , 0, CodeREG);
2092
  AddIntelPseudo(InstTable, eIntPseudoFlag_LittleEndian);
2093
}
2094
 
2095
static void DeinitFields(void)
2096
{
2097
  DestroyInstTable(InstTable);
2098
  order_array_free(FixedOrders);
2099
  order_array_free(Conditions);
2100
}
2101
 
2102
static void MakeCode_166(void)
2103
{
2104
  OpSize = eSymbolSize16Bit;
2105
 
2106
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
2107
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2108
}
2109
 
2110
/*!------------------------------------------------------------------------
2111
 * \fn     InternSymbol_166(char *pArg, TempResult *pResult)
2112
 * \brief  handle built-in symbols on C16x
2113
 * \param  pArg source argument
2114
 * \param  pResult result buffer
2115
 * ------------------------------------------------------------------------ */
2116
 
2117
static void InternSymbol_166(char *pArg, TempResult *pResult)
2118
{
2119
  tRegInt Erg;
2120
  tSymbolSize Size;
2121
 
2122
  if (IsRegCore(pArg, &Erg, &Size))
2123
  {
2124
    pResult->Typ = TempReg;
2125
    pResult->DataSize = Size;
2126
    pResult->Contents.RegDescr.Reg = Erg;
2127
    pResult->Contents.RegDescr.Dissect = DissectReg_166;
2128
    pResult->Contents.RegDescr.compare = NULL;
2129
  }
2130
}
2131
 
2132
static void InitCode_166(void)
2133
{
2134
  int z;
2135
 
2136
  for (z = 0; z < DPPCount; z++)
2137
  {
2138
    DPPAssumes[z] = z;
2139
    N_DPPChanged[z] = False;
2140
  }
2141
  N_CPChanged = False;
2142
  N_SPChanged = False;
2143
 
2144
  MemMode = MemModeStd;
2145
  ExtSFRs = False;
2146
  ExtCounter = (-1);
2147
}
2148
 
2149
static Boolean IsDef_166(void)
2150
{
2151
  return (Memo("BIT")) || (Memo("REG"));
2152
}
2153
 
2154
static void SwitchFrom_166(void)
2155
{
2156
  DeinitFields();
2157
}
2158
 
2159
static void SwitchTo_166(void)
2160
{
2161
  Byte z;
2162
 
2163
  TurnWords = False;
2164
  SetIntConstMode(eIntConstModeIntel);
2165
  OpSize = eSymbolSize16Bit;
2166
 
2167
  PCSymbol = "$";
2168
  HeaderID = 0x4c;
2169
  NOPCode = 0xcc00;
2170
  DivideChars = ",";
2171
  HasAttrs = False;
2172
 
2173
  ValidSegs = (1 << SegCode);
2174
  Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
2175
 
2176
  MakeCode = MakeCode_166;
2177
  IsDef = IsDef_166;
2178
  InternSymbol = InternSymbol_166;
2179
  DissectReg = DissectReg_166;
2180
  SwitchFrom = SwitchFrom_166;
2181
 
2182
  if (MomCPU == CPU80C166)
2183
  {
2184
    MemInt = UInt18;
2185
    MemInt2 = UInt2;
2186
    ASSUME166s[0].Max = 15;
2187
    SegLimits[SegCode] = 0x3ffffl;
2188
  }
2189
  else
2190
  {
2191
    MemInt = UInt24;
2192
    MemInt2 = UInt8;
2193
    ASSUME166s[0].Max = 1023;
2194
    SegLimits[SegCode] = 0xffffffl;
2195
  }
2196
  for (z = 1; z < 4; z++)
2197
    ASSUME166s[z].Max = ASSUME166s[0].Max;
2198
 
2199
  pASSUMERecs = ASSUME166s;
2200
  ASSUMERecCnt = ASSUME166Count;
2201
 
2202
  InitFields();
2203
}
2204
 
2205
void code166_init(void)
2206
{
2207
  CPU80C166 = AddCPU("80C166", SwitchTo_166);
2208
  CPU80C167 = AddCPU("80C167", SwitchTo_166);
2209
  CPU80C167CS = AddCPU("80C167CS", SwitchTo_166);
2210
 
2211
  AddInitPassProc(InitCode_166);
2212
}