Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* codez8.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS-Portierung                                                             */
6
/*                                                                           */
7
/* Codegenerator Zilog Z8                                                    */
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 "asmstructs.h"
22
#include "asmitree.h"
23
#include "asmallg.h"
24
#include "codepseudo.h"
25
#include "intpseudo.h"
26
#include "codevars.h"
27
#include "headids.h"
28
#include "errmsg.h"
29
 
30
#include "codez8.h"
31
 
32
typedef enum
33
{
34
  eCoreNone = 0,
35
  eCoreZ8NMOS = 1 << 0,
36
  eCoreZ8CMOS = 1 << 1,
37
  eCoreSuper8 = 1 << 2,
38
  eCoreZ8Encore = 1 << 3,
39
  eCoreAll = eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore
40
} tCoreFlags;
41
 
42
typedef struct
43
{
44
  const char *pName;
45
  Word Code;
46
  tCoreFlags CoreFlags;
47
} BaseOrder;
48
 
49
typedef struct
50
{
51
  Word Code;
52
  tCoreFlags CoreFlags;
53
  Boolean Is16;
54
} ALU1Order;
55
 
56
typedef struct
57
{
58
  const char *Name;
59
  Byte Code;
60
} Condition;
61
 
62
#ifdef __cplusplus
63
# include "codez8.hpp"
64
#endif
65
 
66
typedef struct
67
{
68
  const char *pName;
69
  tCoreFlags CoreFlags;
70
  Word WorkOfs;
71
  Word RAMEnd, SFRStart;
72
} tCPUProps;
73
 
74
#define LongWorkOfs 0xee0   /* ditto with 12-bit-addresses */
75
 
76
#define EXTPREFIX 0x1f
77
 
78
#define mIsSuper8() (pCurrCPUProps->CoreFlags & eCoreSuper8)
79
#define mIsZ8Encore() (pCurrCPUProps->CoreFlags & eCoreZ8Encore)
80
 
81
/* CAUTION: ModIReg and ModIRReg are mutually exclusive
82
            ModReg  and ModRReg  are mutually exclusive */
83
 
84
enum
85
{
86
  ModNone = -1,
87
  ModWReg = 0,      /* working register R0..R15, 'r' */
88
  ModReg = 1,       /* general register 'R' */
89
  ModRReg = 2,      /* general register pair 'RR' (must be even) */
90
  ModIWReg = 3,     /* indirect working register @R0...@R15 'Ir' */
91
  ModIReg = 4,      /* indirect general register 'IR' */
92
  ModImm = 5,       /* immediate value 'IM' */
93
  ModWRReg = 6,     /* working register pair 'rr' (must be even) */
94
  ModIWRReg = 7,    /* indirect working register pair 'Irr' (must be even) */
95
  ModIRReg = 8,     /* indirect general register pair 'IRR' (must be even) */
96
  ModInd = 9,
97
  ModXReg = 10,
98
  ModIndRR = 11,
99
  ModIndRR16 = 12,
100
  ModWeird = 13,
101
  ModDA = 14
102
};
103
 
104
#define MModWReg   (1 << ModWReg)
105
#define MModReg    (1 << ModReg)
106
#define MModRReg   (1 << ModRReg)
107
#define MModIWReg  (1 << ModIWReg)
108
#define MModIReg   (1 << ModIReg)
109
#define MModImm    (1 << ModImm)
110
#define MModWRReg  (1 << ModWRReg)
111
#define MModIWRReg (1 << ModIWRReg)
112
#define MModIRReg  (1 << ModIRReg)
113
#define MModInd    (1 << ModInd)
114
#define MModXReg   (1 << ModXReg)
115
#define MModIndRR  (1 << ModIndRR)
116
#define MModIndRR16  (1 << ModIndRR16)
117
#define MModWeird  (1 << ModWeird)
118
#define MModDA     (1 << ModDA)
119
 
120
static ShortInt AdrType, OpSize;
121
static Byte AdrVal;
122
static Word AdrWVal;
123
static tSymbolFlags adr_val_flags;
124
static LongInt AdrIndex;
125
 
126
static BaseOrder *FixedOrders;
127
static BaseOrder *ALU2Orders;
128
static BaseOrder *ALUXOrders;
129
static ALU1Order *ALU1Orders;
130
static Condition *Conditions;
131
 
132
static int CondCnt, TrueCond;
133
 
134
static const tCPUProps *pCurrCPUProps;
135
 
136
static LongInt RPVal, RP0Val, RP1Val;
137
static IntType RegSpaceType;
138
 
139
/*--------------------------------------------------------------------------*/
140
/* address expression decoding routines */
141
 
142
/*!------------------------------------------------------------------------
143
 * \fn     IsWRegCore(const char *pArg, Byte *pResult)
144
 * \brief  Is argument a working register? (Rn, n=0..15)
145
 * \param  pArg argument
146
 * \param  pResult resulting register number if it is
147
 * \return True if it is
148
 * ------------------------------------------------------------------------ */
149
 
150
static Boolean IsWRegCore(const char *pArg, Byte *pResult)
151
{
152
  if ((strlen(pArg) < 2) || (as_toupper(*pArg) != 'R')) return False;
153
  else
154
  {
155
    Boolean OK;
156
 
157
    *pResult = ConstLongInt(pArg + 1, &OK, 10);
158
    return OK && (*pResult <= 15);
159
  }
160
}
161
 
162
/*!------------------------------------------------------------------------
163
 * \fn     IsWReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
164
 * \brief  Is argument a working register (Rn, n=0..15) or register alias?
165
 * \param  pArg argument
166
 * \param  pResult resulting register number if it is
167
 * \param  MustBeReg expecting register?
168
 * \return reg eval result
169
 * ------------------------------------------------------------------------ */
170
 
171
static Boolean IsWReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
172
{
173
  tRegDescr RegDescr;
174
  tEvalResult EvalResult;
175
  tRegEvalResult RegEvalResult;
176
 
177
  if (IsWRegCore(pArg->str.p_str, pResult))
178
    return True;
179
 
180
  RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize8Bit, MustBeReg);
181
  *pResult = RegDescr.Reg;
182
  return RegEvalResult;
183
}
184
 
185
/*!------------------------------------------------------------------------
186
 * \fn     IsWRRegCore(const char *pArg, Byte *pResult)
187
 * \brief  Is argument a working register pair? (RRn, n=0..15)
188
 * \param  pArg argument
189
 * \param  pResult resulting value if it is
190
 * \return True if it is
191
 * ------------------------------------------------------------------------ */
192
 
193
static Boolean IsWRRegCore(const char *pArg, Byte *pResult)
194
{
195
  if ((strlen(pArg) < 3) || as_strncasecmp(pArg, "RR", 2)) return False;
196
  else
197
  {
198
    Boolean OK;
199
 
200
    *pResult = ConstLongInt(pArg + 2, &OK, 10);
201
    return OK && (*pResult <= 15);
202
  }
203
}
204
 
205
#if 0
206
/*!------------------------------------------------------------------------
207
 * \fn     IsWRReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
208
 * \brief  Is argument a working register pair (RRn, n=0..15) or register pair alias?
209
 * \param  pArg argument
210
 * \param  pResult resulting value if it is
211
 * \param  MustBeReg expecting register?
212
 * \return reg eval result
213
 * ------------------------------------------------------------------------ */
214
 
215
static Boolean IsWRReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
216
{
217
  tRegDescr RegDescr;
218
  tEvalResult EvalResult;
219
  tRegEvalResult RegEvalResult;
220
 
221
  if (IsWRRegCore(pArg->str.p_str, pResult))
222
    return True;
223
 
224
  RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize16Bit, MustBeReg);
225
  *pResult = RegDescr.Reg;
226
  return RegEvalResult;
227
}
228
#endif
229
 
230
/*!------------------------------------------------------------------------
231
 * \fn     IsWRegOrWRReg(const tStrComp *pArg, Byte *pResult, tSymbolSize *pSize, Boolean MustBeReg)
232
 * \brief  Is argument a working register (pair) ((R)Rn, n=0..15) or register (pair) alias?
233
 * \param  pArg argument
234
 * \param  pResult resulting value if it is
235
 * \param  pSize register size if it is
236
 * \param  MustBeReg expecting register?
237
 * \return reg eval result
238
 * ------------------------------------------------------------------------ */
239
 
240
static tRegEvalResult IsWRegOrWRReg(const tStrComp *pArg, Byte *pResult, tSymbolSize *pSize, Boolean MustBeReg)
241
{
242
  tEvalResult EvalResult;
243
  tRegEvalResult RegEvalResult;
244
 
245
  if (IsWRegCore(pArg->str.p_str, pResult))
246
  {
247
    EvalResult.DataSize = eSymbolSize8Bit;
248
    RegEvalResult = eIsReg;
249
  }
250
  else if (IsWRRegCore(pArg->str.p_str, pResult))
251
  {
252
    EvalResult.DataSize = eSymbolSize16Bit;
253
    RegEvalResult = eIsReg;
254
  }
255
  else
256
  {
257
    tRegDescr RegDescr;
258
 
259
    RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
260
    *pResult = RegDescr.Reg;
261
  }
262
 
263
  if ((eIsReg == RegEvalResult) && (EvalResult.DataSize == eSymbolSize16Bit) && (*pResult & 1))
264
  {
265
    WrStrErrorPos(ErrNum_AddrMustBeEven, pArg);
266
    RegEvalResult = MustBeReg ? eIsNoReg : eRegAbort;
267
  }
268
 
269
  *pSize = EvalResult.DataSize;
270
  return RegEvalResult;
271
}
272
 
273
/*!------------------------------------------------------------------------
274
 * \fn     DissectReg_Z8(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
275
 * \brief  dissect register symbols - Z8 variant
276
 * \param  pDest destination buffer
277
 * \param  DestSize destination buffer size
278
 * \param  Value numeric register value
279
 * \param  InpSize register size
280
 * ------------------------------------------------------------------------ */
281
 
