1 /* code96c141.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* Codegenerator TLCS-900(L) */
8 /* */
9 /* Historie: 27. 6.1996 Grundsteinlegung */
10 /* */
11 /*****************************************************************************/
12
13 #include "stdinc.h"
14 #include <string.h>
15 #include <ctype.h>
16
17 #include "nls.h"
18 #include "bpemu.h"
19 #include "strutil.h"
20
21 #include "asmdef.h"
22 #include "asmsub.h"
23 #include "asmpars.h"
24 #include "asmallg.h"
25 #include "errmsg.h"
26 #include "codepseudo.h"
27 #include "intpseudo.h"
28 #include "asmitree.h"
29 #include "codevars.h"
30 #include "errmsg.h"
31
32 #include "code96c141.h"
33
34 /*-------------------------------------------------------------------------*/
35 /* Daten */
36
37 typedef struct
38 {
39 Word Code;
40 Byte CPUFlag;
41 Boolean InSup;
42 } FixedOrder;
43
44 typedef struct
45 {
46 Word Code;
47 Boolean InSup;
48 Byte MinMax,MaxMax;
49 ShortInt Default;
50 } ImmOrder;
51
52 typedef struct
53 {
54 Word Code;
55 Byte OpMask;
56 } RegOrder;
57
58 typedef struct
59 {
60 const char *Name;
61 Byte Code;
62 } Condition;
63
64 #define FixedOrderCnt 13
65 #define ImmOrderCnt 3
66 #define RegOrderCnt 8
67 #define ConditionCnt 24
68
69 #define ModNone (-1)
70 #define ModReg 0
71 #define MModReg (1 << ModReg)
72 #define ModXReg 1
73 #define MModXReg (1 << ModXReg)
74 #define ModMem 2
75 #define MModMem (1 << ModMem)
76 #define ModImm 3
77 #define MModImm (1 << ModImm)
78 #define ModCReg 4
79 #define MModCReg (1 << ModCReg)
80
81 static FixedOrder *FixedOrders;
82 static RegOrder *RegOrders;
83 static ImmOrder *ImmOrders;
84 static Condition *Conditions;
85 static LongInt DefaultCondition;
86
87 static ShortInt AdrType;
88 static ShortInt OpSize; /* -1/0/1/2 = nix/Byte/Word/Long */
89 static Byte AdrMode;
90 static Byte AdrVals[10];
91 static Boolean MinOneIs0, AutoIncSizeNeeded;
92
93 static CPUVar CPU96C141,CPU93C141;
94
95 /*---------------------------------------------------------------------------*/
96 /* Adressparser */
97
IsRegBase(Byte No,Byte Size)98 static Boolean IsRegBase(Byte No, Byte Size)
99 {
100 return ((Size == 2)
101 || ((Size == 1) && (No < 0xf0) && (!Maximum) && ((No & 3) == 0)));
102 }
103
ChkMaximum(Boolean MustMax,Byte * Result)104 static void ChkMaximum(Boolean MustMax, Byte *Result)
105 {
106 if (Maximum != MustMax)
107 {
108 *Result = 1;
109 WrError((MustMax) ? ErrNum_OnlyInMaxmode : ErrNum_NotInMaxmode);
110 }
111 }
112
IsQuot(char Ch)113 static Boolean IsQuot(char Ch)
114 {
115 return ((Ch == '\'') || (Ch == '`'));
116 }
117
CodeEReg(char * Asc,Byte * ErgNo,Byte * ErgSize)118 static Byte CodeEReg(char *Asc, Byte *ErgNo, Byte *ErgSize)
119 {
120 #define RegCnt 8
121 static const char Reg8Names[RegCnt + 1] = "AWCBEDLH";
122 static const char Reg16Names[RegCnt][3] =
123 {
124 "WA" ,"BC" ,"DE" ,"HL" ,"IX" ,"IY" ,"IZ" ,"SP"
125 };
126 static const char Reg32Names[RegCnt][4] =
127 {
128 "XWA","XBC","XDE","XHL","XIX","XIY","XIZ","XSP"
129 };
130
131 int z, l = strlen(Asc);
132 const char *pos;
133 String HAsc, Asc_N;
134 Byte Result;
135
136 strmaxcpy(Asc_N, Asc, STRINGSIZE);
137 NLS_UpString(Asc_N);
138 Asc = Asc_N;
139
140 Result = 2;
141
142 /* mom. Bank ? */
143
144 if (l == 1)
145 {
146 pos = strchr(Reg8Names, *Asc);
147 if (pos)
148 {
149 z = pos - Reg8Names;
150 *ErgNo = 0xe0 + ((z & 6) << 1) + (z & 1);
151 *ErgSize = 0;
152 return Result;
153 }
154 }
155 for (z = 0; z < RegCnt; z++)
156 {
157 if (!strcmp(Asc, Reg16Names[z]))
158 {
159 *ErgNo = 0xe0 + (z << 2);
160 *ErgSize = 1;
161 return Result;
162 }
163 if (!strcmp(Asc, Reg32Names[z]))
164 {
165 *ErgNo = 0xe0 + (z << 2);
166 *ErgSize = 2;
167 if (z < 4)
168 ChkMaximum(True, &Result);
169 return Result;
170 }
171 }
172
173 /* Bankregister, 8 Bit ? */
174
175 if ((l == 3) && ((*Asc == 'Q') || (*Asc == 'R')) && ((Asc[2] >= '0') && (Asc[2] <= '7')))
176 {
177 for (z = 0; z < RegCnt; z++)
178 if (Asc[1] == Reg8Names[z])
179 {
180 *ErgNo = ((Asc[2] - '0') << 4) + ((z & 6) << 1) + (z & 1);
181 if (*Asc == 'Q')
182 {
183 *ErgNo |= 2;
184 ChkMaximum(True, &Result);
185 }
186 if (((*Asc == 'Q') || (Maximum)) && (Asc[2] > '3'))
187 {
188 WrError(ErrNum_OverRange);
189 Result = 1;
190 }
191 *ErgSize = 0;
192 return Result;
193 }
194 }
195
196 /* Bankregister, 16 Bit ? */
197
198 if ((l == 4) && ((*Asc == 'Q') || (*Asc == 'R')) && ((Asc[3] >= '0') && (Asc[3] <= '7')))
199 {
200 strcpy(HAsc, Asc + 1);
201 HAsc[2] = '\0';
202 for (z = 0; z < RegCnt >> 1; z++)
203 if (!strcmp(HAsc, Reg16Names[z]))
204 {
205 *ErgNo = ((Asc[3] - '0') << 4) + (z << 2);
206 if (*Asc == 'Q')
207 {
208 *ErgNo |= 2;
209 ChkMaximum(True, &Result);
210 }
211 if (((*Asc == 'Q') || (Maximum)) && (Asc[3] > '3'))
212 {
213 WrError(ErrNum_OverRange);
214 Result = 1;
215 }
216 *ErgSize = 1;
217 return Result;
218 }
219 }
220
221 /* Bankregister, 32 Bit ? */
222
223 if ((l == 4) && ((Asc[3] >= '0') && (Asc[3] <= '7')))
224 {
225 for (z = 0; z < RegCnt >> 1; z++)
226 if (strncmp(Asc, Reg32Names[z], 3) == 0)
227 {
228 *ErgNo = ((Asc[3] - '0') << 4) + (z << 2);
229 ChkMaximum(True, &Result);
230 if (Asc[3] > '3')
231 {
232 WrError(ErrNum_OverRange); Result = 1;
233 }
234 *ErgSize = 2;
235 return Result;
236 }
237 }
238
239 /* obere 8-Bit-Haelften momentaner Bank ? */
240
241 if ((l == 2) && (*Asc == 'Q'))
242 for (z = 0; z < RegCnt; z++)
243 if (Asc[1] == Reg8Names[z])
244 {
245 *ErgNo = 0xe2 + ((z & 6) << 1) + (z & 1);
246 ChkMaximum(True, &Result);
247 *ErgSize = 0;
248 return Result;
249 }
250
251 /* obere 16-Bit-Haelften momentaner Bank und von XIX..XSP ? */
252
253 if ((l == 3) && (*Asc == 'Q'))
254 {
255 for (z = 0; z < RegCnt; z++)
256 if (!strcmp(Asc + 1, Reg16Names[z]))
257 {
258 *ErgNo = 0xe2 + (z << 2);
259 if (z < 4) ChkMaximum(True, &Result);
260 *ErgSize = 1;
261 return Result;
262 }
263 }
264
265 /* 8-Bit-Teile von XIX..XSP ? */
266
267 if (((l == 3) || ((l == 4) && (*Asc == 'Q')))
268 && ((Asc[l - 1] == 'L') || (Asc[l - 1] == 'H')))
269 {
270 strcpy(HAsc, Asc + (l - 3)); HAsc[2] = '\0';
271 for (z = 0; z < RegCnt >> 1; z++)
272 if (!strcmp(HAsc, Reg16Names[z + 4]))
273 {
274 *ErgNo = 0xf0 + (z << 2) + ((l - 3) << 1) + (Ord(Asc[l - 1] == 'H'));
275 *ErgSize = 0;
276 return Result;
277 }
278 }
279
280 /* 8-Bit-Teile vorheriger Bank ? */
281
282 if (((l == 2) || ((l == 3) && (*Asc == 'Q'))) && (IsQuot(Asc[l - 1])))
283 for (z = 0; z < RegCnt; z++)
284 if (Asc[l - 2] == Reg8Names[z])
285 {
286 *ErgNo = 0xd0 + ((z & 6) << 1) + ((strlen(Asc) - 2) << 1) + (z & 1);
287 if (l == 3) ChkMaximum(True, &Result);
288 *ErgSize = 0;
289 return Result;
290 }
291
292 /* 16-Bit-Teile vorheriger Bank ? */
293
294 if (((l == 3) || ((l == 4) && (*Asc == 'Q'))) && (IsQuot(Asc[l - 1])))
295 {
296 strcpy(HAsc, Asc + 1);
297 HAsc[l - 2] = '\0';
298 for (z = 0; z < RegCnt >> 1; z++)
299 if (!strcmp(HAsc, Reg16Names[z]))
300 {
301 *ErgNo = 0xd0 + (z << 2) + ((strlen(Asc) - 3) << 1);
302 if (l == 4) ChkMaximum(True, &Result);
303 *ErgSize = 1;
304 return Result;
305 }
306 }
307
308 /* 32-Bit-Register vorheriger Bank ? */
309
310 if ((l == 4) && (IsQuot(Asc[3])))
311 {
312 strcpy(HAsc, Asc); HAsc[3] = '\0';
313 for (z = 0; z < RegCnt >> 1; z++)
314 if (!strcmp(HAsc, Reg32Names[z]))
315 {
316 *ErgNo = 0xd0 + (z << 2);
317 ChkMaximum(True, &Result);
318 *ErgSize = 2;
319 return Result;
320 }
321 }
322
323 return (Result = 0);
324 }
325
ChkL(CPUVar Must,Byte * Result)326 static void ChkL(CPUVar Must, Byte *Result)
327 {
328 if (MomCPU != Must)
329 {
330 WrError(ErrNum_InvCtrlReg);
331 *Result = 0;
332 }
333 }
334
CodeCReg(char * Asc,Byte * ErgNo,Byte * ErgSize)335 static Byte CodeCReg(char *Asc, Byte *ErgNo, Byte *ErgSize)
336 {
337 Byte Result = 2;
338
339 if (!as_strcasecmp(Asc, "NSP"))
340 {
341 *ErgNo = 0x3c;
342 *ErgSize = 1;
343 ChkL(CPU96C141, &Result);
344 return Result;
345 }
346 if (!as_strcasecmp(Asc, "XNSP"))
347 {
348 *ErgNo = 0x3c;
349 *ErgSize = 2;
350 ChkL(CPU96C141, &Result);
351 return Result;
352 }
353 if (!as_strcasecmp(Asc,"INTNEST"))
354 {
355 *ErgNo = 0x3c;
356 *ErgSize = 1;
357 ChkL(CPU93C141, &Result);
358 return Result;
359 }
360 if ((strlen(Asc) == 5)
361 && (!as_strncasecmp(Asc, "DMA", 3))
362 && (Asc[4] >= '0') && (Asc[4] <= '3'))
363 {
364 switch (as_toupper(Asc[3]))
365 {
366 case 'S':
367 *ErgNo = (Asc[4] - '0') * 4;
368 *ErgSize = 2;
369 return Result;
370 case 'D':
371 *ErgNo = (Asc[4] - '0') * 4 + 0x10;
372 *ErgSize = 2;
373 return Result;
374 case 'M':
375 *ErgNo = (Asc[4] - '0') * 4 + 0x22;
376 *ErgSize = 0;
377 return Result;
378 case 'C':
379 *ErgNo = (Asc[4] - '0') * 4 + 0x20;
380 *ErgSize = 1;
381 return Result;
382 }
383 }
384
385 return (Result = 0);
386 }
387
388
389 typedef struct
390 {
391 char *Name;
392 Byte Num;
393 Boolean InMax, InMin;
394 } RegDesc;
395
396
SetOpSize(ShortInt NewSize)397 static void SetOpSize(ShortInt NewSize)
398 {
399 if (OpSize == -1)
400 OpSize = NewSize;
401 else if (OpSize != NewSize)
402 {
403 WrError(ErrNum_ConfOpSizes);
404 AdrType = ModNone;
405 }
406 }
407
IsRegCurrent(Byte No,Byte Size,Byte * Erg)408 static Boolean IsRegCurrent(Byte No, Byte Size, Byte *Erg)
409 {
410 switch (Size)
411 {
412 case 0:
413 if ((No & 0xf2) == 0xe0)
414 {
415 *Erg = ((No & 0x0c) >> 1) + ((No & 1) ^ 1);
416 return True;
417 }
418 else
419 return False;
420 case 1:
421 case 2:
422 if ((No & 0xe3) == 0xe0)
423 {
424 *Erg = ((No & 0x1c) >> 2);
425 return True;
426 }
427 else
428 return False;
429 default:
430 return False;
431 }
432 }
433
434 static const char Sizes[] = "124";
435
GetPostInc(const char * pArg,int ArgLen,ShortInt * pOpSize)436 static int GetPostInc(const char *pArg, int ArgLen, ShortInt *pOpSize)
437 {
438 const char *pPos;
439
440 /* <reg>+ */
441
442 if ((ArgLen > 2) && (pArg[ArgLen - 1] == '+'))
443 {
444 *pOpSize = eSymbolSizeUnknown;
445 return 1;
446 }
447
448 /* <reg>++n, <reg>+:n */
449
450 if ((ArgLen > 4) && (pArg[ArgLen - 3] == '+') && strchr(":+", pArg[ArgLen - 2]))
451 {
452 pPos = strchr(Sizes, pArg[ArgLen - 1]);
453 if (pPos)
454 {
455 *pOpSize = pPos - Sizes;
456 return 3;
457 }
458 }
459 return False;
460 }
461
GetPreDec(const char * pArg,int ArgLen,ShortInt * pOpSize,int * pCutoffLeft,int * pCutoffRight)462 static Boolean GetPreDec(const char *pArg, int ArgLen, ShortInt *pOpSize, int *pCutoffLeft, int *pCutoffRight)
463 {
464 const char *pPos;
465
466 /* n--<reg> */
467
468 if ((ArgLen > 4) && (pArg[1] == '-') && (pArg[2] == '-'))
469 {
470 pPos = strchr(Sizes, pArg[0]);
471 if (pPos)
472 {
473 *pOpSize = pPos - Sizes;
474 *pCutoffLeft = 3;
475 *pCutoffRight = 0;
476 return True;
477 }
478 }
479
480 if ((ArgLen > 2) && (pArg[0] == '-'))
481 {
482 *pCutoffLeft = 1;
483
484 /* -<reg>:n */
485
486 if ((ArgLen > 4) && (pArg[ArgLen - 2] == ':'))
487 {
488 pPos = strchr(Sizes, pArg[ArgLen - 1]);
489 if (pPos)
490 {
491 *pOpSize = pPos - Sizes;
492 *pCutoffRight = 2;
493 return True;
494 }
495 }
496
497 /* -<reg> */
498
499 else
500 {
501 *pOpSize = eSymbolSizeUnknown;
502 *pCutoffRight = 0;
503 return True;
504 }
505 }
506 return False;
507 }
508
ChkAdr(Byte Erl)509 static void ChkAdr(Byte Erl)
510 {
511 if (AdrType != ModNone)
512 if (!(Erl & (1 << AdrType)))
513 {
514 WrError(ErrNum_InvAddrMode);
515 AdrType = ModNone;
516 }
517 }
518
SplitSize(tStrComp * pArg)519 static tSymbolSize SplitSize(tStrComp *pArg)
520 {
521 int l = strlen(pArg->Str);
522
523 if ((l >= 3) && !strcmp(pArg->Str + l - 2, ":8"))
524 {
525 StrCompShorten(pArg, 2);
526 return eSymbolSize8Bit;
527 }
528 if ((l >= 4) && !strcmp(pArg->Str + l - 3, ":16"))
529 {
530 StrCompShorten(pArg, 3);
531 return eSymbolSize16Bit;
532 }
533 if ((l >= 4) && !strcmp(pArg->Str + l - 3, ":24"))
534 {
535 StrCompShorten(pArg, 3);
536 return eSymbolSize24Bit;
537 }
538 return eSymbolSizeUnknown;
539 }
540
DecodeAdrMem(const tStrComp * pArg)541 static void DecodeAdrMem(const tStrComp *pArg)
542 {
543 LongInt DispPart, DispAcc;
544 char *EPos;
545 tStrComp Arg, Remainder;
546 Boolean NegFlag, NNegFlag, FirstFlag, OK;
547 Byte BaseReg, BaseSize;
548 Byte IndReg, IndSize;
549 Byte PartMask;
550 Byte HNum, HSize;
551 int CutoffLeft, CutoffRight, ArgLen = strlen(pArg->Str);
552 ShortInt IncOpSize;
553 tSymbolSize DispSize;
554
555 NegFlag = False;
556 NNegFlag = False;
557 FirstFlag = False;
558 PartMask = 0;
559 DispAcc = 0;
560 BaseReg = IndReg = BaseSize = IndSize = 0xff;
561
562 AdrType = ModNone;
563 AutoIncSizeNeeded = False;
564
565 /* post-increment */
566
567 if ((ArgLen > 2)
568 && (CutoffRight = GetPostInc(pArg->Str, ArgLen, &IncOpSize)))
569 {
570 String Reg;
571 tStrComp RegComp;
572
573 StrCompMkTemp(&RegComp, Reg);
574 StrCompCopy(&RegComp, pArg);
575 StrCompShorten(&RegComp, CutoffRight);
576 if (CodeEReg(RegComp.Str, &HNum, &HSize) == 2)
577 {
578 if (!IsRegBase(HNum, HSize)) WrStrErrorPos(ErrNum_InvAddrMode, &RegComp);
579 else
580 {
581 if (IncOpSize == eSymbolSizeUnknown)
582 IncOpSize = OpSize;
583 AdrType = ModMem;
584 AdrMode = 0x45;
585 AdrCnt = 1;
586 AdrVals[0] = HNum;
587 if (IncOpSize == eSymbolSizeUnknown)
588 AutoIncSizeNeeded = True;
589 else
590 AdrVals[0] += IncOpSize;
591 }
592 return;
593 }
594 }
595
596 /* pre-decrement ? */
597
598 if ((ArgLen > 2)
599 && GetPreDec(pArg->Str, ArgLen, &IncOpSize, &CutoffLeft, &CutoffRight))
600 {
601 String Reg;
602 tStrComp RegComp;
603
604 StrCompMkTemp(&RegComp, Reg);
605 StrCompCopy(&RegComp, pArg);
606 StrCompIncRefLeft(&RegComp, CutoffLeft);
607 StrCompShorten(&RegComp, CutoffRight);
608 if (CodeEReg(RegComp.Str, &HNum, &HSize) == 2)
609 {
610 if (!IsRegBase(HNum, HSize)) WrError(ErrNum_InvAddrMode);
611 else
612 {
613 if (IncOpSize == eSymbolSizeUnknown)
614 IncOpSize = OpSize;
615 AdrType = ModMem;
616 AdrMode = 0x44;
617 AdrCnt = 1;
618 AdrVals[0] = HNum;
619 if (IncOpSize == eSymbolSizeUnknown)
620 AutoIncSizeNeeded = True;
621 else
622 AdrVals[0] += IncOpSize;
623 }
624 return;
625 }
626 }
627
628 Arg = *pArg;
629 DispSize = eSymbolSizeUnknown;
630 do
631 {
632 EPos = QuotMultPos(Arg.Str, "+-");
633 NNegFlag = EPos && (*EPos == '-');
634 if ((EPos == Arg.Str) || (EPos == Arg.Str + strlen(Arg.Str) - 1))
635 {
636 WrError(ErrNum_InvAddrMode);
637 return;
638 }
639 if (EPos)
640 StrCompSplitRef(&Arg, &Remainder, &Arg, EPos);
641 KillPrefBlanksStrComp(&Arg);
642 KillPostBlanksStrComp(&Arg);
643
644 switch (CodeEReg(Arg.Str, &HNum, &HSize))
645 {
646 case 0:
647 {
648 tSymbolSize ThisSize;
649 tSymbolFlags Flags;
650
651 if ((ThisSize = SplitSize(&Arg)) != eSymbolSizeUnknown)
652 if (ThisSize > DispSize)
653 DispSize = ThisSize;
654 DispPart = EvalStrIntExpressionWithFlags(&Arg, Int32, &OK, &Flags);
655 if (mFirstPassUnknown(Flags)) FirstFlag = True;
656 if (!OK) return;
657 if (NegFlag)
658 DispAcc -= DispPart;
659 else
660 DispAcc += DispPart;
661 PartMask |= 1;
662 break;
663 }
664 case 1:
665 break;
666 case 2:
667 if (NegFlag)
668 {
669 WrError(ErrNum_InvAddrMode); return;
670 }
671 else
672 {
673 Boolean MustInd;
674
675 if (HSize == 0)
676 MustInd = True;
677 else if (HSize == 2)
678 MustInd = False;
679 else if (!IsRegBase(HNum, HSize))
680 MustInd = True;
681 else if (PartMask & 4)
682 MustInd = True;
683 else
684 MustInd = False;
685 if (MustInd)
686 {
687 if (PartMask & 2)
688 {
689 WrError(ErrNum_InvAddrMode); return;
690 }
691 else
692 {
693 IndReg = HNum;
694 PartMask |= 2;
695 IndSize = HSize;
696 }
697 }
698 else
699 {
700 if (PartMask & 4)
701 {
702 WrError(ErrNum_InvAddrMode); return;
703 }
704 else
705 {
706 BaseReg = HNum;
707 PartMask |= 4;
708 BaseSize = HSize;
709 }
710 }
711 }
712 break;
713 }
714
715 NegFlag = NNegFlag;
716 NNegFlag = False;
717 if (EPos)
718 Arg = Remainder;
719 }
720 while (EPos);
721
722 /* auto-deduce address/displacement size? */
723
724 if (DispSize == eSymbolSizeUnknown)
725 {
726 switch (PartMask)
727 {
728 case 1:
729 if (DispAcc <= 0xff)
730 DispSize = eSymbolSize8Bit;
731 else if (DispAcc < 0xffff)
732 DispSize = eSymbolSize16Bit;
733 else
734 DispSize = eSymbolSize24Bit;
735 break;
736 case 5:
737 if (!DispAcc)
738 PartMask &= ~1;
739 else if (RangeCheck(DispAcc, SInt8) && IsRegCurrent(BaseReg, BaseSize, &AdrMode))
740 DispSize = eSymbolSize8Bit;
741 else
742 DispSize = eSymbolSize16Bit;
743 break;
744 }
745 }
746
747 switch (PartMask)
748 {
749 case 0:
750 case 2:
751 case 3:
752 case 7:
753 WrError(ErrNum_InvAddrMode);
754 break;
755 case 1:
756 switch (DispSize)
757 {
758 case eSymbolSize8Bit:
759 if (FirstFlag)
760 DispAcc &= 0xff;
761 if (DispAcc > 0xff) WrError(ErrNum_AdrOverflow);
762 else
763 {
764 AdrType = ModMem;
765 AdrMode = 0x40;
766 AdrCnt = 1;
767 AdrVals[0] = DispAcc;
768 }
769 break;
770 case eSymbolSize16Bit:
771 if (FirstFlag)
772 DispAcc &= 0xffff;
773 if (DispAcc > 0xffff) WrError(ErrNum_AdrOverflow);
774 else
775 {
776 AdrType = ModMem;
777 AdrMode = 0x41;
778 AdrCnt = 2;
779 AdrVals[0] = Lo(DispAcc);
780 AdrVals[1] = Hi(DispAcc);
781 }
782 break;
783 case eSymbolSize24Bit:
784 if (FirstFlag)
785 DispAcc &= 0xffffff;
786 if (DispAcc > 0xffffff) WrError(ErrNum_AdrOverflow);
787 else
788 {
789 AdrType = ModMem;
790 AdrMode = 0x42;
791 AdrCnt = 3;
792 AdrVals[0] = DispAcc & 0xff;
793 AdrVals[1] = (DispAcc >> 8) & 0xff;
794 AdrVals[2] = (DispAcc >> 16) & 0xff;
795 }
796 break;
797 default:
798 break; /* assert(0)? */
799 }
800 break;
801 case 4:
802 if (IsRegCurrent(BaseReg, BaseSize, &AdrMode))
803 {
804 AdrType = ModMem;
805 AdrCnt = 0;
806 }
807 else
808 {
809 AdrType = ModMem;
810 AdrMode = 0x43;
811 AdrCnt = 1;
812 AdrVals[0] = BaseReg;
813 }
814 break;
815 case 5:
816 switch (DispSize)
817 {
818 case eSymbolSize8Bit:
819 if (FirstFlag)
820 DispAcc &= 0x7f;
821 if (!IsRegCurrent(BaseReg, BaseSize, &AdrMode)) WrError(ErrNum_InvAddrMode);
822 else if (ChkRange(DispAcc, -128, 127))
823 {
824 AdrType = ModMem;
825 AdrMode += 8;
826 AdrCnt = 1;
827 AdrVals[0] = DispAcc & 0xff;
828 }
829 break;
830 case eSymbolSize16Bit:
831 if (FirstFlag)
832 DispAcc &= 0x7fff;
833 if (ChkRange(DispAcc, -32768, 32767))
834 {
835 AdrType = ModMem;
836 AdrMode = 0x43;
837 AdrCnt = 3;
838 AdrVals[0] = BaseReg + 1;
839 AdrVals[1] = DispAcc & 0xff;
840 AdrVals[2] = (DispAcc >> 8) & 0xff;
841 }
842 break;
843 case eSymbolSize24Bit:
844 WrError(ErrNum_InvAddrMode);
845 break;
846 default:
847 break; /* assert(0)? */
848 }
849 break;
850 case 6:
851 AdrType = ModMem;
852 AdrMode = 0x43;
853 AdrCnt = 3;
854 AdrVals[0] = 3 + (IndSize << 2);
855 AdrVals[1] = BaseReg;
856 AdrVals[2] = IndReg;
857 break;
858 }
859 }
860
DecodeAdr(const tStrComp * pArg,Byte Erl)861 static void DecodeAdr(const tStrComp *pArg, Byte Erl)
862 {
863 Byte HNum, HSize;
864 LongInt DispAcc;
865 Boolean OK;
866
867 AdrType = ModNone;
868 AutoIncSizeNeeded = False;
869
870 /* Register ? */
871
872 switch (CodeEReg(pArg->Str, &HNum, &HSize))
873 {
874 case 1:
875 ChkAdr(Erl);
876 return;
877 case 2:
878 if (IsRegCurrent(HNum, HSize, &AdrMode))
879 AdrType = ModReg;
880 else
881 {
882 AdrType = ModXReg;
883 AdrMode = HNum;
884 }
885 SetOpSize(HSize);
886 ChkAdr(Erl);
887 return;
888 }
889
890 /* Steuerregister ? */
891
892 if (CodeCReg(pArg->Str, &HNum, &HSize) == 2)
893 {
894 AdrType = ModCReg;
895 AdrMode = HNum;
896 SetOpSize(HSize);
897 ChkAdr(Erl);
898 return;
899 }
900
901 /* Speicheroperand ? */
902
903 if (IsIndirect(pArg->Str))
904 {
905 tStrComp Arg;
906
907 StrCompRefRight(&Arg, pArg, 1);
908 StrCompShorten(&Arg, 1);
909 DecodeAdrMem(&Arg);
910 ChkAdr(Erl); return;
911 }
912
913 /* bleibt nur noch immediate... */
914
915 if ((MinOneIs0) && (OpSize == -1))
916 OpSize = 0;
917 switch (OpSize)
918 {
919 case -1:
920 WrError(ErrNum_UndefOpSizes);
921 break;
922 case 0:
923 AdrVals[0] = EvalStrIntExpression(pArg, Int8, &OK);
924 if (OK)
925 {
926 AdrType = ModImm;
927 AdrCnt = 1;
928 }
929 break;
930 case 1:
931 DispAcc = EvalStrIntExpression(pArg, Int16, &OK);
932 if (OK)
933 {
934 AdrType = ModImm;
935 AdrCnt = 2;
936 AdrVals[0] = Lo(DispAcc);
937 AdrVals[1] = Hi(DispAcc);
938 }
939 break;
940 case 2:
941 DispAcc = EvalStrIntExpression(pArg, Int32, &OK);
942 if (OK)
943 {
944 AdrType = ModImm;
945 AdrCnt = 4;
946 AdrVals[0] = Lo(DispAcc);
947 AdrVals[1] = Hi(DispAcc);
948 AdrVals[2] = Lo(DispAcc >> 16);
949 AdrVals[3] = Hi(DispAcc >> 16);
950 }
951 break;
952 }
953 }
954
955 /*---------------------------------------------------------------------------*/
956
SetAutoIncSize(Byte AdrModePos,Byte FixupPos)957 static void SetAutoIncSize(Byte AdrModePos, Byte FixupPos)
958 {
959 if ((BAsmCode[AdrModePos] & 0x4e) == 0x44)
960 BAsmCode[FixupPos] = (BAsmCode[FixupPos] & 0xfc) | OpSize;
961 }
962
ArgPair(const char * Val1,const char * Val2)963 static Boolean ArgPair(const char *Val1, const char *Val2)
964 {
965 return (((!as_strcasecmp(ArgStr[1].Str, Val1)) && (!as_strcasecmp(ArgStr[2].Str, Val2)))
966 || ((!as_strcasecmp(ArgStr[1].Str, Val2)) && (!as_strcasecmp(ArgStr[2].Str, Val1))));
967 }
968
ImmVal(void)969 static LongInt ImmVal(void)
970 {
971 LongInt tmp;
972
973 tmp = AdrVals[0];
974 if (OpSize >= 1)
975 tmp += ((LongInt)AdrVals[1]) << 8;
976 if (OpSize == 2)
977 {
978 tmp += ((LongInt)AdrVals[2]) << 16;
979 tmp += ((LongInt)AdrVals[3]) << 24;
980 }
981 return tmp;
982 }
983
IsPwr2(LongInt Inp,Byte * Erg)984 static Boolean IsPwr2(LongInt Inp, Byte *Erg)
985 {
986 LongInt Shift;
987
988 Shift = 1;
989 *Erg = 0;
990 do
991 {
992 if (Inp == Shift)
993 return True;
994 Shift += Shift;
995 (*Erg)++;
996 }
997 while (Shift != 0);
998 return False;
999 }
1000
IsShort(Byte Code)1001 static Boolean IsShort(Byte Code)
1002 {
1003 return ((Code & 0x4e) == 0x40);
1004 }
1005
CheckSup(void)1006 static void CheckSup(void)
1007 {
1008 if ((MomCPU == CPU96C141)
1009 && (!SupAllowed))
1010 WrError(ErrNum_PrivOrder);
1011 }
1012
DecodeCondition(const char * pAsc)1013 static int DecodeCondition(const char *pAsc)
1014 {
1015 int z;
1016
1017 for (z = 0; (z < ConditionCnt) && (as_strcasecmp(pAsc, Conditions[z].Name)); z++);
1018 return z;
1019 }
1020
SetInstrOpSize(Byte Size)1021 static void SetInstrOpSize(Byte Size)
1022 {
1023 if (Size != 255)
1024 OpSize = Size;
1025 }
1026
1027
1028 /*---------------------------------------------------------------------------*/
1029
DecodeMULA(Word Index)1030 static void DecodeMULA(Word Index)
1031 {
1032 UNUSED(Index);
1033
1034 if (ChkArgCnt(1, 1))
1035 {
1036 DecodeAdr(&ArgStr[1], MModReg | MModXReg);
1037 if ((AdrType != ModNone) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
1038 else switch (AdrType)
1039 {
1040 case ModReg:
1041 CodeLen = 2;
1042 BAsmCode[0] = 0xd8 + AdrMode;
1043 BAsmCode[1] = 0x19;
1044 break;
1045 case ModXReg:
1046 CodeLen = 3;
1047 BAsmCode[0] = 0xd7;
1048 BAsmCode[1] = AdrMode;
1049 BAsmCode[2] = 0x19;
1050 break;
1051 }
1052 }
1053 }
1054
DecodeJPCALL(Word Index)1055 static void DecodeJPCALL(Word Index)
1056 {
1057 int z;
1058
1059 if (ChkArgCnt(1, 2))
1060 {
1061 z = (ArgCnt == 1) ? DefaultCondition : DecodeCondition(ArgStr[1].Str);
1062 if (z >= ConditionCnt) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1063 else
1064 {
1065 OpSize = 2;
1066 DecodeAdr(&ArgStr[ArgCnt], MModMem | MModImm);
1067 if (AdrType == ModImm)
1068 {
1069 if (AdrVals[3] != 0)
1070 {
1071 WrError(ErrNum_OverRange);
1072 AdrType=ModNone;
1073 }
1074 else if (AdrVals[2] != 0)
1075 {
1076 AdrType = ModMem;
1077 AdrMode = 0x42;
1078 AdrCnt = 3;
1079 }
1080 else
1081 {
1082 AdrType = ModMem;
1083 AdrMode = 0x41;
1084 AdrCnt = 2;
1085 }
1086 }
1087 if (AdrType == ModMem)
1088 {
1089 if ((z == DefaultCondition) && ((AdrMode == 0x41) || (AdrMode == 0x42)))
1090 {
1091 CodeLen = 1 + AdrCnt;
1092 BAsmCode[0] = 0x1a + 2 * Index + (AdrCnt - 2);
1093 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1094 }
1095 else
1096 {
1097 CodeLen = 2 + AdrCnt;
1098 BAsmCode[0] = 0xb0 + AdrMode;
1099 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1100 BAsmCode[1 + AdrCnt] = 0xd0 + (Index << 4) + (Conditions[z].Code);
1101 }
1102 }
1103 }
1104 }
1105 }
1106
DecodeJR(Word Index)1107 static void DecodeJR(Word Index)
1108 {
1109 Boolean OK;
1110 int z;
1111 LongInt AdrLong;
1112 tSymbolFlags Flags;
1113
1114 if (ChkArgCnt(1, 2))
1115 {
1116 z = (ArgCnt==1) ? DefaultCondition : DecodeCondition(ArgStr[1].Str);
1117 if (z >= ConditionCnt) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1118 else
1119 {
1120 AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int32, &OK, &Flags);
1121 if (OK)
1122 {
1123 if (Index==1)
1124 {
1125 AdrLong -= EProgCounter() + 3;
1126 if (((AdrLong > 0x7fffl) || (AdrLong < -0x8000l)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_DistTooBig);
1127 else
1128 {
1129 CodeLen = 3;
1130 BAsmCode[0] = 0x70 + Conditions[z].Code;
1131 BAsmCode[1] = Lo(AdrLong);
1132 BAsmCode[2] = Hi(AdrLong);
1133 if (!mFirstPassUnknown(Flags))
1134 {
1135 AdrLong++;
1136 if ((AdrLong >= -128) && (AdrLong <= 127)) WrError(ErrNum_ShortJumpPossible);
1137 }
1138 }
1139 }
1140 else
1141 {
1142 AdrLong -= EProgCounter() + 2;
1143 if (((AdrLong > 127) || (AdrLong < -128)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_DistTooBig);
1144 else
1145 {
1146 CodeLen = 2;
1147 BAsmCode[0] = 0x60 + Conditions[z].Code;
1148 BAsmCode[1] = Lo(AdrLong);
1149 }
1150 }
1151 }
1152 }
1153 }
1154 }
1155
DecodeCALR(Word Index)1156 static void DecodeCALR(Word Index)
1157 {
1158 LongInt AdrLong;
1159 Boolean OK;
1160 tSymbolFlags Flags;
1161
1162 UNUSED(Index);
1163
1164 if (ChkArgCnt(1, 1))
1165 {
1166 AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags) - (EProgCounter() + 3);
1167 if (OK)
1168 {
1169 if (((AdrLong < -32768) || (AdrLong > 32767)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_DistTooBig);
1170 else
1171 {
1172 CodeLen = 3;
1173 BAsmCode[0] = 0x1e;
1174 BAsmCode[1] = Lo(AdrLong);
1175 BAsmCode[2] = Hi(AdrLong);
1176 }
1177 }
1178 }
1179 }
1180
DecodeRET(Word Index)1181 static void DecodeRET(Word Index)
1182 {
1183 int z;
1184 UNUSED(Index);
1185
1186 if (ChkArgCnt(0, 1))
1187 {
1188 z = (ArgCnt == 0) ? DefaultCondition : DecodeCondition(ArgStr[1].Str);
1189 if (z >= ConditionCnt) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1190 else if (z == DefaultCondition)
1191 {
1192 CodeLen = 1;
1193 BAsmCode[0] = 0x0e;
1194 }
1195 else
1196 {
1197 CodeLen = 2;
1198 BAsmCode[0] = 0xb0;
1199 BAsmCode[1] = 0xf0 + Conditions[z].Code;
1200 }
1201 }
1202 }
1203
DecodeRETD(Word Index)1204 static void DecodeRETD(Word Index)
1205 {
1206 Word AdrWord;
1207 Boolean OK;
1208 UNUSED(Index);
1209
1210 if (ChkArgCnt(1, 1))
1211 {
1212 AdrWord = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
1213 if (OK)
1214 {
1215 CodeLen = 3;
1216 BAsmCode[0] = 0x0f;
1217 BAsmCode[1] = Lo(AdrWord);
1218 BAsmCode[2] = Hi(AdrWord);
1219 }
1220 }
1221 }
1222
DecodeDJNZ(Word Index)1223 static void DecodeDJNZ(Word Index)
1224 {
1225 LongInt AdrLong;
1226 Boolean OK;
1227 tSymbolFlags Flags;
1228
1229 UNUSED(Index);
1230
1231 if (ChkArgCnt(1, 2))
1232 {
1233 if (ArgCnt == 1)
1234 {
1235 AdrType = ModReg;
1236 AdrMode = 2;
1237 OpSize = 0;
1238 }
1239 else
1240 DecodeAdr(&ArgStr[1], MModReg | MModXReg);
1241 if (AdrType != ModNone)
1242 {
1243 if (OpSize == 2) WrError(ErrNum_InvOpSize);
1244 else
1245 {
1246 AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int32, &OK, &Flags) - (EProgCounter() + 3 + Ord(AdrType == ModXReg));
1247 if (OK)
1248 {
1249 if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
1250 else
1251 switch (AdrType)
1252 {
1253 case ModReg:
1254 CodeLen = 3;
1255 BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
1256 BAsmCode[1] = 0x1c;
1257 BAsmCode[2] = AdrLong & 0xff;
1258 break;
1259 case ModXReg:
1260 CodeLen = 4;
1261 BAsmCode[0] = 0xc7 + (OpSize << 4);
1262 BAsmCode[1] = AdrMode;
1263 BAsmCode[2] = 0x1c;
1264 BAsmCode[3] = AdrLong & 0xff;
1265 break;
1266 }
1267 }
1268 }
1269 }
1270 }
1271 }
1272
DecodeEX(Word Index)1273 static void DecodeEX(Word Index)
1274 {
1275 Byte HReg;
1276 UNUSED(Index);
1277
1278 /* work around the parser problem related to the ' character */
1279
1280 if (!as_strncasecmp(ArgStr[2].Str, "F\'", 2))
1281 ArgStr[2].Str[2] = '\0';
1282
1283 if (!ChkArgCnt(2, 2));
1284 else if ((ArgPair("F", "F\'")) || (ArgPair("F`", "F")))
1285 {
1286 CodeLen = 1;
1287 BAsmCode[0] = 0x16;
1288 }
1289 else
1290 {
1291 DecodeAdr(&ArgStr[1], MModReg | MModXReg | MModMem);
1292 if (OpSize == 2) WrError(ErrNum_InvOpSize);
1293 else
1294 {
1295 switch (AdrType)
1296 {
1297 case ModReg:
1298 HReg = AdrMode;
1299 DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem);
1300 switch (AdrType)
1301 {
1302 case ModReg:
1303 CodeLen = 2;
1304 BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
1305 BAsmCode[1] = 0xb8 + HReg;
1306 break;
1307 case ModXReg:
1308 CodeLen = 3;
1309 BAsmCode[0] = 0xc7 + (OpSize << 4);
1310 BAsmCode[1] = AdrMode;
1311 BAsmCode[2] = 0xb8 + HReg;
1312 break;
1313 case ModMem:
1314 CodeLen = 2 + AdrCnt;
1315 BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
1316 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1317 BAsmCode[1 + AdrCnt] = 0x30 + HReg;
1318 break;
1319 }
1320 break;
1321 case ModXReg:
1322 HReg = AdrMode;
1323 DecodeAdr(&ArgStr[2], MModReg);
1324 if (AdrType == ModReg)
1325 {
1326 CodeLen = 3;
1327 BAsmCode[0] = 0xc7 + (OpSize << 4);
1328 BAsmCode[1] = HReg;
1329 BAsmCode[2] = 0xb8 + AdrMode;
1330 }
1331 break;
1332 case ModMem:
1333 {
1334 Boolean FixupAutoIncSize = AutoIncSizeNeeded;
1335
1336 MinOneIs0 = True;
1337 HReg = AdrCnt;
1338 BAsmCode[0] = AdrMode;
1339 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1340 DecodeAdr(&ArgStr[2], MModReg);
1341 if (AdrType == ModReg)
1342 {
1343 CodeLen = 2 + HReg;
1344 if (FixupAutoIncSize)
1345 SetAutoIncSize(0, 1);
1346 BAsmCode[0] += 0x80 + (OpSize << 4);
1347 BAsmCode[1 + HReg] = 0x30 + AdrMode;
1348 }
1349 break;
1350 }
1351 }
1352 }
1353 }
1354 }
1355
DecodeBS1x(Word Index)1356 static void DecodeBS1x(Word Index)
1357 {
1358 if (!ChkArgCnt(2, 2));
1359 else if (as_strcasecmp(ArgStr[1].Str, "A")) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
1360 else
1361 {
1362 DecodeAdr(&ArgStr[2], MModReg | MModXReg);
1363 if (OpSize != 1) WrError(ErrNum_InvOpSize);
1364 else switch (AdrType)
1365 {
1366 case ModReg:
1367 CodeLen = 2;
1368 BAsmCode[0] = 0xd8 + AdrMode;
1369 BAsmCode[1] = 0x0e + Index; /* ANSI */
1370 break;
1371 case ModXReg:
1372 CodeLen = 3;
1373 BAsmCode[0] = 0xd7;
1374 BAsmCode[1] = AdrMode;
1375 BAsmCode[2] = 0x0e +Index; /* ANSI */
1376 break;
1377 }
1378 }
1379 }
1380
DecodeLDA(Word Index)1381 static void DecodeLDA(Word Index)
1382 {
1383 Byte HReg;
1384 UNUSED(Index);
1385
1386 if (ChkArgCnt(2, 2))
1387 {
1388 DecodeAdr(&ArgStr[1], MModReg);
1389 if (AdrType != ModNone)
1390 {
1391 if (OpSize < 1) WrError(ErrNum_InvOpSize);
1392 else
1393 {
1394 HReg = AdrMode;
1395 if (IsIndirect(ArgStr[2].Str))
1396 DecodeAdr(&ArgStr[2], MModMem);
1397 else
1398 DecodeAdrMem(&ArgStr[2]);
1399 if (AdrType != ModNone)
1400 {
1401 CodeLen = 2 + AdrCnt;
1402 BAsmCode[0] = 0xb0 + AdrMode;
1403 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1404 BAsmCode[1 + AdrCnt] = 0x20 + ((OpSize - 1) << 4) + HReg;
1405 }
1406 }
1407 }
1408 }
1409 }
1410
DecodeLDAR(Word Index)1411 static void DecodeLDAR(Word Index)
1412 {
1413 LongInt AdrLong;
1414 Boolean OK;
1415 tSymbolFlags Flags;
1416
1417 UNUSED(Index);
1418
1419 if (ChkArgCnt(2, 2))
1420 {
1421 AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[2], Int32, &OK, &Flags) - (EProgCounter() + 4);
1422 if (OK)
1423 {
1424 if (((AdrLong < -32768) || (AdrLong > 32767)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_DistTooBig);
1425 else
1426 {
1427 DecodeAdr(&ArgStr[1], MModReg);
1428 if (AdrType != ModNone)
1429 {
1430 if (OpSize < 1) WrError(ErrNum_InvOpSize);
1431 else
1432 {
1433 CodeLen = 5;
1434 BAsmCode[0] = 0xf3;
1435 BAsmCode[1] = 0x13;
1436 BAsmCode[2] = Lo(AdrLong);
1437 BAsmCode[3] = Hi(AdrLong);
1438 BAsmCode[4] = 0x20 + ((OpSize - 1) << 4) + AdrMode;
1439 }
1440 }
1441 }
1442 }
1443 }
1444 }
1445
DecodeLDC(Word Index)1446 static void DecodeLDC(Word Index)
1447 {
1448 Byte HReg;
1449 UNUSED(Index);
1450
1451 if (ChkArgCnt(2, 2))
1452 {
1453 DecodeAdr(&ArgStr[1], MModReg | MModXReg| MModCReg);
1454 HReg = AdrMode;
1455 switch (AdrType)
1456 {
1457 case ModReg:
1458 DecodeAdr(&ArgStr[2], MModCReg);
1459 if (AdrType != ModNone)
1460 {
1461 CodeLen = 3;
1462 BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
1463 BAsmCode[1] = 0x2f;
1464 BAsmCode[2] = AdrMode;
1465 }
1466 break;
1467 case ModXReg:
1468 DecodeAdr(&ArgStr[2], MModCReg);
1469 if (AdrType != ModNone)
1470 {
1471 CodeLen = 4;
1472 BAsmCode[0] = 0xc7 + (OpSize << 4);
1473 BAsmCode[1] = HReg;
1474 BAsmCode[2] = 0x2f;
1475 BAsmCode[3] = AdrMode;
1476 };
1477 break;
1478 case ModCReg:
1479 DecodeAdr(&ArgStr[2], MModReg | MModXReg);
1480 switch (AdrType)
1481 {
1482 case ModReg:
1483 CodeLen = 3;
1484 BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
1485 BAsmCode[1] = 0x2e;
1486 BAsmCode[2] = HReg;
1487 break;
1488 case ModXReg:
1489 CodeLen = 4;
1490 BAsmCode[0] = 0xc7 + (OpSize << 4);
1491 BAsmCode[1] = AdrMode;
1492 BAsmCode[2] = 0x2e;
1493 BAsmCode[3] = HReg;
1494 break;
1495 }
1496 break;
1497 }
1498 }
1499 }
1500
DecodeLDX(Word Index)1501 static void DecodeLDX(Word Index)
1502 {
1503 Boolean OK;
1504 UNUSED(Index);
1505
1506 if (ChkArgCnt(2, 2))
1507 {
1508 DecodeAdr(&ArgStr[1], MModMem);
1509 if (AdrType != ModNone)
1510 {
1511 if (AdrMode != 0x40) WrError(ErrNum_InvAddrMode);
1512 else
1513 {
1514 BAsmCode[4] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
1515 if (OK)
1516 {
1517 CodeLen = 6;
1518 BAsmCode[0] = 0xf7;
1519 BAsmCode[1] = 0;
1520 BAsmCode[2] = AdrVals[0];
1521 BAsmCode[3] = 0;
1522 BAsmCode[5] = 0;
1523 }
1524 }
1525 }
1526 }
1527 }
1528
DecodeLINK(Word Index)1529 static void DecodeLINK(Word Index)
1530 {
1531 Word AdrWord;
1532 Boolean OK;
1533 UNUSED(Index);
1534
1535 if (ChkArgCnt(2, 2))
1536 {
1537 AdrWord = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
1538 if (OK)
1539 {
1540 DecodeAdr(&ArgStr[1], MModReg | MModXReg);
1541 if ((AdrType != ModNone) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
1542 else
1543 switch (AdrType)
1544 {
1545 case ModReg:
1546 CodeLen = 4;
1547 BAsmCode[0] = 0xe8 + AdrMode;
1548 BAsmCode[1] = 0x0c;
1549 BAsmCode[2] = Lo(AdrWord);
1550 BAsmCode[3] = Hi(AdrWord);
1551 break;
1552 case ModXReg:
1553 CodeLen = 5;
1554 BAsmCode[0] = 0xe7;
1555 BAsmCode[1] = AdrMode;
1556 BAsmCode[2] = 0x0c;
1557 BAsmCode[3] = Lo(AdrWord);
1558 BAsmCode[4] = Hi(AdrWord);
1559 break;
1560 }
1561 }
1562 }
1563 }
1564
DecodeLD(Word Code)1565 static void DecodeLD(Word Code)
1566 {
1567 Byte HReg;
1568 Boolean ShDest, ShSrc, OK;
1569
1570 SetInstrOpSize(Hi(Code));
1571
1572 if (ChkArgCnt(2, 2))
1573 {
1574 DecodeAdr(&ArgStr[1], MModReg | MModXReg | MModMem);
1575 switch (AdrType)
1576 {
1577 case ModReg:
1578 HReg = AdrMode;
1579 DecodeAdr(&ArgStr[2], MModReg | MModXReg| MModMem| MModImm);
1580 switch (AdrType)
1581 {
1582 case ModReg:
1583 CodeLen = 2;
1584 BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
1585 BAsmCode[1] = 0x88 + HReg;
1586 break;
1587 case ModXReg:
1588 CodeLen = 3;
1589 BAsmCode[0] = 0xc7 + (OpSize << 4);
1590 BAsmCode[1] = AdrMode;
1591 BAsmCode[2] = 0x88 + HReg;
1592 break;
1593 case ModMem:
1594 CodeLen = 2 + AdrCnt;
1595 BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
1596 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1597 BAsmCode[1 + AdrCnt] = 0x20 + HReg;
1598 break;
1599 case ModImm:
1600 {
1601 LongInt ImmValue = ImmVal();
1602
1603 if ((ImmValue <= 7) && (ImmValue >= 0))
1604 {
1605 CodeLen = 2;
1606 BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
1607 BAsmCode[1] = 0xa8 + AdrVals[0];
1608 }
1609 else
1610 {
1611 CodeLen = 1 + AdrCnt;
1612 BAsmCode[0] = ((OpSize + 2) << 4) + HReg;
1613 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1614 }
1615 break;
1616 }
1617 }
1618 break;
1619 case ModXReg:
1620 HReg = AdrMode;
1621 DecodeAdr(&ArgStr[2], MModReg + MModImm);
1622 switch (AdrType)
1623 {
1624 case ModReg:
1625 CodeLen = 3;
1626 BAsmCode[0] = 0xc7 + (OpSize << 4);
1627 BAsmCode[1] = HReg;
1628 BAsmCode[2] = 0x98 + AdrMode;
1629 break;
1630 case ModImm:
1631 {
1632 LongInt ImmValue = ImmVal();
1633
1634 if ((ImmValue <= 7) && (ImmValue >= 0))
1635 {
1636 CodeLen = 3;
1637 BAsmCode[0] = 0xc7 + (OpSize << 4);
1638 BAsmCode[1] = HReg;
1639 BAsmCode[2] = 0xa8 + AdrVals[0];
1640 }
1641 else
1642 {
1643 CodeLen = 3 + AdrCnt;
1644 BAsmCode[0] = 0xc7 + (OpSize << 4);
1645 BAsmCode[1] = HReg;
1646 BAsmCode[2] = 3;
1647 memcpy(BAsmCode + 3, AdrVals, AdrCnt);
1648 }
1649 break;
1650 }
1651 }
1652 break;
1653 case ModMem:
1654 {
1655 Boolean FixupAutoIncSize = AutoIncSizeNeeded;
1656
1657 BAsmCode[0] = AdrMode;
1658 HReg = AdrCnt;
1659 MinOneIs0 = True;
1660 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1661 DecodeAdr(&ArgStr[2], MModReg | MModMem | MModImm);
1662 switch (AdrType)
1663 {
1664 case ModReg:
1665 CodeLen = 2 + HReg;
1666 BAsmCode[0] += 0xb0;
1667 if (FixupAutoIncSize)
1668 SetAutoIncSize(0, 1);
1669 BAsmCode[1 + HReg] = 0x40 + (OpSize << 4) + AdrMode;
1670 break;
1671 case ModMem:
1672 if (OpSize == -1) OpSize = 0;
1673 ShDest = IsShort(BAsmCode[0]);
1674 ShSrc = IsShort(AdrMode);
1675 if (!(ShDest || ShSrc)) WrError(ErrNum_InvAddrMode);
1676 else
1677 {
1678 if ((ShDest && (!ShSrc))) OK = True;
1679 else if (ShSrc && (!ShDest)) OK = False;
1680 else if (AdrMode == 0x40) OK = True;
1681 else OK = False;
1682 if (OK) /* dest=(dir8/16) */
1683 {
1684 CodeLen = 4 + AdrCnt;
1685 HReg = BAsmCode[0];
1686 BAsmCode[3 + AdrCnt] = (BAsmCode[0] == 0x40) ? 0 : BAsmCode[2];
1687 BAsmCode[2 + AdrCnt] = BAsmCode[1];
1688 BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
1689 AdrMode = HReg;
1690 if (FixupAutoIncSize)
1691 SetAutoIncSize(0, 1);
1692 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1693 BAsmCode[1 + AdrCnt] = 0x19;
1694 }
1695 else
1696 {
1697 CodeLen = 4 + HReg;
1698 BAsmCode[2 + HReg] = AdrVals[0];
1699 BAsmCode[3 + HReg] = (AdrMode == 0x40) ? 0 : AdrVals[1];
1700 BAsmCode[0] += 0xb0;
1701 if (FixupAutoIncSize)
1702 SetAutoIncSize(0, 1);
1703 BAsmCode[1 + HReg] = 0x14 + (OpSize << 1);
1704 }
1705 }
1706 break;
1707 case ModImm:
1708 if (BAsmCode[0] == 0x40)
1709 {
1710 CodeLen = 2 + AdrCnt;
1711 BAsmCode[0] = 0x08 + (OpSize << 1);
1712 memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1713 }
1714 else
1715 {
1716 CodeLen = 2 + HReg + AdrCnt;
1717 BAsmCode[0] += 0xb0;
1718 BAsmCode[1 + HReg] = OpSize << 1;
1719 memcpy(BAsmCode + 2 + HReg, AdrVals, AdrCnt);
1720 }
1721 break;
1722 }
1723 break;
1724 }
1725 }
1726 }
1727 }
1728
DecodeFixed(Word Index)1729 static void DecodeFixed(Word Index)
1730 {
1731 FixedOrder *FixedZ = FixedOrders + Index;
1732
1733 if (ChkArgCnt(0, 0)
1734 && (ChkExactCPUMask(FixedZ->CPUFlag, CPU96C141) >= 0))
1735 {
1736 if (Hi(FixedZ->Code) == 0)
1737 {
1738 CodeLen = 1;
1739 BAsmCode[0] = Lo(FixedZ->Code);
1740 }
1741 else
1742 {
1743 CodeLen = 2;
1744 BAsmCode[0] = Hi(FixedZ->Code);
1745 BAsmCode[1] = Lo(FixedZ->Code);
1746 }
1747 if (FixedZ->InSup)
1748 CheckSup();
1749 }
1750 }
1751
DecodeImm(Word Index)1752 static void DecodeImm(Word Index)
1753 {
1754 ImmOrder *ImmZ = ImmOrders + Index;
1755 Word AdrWord;
1756 Boolean OK;
1757
1758 if (ChkArgCnt((ImmZ->Default == -1) ? 1 : 0, 1))
1759 {
1760 if (ArgCnt == 0)
1761 {
1762 AdrWord = ImmZ->Default;
1763 OK = True;
1764 }
1765 else
1766 AdrWord = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
1767 if (OK)
1768 {
1769 if (((Maximum) && (AdrWord > ImmZ->MaxMax)) || ((!Maximum) && (AdrWord > ImmZ->MinMax))) WrError(ErrNum_OverRange);
1770 else if (Hi(ImmZ->Code) == 0)
1771 {
1772 CodeLen = 1;
1773 BAsmCode[0] = Lo(ImmZ->Code) + AdrWord;
1774 }
1775 else
1776 {
1777 CodeLen = 2;
1778 BAsmCode[0] = Hi(ImmZ->Code);
1779 BAsmCode[1] = Lo(ImmZ->Code) + AdrWord;
1780 }
1781 }
1782 if (ImmZ->InSup)
1783 CheckSup();
1784 }
1785 }
1786
1787 static void DecodeALU2(Word Code);
1788
DecodeReg(Word Index)1789 static void DecodeReg(Word Index)
1790 {
1791 RegOrder *RegZ = RegOrders + Index;
1792
1793 /* dispatch to CPL as compare-long with two args: */
1794
1795 if ((Memo("CPL")) && (ArgCnt >= 2))
1796 {
1797 DecodeALU2(0x0207);
1798 return;
1799 }
1800
1801 if (ChkArgCnt(1, 1))
1802 {
1803 DecodeAdr(&ArgStr[1], MModReg | MModXReg);
1804 if (AdrType != ModNone)
1805 {
1806 if (((1 << OpSize) & RegZ->OpMask) == 0) WrError(ErrNum_InvOpSize);
1807 else if (AdrType == ModReg)
1808 {
1809 BAsmCode[0] = Hi(RegZ->Code) + 8 + (OpSize << 4) + AdrMode;
1810 BAsmCode[1] = Lo(RegZ->Code);
1811 CodeLen = 2;
1812 }
1813 else
1814 {
1815 BAsmCode[0] = Hi(RegZ->Code) + 7 + (OpSize << 4);
1816 BAsmCode[1] = AdrMode;
1817 BAsmCode[2] = Lo(RegZ->Code);
1818 CodeLen = 3;
1819 }
1820 }
1821 }
1822 }
1823
DecodeALU2(Word Code)1824 static void DecodeALU2(Word Code)
1825 {
1826 Byte HReg;
1827
1828 SetInstrOpSize(Hi(Code));
1829 if (ChkArgCnt(2, 2))
1830 {
1831 DecodeAdr(&ArgStr[1], MModReg | MModXReg | MModMem);
1832 switch (AdrType)
1833 {
1834 case ModReg:
1835 HReg=AdrMode;
1836 DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem | MModImm);
1837 switch (AdrType)
1838 {
1839 case ModReg:
1840 CodeLen = 2;
1841 BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
1842 BAsmCode[1] = 0x80 + (Lo(Code) << 4) + HReg;
1843 break;
1844 case ModXReg:
1845 CodeLen = 3;
1846 BAsmCode[0] = 0xc7 + (OpSize << 4);
1847 BAsmCode[1] = AdrMode;
1848 BAsmCode[2] = 0x80 + (Lo(Code) << 4) + HReg;
1849 break;
1850 case ModMem:
1851 CodeLen = 2 + AdrCnt;
1852 BAsmCode[0] = 0x80 + AdrMode + (OpSize << 4);
1853 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1854 BAsmCode[1 + AdrCnt] = 0x80 + HReg + (Lo(Code) << 4);
1855 break;
1856 case ModImm:
1857 if ((Lo(Code) == 7) && (OpSize != 2) && (ImmVal() <= 7) && (ImmVal() >= 0))
1858 {
1859 CodeLen = 2;
1860 BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
1861 BAsmCode[1] = 0xd8 + AdrVals[0];
1862 }
1863 else
1864 {
1865 CodeLen = 2 + AdrCnt;
1866 BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
1867 BAsmCode[1] = 0xc8 + Lo(Code);
1868 memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1869 }
1870 break;
1871 }
1872 break;
1873 case ModXReg:
1874 HReg = AdrMode;
1875 DecodeAdr(&ArgStr[2], MModImm);
1876 switch (AdrType)
1877 {
1878 case ModImm:
1879 if ((Lo(Code) == 7) && (OpSize != 2) && (ImmVal() <= 7) && (ImmVal() >= 0))
1880 {
1881 CodeLen = 3;
1882 BAsmCode[0] = 0xc7 + (OpSize << 4);
1883 BAsmCode[1] = HReg;
1884 BAsmCode[2] = 0xd8 + AdrVals[0];
1885 }
1886 else
1887 {
1888 CodeLen = 3 + AdrCnt;
1889 BAsmCode[0] = 0xc7 + (OpSize << 4);
1890 BAsmCode[1] = HReg;
1891 BAsmCode[2] = 0xc8 + Lo(Code);
1892 memcpy(BAsmCode + 3, AdrVals, AdrCnt);
1893 }
1894 break;
1895 }
1896 break;
1897 case ModMem:
1898 {
1899 Boolean FixupAutoIncSize = AutoIncSizeNeeded;
1900
1901 MinOneIs0 = True;
1902 HReg = AdrCnt;
1903 BAsmCode[0] = AdrMode;
1904 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1905 DecodeAdr(&ArgStr[2], MModReg | MModImm);
1906 switch (AdrType)
1907 {
1908 case ModReg:
1909 CodeLen = 2 + HReg;
1910 if (FixupAutoIncSize)
1911 SetAutoIncSize(0, 1);
1912 BAsmCode[0] += 0x80 + (OpSize << 4);
1913 BAsmCode[1 + HReg] = 0x88 + (Lo(Code) << 4) + AdrMode;
1914 break;
1915 case ModImm:
1916 CodeLen = 2 + HReg + AdrCnt;
1917 BAsmCode[0] += 0x80 + (OpSize << 4);
1918 BAsmCode[1 + HReg] = 0x38 + Lo(Code);
1919 memcpy(BAsmCode + 2 + HReg, AdrVals, AdrCnt);
1920 break;
1921 };
1922 break;
1923 }
1924 }
1925 }
1926 }
1927
DecodePUSH_POP(Word Code)1928 static void DecodePUSH_POP(Word Code)
1929 {
1930 SetInstrOpSize(Hi(Code));
1931
1932 if (!ChkArgCnt(1, 1));
1933 else if (!as_strcasecmp(ArgStr[1].Str, "F"))
1934 {
1935 CodeLen = 1;
1936 BAsmCode[0] = 0x18 + Lo(Code);
1937 }
1938 else if (!as_strcasecmp(ArgStr[1].Str, "A"))
1939 {
1940 CodeLen = 1;
1941 BAsmCode[0] = 0x14 + Lo(Code);
1942 }
1943 else if (!as_strcasecmp(ArgStr[1].Str, "SR"))
1944 {
1945 CodeLen = 1;
1946 BAsmCode[0] = 0x02 + Lo(Code);
1947 CheckSup();
1948 }
1949 else
1950 {
1951 MinOneIs0 = True;
1952 DecodeAdr(&ArgStr[1], MModReg | MModXReg | MModMem | (Lo(Code) ? 0 : MModImm));
1953 switch (AdrType)
1954 {
1955 case ModReg:
1956 if (OpSize == 0)
1957 {
1958 CodeLen = 2;
1959 BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
1960 BAsmCode[1] = 0x04 + Lo(Code);
1961 }
1962 else
1963 {
1964 CodeLen = 1;
1965 BAsmCode[0] = 0x28 + (Lo(Code) << 5) + ((OpSize - 1) << 4) + AdrMode;
1966 }
1967 break;
1968 case ModXReg:
1969 CodeLen = 3;
1970 BAsmCode[0] = 0xc7 + (OpSize << 4);
1971 BAsmCode[1] = AdrMode;
1972 BAsmCode[2] = 0x04 + Lo(Code);
1973 break;
1974 case ModMem:
1975 if (OpSize == -1)
1976 OpSize=0;
1977 CodeLen = 2 + AdrCnt;
1978 if (Lo(Code))
1979 BAsmCode[0] = 0xb0 + AdrMode;
1980 else
1981 BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
1982 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1983 if (Lo(Code))
1984 BAsmCode[1 + AdrCnt] = 0x04 + (OpSize << 1);
1985 else
1986 BAsmCode[1 + AdrCnt] = 0x04;
1987 break;
1988 case ModImm:
1989 if (OpSize == -1)
1990 OpSize = 0;
1991 BAsmCode[0] = 9 + (OpSize << 1);
1992 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1993 CodeLen = 1 + AdrCnt;
1994 break;
1995 }
1996 }
1997 }
1998
DecodeShift(Word Code)1999 static void DecodeShift(Word Code)
2000 {
2001 Boolean OK;
2002 tSymbolFlags Flags;
2003 Byte HReg;
2004
2005 SetInstrOpSize(Hi(Code));
2006
2007 if (ChkArgCnt(1, 2))
2008 {
2009 OK = True;
2010 if (ArgCnt == 1)
2011 HReg = 1;
2012 else if (!as_strcasecmp(ArgStr[1].Str, "A"))
2013 HReg = 0xff;
2014 else
2015 {
2016 HReg = EvalStrIntExpressionWithFlags(&ArgStr[1], Int8, &OK, &Flags);
2017 if (OK)
2018 {
2019 if (mFirstPassUnknown(Flags))
2020 HReg &= 0x0f;
2021 else
2022 {
2023 if ((HReg == 0) || (HReg > 16))
2024 {
2025 WrError(ErrNum_OverRange);
2026 OK = False;
2027 }
2028 else
2029 HReg &= 0x0f;
2030 }
2031 }
2032 }
2033 if (OK)
2034 {
2035 DecodeAdr(&ArgStr[ArgCnt], MModReg | MModXReg | ((HReg == 0xff) ? 0 : MModMem));
2036 switch (AdrType)
2037 {
2038 case ModReg:
2039 CodeLen = 2 + Ord(HReg != 0xff);
2040 BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
2041 BAsmCode[1] = 0xe8 + Lo(Code);
2042 CodeLen = 2;
2043 if (HReg == 0xff)
2044 BAsmCode[1] += 0x10;
2045 else
2046 BAsmCode[CodeLen++] = HReg;
2047 break;
2048 case ModXReg:
2049 BAsmCode[0] = 0xc7+(OpSize << 4);
2050 BAsmCode[1] = AdrMode;
2051 BAsmCode[2] = 0xe8 + Lo(Code);
2052 CodeLen = 3;
2053 if (HReg == 0xff)
2054 BAsmCode[2] += 0x10;
2055 else
2056 BAsmCode[CodeLen++] = HReg;
2057 break;
2058 case ModMem:
2059 if (HReg != 1) WrError(ErrNum_InvAddrMode);
2060 else
2061 {
2062 if (OpSize == -1)
2063 OpSize = 0;
2064 CodeLen = 2 + AdrCnt;
2065 BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
2066 memcpy(BAsmCode + 1 , AdrVals, AdrCnt);
2067 BAsmCode[1 + AdrCnt] = 0x78 + Lo(Code);
2068 }
2069 break;
2070 }
2071 }
2072 }
2073 }
2074
DecodeMulDiv(Word Code)2075 static void DecodeMulDiv(Word Code)
2076 {
2077 Byte HReg;
2078
2079 if (ChkArgCnt(2, 2))
2080 {
2081 DecodeAdr(&ArgStr[1], MModReg | MModXReg);
2082 if (OpSize == 0) WrError(ErrNum_InvOpSize);
2083 else
2084 {
2085 if ((AdrType == ModReg) && (OpSize == 1))
2086 {
2087 if (AdrMode > 3)
2088 {
2089 AdrType = ModXReg;
2090 AdrMode = 0xe0 + (AdrMode << 2);
2091 }
2092 else
2093 AdrMode += 1 + AdrMode;
2094 }
2095 OpSize--;
2096 HReg = AdrMode;
2097 switch (AdrType)
2098 {
2099 case ModReg:
2100 DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem | MModImm);
2101 switch (AdrType)
2102 {
2103 case ModReg:
2104 CodeLen = 2;
2105 BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
2106 BAsmCode[1] = 0x40 + (Code << 3) + HReg;
2107 break;
2108 case ModXReg:
2109 CodeLen = 3;
2110 BAsmCode[0] = 0xc7 + (OpSize << 4);
2111 BAsmCode[1] = AdrMode;
2112 BAsmCode[2] = 0x40 + (Code << 3) + HReg;
2113 break;
2114 case ModMem:
2115 CodeLen = 2 + AdrCnt;
2116 BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
2117 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
2118 BAsmCode[1 + AdrCnt] = 0x40 + (Code << 3) + HReg;
2119 break;
2120 case ModImm:
2121 CodeLen = 2 + AdrCnt;
2122 BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
2123 BAsmCode[1] = 0x08 + Code;
2124 memcpy(BAsmCode + 2, AdrVals, AdrCnt);
2125 break;
2126 }
2127 break;
2128 case ModXReg:
2129 DecodeAdr(&ArgStr[2], MModImm);
2130 if (AdrType == ModImm)
2131 {
2132 CodeLen = 3 + AdrCnt;
2133 BAsmCode[0] = 0xc7 + (OpSize << 4);
2134 BAsmCode[1] = HReg;
2135 BAsmCode[2] = 0x08 + Code;
2136 memcpy(BAsmCode + 3, AdrVals, AdrCnt);
2137 }
2138 break;
2139 }
2140 }
2141 }
2142 }
2143
DecodeBitCF(Word Code)2144 static void DecodeBitCF(Word Code)
2145 {
2146 Boolean OK;
2147 Byte BitPos;
2148
2149 if (ChkArgCnt(2, 2))
2150 {
2151 DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem);
2152 if (AdrType!=ModNone)
2153 {
2154 if (OpSize == 2) WrError(ErrNum_InvOpSize);
2155 else
2156 {
2157 if (AdrType == ModMem)
2158 OpSize = 0;
2159 if (!as_strcasecmp(ArgStr[1].Str, "A"))
2160 {
2161 BitPos = 0xff;
2162 OK = True;
2163 }
2164 else
2165 BitPos = EvalStrIntExpression(&ArgStr[1], (OpSize == 0) ? UInt3 : Int4, &OK);
2166 if (OK)
2167 switch (AdrType)
2168 {
2169 case ModReg:
2170 BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
2171 BAsmCode[1] = 0x20 + Code;
2172 CodeLen = 2;
2173 if (BitPos == 0xff)
2174 BAsmCode[1] |= 0x08;
2175 else
2176 BAsmCode[CodeLen++] = BitPos;
2177 break;
2178 case ModXReg:
2179 BAsmCode[0] = 0xc7 + (OpSize << 4);
2180 BAsmCode[1] = AdrMode;
2181 BAsmCode[2] = 0x20 + Code;
2182 CodeLen = 3;
2183 if (BitPos == 0xff)
2184 BAsmCode[2] |= 0x08;
2185 else
2186 BAsmCode[CodeLen++] = BitPos;
2187 break;
2188 case ModMem:
2189 CodeLen = 2 + AdrCnt;
2190 BAsmCode[0] = 0xb0 + AdrMode;
2191 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
2192 BAsmCode[1 + AdrCnt] = (BitPos == 0xff)
2193 ? 0x28 + Code
2194 : 0x80 + (Code << 3) + BitPos;
2195 break;
2196 }
2197 }
2198 }
2199 }
2200 }
2201
DecodeBit(Word Code)2202 static void DecodeBit(Word Code)
2203 {
2204 Boolean OK;
2205 Byte BitPos;
2206
2207 if (ChkArgCnt(2, 2))
2208 {
2209 DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem);
2210 if (AdrType == ModMem)
2211 OpSize = 0;
2212 if (AdrType != ModNone)
2213 {
2214 if (OpSize == 2) WrError(ErrNum_InvOpSize);
2215 else
2216 {
2217 BitPos = EvalStrIntExpression(&ArgStr[1], (OpSize == 0) ? UInt3 : Int4, &OK);
2218 if (OK)
2219 {
2220 switch (AdrType)
2221 {
2222 case ModReg:
2223 CodeLen = 3;
2224 BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
2225 BAsmCode[1] = 0x30 + Code;
2226 BAsmCode[2] = BitPos;
2227 break;
2228 case ModXReg:
2229 CodeLen = 4;
2230 BAsmCode[0] = 0xc7 + (OpSize << 4);
2231 BAsmCode[1] = AdrMode;
2232 BAsmCode[2] = 0x30 + Code;
2233 BAsmCode[3] = BitPos;
2234 break;
2235 case ModMem:
2236 CodeLen = 2 + AdrCnt;
2237 Code = (Code == 4) ? 0 : Code + 1;
2238 BAsmCode[0] = 0xb0 + AdrMode;
2239 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
2240 BAsmCode[1 + AdrCnt] = 0xa8 + (Code << 3) + BitPos;
2241 break;
2242 }
2243 }
2244 }
2245 }
2246 }
2247 }
2248
DecodeINC_DEC(Word Code)2249 static void DecodeINC_DEC(Word Code)
2250 {
2251 Boolean OK;
2252 Byte Incr;
2253 tSymbolFlags Flags;
2254
2255 SetInstrOpSize(Hi(Code));
2256
2257 if (ChkArgCnt(1, 2))
2258 {
2259 if (ArgCnt == 1)
2260 {
2261 Incr = 1;
2262 OK = True;
2263 Flags = eSymbolFlag_None;
2264 }
2265 else
2266 Incr = EvalStrIntExpressionWithFlags(&ArgStr[1], Int4, &OK, &Flags);
2267 if (OK)
2268 {
2269 if (mFirstPassUnknown(Flags))
2270 Incr &= 7;
2271 else if ((Incr < 1) || (Incr > 8))
2272 {
2273 WrError(ErrNum_OverRange);
2274 OK = False;
2275 }
2276 }
2277 if (OK)
2278 {
2279 Incr &= 7; /* 8-->0 */
2280 DecodeAdr(&ArgStr[ArgCnt], MModReg | MModXReg | MModMem);
2281 switch (AdrType)
2282 {
2283 case ModReg:
2284 CodeLen = 2;
2285 BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
2286 BAsmCode[1] = 0x60 + (Lo(Code) << 3) + Incr;
2287 break;
2288 case ModXReg:
2289 CodeLen = 3;
2290 BAsmCode[0] = 0xc7 + (OpSize << 4);
2291 BAsmCode[1] = AdrMode;
2292 BAsmCode[2] = 0x60 + (Lo(Code) << 3) + Incr;
2293 break;
2294 case ModMem:
2295 if (OpSize == -1)
2296 OpSize = 0;
2297 CodeLen = 2 + AdrCnt;
2298 BAsmCode[0] = 0x80 + AdrMode + (OpSize << 4);
2299 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
2300 BAsmCode[1 + AdrCnt] = 0x60 + (Lo(Code) << 3) + Incr;
2301 break;
2302 }
2303 }
2304 }
2305 }
2306
DecodeCPxx(Word Code)2307 static void DecodeCPxx(Word Code)
2308 {
2309 Boolean OK;
2310
2311 if (ChkArgCntExtEitherOr(ArgCnt, 0, 2))
2312 {
2313 OK = True;
2314 if (ArgCnt == 0)
2315 {
2316 OpSize = 0;
2317 AdrMode = 3;
2318 }
2319 else
2320 {
2321 Byte HReg;
2322 int l = strlen(ArgStr[2].Str);
2323 const char *CmpStr;
2324
2325 if (!as_strcasecmp(ArgStr[1].Str, "A"))
2326 OpSize = 0;
2327 else if (!as_strcasecmp(ArgStr[1].Str, "WA"))
2328 OpSize = 1;
2329 CmpStr = (Code & 0x02) ? "-)" : "+)";
2330 if (OpSize == -1) OK = False;
2331 else if ((l < 2) || (*ArgStr[2].Str != '(') || (as_strcasecmp(ArgStr[2].Str + l - 2, CmpStr))) OK = False;
2332 else
2333 {
2334 ArgStr[2].Str[l - 2] = '\0';
2335 if (CodeEReg(ArgStr[2].Str + 1, &AdrMode, &HReg) != 2) OK = False;
2336 else if (!IsRegBase(AdrMode, HReg)) OK = False;
2337 else if (!IsRegCurrent(AdrMode, HReg, &AdrMode)) OK = False;
2338 }
2339 if (!OK)
2340 WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
2341 }
2342 if (OK)
2343 {
2344 CodeLen = 2;
2345 BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
2346 BAsmCode[1] = Code;
2347 }
2348 }
2349 }
2350
DecodeLDxx(Word Code)2351 static void DecodeLDxx(Word Code)
2352 {
2353 SetInstrOpSize(Hi(Code));
2354
2355 if (OpSize == -1)
2356 OpSize = 0;
2357 if (OpSize == 2) WrError(ErrNum_InvOpSize);
2358 else if (ChkArgCntExtEitherOr(ArgCnt, 0, 2))
2359 {
2360 Boolean OK;
2361 Byte HReg = 0;
2362
2363 if (ArgCnt == 0)
2364 {
2365 OK = True;
2366 }
2367 else
2368 {
2369 const char *CmpStr;
2370 int l1 = strlen(ArgStr[1].Str),
2371 l2 = strlen(ArgStr[2].Str);
2372
2373 OK = True;
2374 CmpStr = (Code & 0x02) ? "-)" : "+)";
2375 if ((*ArgStr[1].Str != '(') || (*ArgStr[2].Str != '(')
2376 || (l1 < 3) || (l2 < 3)
2377 || (as_strcasecmp(ArgStr[1].Str + l1 - 2, CmpStr))
2378 || (as_strcasecmp(ArgStr[2].Str + l2 - 2, CmpStr)))
2379 OK = False;
2380 else
2381 {
2382 ArgStr[1].Str[l1 - 2] = '\0';
2383 ArgStr[2].Str[l2 - 2] = '\0';
2384 if ((!as_strcasecmp(ArgStr[1].Str + 1,"XIX")) && (!as_strcasecmp(ArgStr[2].Str + 1, "XIY")))
2385 HReg = 2;
2386 else if ((Maximum) && (!as_strcasecmp(ArgStr[1].Str + 1, "XDE")) && (!as_strcasecmp(ArgStr[2].Str + 1 , "XHL")));
2387 else if ((!Maximum) && (!as_strcasecmp(ArgStr[1].Str + 1, "DE")) && (!as_strcasecmp(ArgStr[2].Str + 1 , "HL")));
2388 else
2389 OK = False;
2390 }
2391 }
2392 if (!OK) WrError(ErrNum_InvAddrMode);
2393 else
2394 {
2395 CodeLen = 2;
2396 BAsmCode[0] = 0x83 + (OpSize << 4) + HReg;
2397 BAsmCode[1] = Lo(Code);
2398 }
2399 }
2400 }
2401
DecodeMINC_MDEC(Word Code)2402 static void DecodeMINC_MDEC(Word Code)
2403 {
2404 if (ChkArgCnt(2, 2))
2405 {
2406 Word AdrWord;
2407 Boolean OK;
2408
2409 AdrWord = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
2410 if (OK)
2411 {
2412 Byte Pwr;
2413 Byte ByteSizeLg2 = Code & 3, ByteSize = 1 << ByteSizeLg2;
2414
2415 if (!IsPwr2(AdrWord, &Pwr)) WrStrErrorPos(ErrNum_NotPwr2, &ArgStr[1]);
2416 else if (Pwr <= ByteSizeLg2) WrStrErrorPos(ErrNum_UnderRange, &ArgStr[1]);
2417 else
2418 {
2419 AdrWord -= ByteSize;
2420 DecodeAdr(&ArgStr[2], MModReg | MModXReg);
2421 if ((AdrType != ModNone) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
2422 else
2423 switch (AdrType)
2424 {
2425 case ModReg:
2426 CodeLen = 4;
2427 BAsmCode[0] = 0xd8 + AdrMode;
2428 BAsmCode[1] = Code;
2429 BAsmCode[2] = Lo(AdrWord);
2430 BAsmCode[3] = Hi(AdrWord);
2431 break;
2432 case ModXReg:
2433 CodeLen = 5;
2434 BAsmCode[0] = 0xd7;
2435 BAsmCode[1] = AdrMode;
2436 BAsmCode[2] = Code;
2437 BAsmCode[3] = Lo(AdrWord);
2438 BAsmCode[4] = Hi(AdrWord);
2439 break;
2440 }
2441 }
2442 }
2443 }
2444 }
2445
DecodeRLD_RRD(Word Code)2446 static void DecodeRLD_RRD(Word Code)
2447 {
2448 if (!ChkArgCnt(1, 2));
2449 else if ((ArgCnt == 2) && (as_strcasecmp(ArgStr[1].Str, "A"))) WrError(ErrNum_InvAddrMode);
2450 else
2451 {
2452 DecodeAdr(&ArgStr[ArgCnt], MModMem);
2453 if (AdrType != ModNone)
2454 {
2455 CodeLen = 2 + AdrCnt;
2456 BAsmCode[0] = 0x80 + AdrMode;
2457 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
2458 BAsmCode[1 + AdrCnt] = Code;
2459 }
2460 }
2461 }
2462
DecodeSCC(Word Code)2463 static void DecodeSCC(Word Code)
2464 {
2465 UNUSED(Code);
2466
2467 if (ChkArgCnt(2, 2))
2468 {
2469 int Cond = DecodeCondition(ArgStr[1].Str);
2470 if (Cond >= ConditionCnt) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
2471 else
2472 {
2473 DecodeAdr(&ArgStr[2], MModReg | MModXReg);
2474 if (OpSize > 1) WrError(ErrNum_UndefOpSizes);
2475 else
2476 {
2477 switch (AdrType)
2478 {
2479 case ModReg:
2480 CodeLen = 2;
2481 BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
2482 BAsmCode[1] = 0x70 + Conditions[Cond].Code;
2483 break;
2484 case ModXReg:
2485 CodeLen = 3;
2486 BAsmCode[0] = 0xc7 + (OpSize << 4);
2487 BAsmCode[1] = AdrMode;
2488 BAsmCode[2] = 0x70 + Conditions[Cond].Code;
2489 break;
2490 }
2491 }
2492 }
2493 }
2494 return;
2495 }
2496
2497 /*---------------------------------------------------------------------------*/
2498
AddSize(const char * NName,Byte NCode,InstProc Proc,Word SizeMask)2499 static void AddSize(const char *NName, Byte NCode, InstProc Proc, Word SizeMask)
2500 {
2501 int l;
2502 char SizeName[20];
2503
2504 AddInstTable(InstTable, NName, 0xff00 | NCode, Proc);
2505 l = as_snprintf(SizeName, sizeof(SizeName), "%sB", NName);
2506 if (SizeMask & 1)
2507 AddInstTable(InstTable, SizeName, 0x0000 | NCode, Proc);
2508 if (SizeMask & 2)
2509 {
2510 SizeName[l - 1] = 'W';
2511 AddInstTable(InstTable, SizeName, 0x0100 | NCode, Proc);
2512 }
2513
2514 /* CP(L) would generate conflict with CPL instruction - dispatch
2515 it from CPL single-op instruction if ArgCnt >= 2! */
2516
2517 if ((SizeMask & 4) && (strcmp(NName, "CP")))
2518 {
2519 SizeName[l - 1] = 'L';
2520 AddInstTable(InstTable, SizeName, 0x0200 | NCode, Proc);
2521 }
2522 }
2523
AddMod(const char * NName,Byte NCode)2524 static void AddMod(const char *NName, Byte NCode)
2525 {
2526 int l;
2527 char SizeName[20];
2528
2529 l = as_snprintf(SizeName, sizeof(SizeName), "%s1", NName);
2530 AddInstTable(InstTable, SizeName, NCode, DecodeMINC_MDEC);
2531 SizeName[l - 1] = '2';
2532 AddInstTable(InstTable, SizeName, NCode | 1, DecodeMINC_MDEC);
2533 SizeName[l - 1] = '4';
2534 AddInstTable(InstTable, SizeName, NCode | 2, DecodeMINC_MDEC);
2535 }
2536
AddFixed(const char * NName,Word NCode,Byte NFlag,Boolean NSup)2537 static void AddFixed(const char *NName, Word NCode, Byte NFlag, Boolean NSup)
2538 {
2539 if (InstrZ >= FixedOrderCnt) exit(255);
2540 FixedOrders[InstrZ].Code = NCode;
2541 FixedOrders[InstrZ].CPUFlag = NFlag;
2542 FixedOrders[InstrZ].InSup = NSup;
2543 AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
2544 }
2545
AddReg(const char * NName,Word NCode,Byte NMask)2546 static void AddReg(const char *NName, Word NCode, Byte NMask)
2547 {
2548 if (InstrZ >= RegOrderCnt) exit(255);
2549 RegOrders[InstrZ].Code = NCode;
2550 RegOrders[InstrZ].OpMask = NMask;
2551 AddInstTable(InstTable, NName, InstrZ++, DecodeReg);
2552 }
2553
AddImm(const char * NName,Word NCode,Boolean NInSup,Byte NMinMax,Byte NMaxMax,ShortInt NDefault)2554 static void AddImm(const char *NName, Word NCode, Boolean NInSup,
2555 Byte NMinMax, Byte NMaxMax, ShortInt NDefault)
2556 {
2557 if (InstrZ >= ImmOrderCnt) exit(255);
2558 ImmOrders[InstrZ].Code = NCode;
2559 ImmOrders[InstrZ].InSup = NInSup;
2560 ImmOrders[InstrZ].MinMax = NMinMax;
2561 ImmOrders[InstrZ].MaxMax = NMaxMax;
2562 ImmOrders[InstrZ].Default = NDefault;
2563 AddInstTable(InstTable, NName, InstrZ++, DecodeImm);
2564 }
2565
AddALU2(const char * NName,Byte NCode)2566 static void AddALU2(const char *NName, Byte NCode)
2567 {
2568 AddSize(NName, NCode, DecodeALU2, 7);
2569 }
2570
AddShift(const char * NName)2571 static void AddShift(const char *NName)
2572 {
2573 AddSize(NName, InstrZ++, DecodeShift, 7);
2574 }
2575
AddMulDiv(const char * NName)2576 static void AddMulDiv(const char *NName)
2577 {
2578 AddInstTable(InstTable, NName, InstrZ++, DecodeMulDiv);
2579 }
2580
AddBitCF(const char * NName,Byte NCode)2581 static void AddBitCF(const char *NName, Byte NCode)
2582 {
2583 AddInstTable(InstTable, NName, NCode, DecodeBitCF);
2584 }
2585
AddBit(const char * NName)2586 static void AddBit(const char *NName)
2587 {
2588 AddInstTable(InstTable, NName, InstrZ++, DecodeBit);
2589 }
2590
AddCondition(const char * NName,Byte NCode)2591 static void AddCondition(const char *NName, Byte NCode)
2592 {
2593 if (InstrZ >= ConditionCnt) exit(255);
2594 Conditions[InstrZ].Name = NName;
2595 Conditions[InstrZ++].Code = NCode;
2596 }
2597
InitFields(void)2598 static void InitFields(void)
2599 {
2600 InstTable = CreateInstTable(301);
2601 SetDynamicInstTable(InstTable);
2602
2603 AddInstTable(InstTable, "MULA" , 0, DecodeMULA);
2604 AddInstTable(InstTable, "JP" , 0, DecodeJPCALL);
2605 AddInstTable(InstTable, "CALL" , 1, DecodeJPCALL);
2606 AddInstTable(InstTable, "JR" , 0, DecodeJR);
2607 AddInstTable(InstTable, "JRL" , 1, DecodeJR);
2608 AddInstTable(InstTable, "CALR" , 0, DecodeCALR);
2609 AddInstTable(InstTable, "RET" , 0, DecodeRET);
2610 AddInstTable(InstTable, "RETD" , 0, DecodeRETD);
2611 AddInstTable(InstTable, "DJNZ" , 0, DecodeDJNZ);
2612 AddInstTable(InstTable, "EX" , 0, DecodeEX);
2613 AddInstTable(InstTable, "BS1F" , 0, DecodeBS1x);
2614 AddInstTable(InstTable, "BS1B" , 1, DecodeBS1x);
2615 AddInstTable(InstTable, "LDA" , 0, DecodeLDA);
2616 AddInstTable(InstTable, "LDAR" , 0, DecodeLDAR);
2617 AddInstTable(InstTable, "LDC" , 0, DecodeLDC);
2618 AddInstTable(InstTable, "LDX" , 0, DecodeLDX);
2619 AddInstTable(InstTable, "LINK" , 0, DecodeLINK);
2620 AddSize("LD", 0, DecodeLD, 7);
2621 AddSize("PUSH", 0, DecodePUSH_POP, 7);
2622 AddSize("POP" , 1, DecodePUSH_POP, 7);
2623 AddSize("INC" , 0, DecodeINC_DEC, 7);
2624 AddSize("DEC" , 1, DecodeINC_DEC, 7);
2625 AddInstTable(InstTable, "CPI" , 0x14, DecodeCPxx);
2626 AddInstTable(InstTable, "CPIR" , 0x15, DecodeCPxx);
2627 AddInstTable(InstTable, "CPD" , 0x16, DecodeCPxx);
2628 AddInstTable(InstTable, "CPDR" , 0x17, DecodeCPxx);
2629 AddSize("LDI", 0x10 , DecodeLDxx, 3);
2630 AddSize("LDIR", 0x11, DecodeLDxx, 3);
2631 AddSize("LDD", 0x12 , DecodeLDxx, 3);
2632 AddSize("LDDR", 0x13, DecodeLDxx, 3);
2633 AddMod("MINC", 0x38);
2634 AddMod("MDEC", 0x3c);
2635 AddInstTable(InstTable, "RLD", 0x06, DecodeRLD_RRD);
2636 AddInstTable(InstTable, "RRD", 0x07, DecodeRLD_RRD);
2637 AddInstTable(InstTable, "SCC", 0, DecodeSCC);
2638
2639 FixedOrders = (FixedOrder *) malloc(sizeof(FixedOrder) * FixedOrderCnt); InstrZ = 0;
2640 AddFixed("CCF" , 0x0012, 3, False);
2641 AddFixed("DECF" , 0x000d, 3, False);
2642 AddFixed("DI" , 0x0607, 3, True );
2643 AddFixed("HALT" , 0x0005, 3, True );
2644 AddFixed("INCF" , 0x000c, 3, False);
2645 AddFixed("MAX" , 0x0004, 1, True );
2646 AddFixed("MIN" , 0x0004, 2, True );
2647 AddFixed("NOP" , 0x0000, 3, False);
2648 AddFixed("NORMAL", 0x0001, 1, True );
2649 AddFixed("RCF" , 0x0010, 3, False);
2650 AddFixed("RETI" , 0x0007, 3, True );
2651 AddFixed("SCF" , 0x0011, 3, False);
2652 AddFixed("ZCF" , 0x0013, 3, False);
2653
2654 RegOrders = (RegOrder *) malloc(sizeof(RegOrder) * RegOrderCnt); InstrZ = 0;
2655 AddReg("CPL" , 0xc006, 3);
2656 AddReg("DAA" , 0xc010, 1);
2657 AddReg("EXTS", 0xc013, 6);
2658 AddReg("EXTZ", 0xc012, 6);
2659 AddReg("MIRR", 0xc016, 2);
2660 AddReg("NEG" , 0xc007, 3);
2661 AddReg("PAA" , 0xc014, 6);
2662 AddReg("UNLK", 0xc00d, 4);
2663
2664 ImmOrders = (ImmOrder *) malloc(sizeof(ImmOrder) * ImmOrderCnt); InstrZ = 0;
2665 AddImm("EI" , 0x0600, True, 7, 7, 0);
2666 AddImm("LDF" , 0x1700, False, 7, 3, -1);
2667 AddImm("SWI" , 0x00f8, False, 7, 7, 7);
2668
2669 AddALU2("ADC", 1);
2670 AddALU2("ADD", 0);
2671 AddALU2("AND", 4);
2672 AddALU2("OR" , 6);
2673 AddALU2("SBC", 3);
2674 AddALU2("SUB", 2);
2675 AddALU2("XOR", 5);
2676 AddALU2("CP" , 7);
2677
2678 InstrZ = 0;
2679 AddShift("RLC");
2680 AddShift("RRC");
2681 AddShift("RL");
2682 AddShift("RR");
2683 AddShift("SLA");
2684 AddShift("SRA");
2685 AddShift("SLL");
2686 AddShift("SRL");
2687
2688 InstrZ = 0;
2689 AddMulDiv("MUL");
2690 AddMulDiv("MULS");
2691 AddMulDiv("DIV");
2692 AddMulDiv("DIVS");
2693
2694 AddBitCF("ANDCF" , 0);
2695 AddBitCF("LDCF" , 3);
2696 AddBitCF("ORCF" , 1);
2697 AddBitCF("STCF" , 4);
2698 AddBitCF("XORCF" , 2);
2699
2700 InstrZ = 0;
2701 AddBit("RES");
2702 AddBit("SET");
2703 AddBit("CHG");
2704 AddBit("BIT");
2705 AddBit("TSET");
2706
2707 Conditions = (Condition *) malloc(sizeof(Condition) * ConditionCnt); InstrZ = 0;
2708 AddCondition("F" , 0);
2709 DefaultCondition = InstrZ; AddCondition("T" , 8);
2710 AddCondition("Z" , 6); AddCondition("NZ" , 14);
2711 AddCondition("C" , 7); AddCondition("NC" , 15);
2712 AddCondition("PL" , 13); AddCondition("MI" , 5);
2713 AddCondition("P" , 13); AddCondition("M" , 5);
2714 AddCondition("NE" , 14); AddCondition("EQ" , 6);
2715 AddCondition("OV" , 4); AddCondition("NOV" , 12);
2716 AddCondition("PE" , 4); AddCondition("PO" , 12);
2717 AddCondition("GE" , 9); AddCondition("LT" , 1);
2718 AddCondition("GT" , 10); AddCondition("LE" , 2);
2719 AddCondition("UGE" , 15); AddCondition("ULT" , 7);
2720 AddCondition("UGT" , 11); AddCondition("ULE" , 3);
2721 }
2722
DeinitFields(void)2723 static void DeinitFields(void)
2724 {
2725 DestroyInstTable(InstTable);
2726 free(FixedOrders);
2727 free(RegOrders);
2728 free(ImmOrders);
2729 free(Conditions);
2730 }
2731
MakeCode_96C141(void)2732 static void MakeCode_96C141(void)
2733 {
2734 CodeLen = 0;
2735 DontPrint = False;
2736 OpSize = -1;
2737 MinOneIs0 = False;
2738
2739 /* zu ignorierendes */
2740
2741 if (Memo("")) return;
2742
2743 /* Pseudoanweisungen */
2744
2745 if (DecodeIntelPseudo(False)) return;
2746
2747 /* vermischt */
2748
2749 if (!LookupInstTable(InstTable, OpPart.Str))
2750 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2751 }
2752
ChkPC_96C141(LargeWord Addr)2753 static Boolean ChkPC_96C141(LargeWord Addr)
2754 {
2755 Boolean ok;
2756
2757 switch (ActPC)
2758 {
2759 case SegCode:
2760 if (Maximum) ok = (Addr <= 0xffffff);
2761 else ok = (Addr <= 0xffff);
2762 break;
2763 default:
2764 ok = False;
2765 }
2766 return (ok);
2767 }
2768
2769
IsDef_96C141(void)2770 static Boolean IsDef_96C141(void)
2771 {
2772 return False;
2773 }
2774
SwitchFrom_96C141(void)2775 static void SwitchFrom_96C141(void)
2776 {
2777 DeinitFields();
2778 ClearONOFF();
2779 }
2780
ChkMoreOneArg(void)2781 static Boolean ChkMoreOneArg(void)
2782 {
2783 return (ArgCnt > 1);
2784 }
2785
SwitchTo_96C141(void)2786 static void SwitchTo_96C141(void)
2787 {
2788 TurnWords = False;
2789 ConstMode = ConstModeIntel;
2790 SetIsOccupiedFnc = ChkMoreOneArg;
2791
2792 PCSymbol = "$";
2793 HeaderID = 0x52;
2794 NOPCode = 0x00;
2795 DivideChars = ",";
2796 HasAttrs = False;
2797
2798 ValidSegs = (1 << SegCode);
2799 Grans[SegCode] = 1;
2800 ListGrans[SegCode] = 1;
2801 SegInits[SegCode] = 0;
2802
2803 MakeCode = MakeCode_96C141;
2804 ChkPC = ChkPC_96C141;
2805 IsDef = IsDef_96C141;
2806 SwitchFrom = SwitchFrom_96C141;
2807 AddONOFF("MAXMODE", &Maximum , MaximumName , False);
2808 AddONOFF("SUPMODE", &SupAllowed, SupAllowedName, False);
2809
2810 InitFields();
2811 }
2812
code96c141_init(void)2813 void code96c141_init(void)
2814 {
2815 CPU96C141 = AddCPU("96C141", SwitchTo_96C141);
2816 CPU93C141 = AddCPU("93C141", SwitchTo_96C141);
2817 }
2818