1 /* codexa.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* AS-Codegenerator Philips XA */
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 "asmallg.h"
22 #include "asmitree.h"
23 #include "codepseudo.h"
24 #include "intpseudo.h"
25 #include "motpseudo.h"
26 #include "codevars.h"
27 #include "errmsg.h"
28
29 #include "codexa.h"
30
31 /*-------------------------------------------------------------------------*/
32 /* Definitionen */
33
34 #define ModNone (-1)
35 #define ModReg 0
36 #define MModReg (1 << ModReg)
37 #define ModMem 1
38 #define MModMem (1 << ModMem)
39 #define ModImm 2
40 #define MModImm (1 << ModImm)
41 #define ModAbs 3
42 #define MModAbs (1 << ModAbs)
43
44 #define REG_SP 7
45 #define REG_MARK 16
46
47 #define JBitOrderCnt 3
48 #define RegOrderCnt 4
49 #define RelOrderCount 17
50
51 #define RETICode 0xd690
52
53 #define eSymbolSize5Bit ((tSymbolSize)-4)
54 #define eSymbolSizeSigned4Bit ((tSymbolSize)-3)
55 #define eSymbolSize4Bit ((tSymbolSize)-2)
56
57 typedef struct
58 {
59 Byte SizeMask;
60 Byte Code;
61 } RegOrder;
62
63 typedef struct
64 {
65 const char *Name;
66 Byte SizeMask;
67 Byte Code;
68 Byte Inversion;
69 } InvOrder;
70
71 static CPUVar CPUXAG1,CPUXAG2,CPUXAG3;
72
73 static InvOrder *JBitOrders;
74 static RegOrder *RegOrders;
75 static InvOrder *RelOrders;
76
77 static LongInt Reg_DS;
78
79 static ShortInt AdrMode;
80 static Byte AdrPart,MemPart;
81 static Byte AdrVals[4];
82 static tSymbolSize OpSize;
83
84 #define ASSUMEXACount 1
85 static ASSUMERec ASSUMEXAs[ASSUMEXACount] =
86 {
87 {"DS", &Reg_DS, 0, 0xff, 0x100, NULL}
88 };
89
90 /*-------------------------------------------------------------------------*/
91 /* Hilfsroutinen */
92
SetOpSize(tSymbolSize NSize)93 static void SetOpSize(tSymbolSize NSize)
94 {
95 if (OpSize == eSymbolSizeUnknown) OpSize = NSize;
96 else if (OpSize != NSize)
97 {
98 AdrMode = ModNone; AdrCnt = 0; WrError(ErrNum_ConfOpSizes);
99 }
100 }
101
102 /*!------------------------------------------------------------------------
103 * \fn DecodeRegCore(const char *pArg, tSymbolSize *pSize, Byte *pResult)
104 * \brief check whether argument is a CPU register
105 * \param pArg source argument
106 * \param pSize register size if yes
107 * \param pResult register number if yes
108 * \return Reg eval result
109 * ------------------------------------------------------------------------ */
110
DecodeRegCore(const char * pArg,tSymbolSize * pSize,Byte * pResult)111 static tRegEvalResult DecodeRegCore(const char *pArg, tSymbolSize *pSize, Byte *pResult)
112 {
113 int len;
114
115 if (!as_strcasecmp(pArg, "SP"))
116 {
117 *pResult = REG_SP | REG_MARK;
118 *pSize = eSymbolSize16Bit;
119 return eIsReg;
120 }
121
122 len = strlen(pArg);
123 if ((len >= 2) && (as_toupper(*pArg) == 'R') && (pArg[1] >= '0') && (pArg[1] <= '7'))
124 {
125 *pResult = pArg[1] - '0';
126 if (len == 2)
127 {
128 if (OpSize == eSymbolSize32Bit)
129 {
130 *pSize = eSymbolSize32Bit;
131 if (*pResult & 1)
132 {
133 WrError(ErrNum_InvRegPair);
134 (*pResult)--;
135 return eRegAbort;
136 }
137 else
138 return eIsReg;
139 }
140 else
141 {
142 *pSize = eSymbolSize16Bit;
143 return eIsReg;
144 }
145 }
146 else if ((len == 3) && (as_toupper(pArg[2]) == 'L'))
147 {
148 *pResult <<= 1;
149 *pSize = eSymbolSize8Bit;
150 return eIsReg;
151 }
152 else if ((len == 3) && (as_toupper(pArg[2]) == 'H'))
153 {
154 *pResult = (*pResult << 1) + 1;
155 *pSize = eSymbolSize8Bit;
156 return eIsReg;
157 }
158 else
159 return eIsNoReg;
160 }
161 return eIsNoReg;
162 }
163
164 /*!------------------------------------------------------------------------
165 * \fn DissectReg_XA(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
166 * \brief dissect register symbols - XA variant
167 * \param pDest destination buffer
168 * \param DestSize destination buffer size
169 * \param Value numeric register value
170 * \param InpSize register size
171 * ------------------------------------------------------------------------ */
172
DissectReg_XA(char * pDest,size_t DestSize,tRegInt Value,tSymbolSize InpSize)173 static void DissectReg_XA(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
174 {
175 switch (InpSize)
176 {
177 case eSymbolSize8Bit:
178 as_snprintf(pDest, DestSize, "R%u%c", (unsigned)(Value >> 1), "LH"[Value & 1]);
179 break;
180 case eSymbolSize16Bit:
181 as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
182 break;
183 case eSymbolSize32Bit:
184 as_snprintf(pDest, DestSize, "R%u.D", (unsigned)Value);
185 break;
186 default:
187 as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
188 }
189 }
190
191
192 /*!------------------------------------------------------------------------
193 * \fn DecodeReg(const tStrComp *pArg, tSymbolSize *pSize, Byte *pResult, Boolean MustBeReg)
194 * \brief check whether argument is a CPU register or register alias
195 * \param pArg source argument
196 * \param pSize register size if yes
197 * \param pResult register number if yes
198 * \param MustBeReg expecting register?
199 * \return Reg eval result
200 * ------------------------------------------------------------------------ */
201
DecodeReg(const tStrComp * pArg,tSymbolSize * pSize,Byte * pResult,Boolean MustBeReg)202 static tRegEvalResult DecodeReg(const tStrComp *pArg, tSymbolSize *pSize, Byte *pResult, Boolean MustBeReg)
203 {
204 tRegDescr RegDescr;
205 tEvalResult EvalResult;
206 tRegEvalResult RegEvalResult;
207
208 RegEvalResult = DecodeRegCore(pArg->Str, pSize, pResult);
209 if (RegEvalResult != eIsNoReg)
210 {
211 *pResult &= ~REG_MARK;
212 return RegEvalResult;
213 }
214
215 RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
216 if (RegEvalResult == eIsReg)
217 {
218 *pResult = RegDescr.Reg & ~REG_MARK;
219 *pSize = EvalResult.DataSize;
220 }
221 return RegEvalResult;
222 }
223
ChkAdr(Word Mask,const tStrComp * pComp)224 static Boolean ChkAdr(Word Mask, const tStrComp *pComp)
225 {
226 if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
227 {
228 WrStrErrorPos(ErrNum_InvAddrMode, pComp);
229 AdrMode = ModNone;
230 AdrCnt = 0;
231 return False;
232 }
233 return True;
234 }
235
DecodeAdrIndirect(tStrComp * pArg,Word Mask)236 static Boolean DecodeAdrIndirect(tStrComp *pArg, Word Mask)
237 {
238 unsigned ArgLen;
239 Byte Reg;
240 tSymbolSize NSize;
241
242 ArgLen = strlen(pArg->Str);
243 if (pArg->Str[ArgLen - 1] == '+')
244 {
245 StrCompShorten(pArg, 1); ArgLen--;
246 if (!DecodeReg(pArg, &NSize, &AdrPart, True));
247 else if (NSize != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvAddrMode, pArg);
248 else
249 {
250 AdrMode = ModMem; MemPart = 3;
251 }
252 }
253 else
254 {
255 char *pSplit;
256 Boolean FirstFlag = False, NegFlag = False, NextNegFlag, ErrFlag = False;
257 tStrComp ThisComp = *pArg, RemComp;
258 LongInt DispAcc = 0;
259
260 AdrPart = 0xff;
261 do
262 {
263 pSplit = QuotMultPos(ThisComp.Str, "+-");
264 NextNegFlag = (pSplit && (*pSplit == '-'));
265 if (pSplit)
266 {
267 StrCompRefRight(&RemComp, &ThisComp, pSplit - ThisComp.Str + 1);
268 *pSplit = '\0';
269 }
270 KillPrefBlanksStrComp(&ThisComp);
271 KillPostBlanksStrComp(&ThisComp);
272
273 switch (DecodeReg(&ThisComp, &NSize, &Reg, False))
274 {
275 case eIsReg:
276 if ((NSize != eSymbolSize16Bit) || (AdrPart != 0xff) || NegFlag)
277 {
278 WrStrErrorPos(ErrNum_InvAddrMode, &ThisComp); ErrFlag = True;
279 }
280 else
281 AdrPart = Reg;
282 break;
283 case eRegAbort:
284 return False;
285 default:
286 {
287 LongInt DispPart;
288 tSymbolFlags Flags;
289
290 DispPart = EvalStrIntExpressionWithFlags(&ThisComp, Int32, &ErrFlag, &Flags);
291 ErrFlag = !ErrFlag;
292 if (!ErrFlag)
293 {
294 FirstFlag = FirstFlag || mFirstPassUnknown(Flags);
295 DispAcc += NegFlag ? -DispPart : DispPart;
296 }
297 }
298 }
299
300 NegFlag = NextNegFlag;
301 if (pSplit)
302 ThisComp = RemComp;
303 }
304 while (pSplit && !ErrFlag);
305
306 if (FirstFlag) DispAcc &= 0x7fff;
307 if (AdrPart == 0xff) WrStrErrorPos(ErrNum_InvAddrMode, pArg);
308 else if (DispAcc == 0)
309 {
310 AdrMode = ModMem; MemPart = 2;
311 }
312 else if ((DispAcc >= -128) && (DispAcc < 127))
313 {
314 AdrMode = ModMem; MemPart = 4;
315 AdrVals[0] = DispAcc & 0xff; AdrCnt = 1;
316 }
317 else if (ChkRange(DispAcc, -0x8000l, 0x7fffl))
318 {
319 AdrMode = ModMem; MemPart = 5;
320 AdrVals[0] = (DispAcc >> 8) & 0xff;
321 AdrVals[1] = DispAcc & 0xff;
322 AdrCnt = 2;
323 }
324 }
325 return ChkAdr(Mask, pArg);
326 }
327
DecodeAdr(tStrComp * pArg,Word Mask)328 static Boolean DecodeAdr(tStrComp *pArg, Word Mask)
329 {
330 tSymbolSize NSize;
331 LongInt AdrLong;
332 tEvalResult EvalResult;
333 Word AdrInt;
334 int ArgLen;
335
336 AdrMode = ModNone; AdrCnt = 0;
337 KillPrefBlanksStrComp(pArg);
338 KillPostBlanksStrComp(pArg);
339
340 switch (DecodeReg(pArg, &NSize, &AdrPart, False))
341 {
342 case eIsReg:
343 if (Mask & MModReg)
344 {
345 AdrMode = ModReg;
346 SetOpSize(NSize);
347 }
348 else
349 {
350 AdrMode = ModMem;
351 MemPart = 1;
352 SetOpSize(NSize);
353 }
354 return ChkAdr(Mask, pArg);
355 case eRegAbort:
356 return False;
357 default:
358 break;
359 }
360
361 if (*pArg->Str == '#')
362 {
363 tStrComp ImmComp;
364 Boolean OK;
365
366 StrCompRefRight(&ImmComp, pArg, 1);
367 switch ((int)OpSize)
368 {
369 case eSymbolSize5Bit:
370 AdrVals[0] = EvalStrIntExpression(&ImmComp, UInt5, &OK);
371 if (OK)
372 {
373 AdrCnt = 1; AdrMode = ModImm;
374 }
375 break;
376 case eSymbolSizeSigned4Bit:
377 AdrVals[0] = EvalStrIntExpression(&ImmComp, SInt4, &OK);
378 if (OK)
379 {
380 AdrCnt = 1; AdrMode = ModImm;
381 }
382 break;
383 case eSymbolSize4Bit:
384 AdrVals[0] = EvalStrIntExpression(&ImmComp, UInt4, &OK);
385 if (OK)
386 {
387 AdrCnt = 1; AdrMode = ModImm;
388 }
389 break;
390 case eSymbolSizeUnknown:
391 WrError(ErrNum_UndefOpSizes);
392 break;
393 case eSymbolSize8Bit:
394 AdrVals[0] = EvalStrIntExpression(&ImmComp, Int8, &OK);
395 if (OK)
396 {
397 AdrCnt = 1; AdrMode = ModImm;
398 }
399 break;
400 case eSymbolSize16Bit:
401 AdrInt = EvalStrIntExpression(&ImmComp, Int16, &OK);
402 if (OK)
403 {
404 AdrVals[0] = Hi(AdrInt);
405 AdrVals[1] = Lo(AdrInt);
406 AdrCnt = 2;
407 AdrMode = ModImm;
408 }
409 break;
410 case eSymbolSize32Bit:
411 AdrLong = EvalStrIntExpression(&ImmComp, Int32, &OK);
412 if (OK)
413 {
414 AdrVals[0] = (AdrLong >> 24) & 0xff;
415 AdrVals[1] = (AdrLong >> 16) & 0xff;
416 AdrVals[2] = (AdrLong >> 8) & 0xff;
417 AdrVals[3] = AdrLong & 0xff;
418 AdrCnt = 4;
419 AdrMode = ModImm;
420 }
421 break;
422 default:
423 break;
424 }
425 return ChkAdr(Mask, pArg);
426 }
427
428 ArgLen = strlen(pArg->Str);
429 if ((*pArg->Str == '[') && (pArg->Str[ArgLen - 1] == ']'))
430 {
431 tStrComp IndirComp;
432
433 pArg->Str[--ArgLen] = '\0'; pArg->Pos.Len--;
434 StrCompRefRight(&IndirComp, pArg, 1);
435 KillPrefBlanksStrComp(&IndirComp);
436 KillPostBlanksStrComp(&IndirComp);
437
438 return DecodeAdrIndirect(&IndirComp, Mask);
439 }
440
441 AdrLong = EvalStrIntExpressionWithResult(pArg, UInt24, &EvalResult);
442 if (EvalResult.OK)
443 {
444 if (mFirstPassUnknown(EvalResult.Flags))
445 {
446 if (!(Mask & MModAbs)) AdrLong &= 0x3ff;
447 }
448 if ((AdrLong & 0xffff) > 0x7ff) WrError(ErrNum_AdrOverflow);
449 else if ((AdrLong & 0xffff) <= 0x3ff)
450 {
451 if ((AdrLong >> 16) != Reg_DS) WrError(ErrNum_InAccPage);
452 ChkSpace(SegData, EvalResult.AddrSpaceMask);
453 AdrMode = ModMem; MemPart = 6;
454 AdrPart = Hi(AdrLong);
455 AdrVals[0] = Lo(AdrLong);
456 AdrCnt = 1;
457 }
458 else if (AdrLong > 0x7ff) WrError(ErrNum_AdrOverflow);
459 else
460 {
461 ChkSpace(SegIO, EvalResult.AddrSpaceMask);
462 AdrMode = ModMem; MemPart = 6;
463 AdrPart = Hi(AdrLong);
464 AdrVals[0] = Lo(AdrLong);
465 AdrCnt = 1;
466 }
467 }
468
469 return ChkAdr(Mask, pArg);
470 }
471
DecodeBitAddr(tStrComp * pArg,LongInt * Erg)472 static Boolean DecodeBitAddr(tStrComp *pArg, LongInt *Erg)
473 {
474 char *p;
475 Byte BPos, Reg;
476 ShortInt Res;
477 tSymbolSize Size;
478 LongInt AdrLong;
479 tEvalResult EvalResult;
480
481 p = RQuotPos(pArg->Str, '.'); Res = 0;
482 if (!p)
483 {
484 AdrLong = EvalStrIntExpressionWithResult(pArg, UInt24, &EvalResult);
485 if (mFirstPassUnknown(EvalResult.Flags)) AdrLong &= 0x3ff;
486 *Erg = AdrLong; Res = 1;
487 }
488 else
489 {
490 int l = p - pArg->Str;
491
492 BPos = EvalStrIntExpressionOffsWithResult(pArg, l + 1, UInt4, &EvalResult);
493 if (mFirstPassUnknown(EvalResult.Flags)) BPos &= 7;
494
495 *p = '\0'; pArg->Pos.Len -= l + 1;
496 if (EvalResult.OK)
497 {
498 switch (DecodeReg(pArg, &Size, &Reg, False))
499 {
500 case eRegAbort:
501 return False;
502 case eIsReg:
503 if ((Size == eSymbolSize8Bit) && (BPos > 7)) WrError(ErrNum_OverRange);
504 else
505 {
506 if (Size == eSymbolSize8Bit) *Erg = (Reg << 3) + BPos;
507 else *Erg = (Reg << 4) + BPos;
508 Res = 1;
509 }
510 break;
511 default:
512 if (BPos > 7) WrError(ErrNum_OverRange);
513 else
514 {
515 AdrLong = EvalStrIntExpressionWithResult(pArg, UInt24, &EvalResult);
516 if (EvalResult.AddrSpaceMask & (1 << SegIO))
517 {
518 ChkSpace(SegIO, EvalResult.AddrSpaceMask);
519 if (mFirstPassUnknown(EvalResult.Flags)) AdrLong = (AdrLong & 0x3f) | 0x400;
520 if (ChkRange(AdrLong, 0x400, 0x43f))
521 {
522 *Erg = 0x200 + ((AdrLong & 0x3f) << 3) + BPos;
523 Res = 1;
524 }
525 else
526 Res = -1;
527 }
528 else
529 {
530 ChkSpace(SegData, EvalResult.AddrSpaceMask);
531 if (mFirstPassUnknown(EvalResult.Flags)) AdrLong = (AdrLong & 0x00ff003f) | 0x20;
532 if (ChkRange(AdrLong & 0xff, 0x20, 0x3f))
533 {
534 *Erg = 0x100 + ((AdrLong & 0x1f) << 3) + BPos + (AdrLong & 0xff0000);
535 Res = 1;
536 }
537 else
538 Res = -1;
539 }
540 }
541 break;
542 }
543 }
544 *p = '.';
545 }
546 if (Res == 0) WrError(ErrNum_InvAddrMode);
547 return (Res == 1);
548 }
549
ChkBitPage(LongInt Adr)550 static void ChkBitPage(LongInt Adr)
551 {
552 if ((Adr >> 16) != Reg_DS) WrError(ErrNum_InAccPage);
553 }
554
MkEven24(LongWord Inp)555 static LongWord MkEven24(LongWord Inp)
556 {
557 return Inp & 0xfffffeul;
558 }
559
GetBranchDest(const tStrComp * pComp,tEvalResult * pEvalResult)560 static LongWord GetBranchDest(const tStrComp *pComp, tEvalResult *pEvalResult)
561 {
562 LongWord Result;
563
564 Result = EvalStrIntExpressionWithResult(pComp, UInt24, pEvalResult);
565 if (pEvalResult->OK)
566 {
567 if (mFirstPassUnknown(pEvalResult->Flags)) Result = MkEven24(Result);
568 ChkSpace(SegCode, pEvalResult->AddrSpaceMask);
569 if (Result & 1)
570 {
571 WrStrErrorPos(ErrNum_NotAligned, pComp);
572 pEvalResult->OK = False;
573 }
574 }
575 return Result;
576 }
577
ChkShortEvenDist(LongInt * pDist,tSymbolFlags Flags)578 static Boolean ChkShortEvenDist(LongInt *pDist, tSymbolFlags Flags)
579 {
580 if (!mSymbolQuestionable(Flags) && ((*pDist > 254) || (*pDist < -256)))
581 return False;
582 else
583 {
584 *pDist >>= 1;
585 return True;
586 }
587 }
588
ChkLongEvenDist(LongInt * pDist,const tStrComp * pComp,tSymbolFlags Flags)589 static Boolean ChkLongEvenDist(LongInt *pDist, const tStrComp *pComp, tSymbolFlags Flags)
590 {
591 if (!mSymbolQuestionable(Flags) && ((*pDist > 65534) || (*pDist < -65536)))
592 {
593 WrStrErrorPos(ErrNum_JmpDistTooBig, pComp);
594 return False;
595 }
596 else
597 {
598 *pDist >>= 1;
599 return True;
600 }
601 }
602
603 /*-------------------------------------------------------------------------*/
604 /* Befehlsdekoder */
605
DecodePORT(Word Index)606 static void DecodePORT(Word Index)
607 {
608 UNUSED(Index);
609
610 CodeEquate(SegIO, 0x400, 0x7ff);
611 }
612
DecodeBIT(Word Index)613 static void DecodeBIT(Word Index)
614 {
615 LongInt BAdr;
616
617 UNUSED(Index);
618
619 if (!ChkArgCnt(1, 1));
620 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
621 else if (DecodeBitAddr(&ArgStr[1], &BAdr))
622 {
623 EnterIntSymbol(&LabPart, BAdr, SegNone, False);
624 switch ((BAdr & 0x3ff) >> 8)
625 {
626 case 0:
627 as_snprintf(ListLine, STRINGSIZE, "=R%d.%d",
628 (unsigned)((BAdr >> 4) & 15),
629 (unsigned) (BAdr & 15));
630 break;
631 case 1:
632 as_snprintf(ListLine, STRINGSIZE, "=%x:%x.%d",
633 (unsigned)((BAdr >> 16) & 255),
634 (unsigned)((BAdr & 0x1f8) >> 3), (unsigned)(BAdr & 7));
635 break;
636 default:
637 as_snprintf(ListLine, STRINGSIZE, "=S:%x.%d",
638 (unsigned)(((BAdr >> 3) & 0x3f) + 0x400),
639 (unsigned)(BAdr & 7));
640 break;
641 }
642 }
643 }
644
DecodeFixed(Word Code)645 static void DecodeFixed(Word Code)
646 {
647 if (ChkArgCnt(0, 0))
648 {
649 if (Hi(Code) != 0) BAsmCode[CodeLen++] = Hi(Code);
650 BAsmCode[CodeLen++] = Lo(Code);
651 if ((Code == RETICode) && (!SupAllowed)) WrError(ErrNum_PrivOrder);
652 }
653 }
654
DecodeStack(Word Code)655 static void DecodeStack(Word Code)
656 {
657 Byte HReg;
658 Boolean OK;
659 Word Mask;
660 int i;
661
662 if (ChkArgCnt(1, ArgCntMax))
663 {
664 HReg = 0xff; OK = True; Mask = 0;
665 for (i = 1; i <= ArgCnt; i++)
666 if (OK)
667 {
668 DecodeAdr(&ArgStr[i], MModMem);
669 if (AdrMode == ModNone) OK = False;
670 else switch (MemPart)
671 {
672 case 1:
673 if (HReg == 0)
674 {
675 WrError(ErrNum_InvAddrMode); OK = False;
676 }
677 else
678 {
679 HReg = 1; Mask |= (1 << AdrPart);
680 }
681 break;
682 case 6:
683 if (HReg != 0xff)
684 {
685 WrError(ErrNum_InvAddrMode); OK = False;
686 }
687 else
688 HReg = 0;
689 break;
690 default:
691 WrError(ErrNum_InvAddrMode); OK = False;
692 }
693 }
694 if (OK)
695 {
696 if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
697 else if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
698 else if (HReg == 0)
699 {
700 BAsmCode[CodeLen++] = 0x87 + (OpSize << 3);
701 BAsmCode[CodeLen++] = Hi(Code) + AdrPart;
702 BAsmCode[CodeLen++] = AdrVals[0];
703 }
704 else if (Code < 0x2000) /* POP(U): obere Register zuerst */
705 {
706 if (Hi(Mask) != 0)
707 {
708 BAsmCode[CodeLen++] = Lo(Code) + (OpSize << 3) + 0x40;
709 BAsmCode[CodeLen++]=Hi(Mask);
710 }
711 if (Lo(Mask) != 0)
712 {
713 BAsmCode[CodeLen++] = Lo(Code) + (OpSize << 3);
714 BAsmCode[CodeLen++] = Lo(Mask);
715 }
716 if ((OpSize == eSymbolSize16Bit) && (Code == 0x1027) && (Mask & 0x80)) WrError(ErrNum_Unpredictable);
717 }
718 else /* PUSH(U): untere Register zuerst */
719 {
720 if (Lo(Mask) != 0)
721 {
722 BAsmCode[CodeLen++] = Lo(Code) + (OpSize << 3);
723 BAsmCode[CodeLen++] = Lo(Mask);
724 }
725 if (Hi(Mask) != 0)
726 {
727 BAsmCode[CodeLen++] = Lo(Code) + (OpSize << 3) + 0x40;
728 BAsmCode[CodeLen++] = Hi(Mask);
729 }
730 }
731 }
732 }
733 }
734
DecodeALU(Word Index)735 static void DecodeALU(Word Index)
736 {
737 Byte HReg, HCnt, HVals[3], HMem;
738
739 if (ChkArgCnt(2, 2))
740 {
741 DecodeAdr(&ArgStr[1], MModReg | MModMem);
742 switch (AdrMode)
743 {
744 case ModReg:
745 if (OpSize >= eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
746 else if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
747 else
748 {
749 HReg = AdrPart;
750 DecodeAdr(&ArgStr[2], MModMem | MModImm);
751 switch (AdrMode)
752 {
753 case ModMem:
754 BAsmCode[CodeLen++] = (Index << 4) + (OpSize << 3) + MemPart;
755 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
756 memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
757 CodeLen += AdrCnt;
758 if ((MemPart == 3) && ((HReg >> (1 - OpSize)) == AdrPart)) WrError(ErrNum_Unpredictable);
759 break;
760 case ModImm:
761 BAsmCode[CodeLen++] = 0x91 + (OpSize << 3);
762 BAsmCode[CodeLen++] = (HReg << 4) + Index;
763 memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
764 CodeLen += AdrCnt;
765 break;
766 }
767 }
768 break;
769 case ModMem:
770 HReg = AdrPart; HMem = MemPart; HCnt = AdrCnt;
771 memcpy(HVals, AdrVals, AdrCnt);
772 DecodeAdr(&ArgStr[2], MModReg | MModImm);
773 switch (AdrMode)
774 {
775 case ModReg:
776 if (OpSize == eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
777 else if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
778 else
779 {
780 BAsmCode[CodeLen++] = (Index << 4) + (OpSize << 3) + HMem;
781 BAsmCode[CodeLen++] = (AdrPart << 4) + 8 + HReg;
782 memcpy(BAsmCode + CodeLen, HVals, HCnt);
783 CodeLen += HCnt;
784 if ((HMem == 3) && ((AdrPart >> (1 - OpSize)) == HReg)) WrError(ErrNum_Unpredictable);
785 }
786 break;
787 case ModImm:
788 if (OpSize == eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
789 else if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
790 else
791 {
792 BAsmCode[CodeLen++] = 0x90 + HMem + (OpSize << 3);
793 BAsmCode[CodeLen++] = (HReg << 4) + Index;
794 memcpy(BAsmCode + CodeLen, HVals, HCnt);
795 memcpy(BAsmCode + CodeLen + HCnt, AdrVals, AdrCnt);
796 CodeLen += AdrCnt + HCnt;
797 }
798 break;
799 }
800 break;
801 }
802 }
803 }
804
DecodeRegO(Word Index)805 static void DecodeRegO(Word Index)
806 {
807 RegOrder *Op = RegOrders + Index;
808
809 if (ChkArgCnt(1, 1))
810 {
811 DecodeAdr(&ArgStr[1], MModReg);
812 switch (AdrMode)
813 {
814 case ModReg:
815 if ((Op->SizeMask & (1 << OpSize)) == 0) WrError(ErrNum_InvOpSize);
816 else
817 {
818 BAsmCode[CodeLen++] = 0x90 + (OpSize << 3);
819 BAsmCode[CodeLen++] = (AdrPart << 4) + Op->Code;
820 }
821 break;
822 }
823 }
824 }
825
DecodeShift(Word Index)826 static void DecodeShift(Word Index)
827 {
828 Byte HReg, HMem;
829
830 if (!ChkArgCnt(2, 2));
831 else if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
832 else
833 {
834 DecodeAdr(&ArgStr[1], MModReg);
835 switch (AdrMode)
836 {
837 case ModReg:
838 HReg = AdrPart; HMem = OpSize;
839 if (*ArgStr[2].Str == '#')
840 OpSize = (HMem == 2) ? eSymbolSize5Bit : eSymbolSize4Bit;
841 else
842 OpSize = eSymbolSize8Bit;
843 DecodeAdr(&ArgStr[2], MModReg | ((Index == 3) ? 0 : MModImm));
844 switch (AdrMode)
845 {
846 case ModReg:
847 BAsmCode[CodeLen++] = 0xc0 + ((HMem & 1) << 3) + Index;
848 if (HMem == 2) BAsmCode[CodeLen - 1] += 12;
849 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
850 if (Index == 3)
851 {
852 if (HMem == 2)
853 {
854 if ((AdrPart >> 2) == (HReg >> 1)) WrError(ErrNum_Unpredictable);
855 }
856 else if ((AdrPart >> HMem) == HReg) WrError(ErrNum_Unpredictable);
857 }
858 break;
859 case ModImm:
860 BAsmCode[CodeLen++] = 0xd0 + ((HMem & 1) << 3) + Index;
861 if (HMem == 2)
862 {
863 BAsmCode[CodeLen - 1] += 12;
864 BAsmCode[CodeLen++] = ((HReg & 14) << 4) + AdrVals[0];
865 }
866 else
867 BAsmCode[CodeLen++] = (HReg << 4) + AdrVals[0];
868 break;
869 }
870 break;
871 }
872 }
873 }
874
DecodeRotate(Word Code)875 static void DecodeRotate(Word Code)
876 {
877 Byte HReg, HMem;
878
879 if (ChkArgCnt(2, 2))
880 {
881 DecodeAdr(&ArgStr[1], MModReg);
882 switch (AdrMode)
883 {
884 case ModReg:
885 if (OpSize == eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
886 else
887 {
888 HReg = AdrPart; HMem = OpSize; OpSize = eSymbolSize4Bit;
889 DecodeAdr(&ArgStr[2], MModImm);
890 switch (AdrMode)
891 {
892 case ModImm:
893 BAsmCode[CodeLen++] = Code + (HMem << 3);
894 BAsmCode[CodeLen++] = (HReg << 4) + AdrVals[0];
895 break;
896 }
897 }
898 break;
899 }
900 }
901 }
902
DecodeRel(Word Index)903 static void DecodeRel(Word Index)
904 {
905 InvOrder *Op = RelOrders + Index;
906 LongWord Dest;
907 LongInt Dist;
908 tEvalResult EvalResult;
909
910 if (!ChkArgCnt(1, 1));
911 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
912 else
913 {
914 Dest = GetBranchDest(&ArgStr[1], &EvalResult);
915 if (EvalResult.OK)
916 {
917 Dist = Dest - MkEven24(EProgCounter() + CodeLen + 2);
918 if (ChkShortEvenDist(&Dist, EvalResult.Flags))
919 {
920 BAsmCode[CodeLen++] = Op->Code;
921 BAsmCode[CodeLen++] = Dist & 0xff;
922 }
923 else if (!DoBranchExt) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
924 else if (Op->Inversion == 255) /* BR */
925 {
926 Dist = Dest - MkEven24(EProgCounter() + CodeLen + 3);
927 if (ChkLongEvenDist(&Dist, &ArgStr[1], EvalResult.Flags))
928 {
929 Dist >>= 1;
930 BAsmCode[CodeLen++] = 0xd5;
931 BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
932 BAsmCode[CodeLen++] = Dist & 0xff;
933 }
934 }
935 else
936 {
937 Dist = Dest - MkEven24(EProgCounter() + CodeLen + 5);
938 if (ChkLongEvenDist(&Dist, &ArgStr[1], EvalResult.Flags))
939 {
940 BAsmCode[CodeLen++] = RelOrders[Op->Inversion].Code;
941 BAsmCode[CodeLen++] = 2;
942 BAsmCode[CodeLen++] = 0xd5;
943 BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
944 BAsmCode[CodeLen++] = Dist & 0xff;
945 if (Odd(EProgCounter() + CodeLen)) BAsmCode[CodeLen++] = 0;
946 }
947 }
948 }
949 }
950 }
951
DecodeJBit(Word Index)952 static void DecodeJBit(Word Index)
953 {
954 LongInt BitAdr, Dist, odd;
955 LongWord Dest;
956 tEvalResult EvalResult;
957 InvOrder *Op = JBitOrders + Index;
958
959 if (!ChkArgCnt(2, 2));
960 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
961 else if (DecodeBitAddr(&ArgStr[1], &BitAdr))
962 {
963 Dest = GetBranchDest(&ArgStr[2], &EvalResult);
964 if (EvalResult.OK)
965 {
966 Dist = Dest - MkEven24(EProgCounter() + CodeLen + 4);
967 if (ChkShortEvenDist(&Dist, EvalResult.Flags))
968 {
969 BAsmCode[CodeLen++] = 0x97;
970 BAsmCode[CodeLen++] = Op->Code + Hi(BitAdr);
971 BAsmCode[CodeLen++] = Lo(BitAdr);
972 BAsmCode[CodeLen++] = Dist & 0xff;
973 }
974 else if (!DoBranchExt) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[2]);
975 else if (Op->Inversion == 255)
976 {
977 odd = EProgCounter() & 1;
978 Dist = Dest - MkEven24(EProgCounter() + CodeLen + 9 + odd);
979 if (ChkLongEvenDist(&Dist, &ArgStr[2], EvalResult.Flags))
980 {
981 BAsmCode[CodeLen++] = 0x97;
982 BAsmCode[CodeLen++] = Op->Code + Hi(BitAdr);
983 BAsmCode[CodeLen++] = Lo(BitAdr);
984 BAsmCode[CodeLen++] = 1 + odd;
985 BAsmCode[CodeLen++] = 0xfe;
986 BAsmCode[CodeLen++] = 2 + odd;
987 if (odd) BAsmCode[CodeLen++] = 0;
988 BAsmCode[CodeLen++] = 0xd5;
989 BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
990 BAsmCode[CodeLen++] = Dist & 0xff;
991 BAsmCode[CodeLen++] = 0;
992 }
993 }
994 else
995 {
996 Dist = Dest - MkEven24(EProgCounter() + CodeLen + 7);
997 if (ChkLongEvenDist(&Dist, &ArgStr[2], EvalResult.Flags))
998 {
999 BAsmCode[CodeLen++] = 0x97;
1000 BAsmCode[CodeLen++] = JBitOrders[Op->Inversion].Code + Hi(BitAdr);
1001 BAsmCode[CodeLen++] = Lo(BitAdr);
1002 BAsmCode[CodeLen++] = 2;
1003 BAsmCode[CodeLen++] = 0xd5;
1004 BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
1005 BAsmCode[CodeLen++] = Dist & 0xff;
1006 if (Odd(EProgCounter() + CodeLen)) BAsmCode[CodeLen++] = 0;
1007 }
1008 }
1009 }
1010 }
1011 }
1012
1013
DecodeMOV(Word Index)1014 static void DecodeMOV(Word Index)
1015 {
1016 LongInt AdrLong;
1017 Byte HVals[3], HReg, HPart, HCnt;
1018 UNUSED(Index);
1019
1020 if (!ChkArgCnt(2, 2));
1021 else if (!as_strcasecmp(ArgStr[1].Str, "C"))
1022 {
1023 if (DecodeBitAddr(&ArgStr[2], &AdrLong))
1024 {
1025 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1026 else
1027 {
1028 ChkBitPage(AdrLong);
1029 BAsmCode[CodeLen++] = 0x08;
1030 BAsmCode[CodeLen++] = 0x20 + Hi(AdrLong);
1031 BAsmCode[CodeLen++] = Lo(AdrLong);
1032 }
1033 }
1034 }
1035 else if (!as_strcasecmp(ArgStr[2].Str, "C"))
1036 {
1037 if (DecodeBitAddr(&ArgStr[1], &AdrLong))
1038 {
1039 if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1040 else
1041 {
1042 ChkBitPage(AdrLong);
1043 BAsmCode[CodeLen++] = 0x08;
1044 BAsmCode[CodeLen++] = 0x30 + Hi(AdrLong);
1045 BAsmCode[CodeLen++] = Lo(AdrLong);
1046 }
1047 }
1048 }
1049 else if (!as_strcasecmp(ArgStr[1].Str, "USP"))
1050 {
1051 SetOpSize(eSymbolSize16Bit);
1052 DecodeAdr(&ArgStr[2], MModReg);
1053 if (AdrMode == ModReg)
1054 {
1055 BAsmCode[CodeLen++] = 0x98;
1056 BAsmCode[CodeLen++] = (AdrPart << 4) + 0x0f;
1057 }
1058 }
1059 else if (!as_strcasecmp(ArgStr[2].Str, "USP"))
1060 {
1061 SetOpSize(eSymbolSize16Bit);
1062 DecodeAdr(&ArgStr[1], MModReg);
1063 if (AdrMode == ModReg)
1064 {
1065 BAsmCode[CodeLen++] = 0x90;
1066 BAsmCode[CodeLen++] = (AdrPart << 4)+0x0f;
1067 }
1068 }
1069 else
1070 {
1071 DecodeAdr(&ArgStr[1], MModReg | MModMem);
1072 switch (AdrMode)
1073 {
1074 case ModReg:
1075 if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1076 else
1077 {
1078 HReg = AdrPart;
1079 DecodeAdr(&ArgStr[2], MModMem | MModImm);
1080 switch (AdrMode)
1081 {
1082 case ModMem:
1083 BAsmCode[CodeLen++] = 0x80 + (OpSize << 3) + MemPart;
1084 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1085 memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1086 CodeLen += AdrCnt;
1087 if ((MemPart == 3) && ((HReg >> (1 - OpSize)) == AdrPart)) WrError(ErrNum_Unpredictable);
1088 break;
1089 case ModImm:
1090 BAsmCode[CodeLen++] = 0x91 + (OpSize << 3);
1091 BAsmCode[CodeLen++] = 0x08 + (HReg << 4);
1092 memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1093 CodeLen += AdrCnt;
1094 break;
1095 }
1096 }
1097 break;
1098 case ModMem:
1099 memcpy(HVals, AdrVals, AdrCnt); HCnt = AdrCnt; HPart = MemPart; HReg = AdrPart;
1100 DecodeAdr(&ArgStr[2], MModReg | MModMem | MModImm);
1101 switch (AdrMode)
1102 {
1103 case ModReg:
1104 if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1105 else
1106 {
1107 BAsmCode[CodeLen++] = 0x80 + (OpSize << 3) + HPart;
1108 BAsmCode[CodeLen++] = (AdrPart << 4) + 0x08 + HReg;
1109 memcpy(BAsmCode + CodeLen, HVals, HCnt);
1110 CodeLen += HCnt;
1111 if ((HPart == 3) && ((AdrPart >> (1 - OpSize)) == HReg)) WrError(ErrNum_Unpredictable);
1112 }
1113 break;
1114 case ModMem:
1115 if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
1116 else if ((OpSize != eSymbolSize8Bit) & (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1117 else if ((HPart == 6) && (MemPart == 6))
1118 {
1119 BAsmCode[CodeLen++] = 0x97 + (OpSize << 3);
1120 BAsmCode[CodeLen++] = (HReg << 4)+AdrPart;
1121 BAsmCode[CodeLen++] = HVals[0];
1122 BAsmCode[CodeLen++] = AdrVals[0];
1123 }
1124 else if ((HPart == 6) && (MemPart == 2))
1125 {
1126 BAsmCode[CodeLen++] = 0xa0 + (OpSize << 3);
1127 BAsmCode[CodeLen++] = 0x80 + (AdrPart << 4) + HReg;
1128 BAsmCode[CodeLen++] = HVals[0];
1129 }
1130 else if ((HPart == 2) && (MemPart == 6))
1131 {
1132 BAsmCode[CodeLen++] = 0xa0 + (OpSize << 3);
1133 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1134 BAsmCode[CodeLen++] = AdrVals[0];
1135 }
1136 else if ((HPart == 3) && (MemPart == 3))
1137 {
1138 BAsmCode[CodeLen++] = 0x90 + (OpSize << 3);
1139 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1140 if (HReg == AdrPart) WrError(ErrNum_Unpredictable);
1141 }
1142 else
1143 WrError(ErrNum_InvAddrMode);
1144 break;
1145 case ModImm:
1146 if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
1147 else if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1148 else
1149 {
1150 BAsmCode[CodeLen++] = 0x90 + (OpSize << 3) + HPart;
1151 BAsmCode[CodeLen++] = 0x08 + (HReg << 4);
1152 memcpy(BAsmCode + CodeLen, HVals, HCnt);
1153 memcpy(BAsmCode + CodeLen + HCnt, AdrVals, AdrCnt);
1154 CodeLen += HCnt + AdrCnt;
1155 }
1156 break;
1157 }
1158 break;
1159 }
1160 }
1161 }
1162
DecodeMOVC(Word Index)1163 static void DecodeMOVC(Word Index)
1164 {
1165 Byte HReg;
1166 UNUSED(Index);
1167
1168 if (!ChkArgCnt(2, 2));
1169 else
1170 {
1171 if (!*AttrPart.Str && !as_strcasecmp(ArgStr[1].Str, "A")) OpSize = eSymbolSize8Bit;
1172 if (!as_strcasecmp(ArgStr[2].Str, "[A+DPTR]"))
1173 {
1174 if (as_strcasecmp(ArgStr[1].Str, "A")) WrError(ErrNum_InvAddrMode);
1175 else if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
1176 else
1177 {
1178 BAsmCode[CodeLen++] = 0x90;
1179 BAsmCode[CodeLen++] = 0x4e;
1180 }
1181 }
1182 else if (!as_strcasecmp(ArgStr[2].Str, "[A+PC]"))
1183 {
1184 if (as_strcasecmp(ArgStr[1].Str, "A")) WrError(ErrNum_InvAddrMode);
1185 else if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
1186 else
1187 {
1188 BAsmCode[CodeLen++] = 0x90;
1189 BAsmCode[CodeLen++] = 0x4c;
1190 }
1191 }
1192 else
1193 {
1194 DecodeAdr(&ArgStr[1], MModReg);
1195 if (AdrMode != ModNone)
1196 {
1197 if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1198 else
1199 {
1200 HReg = AdrPart;
1201 DecodeAdr(&ArgStr[2], MModMem);
1202 if (AdrMode != ModNone)
1203 {
1204 if (MemPart != 3) WrError(ErrNum_InvAddrMode);
1205 else
1206 {
1207 BAsmCode[CodeLen++] = 0x80 + (OpSize << 3);
1208 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1209 if ((MemPart == 3) && ((HReg >> (1 - OpSize)) == AdrPart)) WrError(ErrNum_Unpredictable);
1210 }
1211 }
1212 }
1213 }
1214 }
1215 }
1216 }
1217
DecodeMOVX(Word Index)1218 static void DecodeMOVX(Word Index)
1219 {
1220 Byte HReg;
1221 UNUSED(Index);
1222
1223 if (!ChkArgCnt(2, 2));
1224 else
1225 {
1226 DecodeAdr(&ArgStr[1], MModMem);
1227 if (AdrMode == ModMem)
1228 {
1229 switch (MemPart)
1230 {
1231 case 1:
1232 if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1233 else
1234 {
1235 HReg = AdrPart; DecodeAdr(&ArgStr[2], MModMem);
1236 if (AdrMode == ModMem)
1237 {
1238 if (MemPart != 2) WrError(ErrNum_InvAddrMode);
1239 else
1240 {
1241 BAsmCode[CodeLen++] = 0xa7 + (OpSize << 3);
1242 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1243 }
1244 }
1245 }
1246 break;
1247 case 2:
1248 HReg = AdrPart; DecodeAdr(&ArgStr[2], MModReg);
1249 if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1250 else
1251 {
1252 BAsmCode[CodeLen++] = 0xa7 + (OpSize << 3);
1253 BAsmCode[CodeLen++] = 0x08 + (AdrPart << 4) + HReg;
1254 }
1255 break;
1256 default:
1257 WrError(ErrNum_InvAddrMode);
1258 }
1259 }
1260 }
1261 }
1262
DecodeXCH(Word Index)1263 static void DecodeXCH(Word Index)
1264 {
1265 Byte HReg, HPart, HVals[3];
1266 UNUSED(Index);
1267
1268 if (ChkArgCnt(2, 2))
1269 {
1270 DecodeAdr(&ArgStr[1], MModMem);
1271 if (AdrMode == ModMem)
1272 {
1273 switch (MemPart)
1274 {
1275 case 1:
1276 HReg = AdrPart; DecodeAdr(&ArgStr[2], MModMem);
1277 if (AdrMode == ModMem)
1278 {
1279 if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize8Bit)) WrError(ErrNum_InvOpSize);
1280 else switch (MemPart)
1281 {
1282 case 1:
1283 BAsmCode[CodeLen++] = 0x60 + (OpSize << 3);
1284 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1285 if (HReg == AdrPart) WrError(ErrNum_Unpredictable);
1286 break;
1287 case 2:
1288 BAsmCode[CodeLen++] = 0x50 + (OpSize << 3);
1289 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1290 break;
1291 case 6:
1292 BAsmCode[CodeLen++] = 0xa0 + (OpSize << 3);
1293 BAsmCode[CodeLen++] = 0x08 + (HReg << 4) + AdrPart;
1294 BAsmCode[CodeLen++] = AdrVals[0];
1295 break;
1296 default:
1297 WrError(ErrNum_InvAddrMode);
1298 }
1299 }
1300 break;
1301 case 2:
1302 HReg = AdrPart;
1303 DecodeAdr(&ArgStr[2], MModReg);
1304 if (AdrMode == ModReg)
1305 {
1306 if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1307 else
1308 {
1309 BAsmCode[CodeLen++] = 0x50 + (OpSize << 3);
1310 BAsmCode[CodeLen++] = (AdrPart << 4) + HReg;
1311 }
1312 }
1313 break;
1314 case 6:
1315 HPart = AdrPart; HVals[0] = AdrVals[0];
1316 DecodeAdr(&ArgStr[2], MModReg);
1317 if (AdrMode == ModReg)
1318 {
1319 if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1320 else
1321 {
1322 BAsmCode[CodeLen++] = 0xa0 + (OpSize << 3);
1323 BAsmCode[CodeLen++] = 0x08 + (AdrPart << 4) + HPart;
1324 BAsmCode[CodeLen++] = HVals[0];
1325 }
1326 }
1327 break;
1328 default:
1329 WrError(ErrNum_InvAddrMode);
1330 }
1331 }
1332 }
1333 }
1334
DecodeADDSMOVS(Word Index)1335 static void DecodeADDSMOVS(Word Index)
1336 {
1337 Byte HReg;
1338 tSymbolSize HSize;
1339
1340 if (ChkArgCnt(2, 2))
1341 {
1342 HSize = OpSize;
1343 OpSize = eSymbolSizeSigned4Bit;
1344 DecodeAdr(&ArgStr[2], MModImm);
1345 switch (AdrMode)
1346 {
1347 case ModImm:
1348 HReg = AdrVals[0]; OpSize = HSize;
1349 DecodeAdr(&ArgStr[1], MModMem);
1350 switch (AdrMode)
1351 {
1352 case ModMem:
1353 if (OpSize == eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
1354 else if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
1355 else
1356 {
1357 BAsmCode[CodeLen++] = 0xa0 + (Index << 4) + (OpSize << 3) + MemPart;
1358 BAsmCode[CodeLen++] = (AdrPart << 4) + (HReg & 0x0f);
1359 memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1360 CodeLen += AdrCnt;
1361 }
1362 break;
1363 }
1364 break;
1365 }
1366 }
1367 }
1368
DecodeDIV(Word Index)1369 static void DecodeDIV(Word Index)
1370 {
1371 Byte HReg;
1372 UNUSED(Index);
1373
1374 if (ChkArgCnt(2, 2))
1375 {
1376 DecodeAdr(&ArgStr[1], MModReg);
1377 if (AdrMode == ModReg)
1378 {
1379 if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
1380 else
1381 {
1382 HReg = AdrPart; OpSize--; DecodeAdr(&ArgStr[2], MModReg | MModImm);
1383 switch (AdrMode)
1384 {
1385 case ModReg:
1386 BAsmCode[CodeLen++] = 0xe7 + (OpSize << 3);
1387 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1388 break;
1389 case ModImm:
1390 BAsmCode[CodeLen++] = 0xe8 + OpSize;
1391 BAsmCode[CodeLen++] = (HReg << 4) + 0x0b - (OpSize << 1);
1392 memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1393 CodeLen += AdrCnt;
1394 break;
1395 }
1396 }
1397 }
1398 }
1399 }
1400
DecodeDIVU(Word Index)1401 static void DecodeDIVU(Word Index)
1402 {
1403 Byte HReg;
1404 int z;
1405 UNUSED(Index);
1406
1407 if (ChkArgCnt(2, 2))
1408 {
1409 DecodeAdr(&ArgStr[1], MModReg);
1410 if (AdrMode == ModReg)
1411 {
1412 if ((OpSize == eSymbolSize8Bit) && (AdrPart & 1)) WrError(ErrNum_InvReg);
1413 else
1414 {
1415 HReg = AdrPart; z = OpSize; if (OpSize != eSymbolSize8Bit) OpSize--;
1416 DecodeAdr(&ArgStr[2], MModReg | MModImm);
1417 switch (AdrMode)
1418 {
1419 case ModReg:
1420 BAsmCode[CodeLen++] = 0xe1 + (z << 2);
1421 if (z == 2) BAsmCode[CodeLen - 1] += 4;
1422 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1423 break;
1424 case ModImm:
1425 BAsmCode[CodeLen++] = 0xe8 + Ord(z == 2);
1426 BAsmCode[CodeLen++] = (HReg << 4) + 0x01 + (Ord(z == 1) << 1);
1427 memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1428 CodeLen += AdrCnt;
1429 break;
1430 }
1431 }
1432 }
1433 }
1434 }
1435
DecodeMUL(Word Index)1436 static void DecodeMUL(Word Index)
1437 {
1438 Byte HReg;
1439 UNUSED(Index);
1440
1441 if (ChkArgCnt(2, 2))
1442 {
1443 DecodeAdr(&ArgStr[1], MModReg);
1444 if (AdrMode == ModReg)
1445 {
1446 if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
1447 else if (AdrPart & 1) WrError(ErrNum_InvReg);
1448 else
1449 {
1450 HReg = AdrPart; DecodeAdr(&ArgStr[2], MModReg | MModImm);
1451 switch (AdrMode)
1452 {
1453 case ModReg:
1454 BAsmCode[CodeLen++] = 0xe6;
1455 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1456 break;
1457 case ModImm:
1458 BAsmCode[CodeLen++] = 0xe9;
1459 BAsmCode[CodeLen++] = (HReg << 4) + 0x08;
1460 memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1461 CodeLen += AdrCnt;
1462 break;
1463 }
1464 }
1465 }
1466 }
1467 }
1468
DecodeMULU(Word Index)1469 static void DecodeMULU(Word Index)
1470 {
1471 Byte HReg;
1472 UNUSED(Index);
1473
1474 if (ChkArgCnt(2, 2))
1475 {
1476 DecodeAdr(&ArgStr[1], MModReg);
1477 if (AdrMode == ModReg)
1478 {
1479 if (AdrPart & 1) WrError(ErrNum_InvReg);
1480 else
1481 {
1482 HReg = AdrPart;
1483 DecodeAdr(&ArgStr[2], MModReg | MModImm);
1484 switch (AdrMode)
1485 {
1486 case ModReg:
1487 BAsmCode[CodeLen++] = 0xe0 + (OpSize << 2);
1488 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1489 break;
1490 case ModImm:
1491 BAsmCode[CodeLen++] = 0xe8 + OpSize;
1492 BAsmCode[CodeLen++] = (HReg << 4);
1493 memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1494 CodeLen += AdrCnt;
1495 break;
1496 }
1497 }
1498 }
1499 }
1500 }
1501
DecodeLEA(Word Index)1502 static void DecodeLEA(Word Index)
1503 {
1504 Byte HReg;
1505 UNUSED(Index);
1506
1507 if (ChkArgCnt(2, 2))
1508 {
1509 DecodeAdr(&ArgStr[1], MModReg);
1510 if (AdrMode == ModReg)
1511 {
1512 if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
1513 else
1514 {
1515 HReg = AdrPart;
1516 DecodeAdrIndirect(&ArgStr[2], MModMem);
1517 if (AdrMode == ModMem)
1518 switch (MemPart)
1519 {
1520 case 4:
1521 case 5:
1522 BAsmCode[CodeLen++] = 0x20 + (MemPart << 3);
1523 BAsmCode[CodeLen++] = (HReg << 4) + AdrPart;
1524 memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1525 CodeLen += AdrCnt;
1526 break;
1527 default:
1528 WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
1529 }
1530 }
1531 }
1532 }
1533 }
1534
DecodeANLORL(Word Index)1535 static void DecodeANLORL(Word Index)
1536 {
1537 if (!ChkArgCnt(2, 2));
1538 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1539 else if (as_strcasecmp(ArgStr[1].Str, "C")) WrError(ErrNum_InvAddrMode);
1540 else
1541 {
1542 Byte Invert = 0;
1543 LongInt AdrLong;
1544 Boolean Result;
1545
1546 if (*ArgStr[2].Str == '/')
1547 {
1548 tStrComp Comp;
1549
1550 StrCompRefRight(&Comp, &ArgStr[2], 1);
1551 Result = DecodeBitAddr(&Comp, &AdrLong);
1552 Invert = 1;
1553 }
1554 else
1555 Result = DecodeBitAddr(&ArgStr[2], &AdrLong);
1556 if (Result)
1557 {
1558 ChkBitPage(AdrLong);
1559 BAsmCode[CodeLen++] = 0x08;
1560 BAsmCode[CodeLen++] = 0x40 | (Index << 5) | (Ord(Invert) << 4) | (Hi(AdrLong) & 3);
1561 BAsmCode[CodeLen++] = Lo(AdrLong);
1562 }
1563 }
1564 }
1565
DecodeCLRSETB(Word Index)1566 static void DecodeCLRSETB(Word Index)
1567 {
1568 LongInt AdrLong;
1569
1570 if (!ChkArgCnt(1, 1));
1571 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1572 else if (DecodeBitAddr(&ArgStr[1], &AdrLong))
1573 {
1574 ChkBitPage(AdrLong);
1575 BAsmCode[CodeLen++] = 0x08;
1576 BAsmCode[CodeLen++] = (Index << 4) + (Hi(AdrLong) & 3);
1577 BAsmCode[CodeLen++] = Lo(AdrLong);
1578 }
1579 }
1580
DecodeTRAP(Word Index)1581 static void DecodeTRAP(Word Index)
1582 {
1583 UNUSED(Index);
1584
1585 if (!ChkArgCnt(1, 1));
1586 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1587 else
1588 {
1589 OpSize = eSymbolSize4Bit;
1590 DecodeAdr(&ArgStr[1], MModImm);
1591 switch (AdrMode)
1592 {
1593 case ModImm:
1594 BAsmCode[CodeLen++] = 0xd6;
1595 BAsmCode[CodeLen++] = 0x30 + AdrVals[0];
1596 break;
1597 }
1598 }
1599 }
1600
DecodeCALL(Word Index)1601 static void DecodeCALL(Word Index)
1602 {
1603 UNUSED(Index);
1604
1605 if (!ChkArgCnt(1, 1));
1606 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1607 else if (*ArgStr[1].Str == '[')
1608 {
1609 DecodeAdr(&ArgStr[1], MModMem);
1610 if (AdrMode != ModNone)
1611 {
1612 if (MemPart != 2) WrError(ErrNum_InvAddrMode);
1613 else
1614 {
1615 BAsmCode[CodeLen++] = 0xc6;
1616 BAsmCode[CodeLen++] = AdrPart;
1617 }
1618 }
1619 }
1620 else
1621 {
1622 tEvalResult EvalResult;
1623 LongWord Dest = GetBranchDest(&ArgStr[1], &EvalResult);
1624
1625 if (EvalResult.OK)
1626 {
1627 LongInt Dist = Dest - MkEven24(EProgCounter() + CodeLen + 3);
1628
1629 if (ChkLongEvenDist(&Dist, &ArgStr[1], EvalResult.Flags))
1630 {
1631 BAsmCode[CodeLen++] = 0xc5;
1632 BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
1633 BAsmCode[CodeLen++] = Dist & 0xff;
1634 }
1635 }
1636 }
1637 }
1638
DecodeJMP(Word Index)1639 static void DecodeJMP(Word Index)
1640 {
1641 UNUSED(Index);
1642
1643 if (!ChkArgCnt(1, 1));
1644 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1645 else if (!as_strcasecmp(ArgStr[1].Str, "[A+DPTR]"))
1646 {
1647 BAsmCode[CodeLen++] = 0xd6;
1648 BAsmCode[CodeLen++] = 0x46;
1649 }
1650 else if (!strncmp(ArgStr[1].Str, "[[", 2))
1651 {
1652 tStrComp Comp;
1653
1654 ArgStr[1].Str[strlen(ArgStr[1].Str) - 1] = '\0';
1655 ArgStr[1].Pos.Len--;
1656 StrCompRefRight(&Comp, &ArgStr[1], 1);
1657 DecodeAdr(&Comp, MModMem);
1658 if (AdrMode == ModMem)
1659 switch (MemPart)
1660 {
1661 case 3:
1662 BAsmCode[CodeLen++] = 0xd6;
1663 BAsmCode[CodeLen++] = 0x60 + AdrPart;
1664 break;
1665 default:
1666 WrError(ErrNum_InvAddrMode);
1667 }
1668 }
1669 else if (*ArgStr[1].Str == '[')
1670 {
1671 DecodeAdr(&ArgStr[1], MModMem);
1672 if (AdrMode == ModMem)
1673 switch (MemPart)
1674 {
1675 case 2:
1676 BAsmCode[CodeLen++] = 0xd6;
1677 BAsmCode[CodeLen++] = 0x70 + AdrPart;
1678 break;
1679 default:
1680 WrError(ErrNum_InvAddrMode);
1681 }
1682 }
1683 else
1684 {
1685 tEvalResult EvalResult;
1686 LongWord Dest = GetBranchDest(&ArgStr[1], &EvalResult);
1687
1688 if (EvalResult.OK)
1689 {
1690 LongInt Dist = Dest - MkEven24(EProgCounter() + CodeLen + 3);
1691
1692 if (ChkLongEvenDist(&Dist, &ArgStr[1], EvalResult.Flags))
1693 {
1694 BAsmCode[CodeLen++] = 0xd5;
1695 BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
1696 BAsmCode[CodeLen++] = Dist & 0xff;
1697 }
1698 }
1699 }
1700 }
1701
DecodeCJNE(Word Index)1702 static void DecodeCJNE(Word Index)
1703 {
1704 Byte HReg;
1705 UNUSED(Index);
1706
1707 if (ChkArgCnt(3, 3))
1708 {
1709 tEvalResult EvalResult;
1710 LongWord Dest = GetBranchDest(&ArgStr[3], &EvalResult);
1711
1712 if (EvalResult.OK)
1713 {
1714 EvalResult.OK = False; HReg = 0;
1715 DecodeAdr(&ArgStr[1], MModMem);
1716 if (AdrMode == ModMem)
1717 {
1718 switch (MemPart)
1719 {
1720 case 1:
1721 if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1722 else
1723 {
1724 HReg = AdrPart; DecodeAdr(&ArgStr[2], MModMem | MModImm);
1725 switch (AdrMode)
1726 {
1727 case ModMem:
1728 if (MemPart != 6) WrError(ErrNum_InvAddrMode);
1729 else
1730 {
1731 BAsmCode[CodeLen] = 0xe2 + (OpSize << 3);
1732 BAsmCode[CodeLen + 1] = (HReg << 4) + AdrPart;
1733 BAsmCode[CodeLen + 2] = AdrVals[0];
1734 HReg=CodeLen + 3;
1735 CodeLen += 4; EvalResult.OK = True;
1736 }
1737 break;
1738 case ModImm:
1739 BAsmCode[CodeLen] = 0xe3 + (OpSize << 3);
1740 BAsmCode[CodeLen + 1] = HReg << 4;
1741 HReg=CodeLen + 2;
1742 memcpy(BAsmCode + CodeLen + 3, AdrVals, AdrCnt);
1743 CodeLen += 3 + AdrCnt; EvalResult.OK = True;
1744 break;
1745 }
1746 }
1747 break;
1748 case 2:
1749 if ((OpSize != eSymbolSizeUnknown) && (OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1750 else
1751 {
1752 HReg = AdrPart; DecodeAdr(&ArgStr[2], MModImm);
1753 if (AdrMode == ModImm)
1754 {
1755 BAsmCode[CodeLen] = 0xe3 + (OpSize << 3);
1756 BAsmCode[CodeLen + 1] = (HReg << 4)+8;
1757 HReg = CodeLen + 2;
1758 memcpy(BAsmCode + CodeLen + 3, AdrVals, AdrCnt);
1759 CodeLen += 3 + AdrCnt; EvalResult.OK = True;
1760 }
1761 }
1762 break;
1763 default:
1764 WrError(ErrNum_InvAddrMode);
1765 }
1766 }
1767 if (EvalResult.OK)
1768 {
1769 LongInt Dist = Dest - MkEven24(EProgCounter() + CodeLen);
1770
1771 EvalResult.OK = False;
1772 if (ChkShortEvenDist(&Dist, EvalResult.Flags))
1773 {
1774 BAsmCode[HReg] = Dist & 0xff;
1775 EvalResult.OK = True;
1776 }
1777 else if (!DoBranchExt) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[3]);
1778 else
1779 {
1780 LongWord odd = (EProgCounter() + CodeLen) & 1;
1781
1782 Dist = Dest - MkEven24(EProgCounter() + CodeLen + 5 + odd);
1783 if (ChkLongEvenDist(&Dist, &ArgStr[3], EvalResult.Flags))
1784 {
1785 BAsmCode[HReg] = 1 + odd;
1786 BAsmCode[CodeLen++] = 0xfe;
1787 BAsmCode[CodeLen++] = 2 + odd;
1788 if (odd) BAsmCode[CodeLen++] = 0;
1789 BAsmCode[CodeLen++] = 0xd5;
1790 BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
1791 BAsmCode[CodeLen++] = Dist & 0xff;
1792 BAsmCode[CodeLen++] = 0;
1793 EvalResult.OK = True;
1794 }
1795 }
1796 }
1797 if (!EvalResult.OK)
1798 CodeLen = 0;
1799 }
1800 }
1801 }
1802
DecodeDJNZ(Word Index)1803 static void DecodeDJNZ(Word Index)
1804 {
1805 Byte HReg;
1806 UNUSED(Index);
1807
1808 if (ChkArgCnt(2, 2))
1809 {
1810 tEvalResult EvalResult;
1811 LongInt Dest = GetBranchDest(&ArgStr[2], &EvalResult);
1812
1813 if (EvalResult.OK)
1814 {
1815 HReg = 0;
1816 DecodeAdr(&ArgStr[1], MModMem);
1817 EvalResult.OK = False; DecodeAdr(&ArgStr[1], MModMem);
1818 if (AdrMode == ModMem)
1819 switch (MemPart)
1820 {
1821 case 1:
1822 if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1823 else
1824 {
1825 BAsmCode[CodeLen] = 0x87 + (OpSize << 3);
1826 BAsmCode[CodeLen + 1] = (AdrPart << 4) + 0x08;
1827 HReg=CodeLen + 2;
1828 CodeLen += 3; EvalResult.OK = True;
1829 }
1830 break;
1831 case 6:
1832 if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
1833 else if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1834 else
1835 {
1836 BAsmCode[CodeLen] = 0xe2 + (OpSize << 3);
1837 BAsmCode[CodeLen+1] = 0x08 + AdrPart;
1838 BAsmCode[CodeLen+2] = AdrVals[0];
1839 HReg=CodeLen + 3;
1840 CodeLen += 4; EvalResult.OK = True;
1841 }
1842 break;
1843 default:
1844 WrError(ErrNum_InvAddrMode);
1845 }
1846 if (EvalResult.OK)
1847 {
1848 LongInt Dist = Dest - MkEven24(EProgCounter() + CodeLen);
1849
1850 EvalResult.OK = False;
1851 if (ChkShortEvenDist(&Dist, EvalResult.Flags))
1852 {
1853 BAsmCode[HReg] = Dist & 0xff;
1854 EvalResult.OK = True;
1855 }
1856 else if (!DoBranchExt) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[2]);
1857 else
1858 {
1859 LongWord odd = (EProgCounter() + CodeLen) & 1;
1860
1861 Dist = Dest - MkEven24(EProgCounter() + CodeLen + 5 + odd);
1862 if (ChkLongEvenDist(&Dist, &ArgStr[2], EvalResult.Flags))
1863 {
1864 BAsmCode[HReg] = 1 + odd;
1865 BAsmCode[CodeLen++] = 0xfe;
1866 BAsmCode[CodeLen++] = 2 + odd;
1867 if (odd) BAsmCode[CodeLen++] = 0;
1868 BAsmCode[CodeLen++] = 0xd5;
1869 BAsmCode[CodeLen++] = (Dist >> 8) & 0xff;
1870 BAsmCode[CodeLen++] = Dist & 0xff;
1871 BAsmCode[CodeLen++] = 0;
1872 EvalResult.OK = True;
1873 }
1874 }
1875 }
1876 if (!EvalResult.OK)
1877 CodeLen = 0;
1878 }
1879 }
1880 }
1881
DecodeFCALLJMP(Word Index)1882 static void DecodeFCALLJMP(Word Index)
1883 {
1884 if (!ChkArgCnt(1, 1));
1885 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1886 else
1887 {
1888 tEvalResult EvalResult;
1889 LongInt AdrLong = GetBranchDest(&ArgStr[1], &EvalResult);
1890 if (EvalResult.OK)
1891 {
1892 BAsmCode[CodeLen++] = 0xc4 | (Index << 4);
1893 BAsmCode[CodeLen++] = (AdrLong >> 8) & 0xff;
1894 BAsmCode[CodeLen++] = AdrLong & 0xff;
1895 BAsmCode[CodeLen++] = (AdrLong >> 16) & 0xff;
1896 }
1897 }
1898 }
1899
IsRealDef(void)1900 static Boolean IsRealDef(void)
1901 {
1902 switch (*OpPart.Str)
1903 {
1904 case 'P':
1905 return Memo("PORT");
1906 case 'B':
1907 return Memo("BIT");
1908 case 'R':
1909 return Memo("REG");
1910 default:
1911 return FALSE;
1912 }
1913 }
1914
ForceAlign(void)1915 static void ForceAlign(void)
1916 {
1917 if (EProgCounter() & 1)
1918 {
1919 BAsmCode[0] = NOPCode; CodeLen = 1;
1920 }
1921 }
1922
DecodeAttrPart_XA(void)1923 static Boolean DecodeAttrPart_XA(void)
1924 {
1925 if (*AttrPart.Str)
1926 switch (as_toupper(*AttrPart.Str))
1927 {
1928 case 'B': AttrPartOpSize = eSymbolSize8Bit; break;
1929 case 'W': AttrPartOpSize = eSymbolSize16Bit; break;
1930 case 'D': AttrPartOpSize = eSymbolSize32Bit; break;
1931 default : WrStrErrorPos(ErrNum_UndefAttr, &AttrPart); return False;
1932 }
1933 return True;
1934 }
1935
MakeCode_XA(void)1936 static void MakeCode_XA(void)
1937 {
1938 CodeLen = 0; DontPrint = False; OpSize = eSymbolSizeUnknown;
1939
1940 /* Operandengroesse */
1941
1942 if (*AttrPart.Str)
1943 SetOpSize(AttrPartOpSize);
1944
1945 /* Labels muessen auf geraden Adressen liegen */
1946
1947 if ( (ActPC == SegCode) && (!IsRealDef()) &&
1948 ((*LabPart.Str != '\0') ||((ArgCnt == 1) && (!strcmp(ArgStr[1].Str, "$")))) )
1949 {
1950 ForceAlign();
1951 if (*LabPart.Str != '\0')
1952 EnterIntSymbol(&LabPart, EProgCounter() + CodeLen, ActPC, False);
1953 }
1954
1955 if (DecodeMoto16Pseudo(OpSize, False)) return;
1956 if (DecodeIntelPseudo(False)) return;
1957
1958 /* zu ignorierendes */
1959
1960 if (Memo("")) return;
1961
1962 /* via Tabelle suchen */
1963
1964 if (!LookupInstTable(InstTable, OpPart.Str))
1965 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
1966 }
1967
1968 /*-------------------------------------------------------------------------*/
1969 /* Codetabellenverwaltung */
1970
AddFixed(const char * NName,Word NCode)1971 static void AddFixed(const char *NName, Word NCode)
1972 {
1973 AddInstTable(InstTable, NName, NCode, DecodeFixed);
1974 }
1975
AddJBit(const char * NName,Word NCode)1976 static void AddJBit(const char *NName, Word NCode)
1977 {
1978 if (InstrZ >= JBitOrderCnt) exit(255);
1979 JBitOrders[InstrZ].Name = NName;
1980 JBitOrders[InstrZ].Inversion = 255;
1981 JBitOrders[InstrZ].Code = NCode;
1982 AddInstTable(InstTable, NName, InstrZ++, DecodeJBit);
1983 }
1984
AddStack(const char * NName,Word NCode)1985 static void AddStack(const char *NName, Word NCode)
1986 {
1987 AddInstTable(InstTable, NName, NCode, DecodeStack);
1988 }
1989
AddReg(const char * NName,Byte NMask,Byte NCode)1990 static void AddReg(const char *NName, Byte NMask, Byte NCode)
1991 {
1992 if (InstrZ >= RegOrderCnt) exit(255);
1993 RegOrders[InstrZ].Code = NCode;
1994 RegOrders[InstrZ].SizeMask = NMask;
1995 AddInstTable(InstTable, NName, InstrZ++, DecodeRegO);
1996 }
1997
AddRotate(const char * NName,Word NCode)1998 static void AddRotate(const char *NName, Word NCode)
1999 {
2000 AddInstTable(InstTable, NName, NCode, DecodeRotate);
2001 }
2002
AddRel(const char * NName,Word NCode)2003 static void AddRel(const char *NName, Word NCode)
2004 {
2005 if (InstrZ >= RelOrderCount) exit(255);
2006 RelOrders[InstrZ].Name = NName;
2007 RelOrders[InstrZ].Inversion = 255;
2008 RelOrders[InstrZ].Code = NCode;
2009 AddInstTable(InstTable, NName, InstrZ++, DecodeRel);
2010 }
2011
SetInv(const char * Name1,const char * Name2,InvOrder * Orders)2012 static void SetInv(const char *Name1, const char *Name2, InvOrder *Orders)
2013 {
2014 InvOrder *Order1, *Order2;
2015
2016 for (Order1 = Orders; strcmp(Order1->Name, Name1); Order1++);
2017 for (Order2 = Orders; strcmp(Order2->Name, Name2); Order2++);
2018 Order1->Inversion = Order2 - Orders;
2019 Order2->Inversion = Order1 - Orders;
2020 }
2021
InitFields(void)2022 static void InitFields(void)
2023 {
2024 InstTable = CreateInstTable(201);
2025 AddInstTable(InstTable, "MOV" , 0, DecodeMOV);
2026 AddInstTable(InstTable, "MOVC" , 0, DecodeMOVC);
2027 AddInstTable(InstTable, "MOVX" , 0, DecodeMOVX);
2028 AddInstTable(InstTable, "XCH" , 0, DecodeXCH);
2029 AddInstTable(InstTable, "ADDS" , 0, DecodeADDSMOVS);
2030 AddInstTable(InstTable, "MOVS" , 1, DecodeADDSMOVS);
2031 AddInstTable(InstTable, "DIV" , 0, DecodeDIV);
2032 AddInstTable(InstTable, "DIVU" , 0, DecodeDIVU);
2033 AddInstTable(InstTable, "MUL" , 0, DecodeMUL);
2034 AddInstTable(InstTable, "MULU" , 0, DecodeMULU);
2035 AddInstTable(InstTable, "LEA" , 0, DecodeLEA);
2036 AddInstTable(InstTable, "ANL" , 0, DecodeANLORL);
2037 AddInstTable(InstTable, "ORL" , 1, DecodeANLORL);
2038 AddInstTable(InstTable, "CLR" , 0, DecodeCLRSETB);
2039 AddInstTable(InstTable, "SETB" , 1, DecodeCLRSETB);
2040 AddInstTable(InstTable, "TRAP" , 0, DecodeTRAP);
2041 AddInstTable(InstTable, "CALL" , 0, DecodeCALL);
2042 AddInstTable(InstTable, "JMP" , 0, DecodeJMP);
2043 AddInstTable(InstTable, "CJNE" , 0, DecodeCJNE);
2044 AddInstTable(InstTable, "DJNZ" , 0, DecodeDJNZ);
2045 AddInstTable(InstTable, "FCALL", 0, DecodeFCALLJMP);
2046 AddInstTable(InstTable, "FJMP" , 1, DecodeFCALLJMP);
2047 AddInstTable(InstTable, "PORT" , 0, DecodePORT);
2048 AddInstTable(InstTable, "BIT" , 0, DecodeBIT);
2049 AddInstTable(InstTable, "REG" , 0, CodeREG);
2050
2051 AddFixed("NOP" , 0x0000);
2052 AddFixed("RET" , 0xd680);
2053 AddFixed("RETI" , RETICode);
2054 AddFixed("BKPT" , 0x00ff);
2055 AddFixed("RESET", 0xd610);
2056
2057 JBitOrders = (InvOrder *) malloc(sizeof(InvOrder) * JBitOrderCnt); InstrZ = 0;
2058 AddJBit("JB" , 0x80);
2059 AddJBit("JBC" , 0xc0);
2060 AddJBit("JNB" , 0xa0);
2061 SetInv("JB", "JNB", JBitOrders);
2062
2063 AddStack("POP" , 0x1027);
2064 AddStack("POPU" , 0x0037);
2065 AddStack("PUSH" , 0x3007);
2066 AddStack("PUSHU", 0x2017);
2067
2068 InstrZ = 0;
2069 AddInstTable(InstTable, "ADD" , InstrZ++, DecodeALU);
2070 AddInstTable(InstTable, "ADDC", InstrZ++, DecodeALU);
2071 AddInstTable(InstTable, "SUB" , InstrZ++, DecodeALU);
2072 AddInstTable(InstTable, "SUBB", InstrZ++, DecodeALU);
2073 AddInstTable(InstTable, "CMP" , InstrZ++, DecodeALU);
2074 AddInstTable(InstTable, "AND" , InstrZ++, DecodeALU);
2075 AddInstTable(InstTable, "OR" , InstrZ++, DecodeALU);
2076 AddInstTable(InstTable, "XOR" , InstrZ++, DecodeALU);
2077
2078 RegOrders = (RegOrder *) malloc(sizeof(RegOrder) * RegOrderCnt); InstrZ = 0;
2079 AddReg("NEG" , 3, 0x0b);
2080 AddReg("CPL" , 3, 0x0a);
2081 AddReg("SEXT", 3, 0x09);
2082 AddReg("DA" , 1, 0x08);
2083
2084 AddInstTable(InstTable, "LSR" , 0, DecodeShift);
2085 AddInstTable(InstTable, "ASL" , 1, DecodeShift);
2086 AddInstTable(InstTable, "ASR" , 2, DecodeShift);
2087 AddInstTable(InstTable, "NORM", 3, DecodeShift);
2088
2089 AddRotate("RR" , 0xb0); AddRotate("RL" , 0xd3);
2090 AddRotate("RRC", 0xb7); AddRotate("RLC", 0xd7);
2091
2092 RelOrders = (InvOrder *) malloc(sizeof(InvOrder) * RelOrderCount); InstrZ = 0;
2093 AddRel("BCC", 0xf0); AddRel("BCS", 0xf1); AddRel("BNE", 0xf2);
2094 AddRel("BEQ", 0xf3); AddRel("BNV", 0xf4); AddRel("BOV", 0xf5);
2095 AddRel("BPL", 0xf6); AddRel("BMI", 0xf7); AddRel("BG" , 0xf8);
2096 AddRel("BL" , 0xf9); AddRel("BGE", 0xfa); AddRel("BLT", 0xfb);
2097 AddRel("BGT", 0xfc); AddRel("BLE", 0xfd); AddRel("BR" , 0xfe);
2098 AddRel("JZ" , 0xec); AddRel("JNZ", 0xee);
2099 SetInv("BCC", "BCS", RelOrders);
2100 SetInv("BNE", "BEQ", RelOrders);
2101 SetInv("BNV", "BOV", RelOrders);
2102 SetInv("BPL", "BMI", RelOrders);
2103 SetInv("BG" , "BL" , RelOrders);
2104 SetInv("BGE", "BLT", RelOrders);
2105 SetInv("BGT", "BLE", RelOrders);
2106 SetInv("JZ" , "JNZ", RelOrders);
2107 }
2108
DeinitFields(void)2109 static void DeinitFields(void)
2110 {
2111 free(JBitOrders);
2112 free(RegOrders);
2113 free(RelOrders);
2114
2115 DestroyInstTable(InstTable);
2116 }
2117
2118 /*-------------------------------------------------------------------------*/
2119 /* Callbacks */
2120
2121 /*!------------------------------------------------------------------------
2122 * \fn InternSymbol_XA(char *pArg, TempResult *pResult)
2123 * \brief handle built-in symbols on XA
2124 * \param pArg source argument
2125 * \param pResult result buffer
2126 * ------------------------------------------------------------------------ */
2127
InternSymbol_XA(char * pArg,TempResult * pResult)2128 static void InternSymbol_XA(char *pArg, TempResult *pResult)
2129 {
2130 Byte Reg;
2131 tSymbolSize Size;
2132
2133 if (*AttrPart.Str)
2134 OpSize = AttrPartOpSize;
2135
2136 if (DecodeRegCore(pArg, &Size, &Reg))
2137 {
2138 pResult->Typ = TempReg;
2139 pResult->DataSize = Size;
2140 pResult->Contents.RegDescr.Reg = Reg;
2141 pResult->Contents.RegDescr.Dissect = DissectReg_XA;
2142 }
2143 }
2144
InitCode_XA(void)2145 static void InitCode_XA(void)
2146 {
2147 Reg_DS = 0;
2148 }
2149
ChkPC_XA(LargeWord Addr)2150 static Boolean ChkPC_XA(LargeWord Addr)
2151 {
2152 switch (ActPC)
2153 {
2154 case SegCode:
2155 case SegData:
2156 return (Addr<0x1000000);
2157 case SegIO:
2158 return ((Addr > 0x3ff) && (Addr < 0x800));
2159 default:
2160 return False;
2161 }
2162 }
2163
IsDef_XA(void)2164 static Boolean IsDef_XA(void)
2165 {
2166 return (ActPC == SegCode) || IsRealDef();
2167 }
2168
SwitchFrom_XA(void)2169 static void SwitchFrom_XA(void)
2170 {
2171 DeinitFields(); ClearONOFF();
2172 }
2173
SwitchTo_XA(void)2174 static void SwitchTo_XA(void)
2175 {
2176 TurnWords = False; ConstMode = ConstModeIntel;
2177
2178 PCSymbol = "$"; HeaderID = 0x3c; NOPCode = 0x00;
2179 DivideChars = ","; HasAttrs = True; AttrChars = ".";
2180
2181 ValidSegs =(1 << SegCode) | (1 << SegData) | (1 << SegIO);
2182 Grans[SegCode ] = 1; ListGrans[SegCode ] = 1; SegInits[SegCode ] = 0;
2183 Grans[SegData ] = 1; ListGrans[SegData ] = 1; SegInits[SegData ] = 0;
2184 Grans[SegIO ] = 1; ListGrans[SegIO ] = 1; SegInits[SegIO ] = 0x400;
2185
2186 DecodeAttrPart = DecodeAttrPart_XA;
2187 MakeCode = MakeCode_XA;
2188 ChkPC = ChkPC_XA;
2189 IsDef = IsDef_XA;
2190 InternSymbol = InternSymbol_XA;
2191 DissectReg = DissectReg_XA;
2192 SwitchFrom = SwitchFrom_XA; InitFields();
2193 AddONOFF("SUPMODE", &SupAllowed, SupAllowedName, False);
2194 AddONOFF("BRANCHEXT", &DoBranchExt, BranchExtName , False);
2195 AddMoto16PseudoONOFF();
2196
2197 pASSUMERecs = ASSUMEXAs;
2198 ASSUMERecCnt = ASSUMEXACount;
2199
2200 SetFlag(&DoPadding, DoPaddingName, False);
2201 }
2202
codexa_init(void)2203 void codexa_init(void)
2204 {
2205 CPUXAG1 = AddCPU("XAG1", SwitchTo_XA);
2206 CPUXAG2 = AddCPU("XAG2", SwitchTo_XA);
2207 CPUXAG3 = AddCPU("XAG3", SwitchTo_XA);
2208
2209 AddInitPassProc(InitCode_XA);
2210 }
2211