282
static void DissectReg_Z8(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
283
{
284
  switch (InpSize)
285
  {
286
    case eSymbolSize8Bit:
287
      as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
288
      break;
289
    case eSymbolSize16Bit:
290
      as_snprintf(pDest, DestSize, "RR%u", (unsigned)Value);
291
      break;
292
    default:
293
      as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
294
  }
295
}
296
 
297
/*!------------------------------------------------------------------------
298
 * \fn     CorrMode8(Word Mask, ShortInt Old, ShortInt New)
299
 * \brief  upgrade from working reg mode to gen. reg mode if necessary & possible?
300
 * \param  Mask bit mask of allowed addressing modes
301
 * \param  Old currently selected (working reg) mode
302
 * \param  New possible new mode
303
 * \return True if converted
304
 * ------------------------------------------------------------------------ */
305
 
306
static Boolean CorrMode8(Word Mask, ShortInt Old, ShortInt New)
307
{
308
   if ((AdrType == Old) && ((Mask & (1 << Old)) == 0) && ((Mask & (1 << New)) != 0))
309
   {
310
     AdrType = New;
311
     AdrVal += pCurrCPUProps->WorkOfs;
312
     return True;
313
   }
314
   else
315
     return False;
316
}
317
 
318
/*!------------------------------------------------------------------------
319
 * \fn     Boolean CorrMode12(Word Mask, ShortInt Old, ShortInt New)
320
 * \brief  upgrade from working reg mode to ext. reg (12 bit) mode if necessary & possible?
321
 * \param  Mask bit mask of allowed addressing modes
322
 * \param  Old currently selected (working reg) mode
323
 * \param  New possible new mode
324
 * \return True if converted
325
 * ------------------------------------------------------------------------ */
326
 
327
static Boolean CorrMode12(Word Mask, ShortInt Old, ShortInt New)
328
{
329
   if ((AdrType == Old) && ((Mask & (1 << Old)) == 0) && ((Mask & (1 << New)) != 0))
330
   {
331
     AdrType = New;
332
     AdrWVal = AdrVal + LongWorkOfs;
333
     return True;
334
   }
335
   else
336
     return False;
337
}
338
 
339
/*!------------------------------------------------------------------------
340
 * \fn     ChkAdr(Word Mask, const tStrComp *pArg)
341
 * \brief  check for validity of decoded addressing mode
342
 * \param  Mask bit mask of allowed addressing modes
343
 * \param  pArg original expression
344
 * \return true if OK
345
 * ------------------------------------------------------------------------ */
346
 
347
static Boolean ChkAdr(Word Mask, const tStrComp *pArg)
348
{
349
   CorrMode8(Mask, ModWReg, ModReg);
350
   CorrMode12(Mask, ModWReg, ModXReg);
351
   CorrMode8(Mask, ModIWReg, ModIReg);
352
 
353
   if ((AdrType != ModNone) && !(Mask & (1 << AdrType)))
354
   {
355
     WrStrErrorPos(ErrNum_InvAddrMode, pArg); AdrType = ModNone;
356
     return False;
357
   }
358
   return True;
359
}
360
 
361
/*!------------------------------------------------------------------------
362
 * \fn     IsWRegAddress(Word Address, Byte *pWorkReg)
363
 * \brief  check whether data address is accessible as work register
364
 * \param  Address data address in 8/12 bit data space
365
 * \param  pWorkReg resulting work register # if yes
366
 * \param  FirstPassUnknown flag about questionable value
367
 * \return true if accessible as work register
368
 * ------------------------------------------------------------------------ */
369
 
370
static Boolean ChkInRange(Word Address, Word Base, Word Length, Byte *pOffset)
371
{
372
  if ((Address >= Base) && (Address < Base + Length))
373
  {
374
    *pOffset = Address - Base;
375
    return True;
376
  }
377
  return False;
378
}
379
 
380
static Boolean IsWRegAddress(Word Address, Byte *pWorkReg)
381
{
382
  if (mIsSuper8())
383
  {
384
    if ((RP0Val <= 0xff) && ChkInRange(Address, RP0Val & 0xf8, 8, pWorkReg))
385
      return True;
386
    if ((RP1Val <= 0xff) && ChkInRange(Address, RP1Val & 0xf8, 8, pWorkReg))
387
    {
388
      *pWorkReg += 8;
389
      return True;
390
    }
391
  }
392
  else if (mIsZ8Encore())
393
  {
394
    if ((RPVal <= 0xff) && ChkInRange(Address, (RPVal & 0xf0) | ((RPVal & 0x0f) << 8), 16, pWorkReg))
395
      return True;
396
  }
397
  else
398
  {
399
    if ((RPVal <= 0xff) && ChkInRange(Address, RPVal & 0xf0, 16, pWorkReg))
400
      return True;
401
  }
402
  return False;
403
}
404
 
405
/*!------------------------------------------------------------------------
406
 * \fn     IsRegAddress(Word Address)
407
 * \brief  check whether data address is accessible via 8-bit address
408
 * \param  Address data address in 8/12 bit data space
409
 * \return true if accessible via 8-bit address
410
 * ------------------------------------------------------------------------ */
411
 
412
static Boolean IsRegAddress(Word Address)
413
{
414
  /* simple Z8 does not support 12 bit register addresses, so
415
     always force this to TRUE for it */
416
 
417
  if (!(pCurrCPUProps->CoreFlags & eCoreZ8Encore))
418
    return TRUE;
419
  return ((RPVal <= 0xff)
420
       && (Hi(Address) == (RPVal & 15)));
421
}
422
 
423
/*!------------------------------------------------------------------------
424
 * \fn     DecodeAdr(const tStrComp *pArg, Word Mask)
425
 * \brief  decode address expression
426
 * \param  pArg expression in source code
427
 * \param  Mask bit mask of allowed modes
428
 * \return True if successfully decoded to an allowed mode
429
 * ------------------------------------------------------------------------ */
430
 
431
int GetForceLen(const char *pArg)
432
{
433
  int Result = 0;
434
 
435
  while ((Result < 2) && (pArg[Result] == '>'))
436
    Result++;
437
  return Result;
438
}
439
 
440
static ShortInt IsWRegWithRP(const tStrComp *pComp, Byte *pResult, Word Mask16Modes, Word Mask8Modes)
441
{
442
  tEvalResult EvalResult;
443
  Word Address;
444
  tSymbolSize Size;
445
 
446
  switch (IsWRegOrWRReg(pComp, pResult, &Size, False))
447
  {
448
    case eIsReg:
449
      return Size;
450
    case eIsNoReg:
451
      break;
452
    case eRegAbort:
453
      return eSymbolSizeUnknown;
454
  }
455
 
456
  /* It's neither Rn nor RRn.  Since an address by itself has no
457
     operand size, only one mode may be allowed to keep things
458
     unambiguous: */
459
 
460
  if (Mask16Modes && Mask8Modes)
461
  {
462
    WrStrErrorPos(ErrNum_InvReg, pComp);
463
    return eSymbolSizeUnknown;
464
  }
465
 
466
  Address = EvalStrIntExpressionWithResult(pComp, UInt8, &EvalResult);
467
  if (!EvalResult.OK)
468
    return eSymbolSizeUnknown;
469
  /* if (mFirstPassUnknown(EvalResult.Flags)) ... */
470
 
471
  if (Mask16Modes && IsWRegAddress(Address, pResult))
472
  {
473
    if (mFirstPassUnknown(EvalResult.Flags)) *pResult &= ~1;
474
    if (*pResult & 1)
475
    {
476
      WrStrErrorPos(ErrNum_AddrMustBeEven, pComp);
477
      return eSymbolSizeUnknown;
478
    }
479
    return eSymbolSize16Bit;
480
  }
481
 
482
  if (Mask8Modes && IsWRegAddress(Address, pResult))
483
    return eSymbolSize8Bit;
484
 
485
  WrStrErrorPos(ErrNum_InvReg, pComp);
486
  return eSymbolSizeUnknown;
487
}
488
 
489
static Boolean DecodeAdr(const tStrComp *pArg, Word Mask)
490
{
491
  Boolean OK;
492
  tEvalResult EvalResult;
493
  char  *p;
494
  int ForceLen, l;
495
  tSymbolSize Size;
496
 
497
  if (!mIsSuper8() && !mIsZ8Encore())
498
    Mask &= ~MModIndRR;
499
  if (!mIsSuper8())
500
    Mask &= ~MModIndRR16;
501
  if (!mIsZ8Encore())
502
    Mask &= ~(MModXReg | MModWeird);
503
 
504
  AdrType = ModNone;
505
  adr_val_flags = eSymbolFlag_None;
506
 
507
  /* immediate ? */
508
 
509
  if (*pArg->str.p_str == '#')
510
  {
511
    switch (OpSize)
512
    {
513
      case eSymbolSize8Bit:
514
        AdrVal = EvalStrIntExpressionOffsWithFlags(pArg, 1, Int8, &OK, &adr_val_flags);
515
        break;
516
      case eSymbolSize16Bit:
517
        AdrWVal = EvalStrIntExpressionOffsWithFlags(pArg, 1, Int16, &OK, &adr_val_flags);
518
        break;
519
      default:
520
        OK = False;
521
    }
522
    if (OK) AdrType = ModImm;
523
    return ChkAdr(Mask, pArg);
524
  }
525
 
526
  /* Register ? */
527
 
528
  switch (IsWRegOrWRReg(pArg, &AdrVal, &Size, False))
529
  {
530
    case eIsReg:
531
      AdrType = (Size == eSymbolSize16Bit) ? ModWRReg : ModWReg;
532
      return ChkAdr(Mask, pArg);
533
    case eIsNoReg:
534
      break;
535
    case eRegAbort:
536
      return False;
537
  }
538
 
539
  /* treat absolute address as register? */
540
 
541
  if (*pArg->str.p_str == '!')
542
  {
543
    AdrWVal = EvalStrIntExpressionOffsWithResult(pArg, 1, UInt16, &EvalResult);
544
    if (EvalResult.OK)
545
    {
546
      if (!mFirstPassUnknown(EvalResult.Flags) && !IsWRegAddress(AdrWVal, &AdrVal))
547
        WrError(ErrNum_InAccPage);
548
      AdrType = ModWReg;
549
      adr_val_flags = EvalResult.Flags;
550
      return ChkAdr(Mask, pArg);
551
    }
552
    return False;
553
  }
554
 
555
  /* indirekte Konstrukte ? */
556
 
557
  if (*pArg->str.p_str == '@')
558
  {
559
    tStrComp Comp;
560
    tRegEvalResult RegEvalResult;
561
 
562
    StrCompRefRight(&Comp, pArg, 1);
563
    if ((strlen(Comp.str.p_str) >= 6) && (!as_strncasecmp(Comp.str.p_str, ".RR", 3)) && (IsIndirect(Comp.str.p_str + 3)))
564
    {
565
      AdrVal = EvalStrIntExpressionOffsWithResult(&Comp, 3, Int8, &EvalResult);
566
      if (EvalResult.OK)
567
      {
568
        AdrType = ModWeird;
569
        adr_val_flags = EvalResult.Flags;
570
        ChkSpace(SegData, EvalResult.AddrSpaceMask);
571
      }
572
    }
573
    else if ((RegEvalResult = IsWRegOrWRReg(&Comp, &AdrVal, &Size, False)) != eIsNoReg)
574
    {
575
      if (RegEvalResult == eRegAbort)
576
        return False;
577
      AdrType = (Size == eSymbolSize16Bit) ? ModIWRReg : ModIWReg;
578
    }
579
    else
580
    {
581
      /* Trying to do a working register optimization at this place is
582
         extremely tricky since an expression like @<address> has no
583
         inherent operand size (8/16 bit).  So the optimization IRR->Irr
584
         will only be allowed if IR is not allowed, or Irr is the only
585
         mode allowed: */
586
 
587
      Word ModeMask = Mask & (MModIRReg | MModIWRReg | MModIReg | MModIWReg);
588
 
589
      if (ModeMask == (MModIWReg | MModIWRReg))
590
      {
591
        WrStrErrorPos(ErrNum_UndefRegSize, &Comp);
592
        return False;
593
      }
594
 
595
      AdrWVal = EvalStrIntExpressionOffsWithResult(&Comp, ForceLen = GetForceLen(pArg->str.p_str), Int8, &EvalResult);
596
      if (EvalResult.OK)
597
      {
598
        ChkSpace(SegData, EvalResult.AddrSpaceMask);
599
        if (!(ModeMask & MModIReg) || (ModeMask == MModIWRReg))
600
        {
601
          if (mFirstPassUnknown(EvalResult.Flags)) AdrWVal &= ~1;
602
          if (AdrWVal & 1) WrStrErrorPos(ErrNum_AddrMustBeEven, &Comp);
603
          else if ((Mask & MModIWRReg) && (ForceLen <= 0) && IsWRegAddress(AdrWVal, &AdrVal))
604
            AdrType = ModIWRReg;
605
          else
606
          {
607
            AdrVal = AdrWVal;
608
            AdrType = ModIRReg;
609
          }
610
        }
611
        else
612
        {
613
          if ((Mask & MModIWReg) && (ForceLen <= 0) && IsWRegAddress(AdrWVal, &AdrVal))
614
            AdrType = ModIWReg;
615
          else
616
          {
617
            AdrVal = AdrWVal;
618
            AdrType = ModIReg;
619
          }
620
        }
621
      }
622
    }
623
    return ChkAdr(Mask, pArg);
624
  }
625
 
626
  /* indiziert ? */
627
 
628
  l = strlen(pArg->str.p_str);
629
  if ((l > 4) && (pArg->str.p_str[l - 1] == ')'))
630
  {
631
    tStrComp Left, Right;
632
 
633
    StrCompRefRight(&Right, pArg, 0);
634
    StrCompShorten(&Right, 1);
635
    p = RQuotPos(pArg->str.p_str, '(');
636
    if (!p)
637
    {
638
      WrStrErrorPos(ErrNum_BrackErr, pArg);
639
      return False;
640
    }
641
    StrCompSplitRef(&Left, &Right, &Right, p);
642
 
643
    switch (IsWRegWithRP(&Right, &AdrVal, Mask & (MModIndRR | MModIndRR16), Mask & MModInd))
644
    {
645
      case eSymbolSize8Bit:
646
        /* We are operating on a single base register and therefore in a 8-bit address space.
647
           So we may allow both a signed or unsigned displacements since addresses will wrap
648
           around anyway: */
649
 
650
        AdrIndex = EvalStrIntExpressionWithResult(&Left, Int8, &EvalResult);
651
        if (EvalResult.OK)
652
        {
653
          AdrType = ModInd; ChkSpace(SegData, EvalResult.AddrSpaceMask);
654
        }
655
        return ChkAdr(Mask, pArg);
656
 
657
      case eSymbolSize16Bit:
658
        /* 16 bit index only allowed if index register is not zero */
659
        AdrIndex = EvalStrIntExpressionWithResult(&Left, ((Mask & MModIndRR16) && (AdrVal != 0)) ? Int16 : SInt8, &EvalResult);
660
        if (EvalResult.OK)
661
        {
662
          if ((Mask & MModIndRR) && RangeCheck(AdrIndex, SInt8))
663
            AdrType = ModIndRR;
664
          else
665
            AdrType = ModIndRR16;
666
          /* TODO: differentiate LDC/LDE */
667
          ChkSpace(SegData, EvalResult.AddrSpaceMask);
668
        }
669
        return ChkAdr(Mask, pArg);
670
 
671
      default:
672
        return False;
673
    }
674
  }
675
 
676
  /* simple direct address ? */
677
 
678
  AdrWVal = EvalStrIntExpressionOffsWithResult(pArg, ForceLen = GetForceLen(pArg->str.p_str),
679
                                      (Mask & MModDA) ? UInt16 : RegSpaceType, &EvalResult);
680
  if (EvalResult.OK)
681
  {
682
    if (Mask & MModDA)
683
    {
684
      AdrType = ModDA;
685
      adr_val_flags = EvalResult.Flags;
686
      ChkSpace(SegCode, EvalResult.AddrSpaceMask);
687
    }
688
    else
689
    {
690
      if (mFirstPassUnknown(EvalResult.Flags) && !(Mask & ModXReg))
691
        AdrWVal = Lo(AdrWVal) | ((RPVal & 15) << 8);
692
      if (IsWRegAddress(AdrWVal, &AdrVal) && (Mask & MModWReg) && (ForceLen <= 0))
693
      {
694
        AdrType = ModWReg;
695
      }
696
      else if (IsRegAddress(AdrWVal) && (Mask & (MModReg | MModRReg)) && (ForceLen <= 1))
697
      {
698
        if (Mask & MModRReg)
699
        {
700
          if (mFirstPassUnknown(EvalResult.Flags))
701
            AdrWVal &= ~1;
702
          if (AdrWVal & 1)
703
          {
704
            WrStrErrorPos(ErrNum_AddrMustBeEven, pArg);
705
            return False;
706
          }
707
          AdrType = ModRReg;
708
        }
709
        else
710
          AdrType = ModReg;
711
        AdrVal = Lo(AdrWVal);
712
      }
713
      else
714
        AdrType = ModXReg;
715
      ChkSpace(SegData, EvalResult.AddrSpaceMask);
716
    }
717
    return ChkAdr(Mask, pArg);
718
  }
719
  else
720
    return False;
721
}
722
 
723
static int DecodeCond(const tStrComp *pArg)
724
{
725
  int z;
726
 
727
  NLS_UpString(pArg->str.p_str);
728
  for (z = 0; z < CondCnt; z++)
729
    if (strcmp(Conditions[z].Name, pArg->str.p_str) == 0)
730
      break;
731
 
732
  if (z >= CondCnt)
733
    WrStrErrorPos(ErrNum_UndefCond, pArg);
734
 
735
  return z;
736
}
737
 
738
static Boolean ChkCoreFlags(tCoreFlags CoreFlags)
739
{
740
  if (pCurrCPUProps->CoreFlags & CoreFlags)
741
    return True;
742
  WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
743
  return False;
744
}
745
 
746
/*--------------------------------------------------------------------------*/
747
/* Bit Symbol Handling */
748
 
749
/*
750
 * Compact representation of bits and bit fields in symbol table:
751
 * bits 0..2: (start) bit position
752
 * bits 3...10/14: register address in SFR space (256B/4KB)
753
 */
754
 
755
/*!------------------------------------------------------------------------
756
 * \fn     EvalBitPosition(const char *pBitArg, Boolean *pOK, ShortInt OpSize)
757
 * \brief  evaluate constant bit position, with bit range depending on operand size
758
 * \param  pBitArg bit position argument
759
 * \param  pOK returns True if OK
760
 * \param  OpSize operand size (0 -> 8 bits)
761
 * \return bit position as number
762
 * ------------------------------------------------------------------------ */
763
 
764
static Byte EvalBitPosition(const tStrComp *pBitArg, Boolean *pOK, ShortInt OpSize)
765
{
766
  switch (OpSize)
767
  {
768
    case eSymbolSize8Bit:
769
      return EvalStrIntExpressionOffs(pBitArg, !!(*pBitArg->str.p_str == '#'), UInt3, pOK);
770
    default:
771
      WrStrErrorPos(ErrNum_InvOpSize, pBitArg);
772
      *pOK = False;
773
      return 0;
774
  }
775
}
776
 
777
/*!------------------------------------------------------------------------
778
 * \fn     AssembleBitSymbol(Byte BitPos, ShortInt OpSize, Word Address)
779
 * \brief  build the compact internal representation of a bit field symbol
780
 * \param  BitPos bit position in word
781
 * \param  Width width of bit field
782
 * \param  OpSize operand size (0..2)
783
 * \param  Address register address
784
 * \return compact representation
785
 * ------------------------------------------------------------------------ */
786
 
787
static LongWord AssembleBitSymbol(Byte BitPos, ShortInt OpSize, Word Address)
788
{
789
  UNUSED(OpSize);
790
  return BitPos
791
       | (((LongWord)Address & 0xfff) << 3);
792
}
793
 
794
/*!------------------------------------------------------------------------
795
 * \fn     DecodeBitArg2(LongWord *pResult, const tStrComp *pRegArg, const tStrComp *pBitArg, ShortInt OpSize)
796
 * \brief  encode a bit symbol, address & bit position separated
797
 * \param  pResult resulting encoded bit
798
 * \param  pRegArg register argument
799
 * \param  pBitArg bit argument
800
 * \param  OpSize register size (0 = 8 bit)
801
 * \return True if success
802
 * ------------------------------------------------------------------------ */
803
 
804
static Boolean DecodeBitArg2(LongWord *pResult, const tStrComp *pRegArg, const tStrComp *pBitArg, ShortInt OpSize)
805
{
806
  Boolean OK;
807
  LongWord Addr;
808
  Byte BitPos;
809
 
810
  BitPos = EvalBitPosition(pBitArg, &OK, OpSize);
811
  if (!OK)
812
    return False;
813
 
814
  /* all I/O registers reside in the first 256/4K byte of the address space */
815
 
816
  DecodeAdr(pRegArg, MModWReg | (mIsZ8Encore() ? MModXReg : MModReg));
817
  switch (AdrType)
818
  {
819
    case ModXReg:
820
      Addr = AdrWVal;
821
      break;
822
    case ModWReg:
823
      Addr = AdrVal + pCurrCPUProps->WorkOfs;
824
      break;
825
    case ModReg:
826
      Addr = AdrVal;
827
      break;
828
    default:
829
      return False;
830
  }
831
 
832
  *pResult = AssembleBitSymbol(BitPos, OpSize, Addr);
833
 
834
  return True;
835
}
836
 
837
/*!------------------------------------------------------------------------
838
 * \fn     DecodeBitArg(LongWord *pResult, int Start, int Stop, ShortInt OpSize)
839
 * \brief  encode a bit symbol from instruction argument(s)
840
 * \param  pResult resulting encoded bit
841
 * \param  Start first argument
842
 * \param  Stop last argument
843
 * \param  OpSize register size (0 = 8 bit)
844
 * \return True if success
845
 * ------------------------------------------------------------------------ */
846
 
847
static Boolean DecodeBitArg(LongWord *pResult, int Start, int Stop, ShortInt OpSize)
848
{
849
  *pResult = 0;
850
 
851
  /* Just one argument -> parse as bit argument */
852
 
853
  if (Start == Stop)
854
  {
855
    tEvalResult EvalResult;
856
 
857
    *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start],
858
                                    mIsZ8Encore() ? UInt15 : UInt11,
859
                                    &EvalResult);
860
    if (EvalResult.OK)
861
      ChkSpace(SegBData, EvalResult.AddrSpaceMask);
862
    return EvalResult.OK;
863
  }
