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