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