864
 
865
  /* register & bit position are given as separate arguments */
866
 
867
  else if (Stop == Start + 1)
868
    return DecodeBitArg2(pResult, &ArgStr[Start], &ArgStr[Stop], OpSize);
869
 
870
  /* other # of arguments not allowed */
871
 
872
  else
873
  {
874
    WrError(ErrNum_WrongArgCnt);
875
    return False;
876
  }
877
}
878
 
879
/*!------------------------------------------------------------------------
880
 * \fn     ExpandZ8Bit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
881
 * \brief  expands bit definition when a structure is instantiated
882
 * \param  pVarName desired symbol name
883
 * \param  pStructElem element definition
884
 * \param  Base base address of instantiated structure
885
 * ------------------------------------------------------------------------ */
886
 
887
static void ExpandZ8Bit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
888
{
889
  LongWord Address = Base + pStructElem->Offset;
890
 
891
  if (pInnermostNamedStruct)
892
  {
893
    PStructElem pElem = CloneStructElem(pVarName, pStructElem);
894
 
895
    if (!pElem)
896
      return;
897
    pElem->Offset = Address;
898
    AddStructElem(pInnermostNamedStruct->StructRec, pElem);
899
  }
900
  else
901
  {
902
    if (!ChkRange(Address, 0, 0x7ff)
903
     || !ChkRange(pStructElem->BitPos, 0, 7))
904
      return;
905
 
906
    PushLocHandle(-1);
907
    EnterIntSymbol(pVarName, AssembleBitSymbol(pStructElem->BitPos, eSymbolSize8Bit, Address), SegBData, False);
908
    PopLocHandle();
909
    /* TODO: MakeUseList? */
910
  }
911
}
912
 
913
/*!------------------------------------------------------------------------
914
 * \fn     DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos, ShortInt *pOpSize)
915
 * \brief  transform compact represenation of bit (field) symbol into components
916
 * \param  BitSymbol compact storage
917
 * \param  pAddress (I/O) register address
918
 * \param  pBitPos (start) bit position
919
 * \param  pWidth pWidth width of bit field, always one for individual bit
920
 * \param  pOpSize returns register size (0 for 8 bits)
921
 * \return constant True
922
 * ------------------------------------------------------------------------ */
923
 
924
static Boolean DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos, ShortInt *pOpSize)
925
{
926
  *pAddress = (BitSymbol >> 3) & 0xfff;
927
  *pBitPos = BitSymbol & 7;
928
  *pOpSize = eSymbolSize8Bit;
929
  return True;
930
}
931
 
932
/*!------------------------------------------------------------------------
933
 * \fn     DecodeWRBitArg(int StartArg, int EndArg, Byte *pResult)
934
 * \brief  decode bit argument in working register
935
 * \param  StartArg 1st argument
936
 * \param  EndArg last argument
937
 * \param  pResult resulting encoded bit
938
 * \return TRUE if successfully decoded
939
 * ------------------------------------------------------------------------ */
940
 
941
static Boolean DecodeWRBitArg(int StartArg, int EndArg, Byte *pResult)
942
{
943
  LongWord Result;
944
  Word Address;
945
  Byte BitPos;
946
  ShortInt OpSize;
947
 
948
  if (!DecodeBitArg(&Result, StartArg, EndArg, eSymbolSize8Bit))
949
    return False;
950
  (void)DissectBitSymbol(Result, &Address, &BitPos, &OpSize);
951
  if ((Address < pCurrCPUProps->WorkOfs) || (Address >= pCurrCPUProps->WorkOfs + 16))
952
  {
953
    WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[StartArg]);
954
    return False;
955
  }
956
  *pResult = ((Address & 15) << 3) | BitPos;
957
  return True;
958
}
959
 
960
/*!------------------------------------------------------------------------
961
 * \fn     DissectBit_Z8(char *pDest, size_t DestSize, LargeWord Inp)
962
 * \brief  dissect compact storage of bit (field) into readable form for listing
963
 * \param  pDest destination for ASCII representation
964
 * \param  DestSize destination buffer size
965
 * \param  Inp compact storage
966
 * ------------------------------------------------------------------------ */
967
 
968
static void DissectBit_Z8(char *pDest, size_t DestSize, LargeWord Inp)
969
{
970
  Byte BitPos;
971
  Word Address;
972
  ShortInt OpSize;
973
 
974
  DissectBitSymbol(Inp, &Address, &BitPos, &OpSize);
975
  UNUSED(OpSize);
976
 
977
  UNUSED(DestSize);
978
  if ((Address >= pCurrCPUProps->WorkOfs) && (Address <= pCurrCPUProps->WorkOfs + 15))
979
    as_snprintf(pDest, DestSize, "%c%u", HexStartCharacter + ('r' - 'a'), (unsigned)(Address & 15));
980
  else
981
    SysString(pDest, DestSize, Address, ListRadixBase,
982
              mIsZ8Encore() ? 3 : 2, (16 == ListRadixBase) && (IntConstMode == eIntConstModeIntel),
983
              HexStartCharacter, SplitByteCharacter);
984
  as_snprcatf(pDest, DestSize, ".%u", (unsigned)BitPos);
985
}
986
 
987
/*--------------------------------------------------------------------------*/
988
/* Instruction Decoders */
989
 
990
static void DecodeFixed(Word Index)
991
{
992
  BaseOrder *pOrder = FixedOrders + Index;
993
 
994
  if (ChkArgCnt(0, 0)
995
   && ChkCoreFlags(pOrder->CoreFlags))
996
  {
997
    CodeLen = 1;
998
    BAsmCode[0] = pOrder->Code;
999
  }
1000
}
1001
 
1002
static void DecodeALU2(Word Index)
1003
{
1004
  BaseOrder *pOrder = ALU2Orders + Index;
1005
  Byte Save;
1006
  int l = 0;
1007
 
1008
  if (ChkArgCnt(2, 2)
1009
   && ChkCoreFlags(pOrder->CoreFlags))
1010
  {
1011
    if (Hi(pOrder->Code))
1012
      BAsmCode[l++] = Hi(pOrder->Code);
1013
    DecodeAdr(&ArgStr[1], MModReg | MModWReg | ((pCurrCPUProps->CoreFlags & eCoreSuper8) ? 0 : MModIReg));
1014
    switch (AdrType)
1015
    {
1016
      case ModReg:
1017
       Save = AdrVal;
1018
       DecodeAdr(&ArgStr[2], MModReg | MModIReg | MModImm);
1019
       switch (AdrType)
1020
       {
1021
         case ModReg:
1022
          BAsmCode[l++] = pOrder->Code + 4;
1023
          BAsmCode[l++] = AdrVal;
1024
          BAsmCode[l++] = Save;
1025
          CodeLen = l;
1026
          break;
1027
         case ModIReg:
1028
          BAsmCode[l++] = pOrder->Code + 5;
1029
          BAsmCode[l++] = AdrVal;
1030
          BAsmCode[l++] = Save;
1031
          CodeLen = l;
1032
          break;
1033
         case ModImm:
1034
          BAsmCode[l++] = pOrder->Code + 6;
1035
          BAsmCode[l++] = Save;
1036
          BAsmCode[l++] = AdrVal;
1037
          CodeLen = l;
1038
          break;
1039
       }
1040
       break;
1041
      case ModWReg:
1042
       Save = AdrVal;
1043
       DecodeAdr(&ArgStr[2], MModWReg| MModReg | MModIWReg | MModIReg | MModImm);
1044
       switch (AdrType)
1045
       {
1046
         case ModWReg:
1047
          BAsmCode[l++] = pOrder->Code + 2;
1048
          BAsmCode[l++] = (Save << 4) + AdrVal;
1049
          CodeLen = l;
1050
          break;
1051
         case ModReg:
1052
          BAsmCode[l++] = pOrder->Code + 4;
1053
          BAsmCode[l++] = AdrVal;
1054
          BAsmCode[l++] = pCurrCPUProps->WorkOfs + Save;
1055
          CodeLen = l;
1056
          break;
1057
         case ModIWReg:
1058
          BAsmCode[l++] = pOrder->Code + 3;
1059
          BAsmCode[l++] = (Save << 4) + AdrVal;
1060
          CodeLen = l;
1061
          break;
1062
         case ModIReg:
1063
          BAsmCode[l++] = pOrder->Code + 5;
1064
          BAsmCode[l++] = AdrVal;
1065
          BAsmCode[l++] = pCurrCPUProps->WorkOfs + Save;
1066
          CodeLen = l;
1067
          break;
1068
         case ModImm:
1069
          BAsmCode[l++] = pOrder->Code + 6;
1070
          BAsmCode[l++] = Save + pCurrCPUProps->WorkOfs;
1071
          BAsmCode[l++] = AdrVal;
1072
          CodeLen = l;
1073
          break;
1074
       }
1075
       break;
1076
      case ModIReg:
1077
       Save = AdrVal;
1078
       if (DecodeAdr(&ArgStr[2], MModImm))
1079
       {
1080
         BAsmCode[l++] = pOrder->Code + 7;
1081
         BAsmCode[l++] = Save;
1082
         BAsmCode[l++] = AdrVal;
1083
         CodeLen = l;
1084
       }
1085
       break;
1086
    }
1087
  }
1088
}
1089
 
1090
static void DecodeALUX(Word Index)
1091
{
1092
  BaseOrder *pOrder = ALUXOrders + Index;
1093
  int l = 0;
1094
 
1095
  if (ChkArgCnt(2, 2)
1096
   && ChkCoreFlags(pOrder->CoreFlags))
1097
  {
1098
    if (Hi(pOrder->Code))
1099
      BAsmCode[l++] = Hi(pOrder->Code);
1100
    if (DecodeAdr(&ArgStr[1], MModXReg))
1101
    {
1102
      BAsmCode[l + 3] = Lo(AdrWVal);
1103
      BAsmCode[l + 2] = Hi(AdrWVal) & 15;
1104
      DecodeAdr(&ArgStr[2], MModXReg | MModImm);
1105
      switch (AdrType)
1106
      {
1107
        case ModXReg:
1108
          BAsmCode[l + 0] = pOrder->Code;
1109
          BAsmCode[l + 1] = AdrWVal >> 4;
1110
          BAsmCode[l + 2] |= (AdrWVal & 15) << 4;
1111
          CodeLen = l + 4;
1112
          break;
1113
        case ModImm:
1114
          BAsmCode[l + 0] = pOrder->Code + 1;
1115
          BAsmCode[l + 1] = AdrVal;
1116
          CodeLen = l + 4;
1117
          break;
1118
      }
1119
    }
1120
  }
1121
}
1122
 
1123
static void DecodeALU1(Word Index)
1124
{
1125
  ALU1Order *pOrder = ALU1Orders + Index;
1126
  int l = 0;
1127
 
1128
  if (ChkArgCnt(1, 1)
1129
   && ChkCoreFlags(pOrder->CoreFlags))
1130
  {
1131
    if (Hi(pOrder->Code))
1132
      BAsmCode[l++] = Hi(pOrder->Code);
1133
    DecodeAdr(&ArgStr[1], (pOrder->Is16 ? (MModWRReg | MModRReg) : MModReg) | MModIReg);
1134
    switch (AdrType)
1135
    {
1136
      case ModReg:
1137
      case ModRReg:
1138
       BAsmCode[l++] = pOrder->Code;
1139
       BAsmCode[l++] = AdrVal;
1140
       CodeLen = l;
1141
       break;
1142
      case ModWRReg:
1143
       BAsmCode[l++] = pOrder->Code;
1144
       BAsmCode[l++] = pCurrCPUProps->WorkOfs + AdrVal;
1145
       CodeLen = l;
1146
       break;
1147
      case ModIReg:
1148
       BAsmCode[l++] = pOrder->Code + 1;
1149
       BAsmCode[l++] = AdrVal;
1150
       CodeLen = l;
1151
       break;
1152
    }
1153
  }
1154
}
1155
 
1156
static void DecodeLD(Word Index)
1157
{
1158
  Word Save;
1159
 
1160
  UNUSED(Index);
1161
 
1162
  if (ChkArgCnt(2, 2)
1163
   && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore))
1164
  {
1165
    DecodeAdr(&ArgStr[1], MModReg | MModWReg | MModIReg | MModIWReg | MModInd);
1166
    switch (AdrType)
1167
    {
1168
      case ModReg:
1169
        Save = AdrVal;
1170
        DecodeAdr(&ArgStr[2], MModReg | MModWReg | MModIReg | MModImm);
1171
        switch (AdrType)
1172
        {
1173
         case ModReg: /* Super8 OK */
1174
           BAsmCode[0] = 0xe4;
1175
           BAsmCode[1] = AdrVal;
1176
           BAsmCode[2] = Save;
1177
           CodeLen = 3;
1178
           break;
1179
         case ModWReg:
1180
           if (pCurrCPUProps->CoreFlags & eCoreZ8Encore)
1181
           {
1182
             BAsmCode[0] = 0xe4;
1183
             BAsmCode[1] = AdrVal + pCurrCPUProps->WorkOfs;
1184
             BAsmCode[2] = Save;
1185
             CodeLen = 3;
1186
           }
1187
           else /** non-eZ8 **/ /* Super8 OK */
1188
           {
1189
             BAsmCode[0] = (AdrVal << 4) + 9;
1190
             BAsmCode[1] = Save;
1191
             CodeLen = 2;
1192
           }
1193
           break;
1194
         case ModIReg: /* Super8 OK */
1195
           BAsmCode[0] = 0xe5;
1196
           BAsmCode[1] = AdrVal;
1197
           BAsmCode[2] = Save;
1198
           CodeLen = 3;
1199
           break;
1200
         case ModImm: /* Super8 OK */
1201
           BAsmCode[0] = 0xe6;
1202
           BAsmCode[1] = Save;
1203
           BAsmCode[2] = AdrVal;
1204
           CodeLen = 3;
1205
           break;
1206
        }
1207
        break;
1208
      case ModWReg:
1209
        Save = AdrVal;
1210
        DecodeAdr(&ArgStr[2], MModWReg | MModReg | MModIWReg | MModIReg | MModImm | MModInd);
1211
        switch (AdrType)
1212
        {
1213
          case ModWReg:
1214
            if (pCurrCPUProps->CoreFlags & eCoreZ8Encore)
1215
            {
1216
              BAsmCode[0] = 0xe4;
1217
              BAsmCode[1] = AdrVal + pCurrCPUProps->WorkOfs;
1218
              BAsmCode[2] = Save + pCurrCPUProps->WorkOfs;
1219
              CodeLen = 3;
1220
            }
1221
            else /** non-eZ8 */ /* Super8 OK */
1222
            {
1223
              BAsmCode[0] = (Save << 4) + 8;
1224
              BAsmCode[1] = AdrVal + pCurrCPUProps->WorkOfs;
1225
              CodeLen = 2;
1226
            }
1227
            break;
1228
          case ModReg:
1229
            if (pCurrCPUProps->CoreFlags & eCoreZ8Encore)
1230
            {
1231
              BAsmCode[0] = 0xe4;
1232
              BAsmCode[1] = AdrVal;
1233
              BAsmCode[2] = Save + pCurrCPUProps->WorkOfs;
1234
              CodeLen = 3;
1235
            }
1236
            else /** non-eZ8 **/ /* Super8 OK */
1237
            {
1238
              BAsmCode[0] = (Save << 4) + 8;
1239
              BAsmCode[1] = AdrVal;
1240
              CodeLen = 2;
1241
            }
1242
            break;
1243
          case ModIWReg:
1244
            /* is C7 r,IR or r,ir? */
1245
            BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreSuper8) ? 0xc7 : 0xe3;
1246
            BAsmCode[1] = (Save << 4) + AdrVal;
1247
            CodeLen = 2;
1248
            break;
1249
          case ModIReg: /* Super8 OK */
1250
            BAsmCode[0] = 0xe5;
1251
            BAsmCode[1] = AdrVal;
1252
            BAsmCode[2] = pCurrCPUProps->WorkOfs + Save;
1253
            CodeLen = 3;
1254
            break;
1255
          case ModImm: /* Super8 OK */
1256
            BAsmCode[0] = (Save << 4) + 12;
1257
            BAsmCode[1] = AdrVal;
1258
            CodeLen = 2;
1259
            break;
1260
          case ModInd:
1261
            BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreSuper8) ? 0x87 : 0xc7;
1262
            BAsmCode[1] = (Save << 4) + AdrVal;
1263
            BAsmCode[2] = AdrIndex;
1264
            CodeLen = 3;
1265
            break;
1266
        }
1267
        break;
1268
      case ModIReg:
1269
        Save = AdrVal;
1270
        DecodeAdr(&ArgStr[2], MModReg | MModImm);
1271
        switch (AdrType)
1272
        {
1273
          case ModReg: /* Super8 OK */
1274
            BAsmCode[0] = 0xf5;
1275
            BAsmCode[1] = AdrVal;
1276
            BAsmCode[2] = Save;
1277
            CodeLen = 3;
1278
            break;
1279
          case ModImm:
1280
            BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreSuper8) ? 0xd6 : 0xe7;
1281
            BAsmCode[1] = Save;
1282
            BAsmCode[2] = AdrVal;
1283
            CodeLen = 3;
1284
            break;
1285
        }
1286
        break;
1287
      case ModIWReg:
1288
        Save = AdrVal;
1289
        DecodeAdr(&ArgStr[2], MModWReg | MModReg | MModImm);
1290
        switch (AdrType)
1291
        {
1292
          case ModWReg:
1293
            BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreSuper8) ? 0xd7 : 0xf3;
1294
            BAsmCode[1] = (Save << 4) + AdrVal;
1295
            CodeLen = 2;
1296
            break;
1297
          case ModReg: /* Super8 OK */
1298
            BAsmCode[0] = 0xf5;
1299
            BAsmCode[1] = AdrVal;
1300
            BAsmCode[2] = pCurrCPUProps->WorkOfs + Save;
1301
            CodeLen = 3;
1302
            break;
1303
          case ModImm:
1304
            BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreSuper8) ? 0xd6 : 0xe7;
1305
            BAsmCode[1] = pCurrCPUProps->WorkOfs + Save;
1306
            BAsmCode[2] = AdrVal;
1307
            CodeLen = 3;
1308
            break;
1309
        }
1310
        break;
1311
      case ModInd:
1312
        Save = AdrVal;
1313
        if (DecodeAdr(&ArgStr[2], MModWReg))
1314
        {
1315
          BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreSuper8) ? 0x97 : 0xd7;
1316
          BAsmCode[1] = (AdrVal << 4) + Save;
1317
          BAsmCode[2] = AdrIndex;
1318
          CodeLen = 3;
1319
        }
1320
        break;
1321
    }
1322
  }
1323
}
1324
 
1325
static void DecodeLDCE(Word Code)
1326
{
1327
  Byte Save, Super8Add = mIsSuper8() && !!(Code == 0x82);
1328
 
1329
  if (ChkArgCnt(2, 2)
1330
   && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore))
1331
  {
1332
    LongWord DestMask = MModWReg | MModIWRReg, SrcMask;
1333
 
1334
    if ((pCurrCPUProps->CoreFlags & eCoreZ8Encore) && (Code == 0xc2))
1335
      DestMask |= MModIWReg;
1336
    if (mIsSuper8())
1337
      DestMask |= MModIndRR | MModIndRR16 | MModDA;
1338
    DecodeAdr(&ArgStr[1], DestMask);
1339
    switch (AdrType)
1340
    {
1341
      case ModWReg:
1342
        SrcMask = MModIWRReg;
1343
        if (pCurrCPUProps->CoreFlags & eCoreSuper8)
1344
          SrcMask |= MModIndRR | MModIndRR16 | MModDA;
1345
        Save = AdrVal; DecodeAdr(&ArgStr[2], SrcMask);
1346
        switch (AdrType)
1347
        {
1348
          case ModIWRReg:
1349
            BAsmCode[0] = mIsSuper8() ? 0xc3 : Code;
1350
            BAsmCode[1] = (Save << 4) | AdrVal | Super8Add;
1351
            CodeLen = 2;
1352
            break;
1353
          case ModDA:
1354
            BAsmCode[0] = 0xa7;
1355
            BAsmCode[1] = (Save << 4) | Super8Add;
1356
            BAsmCode[2] = Lo(AdrWVal);
1357
            BAsmCode[3] = Hi(AdrWVal);
1358
            CodeLen = 4;
1359
            break;
1360
          case ModIndRR:
1361
            BAsmCode[0] = 0xe7;
1362
            BAsmCode[1] = (Save << 4) | AdrVal | Super8Add;
1363
            BAsmCode[2] = Lo(AdrIndex);
1364
            CodeLen = 3;
1365
            break;
1366
          case ModIndRR16:
1367
            BAsmCode[0] = 0xa7;
1368
            BAsmCode[1] = (Save << 4) | AdrVal | Super8Add;
1369
            BAsmCode[2] = Lo(AdrIndex);
1370
            BAsmCode[3] = Hi(AdrIndex);
1371
            CodeLen = 4;
1372
            break;
1373
        }
1374
        break;
1375
      case ModIWReg:
1376
        Save = AdrVal; DecodeAdr(&ArgStr[2], MModIWRReg);
1377
        if (AdrType != ModNone)
1378
        {
1379
          BAsmCode[0] = 0xc5;
1380
          BAsmCode[1] = (Save << 4) | AdrVal;
1381
          CodeLen = 2;
1382
        }
1383
        break;
1384
      case ModIWRReg:
1385
        Save = AdrVal; DecodeAdr(&ArgStr[2], MModWReg);
1386
        if (AdrType != ModNone)
1387
        {
1388
          BAsmCode[0] = mIsSuper8() ? 0xd3 : Code + 0x10;
1389
          BAsmCode[1] = (AdrVal << 4) | Save | Super8Add;
1390
          CodeLen = 2;
1391
        }
1392
        break;
1393
      case ModDA: /* Super8 only */
1394
        BAsmCode[2] = Lo(AdrWVal);
1395
        BAsmCode[3] = Hi(AdrWVal);
1396
        DecodeAdr(&ArgStr[2], MModWReg);
1397
        if (AdrType != ModNone)
1398
        {
1399
          BAsmCode[0] = 0xb7;
1400
          BAsmCode[1] = (AdrVal << 4) | Super8Add;
1401
          CodeLen = 4;
1402
        }
1403
        break;
1404
      case ModIndRR: /* Super8 only */
1405
        BAsmCode[2] = Lo(AdrIndex);
1406
        Save = AdrVal;
1407
        DecodeAdr(&ArgStr[2], MModWReg);
1408
        if (AdrType != ModNone)
1409
        {
1410
          BAsmCode[0] = 0xf7;
1411
          BAsmCode[1] = (AdrVal << 4) | Save | Super8Add;
1412
          CodeLen = 3;
1413
        }
1414
        break;
1415
      case ModIndRR16: /* Super8 only */
1416
        BAsmCode[2] = Lo(AdrIndex);
1417
        BAsmCode[3] = Hi(AdrIndex);
1418
        Save = AdrVal;
1419
        DecodeAdr(&ArgStr[2], MModWReg);
1420
        if (AdrType != ModNone)
1421
        {
1422
          BAsmCode[0] = 0xb7;
1423
          BAsmCode[1] = (AdrVal << 4) | Save | Super8Add;
1424
          CodeLen = 4;
1425
        }
1426
        break;
1427
    }
1428
  }
1429
}
1430
 
1431
static void DecodeLDCEI(Word Index)
1432
{
1433
  Byte Save;
1434
 
1435
  if (ChkArgCnt(2, 2)
1436
   && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreZ8Encore))
1437
  {
1438
    DecodeAdr(&ArgStr[1], MModIWReg | MModIWRReg);
1439
    switch (AdrType)
1440
    {
1441
      case ModIWReg:
1442
        Save = AdrVal; DecodeAdr(&ArgStr[2], MModIWRReg);
1443
        if (AdrType != ModNone)
1444
        {
1445
          BAsmCode[0] = Index;
1446
          BAsmCode[1] = (Save << 4) + AdrVal;
1447
          CodeLen = 2;
1448
        }
1449
        break;
1450
      case ModIWRReg:
1451
        Save = AdrVal; DecodeAdr(&ArgStr[2], MModIWReg);
1452
        if (AdrType != ModNone)
1453
        {
1454
          BAsmCode[0] = Index + 0x10;
1455
          BAsmCode[1] = (AdrVal << 4) + Save;
1456
          CodeLen = 2;
1457
        }
1458
        break;
1459
    }
1460
  }
1461
}
1462
 
1463
static void DecodeLDCEDI(Word Code)
1464
{
1465
  if (ChkArgCnt(2, 2)
1466
   && ChkCoreFlags(eCoreSuper8)
1467
   && DecodeAdr(&ArgStr[1], MModWReg))
1468
  {
1469
    BAsmCode[0] = Lo(Code);
1470
    BAsmCode[1] = AdrVal << 4;
1471
    DecodeAdr(&ArgStr[2], MModIWRReg);
1472
    if (AdrType == ModIWRReg)
1473
    {
1474
      BAsmCode[1] |= AdrVal | Hi(Code);
1475
      CodeLen = 2;
1476
    }
1477
  }
1478
}
1479
 
1480
static void DecodeLDCEPDI(Word Code)
1481
{
1482
  if (ChkArgCnt(2, 2)
1483
   && ChkCoreFlags(eCoreSuper8)
1484
   && DecodeAdr(&ArgStr[1], MModIWRReg))
1485
  {
1486
    BAsmCode[0] = Lo(Code);
1487
    BAsmCode[1] = AdrVal | Hi(Code);
1488
    DecodeAdr(&ArgStr[2], MModWReg);
1489
    if (AdrType == ModWReg)
1490
    {
1491
      BAsmCode[1] |= AdrVal << 4;
1492
      CodeLen = 2;
1493
    }
1494
  }
1495
}
1496
 
1497
static void DecodeINC(Word Index)
1498
{
1499
  UNUSED(Index);
1500
 
1501
  if (ChkArgCnt(1, 1)
1502
   && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore))
1503
  {
1504
    DecodeAdr(&ArgStr[1], MModWReg | MModReg | MModIReg);
1505
    switch (AdrType)
1506
    {
1507
      case ModWReg:
1508
        BAsmCode[0] = (AdrVal << 4) + 0x0e;
1509
        CodeLen = 1;
1510
        break;
1511
      case ModReg:
1512
        BAsmCode[0] = 0x20;
1513
        BAsmCode[1] = AdrVal;
1514
        CodeLen = 2;
1515
        break;
1516
      case ModIReg:
1517
        BAsmCode[0] = 0x21;
1518
        BAsmCode[1] = AdrVal;
1519
        CodeLen = 2;
1520
        break;
1521
    }
1522
  }
1523
}
1524
 
1525
static void DecodeJR(Word Index)
1526
{
1527
  Integer AdrInt;
1528
  int z;
1529
  tEvalResult EvalResult;
1530
 
1531
  UNUSED(Index);
1532
 
1533
  if (ChkArgCnt(1, 2)
1534
   && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore))
1535
  {
1536
    z = (ArgCnt == 1) ? TrueCond : DecodeCond(&ArgStr[1]);
1537
    if (z < CondCnt)
1538
    {
1539
      AdrInt = EvalStrIntExpressionWithResult(&ArgStr[ArgCnt], Int16, &EvalResult) - (EProgCounter() + 2);
1540
      if (EvalResult.OK)
1541
      {
1542
        if (!mSymbolQuestionable(EvalResult.Flags)
1543
         && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
1544
        else
1545
        {
1546
          ChkSpace(SegCode, EvalResult.AddrSpaceMask);
1547
          BAsmCode[0] = (Conditions[z].Code << 4) + 0x0b;
1548
          BAsmCode[1] = Lo(AdrInt);
1549
          CodeLen = 2;
1550
        }
1551
      }
1552
    }
1553
  }
1554
}
1555
 
1556
static void DecodeDJNZ(Word Index)
1557
{
1558
  Integer AdrInt;
1559
  Boolean OK;
1560
  tSymbolFlags Flags;
1561
 
1562
  UNUSED(Index);
1563
 
1564
  if (ChkArgCnt(2, 2)
1565
   && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore)
1566
   && DecodeAdr(&ArgStr[1], MModWReg))
1567
  {
1568
    AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[2], Int16, &OK, &Flags) - (EProgCounter() + 2);
1569
    if (OK)
1570
    {
1571
      if (!mSymbolQuestionable(Flags)
1572
       && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
1573
      else
1574
      {
1575
        BAsmCode[0] = (AdrVal << 4) + 0x0a;
1576
        BAsmCode[1] = Lo(AdrInt);
1577
        CodeLen = 2;
1578
      }
1579
    }
1580
  }
1581
}
1582
 
1583
static void DecodeCPIJNE(Word Code)
1584
{
1585
  if (ChkArgCnt(3, 3)
1586
   && ChkCoreFlags(eCoreSuper8)
1587
   && DecodeAdr(&ArgStr[1], MModWReg))
1588
  {
1589
    BAsmCode[1] = AdrVal & 0x0f;
1590
 
1591
    DecodeAdr(&ArgStr[2], MModIWReg);
1592
    if (AdrType != ModNone)
1593
    {
1594
      Boolean OK;
1595
      tSymbolFlags Flags;
1596
      Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[3], Int16, &OK, &Flags) - (EProgCounter() + 3);
1597
 
1598
      BAsmCode[1] |= AdrVal << 4;
1599
 
1600
      if (OK)
1601
      {
1602
        if (!mSymbolQuestionable(Flags)
1603
         && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
1604
        else
1605
        {
1606
          BAsmCode[0] = Code;
1607
          BAsmCode[2] = Lo(AdrInt);
1608
          CodeLen = 3;
1609
        }
1610
      }
1611
    }
1612
  }
1613
}
1614
 
1615
static void DecodeCALL(Word Index)
1616
{
1617
  Boolean IsSuper8 = !!(pCurrCPUProps->CoreFlags & eCoreSuper8);
1618
  UNUSED(Index);
1619
 
1620
  if (ChkArgCnt(1, 1)
1621
   && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore))
1622
  {
1623
    DecodeAdr(&ArgStr[1], MModIWRReg | MModIRReg | MModDA | (IsSuper8 ? MModImm : 0));
1624
    switch (AdrType)
1625
    {
1626
      case ModIWRReg:
1627
        BAsmCode[0] = IsSuper8 ? 0xf4 : 0xd4;
1628
        BAsmCode[1] = pCurrCPUProps->WorkOfs + AdrVal;
1629
        CodeLen = 2;
1630
        break;
1631
      case ModIRReg:
1632
        BAsmCode[0] = IsSuper8 ? 0xf4 : 0xd4;
1633
        BAsmCode[1] = AdrVal;
1634
        CodeLen = 2;
1635
        break;
1636
      case ModDA:
1637
        BAsmCode[0] = IsSuper8 ? 0xf6 : 0xd6;
1638
        BAsmCode[1] = Hi(AdrWVal);
1639
        BAsmCode[2] = Lo(AdrWVal);
1640
        CodeLen = 3;
1641
        break;
1642
      case ModImm:
1643
        if (!mFirstPassUnknownOrQuestionable(adr_val_flags)
1644
         && (AdrVal & 1))
1645
         WrStrErrorPos(ErrNum_AddrMustBeEven, &ArgStr[1]);
1646
        else
1647
        {
1648
          BAsmCode[0] = 0xd4;
1649
          BAsmCode[1] = AdrVal;
1650
          CodeLen = 2;
1651
        }
1652
        break;
1653
    }
1654
  }
1655
}
1656
 
1657
static void DecodeJP(Word Index)
1658
{
1659
  int z;
1660
 
1661
  UNUSED(Index);
1662
 
1663
  if (ChkArgCnt(1, 2)
1664
   && ChkCoreFlags(eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore))
1665
  {
1666
    z = (ArgCnt == 1) ? TrueCond : DecodeCond(&ArgStr[1]);
1667
    if (z < CondCnt)
1668
    {
1669
      DecodeAdr(&ArgStr[ArgCnt], MModIWRReg | MModIRReg | MModDA);
1670
      switch (AdrType)
1671
      {
1672
        case ModIWRReg:
1673
          if (z != TrueCond) WrError(ErrNum_InvAddrMode);
1674
          else
1675
          {
1676
            BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreZ8Encore) ? 0xc4 : 0x30;
1677
            BAsmCode[1] = pCurrCPUProps->WorkOfs + AdrVal;
1678
            CodeLen = 2;
1679
          }
1680
          break;
1681
        case ModIRReg:
1682
          if (z != TrueCond) WrError(ErrNum_InvAddrMode);
1683
          else
1684
          {
1685
            BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreZ8Encore) ? 0xc4 : 0x30;
1686
            BAsmCode[1] = AdrVal;
1687
            CodeLen = 2;
1688
          }
1689
          break;
1690
        case ModDA:
1691
          BAsmCode[0] = (Conditions[z].Code << 4) + 0x0d;
1692
          BAsmCode[1] = Hi(AdrWVal);
1693
          BAsmCode[2] = Lo(AdrWVal);
1694
          CodeLen = 3;
1695
          break;
1696
      }
1697
    }
1698
  }
1699
}
1700
 
1701
static void DecodeSRP(Word Code)
1702
{
1703
  Boolean Valid;
1704
 
1705
  if (ChkArgCnt(1, 1)
1706
   && ChkCoreFlags((Hi(Code) ? eCoreNone : (eCoreZ8NMOS | eCoreZ8CMOS | eCoreZ8Encore)) | eCoreSuper8)
1707
   && DecodeAdr(&ArgStr[1], MModImm))
1708
  {
1709
    if (pCurrCPUProps->CoreFlags & eCoreZ8Encore || Memo("RDR"))
1710
      Valid = True;
1711
    else
1712
    {
1713
      Byte MuteMask = Hi(Code) ? 7 : 15;
1714
 
1715
      Valid = (((AdrVal & MuteMask) == 0) && ((AdrVal <= pCurrCPUProps->RAMEnd) || (AdrVal >= pCurrCPUProps->SFRStart)));
1716
    }
1717
    if (!Valid) WrError(ErrNum_InvRegisterPointer);
1718
    BAsmCode[0] = (pCurrCPUProps->CoreFlags & eCoreZ8Encore) ? 0x01 : Lo(Code);
1719
    BAsmCode[1] = AdrVal | Hi(Code);
1720
    CodeLen = 2;
1721
  }
1722
}
1723
 
1724
static void DecodeStackExt(Word Index)
1725
{
1726
  if (ChkArgCnt(1, 1)
1727
   && ChkCoreFlags(eCoreZ8Encore)
1728
   && DecodeAdr(&ArgStr[1], MModXReg))
1729
  {
1730
    BAsmCode[0] = Index;
1731
    BAsmCode[1] = AdrWVal >> 4;
1732
    BAsmCode[2] = (AdrWVal & 15) << 4;
1733
    CodeLen = 3;
1734
  }
1735
}
1736
 
1737
static void DecodeStackDI(Word Code)
1738
{
1739
  int MemIdx = ((Code >> 4) & 15) - 7;
1740
 
1741
  if (ChkArgCnt(2, 2)
1742
     && ChkCoreFlags(eCoreSuper8))
1743
  {
1744
    Byte Reg;
1745
 
1746
    DecodeAdr(&ArgStr[3 - MemIdx], MModReg | MModWReg);
1747
    Reg = (AdrType == ModWReg) ? AdrVal + pCurrCPUProps->WorkOfs : AdrVal;
1748
    if (AdrType != ModNone)
1749
    {
1750
      DecodeAdr(&ArgStr[MemIdx], MModIReg | MModIWReg);
1751
      if (AdrType == ModIWReg)
1752
        AdrVal += pCurrCPUProps->WorkOfs;
1753
      if (AdrType != ModNone)
1754
      {
1755
        BAsmCode[0] = Code;
1756
        BAsmCode[1] = AdrVal;
1757
        BAsmCode[2] = Reg;
1758
        CodeLen = 3;
1759
      }
1760
    }
1761
  }
1762
}
1763
 
1764
static void DecodeTRAP(Word Index)
1765
{
1766
  UNUSED(Index);
1767
 
1768
  if (ChkArgCnt(1, 1)
1769
   && ChkCoreFlags(eCoreZ8Encore)
1770
   && DecodeAdr(&ArgStr[1], MModImm))
1771
  {
1772
    BAsmCode[0] = 0xf2;
1773
    BAsmCode[1] = AdrVal;
1774
    CodeLen = 2;
1775
  }
1776
}
1777
 
1778
static void DecodeBSWAP(Word Index)
1779
{
1780
  UNUSED(Index);
1781
 
1782
  if (ChkArgCnt(1, 1)
1783
   && ChkCoreFlags(eCoreZ8Encore)
1784
   && DecodeAdr(&ArgStr[1], MModReg))
1785
  {
1786
    BAsmCode[0] = 0xd5;
1787
    BAsmCode[1] = AdrVal;
1788
    CodeLen = 2;
1789
  }
1790
}
1791
 
1792
static void DecodeMULT(Word Index)
1793
{
1794
  UNUSED(Index);
1795
 
1796
  if (ChkArgCnt(1, 1)
1797
   && ChkCoreFlags(eCoreZ8Encore))
1798
  {
1799
    DecodeAdr(&ArgStr[1], MModWRReg | MModReg);
1800
    switch (AdrType)
1801
    {
1802
      case ModWRReg:
1803
        BAsmCode[0] = 0xf4;
1804
        BAsmCode[1] = AdrVal + pCurrCPUProps->WorkOfs;
1805
        CodeLen = 2;
1806
        break;
1807
      case ModReg:
1808
        BAsmCode[0] = 0xf4;
1809
        BAsmCode[1] = AdrVal;
1810
        CodeLen = 2;
1811
        break;
1812
    }
1813
  }
1814
}
1815
 
1816
static void DecodeMULT_DIV(Word Code)
1817
{
1818
  if (ChkArgCnt(2, 2)
1819
   && ChkCoreFlags(eCoreSuper8)
1820
   && DecodeAdr(&ArgStr[1], MModWRReg | MModRReg))
1821
  {
1822
    BAsmCode[2] = (AdrType == ModWRReg) ? AdrVal + pCurrCPUProps->WorkOfs : AdrVal;
1823
    DecodeAdr(&ArgStr[2], MModWReg | MModReg | MModIReg | MModImm);
1824
    switch (AdrType)
1825
    {
1826
      case ModWReg:
1827
        BAsmCode[0] = Code;
1828
        BAsmCode[1] = AdrVal + pCurrCPUProps->WorkOfs;
1829
        CodeLen = 3;
1830
        break;
1831
      case ModReg:
1832
        BAsmCode[0] = Code;
1833
        BAsmCode[1] = AdrVal;
1834
        CodeLen = 3;
1835
        break;
1836
      case ModIReg:
1837
        BAsmCode[0] = Code  + 1;
1838
        BAsmCode[1] = AdrVal;
1839
        CodeLen = 3;
1840
        break;
1841
      case ModImm:
1842
        BAsmCode[0] = Code  + 2;
1843
        BAsmCode[1] = AdrVal;
1844
        CodeLen = 3;
1845
        break;
1846
    }
1847
  }
1848
}
1849
 
1850
static void DecodeLDX(Word Index)
1851
{
1852
  Word Save;
1853
 
1854
  UNUSED(Index);
1855
 
1856
  if (ChkArgCnt(2, 2)
1857
   && ChkCoreFlags(eCoreZ8Encore))
1858
  {
1859
    DecodeAdr(&ArgStr[1], MModWReg | MModIWReg | MModReg | MModIReg | MModIWRReg | MModIndRR | MModXReg | MModWeird);
1860
    switch (AdrType)
1861
    {
1862
      case ModWReg:
1863
        Save = AdrVal;
1864
        DecodeAdr(&ArgStr[2], MModXReg | MModIndRR | MModImm);
1865
        switch (AdrType)
1866
        {
1867
          case ModXReg:
1868
            Save += LongWorkOfs;
1869
            BAsmCode[0] = 0xe8;
1870
            BAsmCode[1] = AdrWVal >> 4;
1871
            BAsmCode[2] = ((AdrWVal & 15) << 4) | (Hi(Save) & 15);
1872
            BAsmCode[3] = Lo(Save);
1873
            CodeLen = 4;
1874
            break;
1875
          case ModIndRR:
1876
            BAsmCode[0] = 0x88;
1877
            BAsmCode[1] = (Save << 4) | AdrVal;
1878
            BAsmCode[2] = AdrIndex;
1879
            CodeLen = 3;
1880
            break;
1881
          case ModImm:
1882
            BAsmCode[0] = 0xe9;
1883
            BAsmCode[1] = AdrVal;
1884
            BAsmCode[2] = Hi(LongWorkOfs | Save);
1885
            BAsmCode[3] = Lo(LongWorkOfs | Save);
1886
            CodeLen = 4;
1887
            break;
1888
        }
1889
        break;
1890
      case ModIWReg:
1891
        Save = AdrVal;
1892
        DecodeAdr(&ArgStr[2], MModXReg);
1893
        switch (AdrType)
1894
        {
1895
          case ModXReg:
1896
            BAsmCode[0] = 0x85;
1897
            BAsmCode[1] = (Save << 4) | (Hi(AdrWVal) & 15);
1898
            BAsmCode[2] = Lo(AdrWVal);
1899
            CodeLen = 3;
1900
            break;
1901
        }
1902
        break;
1903
      case ModReg:
1904
        Save = AdrVal;
1905
        DecodeAdr(&ArgStr[2], MModIReg);
1906
        switch (AdrType)
1907
        {
1908
          case ModIReg:
1909
            BAsmCode[0] = 0x86;
1910
            BAsmCode[1] = AdrVal;
1911
            BAsmCode[2] = Save;
1912
            CodeLen = 3;
1913
            break;
1914
        }
1915
        break;
1916
      case ModIReg:
1917
        Save = AdrVal;
1918
        DecodeAdr(&ArgStr[2], MModReg | MModWeird);
1919
        switch (AdrType)
1920
        {
1921
          case ModReg:
1922
            BAsmCode[0] = 0x96;
1923
            BAsmCode[1] = AdrVal;
1924
            BAsmCode[2] = Save;
1925
            CodeLen = 3;
1926
            break;
1927
          case ModWeird:
1928
            BAsmCode[0] = 0x87;
1929
            BAsmCode[1] = AdrVal;
1930
            BAsmCode[2] = Save;
1931
            CodeLen = 3;
1932
            break;
1933
        }
1934
        break;
1935
      case ModIWRReg:
1936
        Save = pCurrCPUProps->WorkOfs + AdrVal;
1937
        DecodeAdr(&ArgStr[2], MModReg);
1938
        switch (AdrType)
1939
        {
1940
          case ModReg:
1941
            BAsmCode[0] = 0x96;
1942
            BAsmCode[1] = AdrVal;
1943
            BAsmCode[2] = Save;
1944
            CodeLen = 3;
1945
            break;
1946
        }
1947
        break;
1948
      case ModIndRR:
1949
        BAsmCode[2] = AdrIndex;
1950
        Save = AdrVal;
1951
        DecodeAdr(&ArgStr[2], MModWReg);
1952
        switch (AdrType)
1953
        {
1954
          case ModWReg:
1955
            BAsmCode[0] = 0x89;
1956
            BAsmCode[1] = (Save << 4) | AdrVal;
1957
            CodeLen = 3;
1958
            break;
1959
        }
1960
        break;
1961
      case ModXReg:
1962
        Save = AdrWVal;
1963
        DecodeAdr(&ArgStr[2], MModWReg | MModIWReg | MModXReg | MModImm);
1964
        switch (AdrType)
1965
        {
1966
          case ModWReg:
1967
            BAsmCode[0] = 0x94;
1968
            BAsmCode[1] = (AdrVal << 4) | (Hi(Save) & 15);
1969
            BAsmCode[2] = Lo(Save);
1970
            CodeLen = 3;
1971
            break;
1972
          case ModIWReg:
1973
            BAsmCode[0] = 0x95;
1974
            BAsmCode[1] = (AdrVal << 4) | (Hi(Save) & 15);
1975
            BAsmCode[2] = Lo(Save);
1976
            CodeLen = 3;
1977
            break;
1978
          case ModXReg:
1979
            BAsmCode[0] = 0xe8;
1980
            BAsmCode[1] = AdrWVal >> 4;
1981
            BAsmCode[2] = ((AdrWVal & 15) << 4) | (Hi(Save) & 15);
1982
            BAsmCode[3] = Lo(Save);
1983
            CodeLen = 4;
1984
            break;
1985
          case ModImm:
1986
            BAsmCode[0] = 0xe9;
1987
            BAsmCode[1] = AdrVal;
1988
            BAsmCode[2] = (Hi(Save) & 15);
1989
            BAsmCode[3] = Lo(Save);
1990
            CodeLen = 4;
1991
            break;
1992
        }
1993
        break;
1994
      case ModWeird:
1995
        Save = AdrVal;
1996
        DecodeAdr(&ArgStr[2], MModIReg);
1997
        switch (AdrType)
1998
        {
1999
          case ModIReg:
2000
            BAsmCode[0] = 0x97;
2001
            BAsmCode[1] = AdrVal;
2002
            BAsmCode[2] = Save;
2003
            CodeLen = 3;
2004
            break;
2005
        }
2006
        break;
2007
    }
2008
  }
2009
}
2010
 
2011
static void DecodeLDW(Word Code)
2012
{
2013
  if (ChkArgCnt(2, 2)
2014
   && ChkCoreFlags(eCoreSuper8))
2015
  {
2016
    DecodeAdr(&ArgStr[1], MModRReg | MModWRReg);
2017
    if (AdrType != ModNone)
2018
    {
2019
      Byte Dest = (AdrType == ModRReg) ? AdrVal : AdrVal + pCurrCPUProps->WorkOfs;
2020
 
2021
      OpSize = eSymbolSize16Bit;
2022
      DecodeAdr(&ArgStr[2], MModRReg | MModWRReg | MModIReg | MModImm);
2023
      switch (AdrType)
2024
      {
2025
        case ModWRReg:
2026
        case ModRReg:
2027
          BAsmCode[0] = Code;
2028
          BAsmCode[1] = (AdrType == ModRReg) ? AdrVal : AdrVal + pCurrCPUProps->WorkOfs;
2029
          BAsmCode[2] = Dest;
2030
          CodeLen = 3;
2031
          break;
2032
        case ModIReg:
2033
          BAsmCode[0] = Code + 1;
2034
          BAsmCode[1] = AdrVal;
2035
          BAsmCode[2] = Dest;
2036
          CodeLen = 3;
2037
          break;
2038
        case ModImm:
2039
          BAsmCode[0] = Code + 2;
2040
          BAsmCode[1] = Dest;
2041
          BAsmCode[2] = Hi(AdrWVal);
2042
          BAsmCode[3] = Lo(AdrWVal);
2043
          CodeLen = 4;
2044
          break;
2045
      }
2046
    }
2047
  }
2048
}
2049
 
2050
static void DecodeLDWX(Word Index)
2051
{
2052
  UNUSED(Index);
2053
 
2054
  if (ChkArgCnt(2, 2)
2055
   && ChkCoreFlags(eCoreZ8Encore)
2056
   && DecodeAdr(&ArgStr[1], MModXReg))
2057
  {
2058
    BAsmCode[0] = 0x1f;
2059
    BAsmCode[1] = 0xe8;
2060
    BAsmCode[3] = Hi(AdrWVal);
2061
    BAsmCode[4] = Lo(AdrWVal);
2062
    if (DecodeAdr(&ArgStr[2], MModXReg))
2063
    {
2064
      BAsmCode[2] = AdrWVal >> 4;
2065
      BAsmCode[3] |= (AdrWVal & 0x0f) << 4;
2066
      CodeLen = 5;
2067
    }
2068
  }
2069
}
2070
 
2071
static void DecodeLEA(Word Index)
2072
{
2073
  Byte Save;
2074
 
2075
  UNUSED(Index);
2076
 
2077
  if (ChkArgCnt(2, 2)
2078
   && ChkCoreFlags(eCoreZ8Encore))
2079
  {
2080
    DecodeAdr(&ArgStr[1], MModWReg | MModWRReg);
2081
    switch (AdrType)
2082
    {
2083
      case ModWReg:
2084
        Save = AdrVal;
2085
        if (DecodeAdr(&ArgStr[2], MModInd))
2086
        {
2087
          BAsmCode[0] = 0x98;
2088
          BAsmCode[1] = (Save << 4) | AdrVal;
2089
          BAsmCode[2] = AdrIndex;
2090
          CodeLen = 3;
2091
        }
2092
        break;
2093
      case ModWRReg:
2094
        Save = AdrVal;
2095
        if (DecodeAdr(&ArgStr[2], MModIndRR))
2096
        {
2097
          BAsmCode[0] = 0x99;
2098
          BAsmCode[1] = (Save << 4) | AdrVal;
2099
          BAsmCode[2] = AdrIndex;
2100
          CodeLen = 3;
2101
        }
2102
        break;
2103
    }
2104
  }
2105
}
2106
 
2107
static void DecodeBIT(Word Index)
2108
{
2109
  Boolean OK;
2110
 
2111
  UNUSED(Index);
2112
 
2113
  if (ChkArgCnt(3, 3)
2114
   && ChkCoreFlags(eCoreZ8Encore))
2115
  {
2116
    BAsmCode[1] = EvalStrIntExpression(&ArgStr[1], UInt1, &OK) << 7;
2117
    if (OK)
2118
    {
2119
      BAsmCode[1] |= EvalStrIntExpression(&ArgStr[2], UInt3, &OK) << 4;
2120
      if (OK)
2121
      {
2122
        DecodeAdr(&ArgStr[3], MModWReg);
2123
        switch (AdrType)
2124
        {
2125
          case ModWReg:
2126
            BAsmCode[0] = 0xe2;
2127
            BAsmCode[1] |= AdrVal;
2128
            CodeLen = 2;
2129
            break;
2130
        }
2131
      }
2132
    }
2133
  }
2134
}
2135
 
2136
static void DecodeBit(Word Index)
2137
{
2138
  Boolean OK;
2139
 
2140
  if (ChkCoreFlags(eCoreZ8Encore))
2141
    switch (ArgCnt)
2142
    {
2143
      case 1:
2144
      {
2145
        LongWord BitArg;
2146
        ShortInt OpSize = eSymbolSize8Bit;
2147
 
2148
        if (DecodeBitArg(&BitArg, 1, 1, OpSize))
2149
        {
2150
          Word Address;
2151
          Byte BitPos;
2152
 
2153
          (void)DissectBitSymbol(BitArg, &Address, &BitPos, &OpSize);
2154
          if ((Address & 0xff0) == pCurrCPUProps->WorkOfs)
2155
          {
2156
            BAsmCode[0] = 0xe2;
2157
            BAsmCode[1] = Index | (BitPos << 4) | (Address & 15);
2158
            CodeLen = 2;
2159
          }
2160
          else /* -> ANDX,ORX ER,IM */
2161
          {
2162
            BAsmCode[0] = Index ? 0x49 : 0x59;
2163
            BAsmCode[1] = Index ? (1 << BitPos) : ~(1 << BitPos);
2164
            BAsmCode[2] = Hi(Address);
2165
            BAsmCode[3] = Lo(Address);
2166
            CodeLen = 4;
2167
          }
2168
        }
2169
        break;
2170
      }
2171
      case 2:
2172
        BAsmCode[1] = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
2173
        if (OK)
2174
        {
2175
          DecodeAdr(&ArgStr[2], MModWReg | MModXReg);
2176
          switch (AdrType)
2177
          {
2178
            case ModWReg:
2179
              BAsmCode[0] = 0xe2;
2180
              BAsmCode[1] = (BAsmCode[1] << 4) | Index | AdrVal;
2181
              CodeLen = 2;
2182
              break;
2183
            case ModXReg: /* -> ANDX,ORX ER,IM */
2184
              BAsmCode[0] = Index ? 0x49 : 0x59;
2185
              BAsmCode[1] = Index ? (1 << BAsmCode[1]) : ~(1 << BAsmCode[1]);
2186
              BAsmCode[2] = Hi(AdrWVal);
2187
              BAsmCode[3] = Lo(AdrWVal);
2188
              CodeLen = 4;
2189
              break;
2190
          }
2191
        }
2192
        break;
2193
      default:
2194
        (void)ChkArgCnt(1, 2);
2195
    }
2196
}
2197
 
2198
static void DecodeBTJCore(Word Index, int ArgOffset)
2199
{
2200
  int TmpCodeLen = 0;
2201
 
2202
  switch (ArgCnt - ArgOffset)
2203
  {
2204
    case 2:
2205
    {
2206
      LongWord BitArg;
2207
      ShortInt OpSize = eSymbolSize8Bit;
2208
 
2209
      if (DecodeBitArg(&BitArg, 1 + ArgOffset, 1 + ArgOffset, OpSize))
2210
      {
2211
        Word Address;
2212
        Byte BitPos;
2213
 
2214
        (void)DissectBitSymbol(BitArg, &Address, &BitPos, &OpSize);
2215
        if ((Address & 0xff0) == pCurrCPUProps->WorkOfs)
2216
        {
2217
          BAsmCode[0] = 0xf6;
2218
          BAsmCode[1] = (Address & 15) | (BitPos << 4);
2219
          TmpCodeLen = 2;
2220
        }
2221
        else
2222
          WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
2223
      }
2224
      break;
2225
    }
2226
    case 3:
2227
    {
2228
      Boolean OK;
2229
 
2230
      BAsmCode[1] = EvalStrIntExpression(&ArgStr[1 + ArgOffset], UInt3, &OK) << 4;
2231
      if (OK)
2232
      {
2233
        DecodeAdr(&ArgStr[2 + ArgOffset], MModWReg | MModIWReg);
2234
        switch (AdrType)
2235
        {
2236
          case ModWReg:
2237
            BAsmCode[0] = 0xf6;
2238
            BAsmCode[1] |= AdrVal;
2239
            TmpCodeLen = 2;
2240
            break;
2241
          case ModIWReg:
2242
            BAsmCode[0] = 0xf7;
2243
            BAsmCode[1] |= AdrVal;
2244
            TmpCodeLen = 2;
2245
            break;
2246
        }
2247
      }
2248
      break;
2249
    }
2250
    default:
2251
      (void)ChkArgCnt(3, 4);
2252
  }
2253
  if (TmpCodeLen > 0)
2254
  {
2255
    tEvalResult EvalResult;
2256
    Integer AdrInt = EvalStrIntExpressionWithResult(&ArgStr[ArgCnt], Int16, &EvalResult) - (EProgCounter() + TmpCodeLen + 1);
2257
 
2258
    BAsmCode[1] |= Index;
2259
    if (EvalResult.OK)
2260
    {
2261
      if (!mSymbolQuestionable(EvalResult.Flags)
2262
       && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
2263
      else
2264
      {
2265
        ChkSpace(SegCode, EvalResult.AddrSpaceMask);
2266
        BAsmCode[TmpCodeLen] = Lo(AdrInt);
2267
        CodeLen = TmpCodeLen + 1;
2268
      }
2269
    }
2270
  }
2271
}
2272
 
2273
static void DecodeBTJ(Word Index)
2274
{
2275
  if (ChkCoreFlags(eCoreZ8Encore)
2276
   && ChkArgCnt(3, 4))
2277
  {
2278
    Boolean OK;
2279
 
2280
    Index = EvalStrIntExpression(&ArgStr[1], UInt1, &OK) << 7;
2281
    if (OK)
2282
      DecodeBTJCore(Index, 1);
2283
  }
2284
}
2285
 
2286
static void DecodeBtj(Word Index)
2287
{
2288
  UNUSED(Index);
2289
 
2290
  if (ChkArgCnt(2, 3)
2291
   && ChkCoreFlags(eCoreZ8Encore))
2292
    DecodeBTJCore(Index, 0);
2293
}
2294
 
2295
static void DecodeBit1(Word Code)
2296
{
2297
  if (ChkArgCnt(1, 2)
2298
   && ChkCoreFlags(eCoreSuper8)
2299
   && DecodeWRBitArg(1, ArgCnt, &BAsmCode[1]))
2300
  {
2301
    BAsmCode[1] = (BAsmCode[1] << 1) | Hi(Code);
2302
    BAsmCode[0] = Lo(Code);
2303
    CodeLen = 2;
2304
  }
2305
}
2306
 
2307
static void DecodeBit2(Word Code)
2308
{
2309
  if (ChkCoreFlags(eCoreSuper8))
2310
  {
2311
    LongWord BitValue;
2312
    Byte Reg;
2313
 
2314
    switch (ArgCnt)
2315
    {
2316
      case 3:
2317
      {
2318
        int BitStart, BitEnd, RegIdx;
2319
 
2320
        if ((*ArgStr[2].str.p_str == '#') && Hi(Code))
2321
        {
2322
          BitStart = 1;
2323
          BitEnd = 2;
2324
          RegIdx = 3;
2325
          BAsmCode[1] = 0x01;
2326
        }
2327
        else
2328
        {
2329
          BitStart = 2;
2330
          BitEnd = 3;
2331
          RegIdx = 1;
2332
          BAsmCode[1] = 0x00;
2333
        }
2334
        DecodeAdr(&ArgStr[RegIdx], MModWReg); Reg = AdrVal;
2335
        if ((AdrType == ModWReg) && DecodeBitArg2(&BitValue, &ArgStr[BitStart], &ArgStr[BitEnd], eSymbolSize8Bit));
2336
        else
2337
          return;
2338
        break;
2339
      }
2340
      case 2:
2341
      {
2342
        if ((IsWReg(&ArgStr[1], &Reg, False) == eIsReg)
2343
         && DecodeBitArg(&BitValue, 2, 2, eSymbolSize8Bit))
2344
        {
2345
          BAsmCode[1] = 0x00;
2346
        }
2347
        else if ((IsWReg(&ArgStr[2], &Reg, False) == eIsReg)
2348
              && DecodeBitArg(&BitValue, 1, 1, eSymbolSize8Bit)
2349
              && Hi(Code))
2350
        {
2351
          BAsmCode[1] = 0x01;
2352
        }
2353
        else
2354
        {
2355
          WrError(ErrNum_InvAddrMode);
2356
          return;
2357
        }
2358
        break;
2359
      }
2360
      default:
2361
        (void)ChkArgCnt(2, 3);
2362
        return;
2363
    }
2364
    CodeLen = 3;
2365
    BAsmCode[0] = Lo(Code);
2366
    BAsmCode[1] |= (Reg << 4) | ((BitValue & 7) << 1);
2367
    BAsmCode[2] = BitValue >> 3;
2368
    CodeLen = 3;
2369
  }
2370
}
2371
 
2372
static void DecodeBitRel(Word Code)
2373
{
2374
  if (ChkArgCnt(2, 3)
2375
   && ChkCoreFlags(eCoreSuper8)
2376
   && DecodeWRBitArg(2, ArgCnt, &BAsmCode[1]))
2377
  {
2378
    tEvalResult EvalResult;
2379
    Integer AdrInt = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult) - (EProgCounter() + 3);
2380
    if (EvalResult.OK)
2381
    {
2382
      if (!mSymbolQuestionable(EvalResult.Flags)
2383
       && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
2384
      else
2385
      {
2386
        ChkSpace(SegCode, EvalResult.AddrSpaceMask);
2387
        BAsmCode[0] = Lo(Code);
2388
        BAsmCode[1] = (BAsmCode[1] << 1) | Hi(Code);
2389
        BAsmCode[2] = Lo(AdrInt);
2390
        CodeLen = 3;
2391
      }
2392
    }
2393
  }
2394
}
2395
 
2396
static void DecodeSFR(Word Code)
2397
{
2398
  UNUSED(Code);
2399
 
2400
  CodeEquate(SegData, 0, mIsZ8Encore() ? 0xfff : 0xff);
2401
}
2402
 
2403
static void DecodeDEFBIT(Word Code)
2404
{
2405
  LongWord BitSpec;
2406
 
2407
  UNUSED(Code);
2408
 
2409
  /* if in structure definition, add special element to structure */
2410
 
2411
  if (ActPC == StructSeg)
2412
  {
2413
    Boolean OK;
2414
    Byte BitPos;
2415
    PStructElem pElement;
2416
 
2417
    if (!ChkArgCnt(2, 2))
2418
      return;
2419
    BitPos = EvalBitPosition(&ArgStr[2], &OK, eSymbolSize8Bit);
2420
    if (!OK)
2421
      return;
2422
    pElement = CreateStructElem(&LabPart);
2423
    if (!pElement)
2424
      return;
2425
    pElement->pRefElemName = as_strdup(ArgStr[1].str.p_str);
2426
    pElement->OpSize = eSymbolSize8Bit;
2427
    pElement->BitPos = BitPos;
2428
    pElement->ExpandFnc = ExpandZ8Bit;
2429
    AddStructElem(pInnermostNamedStruct->StructRec, pElement);
2430
  }
2431
  else
2432
  {
2433
    if (DecodeBitArg(&BitSpec, 1, ArgCnt, eSymbolSize8Bit))
2434
    {
2435
      *ListLine = '=';
2436
      DissectBit_Z8(ListLine + 1, STRINGSIZE - 3, BitSpec);
2437
      PushLocHandle(-1);
2438
      EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
2439
      PopLocHandle();
2440
      /* TODO: MakeUseList? */
2441
    }
2442
  }
2443
}
2444
 
2445
/*--------------------------------------------------------------------------*/
2446
/* Instruction Table Buildup/Teardown */
2447
 
2448
static void AddFixed(const char *NName, Word Code, tCoreFlags CoreFlags)
2449
{
2450
  order_array_rsv_end(FixedOrders, BaseOrder);
2451
  FixedOrders[InstrZ].Code = Code;
2452
  FixedOrders[InstrZ].CoreFlags = CoreFlags;
2453
  AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
2454
}
2455
 
2456
static void AddALU2(const char *NName, Word Code, tCoreFlags CoreFlags)
2457
{
2458
  order_array_rsv_end(ALU2Orders, BaseOrder);
2459
  ALU2Orders[InstrZ].Code = Code;
2460
  ALU2Orders[InstrZ].CoreFlags = CoreFlags;
2461
  AddInstTable(InstTable, NName, InstrZ++, DecodeALU2);
2462
}
2463
 
2464
static void AddALUX(const char *NName, Word Code, tCoreFlags CoreFlags)
2465
{
2466
  order_array_rsv_end(ALUXOrders, BaseOrder);
2467
  ALUXOrders[InstrZ].Code = Code;
2468
  ALUXOrders[InstrZ].CoreFlags = CoreFlags;
2469
  AddInstTable(InstTable, NName, InstrZ++, DecodeALUX);
2470
}
2471
 
2472
static void AddALU1(const char *NName, Word Code, tCoreFlags CoreFlags, Boolean Is16)
2473
{
2474
  order_array_rsv_end(ALU1Orders, ALU1Order);
2475
  ALU1Orders[InstrZ].Code = Code;
2476
  ALU1Orders[InstrZ].CoreFlags = CoreFlags;
2477
  ALU1Orders[InstrZ].Is16 = Is16;
2478
  AddInstTable(InstTable, NName, InstrZ++, DecodeALU1);
2479
}
2480
 
2481
static void AddCondition(const char *NName, Byte NCode)
2482
{
2483
  order_array_rsv_end(Conditions, Condition);
2484
  Conditions[InstrZ].Name = NName;
2485
  Conditions[InstrZ++].Code = NCode;
2486
}
2487
 
2488
static void InitFields(void)
2489
{
2490
  InstTable = CreateInstTable(201);
2491
 
2492
  add_null_pseudo(InstTable);
2493
 
2494
  InstrZ = 0;
2495
  AddFixed("CCF"  , 0xef   , eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2496
  AddFixed("DI"   , 0x8f   , eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2497
  AddFixed("EI"   , 0x9f   , eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2498
  AddFixed("HALT" , 0x7f   ,               eCoreZ8CMOS               | eCoreZ8Encore);
2499
  AddFixed("IRET" , 0xbf   , eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2500
  AddFixed("NOP"  , NOPCode, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2501
  AddFixed("RCF"  , 0xcf   , eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2502
  AddFixed("RET"  , 0xaf   , eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2503
  AddFixed("SCF"  , 0xdf   , eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2504
  AddFixed("STOP" , 0x6f   ,               eCoreZ8CMOS               | eCoreZ8Encore);
2505
  AddFixed("ATM"  , 0x2f   , eCoreZ8NMOS | eCoreZ8CMOS               | eCoreZ8Encore);
2506
  AddFixed("BRK"  , 0x00   ,                                           eCoreZ8Encore);
2507
  AddFixed("WDH"  , 0x4f   , eCoreZ8NMOS | eCoreZ8CMOS                              );
2508
  AddFixed("WDT"  , 0x5f   , eCoreZ8NMOS | eCoreZ8CMOS               | eCoreZ8Encore);
2509
  AddFixed("ENTER", 0x1f   ,                             eCoreSuper8                );
2510
  AddFixed("EXIT" , 0x2f   ,                             eCoreSuper8                );
2511
  AddFixed("NEXT" , 0x0f   ,                             eCoreSuper8                );
2512
  AddFixed("SB0"  , 0x4f   ,                             eCoreSuper8                );
2513
  AddFixed("SB1"  , 0x5f   ,                             eCoreSuper8                );
2514
  AddFixed("WFI"  , 0x3f   ,                             eCoreSuper8                );
2515
 
2516
  InstrZ = 0;
2517
  AddALU2("ADD" , 0x0000, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2518
  AddALU2("ADC" , 0x0010, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2519
  AddALU2("SUB" , 0x0020, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2520
  AddALU2("SBC" , 0x0030, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2521
  AddALU2("OR"  , 0x0040, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2522
  AddALU2("AND" , 0x0050, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2523
  AddALU2("TCM" , 0x0060, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2524
  AddALU2("TM"  , 0x0070, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2525
  AddALU2("CP"  , 0x00a0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2526
  AddALU2("XOR" , 0x00b0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore);
2527
  AddALU2("CPC" , (EXTPREFIX << 8) | 0xa0, eCoreZ8Encore);
2528
 
2529
  InstrZ = 0;
2530
  AddALUX("ADDX", 0x0008, eCoreZ8Encore);
2531
  AddALUX("ADCX", 0x0018, eCoreZ8Encore);
2532
  AddALUX("SUBX", 0x0028, eCoreZ8Encore);
2533
  AddALUX("SBCX", 0x0038, eCoreZ8Encore);
2534
  AddALUX("ORX" , 0x0048, eCoreZ8Encore);
2535
  AddALUX("ANDX", 0x0058, eCoreZ8Encore);
2536
  AddALUX("TCMX", 0x0068, eCoreZ8Encore);
2537
  AddALUX("TMX" , 0x0078, eCoreZ8Encore);
2538
  AddALUX("CPX" , 0x00a8, eCoreZ8Encore);
2539
  AddALUX("XORX", 0x00b8, eCoreZ8Encore);
2540
  AddALUX("CPCX", (EXTPREFIX << 8) | 0xa8, eCoreZ8Encore);
2541
 
2542
  InstrZ = 0;
2543
  AddALU1("DEC" , (pCurrCPUProps->CoreFlags & eCoreZ8Encore) ? 0x0030 : 0x0000, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
2544
  AddALU1("RLC" , 0x0010, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
2545
  AddALU1("DA"  , 0x0040, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
2546
  AddALU1("POP" , 0x0050, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
2547
  AddALU1("COM" , 0x0060, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
2548
  AddALU1("PUSH", 0x0070, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
2549
  AddALU1("DECW", 0x0080, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, True );
2550
  AddALU1("RL"  , 0x0090, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
2551
  AddALU1("INCW", 0x00a0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, True );
2552
  AddALU1("CLR" , 0x00b0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
2553
  AddALU1("RRC" , 0x00c0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
2554
  AddALU1("SRA" , 0x00d0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
2555
  AddALU1("RR"  , 0x00e0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
2556
  AddALU1("SWAP", 0x00f0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreSuper8 | eCoreZ8Encore, False);
2557
  AddALU1("SRL" , (EXTPREFIX << 8) | 0xc0, eCoreZ8NMOS | eCoreZ8CMOS | eCoreZ8Encore, False);
2558
 
2559
  InstrZ = 0;
2560
  AddCondition("F"  , 0); TrueCond = InstrZ; AddCondition("T"  , 8);
2561
  AddCondition("C"  , 7); AddCondition("NC" ,15);
2562
  AddCondition("Z"  , 6); AddCondition("NZ" ,14);
2563
  AddCondition("MI" , 5); AddCondition("PL" ,13);
2564
  AddCondition("OV" , 4); AddCondition("NOV",12);
2565
  AddCondition("EQ" , 6); AddCondition("NE" ,14);
2566
  AddCondition("LT" , 1); AddCondition("GE" , 9);
2567
  AddCondition("LE" , 2); AddCondition("GT" ,10);
2568
  AddCondition("ULT", 7); AddCondition("UGE",15);
2569
  AddCondition("ULE", 3); AddCondition("UGT",11);
2570
  CondCnt = InstrZ;
2571
 
2572
  AddInstTable(InstTable, "LD", 0, DecodeLD);
2573
  AddInstTable(InstTable, "LDX", 0, DecodeLDX);
2574
  AddInstTable(InstTable, "LDW", 0xc4, DecodeLDW);
2575
  AddInstTable(InstTable, "LDWX", 0, DecodeLDWX);
2576
  AddInstTable(InstTable, "LDC", 0xc2, DecodeLDCE);
2577
  AddInstTable(InstTable, "LDE", 0x82, DecodeLDCE);
2578
  if (mIsSuper8())
2579
  {
2580
    AddInstTable(InstTable, "LDCI", 0x00e3, DecodeLDCEDI);
2581
    AddInstTable(InstTable, "LDEI", 0x01e3, DecodeLDCEDI);
2582
  }
2583
  else
2584
  {
2585
    AddInstTable(InstTable, "LDCI", 0xc3, DecodeLDCEI);
2586
    AddInstTable(InstTable, "LDEI", 0x83, DecodeLDCEI);
2587
  }
2588
  AddInstTable(InstTable, "LDCD", 0x00e2, DecodeLDCEDI);
2589
  AddInstTable(InstTable, "LDED", 0x01e2, DecodeLDCEDI);
2590
  AddInstTable(InstTable, "LDCPD", 0x00f2, DecodeLDCEPDI);
2591
  AddInstTable(InstTable, "LDEPD", 0x01f2, DecodeLDCEPDI);
2592
  AddInstTable(InstTable, "LDCPI", 0x00f3, DecodeLDCEPDI);
2593
  AddInstTable(InstTable, "LDEPI", 0x01f3, DecodeLDCEPDI);
2594
  AddInstTable(InstTable, "INC", 0, DecodeINC);
2595
  AddInstTable(InstTable, "JR", 0, DecodeJR);
2596
  AddInstTable(InstTable, "JP", 0, DecodeJP);
2597
  AddInstTable(InstTable, "CALL", 0, DecodeCALL);
2598
  AddInstTable(InstTable, "SRP", 0x0031, DecodeSRP);
2599
  AddInstTable(InstTable, "SRP0", 0x0231, DecodeSRP);
2600
  AddInstTable(InstTable, "SRP1", 0x0131, DecodeSRP);
2601
  AddInstTable(InstTable, "RDR", 0x01d5, DecodeSRP);
2602
  AddInstTable(InstTable, "DJNZ", 0, DecodeDJNZ);
2603
  AddInstTable(InstTable, "LEA", 0, DecodeLEA);
2604
 
2605
  AddInstTable(InstTable, "POPX" , 0xd8, DecodeStackExt);
2606
  AddInstTable(InstTable, "PUSHX", 0xc8, DecodeStackExt);
2607
  AddInstTable(InstTable, "POPUD", 0x92, DecodeStackDI);
2608
  AddInstTable(InstTable, "POPUI", 0x93, DecodeStackDI);
2609
  AddInstTable(InstTable, "PUSHUD", 0x82, DecodeStackDI);
2610
  AddInstTable(InstTable, "PUSHUI", 0x83, DecodeStackDI);
2611
  AddInstTable(InstTable, "TRAP" , 0, DecodeTRAP);
2612
  AddInstTable(InstTable, "BSWAP", 0, DecodeBSWAP);
2613
  if (mIsSuper8())
2614
    AddInstTable(InstTable, "MULT" , 0x84, DecodeMULT_DIV);
2615
  else
2616
    AddInstTable(InstTable, "MULT" , 0, DecodeMULT);
2617
  AddInstTable(InstTable, "DIV" , 0x94, DecodeMULT_DIV);
2618
  AddInstTable(InstTable, "BIT", 0, DecodeBIT);
2619
  AddInstTable(InstTable, "BCLR", 0x00, DecodeBit);
2620
  AddInstTable(InstTable, "BSET", 0x80, DecodeBit);
2621
  AddInstTable(InstTable, "BTJ", 0, DecodeBTJ);
2622
  AddInstTable(InstTable, "BTJZ", 0x00, DecodeBtj);
2623
  AddInstTable(InstTable, "BTJNZ", 0x80, DecodeBtj);
2624
  AddInstTable(InstTable, "CPIJNE", 0xd2, DecodeCPIJNE);
2625
  AddInstTable(InstTable, "CPIJE", 0xc2, DecodeCPIJNE);
2626
  AddInstTable(InstTable, "BITC", 0x0057, DecodeBit1);
2627
  AddInstTable(InstTable, "BITR", 0x0077, DecodeBit1);
2628
  AddInstTable(InstTable, "BITS", 0x0177, DecodeBit1);
2629
  AddInstTable(InstTable, "BAND", 0x0167, DecodeBit2);
2630
  AddInstTable(InstTable, "BOR",  0x0107, DecodeBit2);
2631
  AddInstTable(InstTable, "BXOR", 0x0127, DecodeBit2);
2632
  AddInstTable(InstTable, "LDB",  0x0147, DecodeBit2);
2633
  AddInstTable(InstTable, "BCP",  0x0017, DecodeBit2);
2634
  AddInstTable(InstTable, "BTJRF",0x0037, DecodeBitRel);
2635
  AddInstTable(InstTable, "BTJRT",0x0137, DecodeBitRel);
2636
 
2637
  AddInstTable(InstTable, "SFR", 0, DecodeSFR);
2638
  AddInstTable(InstTable, "REG", 0, CodeREG);
2639
  AddInstTable(InstTable, "DEFBIT", 0, DecodeDEFBIT);
2640
  AddIntelPseudo(InstTable, eIntPseudoFlag_BigEndian);
2641
}
2642
 
2643
static void DeinitFields(void)
2644
{
2645
  order_array_free(FixedOrders);
2646
  order_array_free(ALU2Orders);
2647
  order_array_free(ALU1Orders);
2648
  order_array_free(ALUXOrders);
2649
  order_array_free(Conditions);
2650
 
2651
  DestroyInstTable(InstTable);
2652
}
2653
 
2654
/*---------------------------------------------------------------------*/
2655
 
2656
/*!------------------------------------------------------------------------
2657
 * \fn     InternSymbol_Z8(char *pArg, TempResult *pResult)
2658
 * \brief  handle built-in symbols on Z8
2659
 * \param  pArg source code argument
2660
 * \param  pResult result buffer
2661
 * ------------------------------------------------------------------------ */
2662
 
2663
static void InternSymbol_Z8(char *pArg, TempResult *pResult)
2664
{
2665
  Byte RegNum;
2666
 
2667
  if (IsWRegCore(pArg, &RegNum))
2668
  {
2669
    pResult->Typ = TempReg;
2670
    pResult->DataSize = eSymbolSize8Bit;
2671
    pResult->Contents.RegDescr.Reg = RegNum;
2672
    pResult->Contents.RegDescr.Dissect = DissectReg_Z8;
2673
    pResult->Contents.RegDescr.compare = NULL;
2674
  }
2675
  else if (IsWRRegCore(pArg, &RegNum))
2676
  {
2677
    pResult->Typ = TempReg;
2678
    pResult->DataSize = eSymbolSize16Bit;
2679
    pResult->Contents.RegDescr.Reg = RegNum;
2680
    pResult->Contents.RegDescr.Dissect = DissectReg_Z8;
2681
    pResult->Contents.RegDescr.compare = NULL;
2682
  }
2683
}
2684
 
2685
static void MakeCode_Z8(void)
2686
{
2687
  OpSize = eSymbolSize8Bit;
2688
 
2689
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
2690
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2691
}
2692
 
2693
static void InitCode_Z8(void)
2694
{
2695
  RPVal = 0;
2696
}
2697
 
2698
static Boolean IsDef_Z8(void)
2699
{
2700
  return (Memo("SFR") || Memo("REG") || Memo("DEFBIT"));
2701
}
2702
 
2703
static void SwitchFrom_Z8(void)
2704
{
2705
  DeinitFields();
2706
}
2707
 
2708
static void AdaptRP01(void)
2709
{
2710
  /* SRP on Super8 sets RP0 & RP1.  Act similar for ASSUME on Super8: */
2711
 
2712
  if (RPVal >= 0x100)
2713
    RP0Val = RP1Val = RPVal;
2714
  else
2715
  {
2716
    RP0Val = RPVal;
2717
    RP1Val = RPVal + 8;
2718
  }
2719
}
2720
 
2721
#define ASSUMEeZ8Count 1
2722
#define ASSUMESuper8Count 3
2723
static ASSUMERec ASSUMEeZ8s[] =
2724
{
2725
  {"RP"  , &RPVal  , 0, 0xff, 0x100, AdaptRP01},
2726
  {"RP0" , &RP0Val , 0, 0xff, 0x100, NULL},
2727
  {"RP1" , &RP1Val , 0, 0xff, 0x100, NULL}
2728
};
2729
 
2730
/*!------------------------------------------------------------------------
2731
 * \fn     SwitchTo_Z8(void *pUser)
2732
 * \brief  prepare to assemble code for this target
2733
 * \param  pUser CPU properties
2734
 * ------------------------------------------------------------------------ */
2735
 
2736
static void SwitchTo_Z8(void *pUser)
2737
{
2738
  const TFamilyDescr *pDescr;
2739
 
2740
  TurnWords = False;
2741
  SetIntConstMode(eIntConstModeIntel);
2742
 
2743
  pCurrCPUProps = (const tCPUProps*)pUser;
2744
 
2745
  if (mIsSuper8())
2746
    pDescr = FindFamilyByName("Super8");
2747
  else if (mIsZ8Encore())
2748
    pDescr = FindFamilyByName("eZ8");
2749
  else
2750
    pDescr = FindFamilyByName("Z8");
2751
 
2752
  PCSymbol = "$"; HeaderID = pDescr->Id;
2753
  NOPCode = mIsZ8Encore() ? 0x0f : 0xff;
2754
  DivideChars = ","; HasAttrs = False;
2755
 
2756
  ValidSegs = (1 << SegCode) | (1 << SegData);
2757
  Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
2758
  SegLimits[SegCode] = 0xffff;
2759
  Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 0;
2760
  if (pCurrCPUProps->CoreFlags & eCoreZ8Encore)
2761
  {
2762
    RegSpaceType = UInt12;
2763
    SegLimits[SegData] = 0xfff;
2764
    ValidSegs |= 1 << SegXData;
2765
    Grans[SegXData] = 1; ListGrans[SegXData] = 1; SegInits[SegXData] = 0;
2766
    SegLimits[SegXData] = 0xffff;
2767
  }
2768
  else
2769
  {
2770
    RegSpaceType = UInt8;
2771
    SegLimits[SegData] = 0xff;
2772
  }
2773
 
2774
  pASSUMERecs = ASSUMEeZ8s;
2775
  ASSUMERecCnt = mIsSuper8() ? ASSUMESuper8Count : ASSUMEeZ8Count;
2776
 
2777
  MakeCode = MakeCode_Z8;
2778
  IsDef = IsDef_Z8;
2779
  InternSymbol = InternSymbol_Z8;
2780
  DissectReg = DissectReg_Z8;
2781
  DissectBit = DissectBit_Z8;
2782
  SwitchFrom = SwitchFrom_Z8;
2783
  InitFields();
2784
}
2785
 
2786
/*!------------------------------------------------------------------------
2787
 * \fn     codez8_init(void)
2788
 * \brief  register target to AS
2789
 * ------------------------------------------------------------------------ */
2790
 
2791
static const tCPUProps CPUProps[] =
2792
{
2793
  { "Z8601"    , eCoreZ8NMOS   , 0xe0,  0x7f,  0xf0 },
2794
  { "Z8603"    , eCoreZ8NMOS   , 0xe0,  0x7f,  0xf0 },
2795
  { "Z86C03"   , eCoreZ8CMOS   , 0xe0,  0x3f,  0xf0 },
2796
  { "Z86E03"   , eCoreZ8CMOS   , 0xe0,  0x3f,  0xf0 },
2797
/*{ "Z8604"    , eCoreZ8       , 0xe0,  0x7f,  0xf0 },*/
2798
  { "Z86C06"   , eCoreZ8CMOS   , 0xe0,  0x7f,  0xf0 },
2799
  { "Z86E06"   , eCoreZ8CMOS   , 0xe0,  0x7f,  0xf0 },
2800
  { "Z86C08"   , eCoreZ8CMOS   , 0xe0,  0x7f,  0xf0 },
2801
  { "Z86C30"   , eCoreZ8CMOS   , 0xe0,  0xef,  0xf0 },
2802
  { "Z86C21"   , eCoreZ8CMOS   , 0xe0,  0xef,  0xf0 },
2803
  { "Z86E21"   , eCoreZ8CMOS   , 0xe0,  0xef,  0xf0 },
2804
  { "Z86C31"   , eCoreZ8CMOS   , 0xe0,  0x7f,  0xf0 },
2805
  { "Z86C32"   , eCoreZ8CMOS   , 0xe0,  0xef,  0xf0 },
2806
  { "Z86C40"   , eCoreZ8CMOS   , 0xe0,  0xef,  0xf0 },
2807
  { "Z88C00"   , eCoreSuper8   , 0xc0,  0xbf,  0xe0 },
2808
  { "Z88C01"   , eCoreSuper8   , 0xc0,  0xbf,  0xe0 },
2809
  { "eZ8"      , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
2810
  { "Z8F0113"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
2811
  { "Z8F011A"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
2812
  { "Z8F0123"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
2813
  { "Z8F012A"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
2814
  { "Z8F0130"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
2815
  { "Z8F0131"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
2816
  { "Z8F0213"  , eCoreZ8Encore , 0xee0, 0x1ff, 0xf00 },
2817
  { "Z8F021A"  , eCoreZ8Encore , 0xee0, 0x1ff, 0xf00 },
2818
  { "Z8F0223"  , eCoreZ8Encore , 0xee0, 0x1ff, 0xf00 },
2819
  { "Z8F022A"  , eCoreZ8Encore , 0xee0, 0x1ff, 0xf00 },
2820
  { "Z8F0230"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
2821
  { "Z8F0231"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
2822
  { "Z8F0411"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2823
  { "Z8F0412"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2824
  { "Z8F0413"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2825
  { "Z8F041A"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2826
  { "Z8F0421"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2827
  { "Z8F0422"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2828
  { "Z8F0423"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2829
  { "Z8F042A"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2830
  { "Z8F0430"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
2831
  { "Z8F0431"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
2832
  { "Z8F0811"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2833
  { "Z8F0812"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2834
  { "Z8F0813"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2835
  { "Z8F081A"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2836
  { "Z8F0821"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2837
  { "Z8F0822"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2838
  { "Z8F0823"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2839
  { "Z8F082A"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2840
  { "Z8F0830"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
2841
  { "Z8F0831"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
2842
  { "Z8F0880"  , eCoreZ8Encore , 0xee0, 0x3ff, 0xf00 },
2843
  { "Z8F1232"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
2844
  { "Z8F1233"  , eCoreZ8Encore , 0xee0,  0xff, 0xf00 },
2845
  { "Z8F1621"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
2846
  { "Z8F1622"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
2847
  { "Z8F1680"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
2848
  { "Z8F1681"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
2849
  { "Z8F1682"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
2850
  { "Z8F2421"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
2851
  { "Z8F2422"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
2852
  { "Z8F2480"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
2853
  { "Z8F3221"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
2854
  { "Z8F3222"  , eCoreZ8Encore , 0xee0, 0x7ff, 0xf00 },
2855
  { "Z8F3281"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
2856
  { "Z8F3282"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
2857
  { "Z8F4821"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
2858
  { "Z8F4822"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
2859
  { "Z8F4823"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
2860
  { "Z8F6081"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
2861
  { "Z8F6082"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
2862
  { "Z8F6421"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
2863
  { "Z8F6422"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
2864
  { "Z8F6423"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
2865
  { "Z8F6481"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
2866
  { "Z8F6482"  , eCoreZ8Encore , 0xee0, 0xeff, 0xf00 },
2867
  { NULL       , eCoreNone     , 0x00,  0x00, 0x000 }
2868
};
2869
 
2870
void codez8_init(void)
2871
{
2872
  const tCPUProps *pRun;
2873
 
2874
  for (pRun = CPUProps; pRun->pName; pRun++)
2875
    (void)AddCPUUser(pRun->pName, SwitchTo_Z8, (void*)pRun, NULL);
2876
 
2877
  AddInitPassProc(InitCode_Z8);
2878
}