1 /* code86.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* Codegenerator 8086/V-Serie */
8 /* */
9 /*****************************************************************************/
10
11 #include "stdinc.h"
12 #include <string.h>
13
14 #include "bpemu.h"
15 #include "strutil.h"
16 #include "errmsg.h"
17 #include "asmdef.h"
18 #include "asmsub.h"
19 #include "asmpars.h"
20 #include "asmallg.h"
21 #include "codepseudo.h"
22 #include "intpseudo.h"
23 #include "asmitree.h"
24 #include "codevars.h"
25
26 /*---------------------------------------------------------------------------*/
27
28 typedef struct
29 {
30 const char *Name;
31 CPUVar MinCPU;
32 Word Code;
33 } FixedOrder;
34
35 typedef struct
36 {
37 CPUVar MinCPU;
38 Word Code;
39 Byte Add;
40 } AddOrder;
41
42 #define NO_FWAIT_FLAG 0x2000
43
44 #define FixedOrderCnt 43
45 #define ReptOrderCnt 7
46 #define ShiftOrderCnt 8
47 #define Reg16OrderCnt 3
48 #define ModRegOrderCnt 4
49 #define StringOrderCnt 14
50 #define RelOrderCnt 36
51
52 #define SegRegCnt 3
53 static const char SegRegNames[SegRegCnt + 1][3] =
54 {
55 "ES", "CS", "SS", "DS"
56 };
57 static const Byte SegRegPrefixes[SegRegCnt + 1] =
58 {
59 0x26, 0x2e, 0x36, 0x3e
60 };
61
62 static char ArgSTStr[] = "ST";
63 static const tStrComp ArgST = { { 0, 0 }, ArgSTStr };
64
65 #define TypeNone (-1)
66 #define TypeReg8 0
67 #define TypeReg16 1
68 #define TypeRegSeg 2
69 #define TypeMem 3
70 #define TypeImm 4
71 #define TypeFReg 5
72
73 static ShortInt AdrType;
74 static Byte AdrMode;
75 static Byte AdrVals[6];
76 static ShortInt OpSize;
77 static Boolean UnknownFlag;
78 static unsigned ImmAddrSpaceMask;
79
80 static Boolean NoSegCheck;
81
82 static Byte Prefixes[6];
83 static Byte PrefixLen;
84
85 static Byte SegAssumes[SegRegCnt + 1];
86
87 static CPUVar CPU8086, CPU80186, CPUV30, CPUV35;
88
89 static FixedOrder *FixedOrders, *StringOrders, *ReptOrders, *ShiftOrders,
90 *ModRegOrders, *RelOrders;
91 static AddOrder *Reg16Orders;
92
93 /*------------------------------------------------------------------------------------*/
94
PutCode(Word Code)95 static void PutCode(Word Code)
96 {
97 if (Hi(Code) != 0)
98 BAsmCode[CodeLen++] = Hi(Code);
99 BAsmCode[CodeLen++] = Lo(Code);
100 }
101
MoveAdr(int Dest)102 static void MoveAdr(int Dest)
103 {
104 memcpy(BAsmCode + CodeLen + Dest, AdrVals, AdrCnt);
105 }
106
Sgn(Byte inp)107 static Byte Sgn(Byte inp)
108 {
109 return (inp > 127) ? 0xff : 0;
110 }
111
AddPrefix(Byte Prefix)112 static void AddPrefix(Byte Prefix)
113 {
114 Prefixes[PrefixLen++] = Prefix;
115 }
116
AddPrefixes(void)117 static void AddPrefixes(void)
118 {
119 if ((CodeLen != 0) && (PrefixLen != 0))
120 {
121 memmove(BAsmCode + PrefixLen, BAsmCode, CodeLen);
122 memcpy(BAsmCode, Prefixes, PrefixLen);
123 CodeLen += PrefixLen;
124 }
125 }
126
AbleToSign(Word Arg)127 static Boolean AbleToSign(Word Arg)
128 {
129 return ((Arg <= 0x7f) || (Arg >= 0xff80));
130 }
131
MinOneIs0(void)132 static Boolean MinOneIs0(void)
133 {
134 if ((UnknownFlag) && (OpSize == -1))
135 {
136 OpSize = 0;
137 return True;
138 }
139 else
140 return False;
141 }
142
ChkOpSize(ShortInt NewSize)143 static void ChkOpSize(ShortInt NewSize)
144 {
145 if (OpSize == -1)
146 OpSize = NewSize;
147 else if (OpSize != NewSize)
148 {
149 AdrType = TypeNone;
150 WrError(ErrNum_ConfOpSizes);
151 }
152 }
153
ChkSingleSpace(Byte Seg,Byte EffSeg,Byte MomSegment)154 static void ChkSingleSpace(Byte Seg, Byte EffSeg, Byte MomSegment)
155 {
156 Byte z;
157
158 /* liegt Operand im zu pruefenden Segment? nein-->vergessen */
159
160 if (!(MomSegment & (1 << Seg)))
161 return;
162
163 /* zeigt bish. benutztes Segmentregister auf dieses Segment? ja-->ok */
164
165 if (EffSeg == Seg)
166 return;
167
168 /* falls schon ein Override gesetzt wurde, nur warnen */
169
170 if (PrefixLen > 0)
171 WrError(ErrNum_WrongSegment);
172
173 /* ansonsten ein passendes Segment suchen und warnen, falls keines da */
174
175 else
176 {
177 z = 0;
178 while ((z <= SegRegCnt) && (SegAssumes[z] != Seg))
179 z++;
180 if (z > SegRegCnt)
181 WrXError(ErrNum_InAccSegment, SegNames[Seg]);
182 else
183 AddPrefix(SegRegPrefixes[z]);
184 }
185 }
186
ChkSpaces(ShortInt SegBuffer,Byte MomSegment)187 static void ChkSpaces(ShortInt SegBuffer, Byte MomSegment)
188 {
189 Byte EffSeg;
190
191 if (NoSegCheck)
192 return;
193
194 /* in welches Segment geht das benutzte Segmentregister ? */
195
196 EffSeg = SegAssumes[SegBuffer];
197
198 /* Zieloperand in Code-/Datensegment ? */
199
200 ChkSingleSpace(SegCode, EffSeg, MomSegment);
201 ChkSingleSpace(SegXData, EffSeg, MomSegment);
202 ChkSingleSpace(SegData, EffSeg, MomSegment);
203 }
204
DecodeAdr(const tStrComp * pArg)205 static void DecodeAdr(const tStrComp *pArg)
206 {
207 static const int RegCnt = 8;
208 static const char Reg16Names[8][3] =
209 {
210 "AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI"
211 };
212 static const char Reg8Names[8][3] =
213 {
214 "AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH"
215 };
216 static const Byte RMCodes[8] =
217 {
218 11, 12, 21, 22, 1, 2 , 20, 10
219 };
220
221 int RegZ, z;
222 Boolean IsImm;
223 ShortInt IndexBuf, BaseBuf;
224 Byte SumBuf;
225 LongInt DispAcc, DispSum;
226 char *pIndirStart, *pIndirEnd, *pSep;
227 ShortInt SegBuffer;
228 Byte MomSegment;
229 ShortInt FoundSize;
230 tStrComp Arg;
231 int ArgLen = strlen(pArg->Str);
232
233 AdrType = TypeNone; AdrCnt = 0;
234 SegBuffer = -1; MomSegment = 0;
235
236 for (RegZ = 0; RegZ < RegCnt; RegZ++)
237 {
238 if (!as_strcasecmp(pArg->Str, Reg16Names[RegZ]))
239 {
240 AdrType = TypeReg16; AdrMode = RegZ;
241 ChkOpSize(1);
242 return;
243 }
244 if (!as_strcasecmp(pArg->Str, Reg8Names[RegZ]))
245 {
246 AdrType = TypeReg8; AdrMode = RegZ;
247 ChkOpSize(0);
248 return;
249 }
250 }
251
252 for (RegZ = 0; RegZ <= SegRegCnt; RegZ++)
253 if (!as_strcasecmp(pArg->Str, SegRegNames[RegZ]))
254 {
255 AdrType = TypeRegSeg; AdrMode = RegZ;
256 ChkOpSize(1);
257 return;
258 }
259
260 if (FPUAvail)
261 {
262 if (!as_strcasecmp(pArg->Str, "ST"))
263 {
264 AdrType = TypeFReg; AdrMode = 0;
265 ChkOpSize(4);
266 return;
267 }
268
269 if ((ArgLen > 4) && (!as_strncasecmp(pArg->Str, "ST(", 3)) && (pArg->Str[ArgLen - 1] == ')'))
270 {
271 tStrComp Num;
272 Boolean OK;
273
274 StrCompRefRight(&Num, pArg, 3);
275 StrCompShorten(&Num, 1);
276 AdrMode = EvalStrIntExpression(&Num, UInt3, &OK);
277 if (OK)
278 {
279 AdrType = TypeFReg;
280 ChkOpSize(4);
281 }
282 return;
283 }
284 }
285
286 IsImm = True;
287 IndexBuf = 0; BaseBuf = 0;
288 DispAcc = 0; FoundSize = -1;
289 Arg = *pArg;
290 if (!as_strncasecmp(Arg.Str, "WORD PTR", 8))
291 {
292 StrCompIncRefLeft(&Arg, 8);
293 FoundSize = 1;
294 IsImm = False;
295 KillPrefBlanksStrCompRef(&Arg);
296 }
297 else if (!as_strncasecmp(Arg.Str, "BYTE PTR", 8))
298 {
299 StrCompIncRefLeft(&Arg, 8);
300 FoundSize = 0;
301 IsImm = False;
302 KillPrefBlanksStrCompRef(&Arg);
303 }
304 else if (!as_strncasecmp(Arg.Str, "DWORD PTR", 9))
305 {
306 StrCompIncRefLeft(&Arg, 9);
307 FoundSize = 2;
308 IsImm = False;
309 KillPrefBlanksStrCompRef(&Arg);
310 }
311 else if (!as_strncasecmp(Arg.Str, "QWORD PTR", 9))
312 {
313 StrCompIncRefLeft(&Arg, 9);
314 FoundSize = 3;
315 IsImm = False;
316 KillPrefBlanksStrCompRef(&Arg);
317 }
318 else if (!as_strncasecmp(Arg.Str, "TBYTE PTR", 9))
319 {
320 StrCompIncRefLeft(&Arg, 9);
321 FoundSize = 4;
322 IsImm = False;
323 KillPrefBlanksStrCompRef(&Arg);
324 }
325
326 if ((strlen(Arg.Str) > 2) && (Arg.Str[2] == ':'))
327 {
328 tStrComp Remainder;
329
330 StrCompSplitRef(&Arg, &Remainder, &Arg, Arg.Str + 2);
331 for (z = 0; z <= SegRegCnt; z++)
332 if (!as_strcasecmp(Arg.Str, SegRegNames[z]))
333 {
334 SegBuffer = z;
335 AddPrefix(SegRegPrefixes[SegBuffer]);
336 break;
337 }
338 if (SegBuffer < 0)
339 {
340 WrStrErrorPos(ErrNum_InvReg, &Arg);
341 return;
342 }
343 Arg = Remainder;
344 }
345
346 do
347 {
348 pIndirStart = QuotPos(Arg.Str, '[');
349
350 /* no address expr or outer displacement: */
351
352 if (!pIndirStart || (pIndirStart != Arg.Str))
353 {
354 tStrComp Remainder;
355 tEvalResult EvalResult;
356
357 if (pIndirStart)
358 StrCompSplitRef(&Arg, &Remainder, &Arg, pIndirStart);
359 DispAcc += EvalStrIntExpressionWithResult(&Arg, Int16, &EvalResult);
360 if (!EvalResult.OK)
361 return;
362 UnknownFlag = UnknownFlag || mFirstPassUnknown(EvalResult.Flags);
363 MomSegment |= EvalResult.AddrSpaceMask;
364 if (FoundSize == eSymbolSizeUnknown)
365 FoundSize = EvalResult.DataSize;
366 if (pIndirStart)
367 Arg = Remainder;
368 else
369 break;
370 }
371 else
372 StrCompIncRefLeft(&Arg, 1);
373
374 /* Arg now points right behind [ */
375
376 if (pIndirStart)
377 {
378 tStrComp IndirArg, OutRemainder, IndirArgRemainder;
379 Boolean NegFlag, OldNegFlag;
380
381 IsImm = False;
382
383 pIndirEnd = RQuotPos(Arg.Str, ']');
384 if (!pIndirEnd)
385 {
386 WrError(ErrNum_BrackErr);
387 return;
388 }
389
390 StrCompSplitRef(&IndirArg, &OutRemainder, &Arg, pIndirEnd);
391 OldNegFlag = False;
392
393 do
394 {
395 NegFlag = False;
396 pSep = QuotMultPos(IndirArg.Str, "+-");
397 NegFlag = pSep && (*pSep == '-');
398
399 if (pSep)
400 StrCompSplitRef(&IndirArg, &IndirArgRemainder, &IndirArg, pSep);
401
402 if (!as_strcasecmp(IndirArg.Str, "BX"))
403 {
404 if ((OldNegFlag) || (BaseBuf != 0))
405 return;
406 else
407 BaseBuf = 1;
408 }
409 else if (!as_strcasecmp(IndirArg.Str, "BP"))
410 {
411 if ((OldNegFlag) || (BaseBuf != 0))
412 return;
413 else
414 BaseBuf = 2;
415 }
416 else if (!as_strcasecmp(IndirArg.Str, "SI"))
417 {
418 if ((OldNegFlag) || (IndexBuf != 0))
419 return;
420 else
421 IndexBuf = 1;
422 }
423 else if (!as_strcasecmp(IndirArg.Str, "DI"))
424 {
425 if ((OldNegFlag) || (IndexBuf !=0 ))
426 return;
427 else
428 IndexBuf = 2;
429 }
430 else
431 {
432 tEvalResult EvalResult;
433
434 DispSum = EvalStrIntExpressionWithResult(&IndirArg, Int16, &EvalResult);
435 if (!EvalResult.OK)
436 return;
437 UnknownFlag = UnknownFlag || mFirstPassUnknown(EvalResult.Flags);
438 DispAcc = OldNegFlag ? DispAcc - DispSum : DispAcc + DispSum;
439 MomSegment |= EvalResult.AddrSpaceMask;
440 if (FoundSize == eSymbolSizeUnknown)
441 FoundSize = EvalResult.DataSize;
442 }
443 OldNegFlag = NegFlag;
444 if (pSep)
445 IndirArg = IndirArgRemainder;
446 }
447 while (pSep);
448 Arg = OutRemainder;
449 }
450 }
451 while (*Arg.Str);
452
453 SumBuf = BaseBuf * 10 + IndexBuf;
454
455 /* welches Segment effektiv benutzt ? */
456
457 if (SegBuffer == -1)
458 SegBuffer = (BaseBuf == 2) ? 2 : 3;
459
460 /* nur Displacement */
461
462 if (0 == SumBuf)
463 {
464 /* immediate */
465
466 if (IsImm)
467 {
468 ImmAddrSpaceMask = MomSegment;
469 if (((UnknownFlag) && (OpSize == 0)) || (MinOneIs0()))
470 DispAcc &= 0xff;
471 switch (OpSize)
472 {
473 case -1:
474 WrError(ErrNum_UndefOpSizes);
475 break;
476 case 0:
477 if ((DispAcc <- 128) || (DispAcc > 255)) WrError(ErrNum_OverRange);
478 else
479 {
480 AdrType = TypeImm;
481 AdrVals[0] = DispAcc & 0xff;
482 AdrCnt = 1;
483 }
484 break;
485 case 1:
486 AdrType = TypeImm;
487 AdrVals[0] = Lo(DispAcc);
488 AdrVals[1] = Hi(DispAcc);
489 AdrCnt = 2;
490 break;
491 default:
492 WrError(ErrNum_InvOpSize);
493 break;
494 }
495 }
496
497 /* absolut */
498
499 else
500 {
501 AdrType = TypeMem;
502 AdrMode = 0x06;
503 AdrVals[0] = Lo(DispAcc);
504 AdrVals[1] = Hi(DispAcc);
505 AdrCnt = 2;
506 if (FoundSize != -1)
507 ChkOpSize(FoundSize);
508 ChkSpaces(SegBuffer, MomSegment);
509 }
510 }
511
512 /* kombiniert */
513
514 else
515 {
516 AdrType = TypeMem;
517 for (z = 0; z < 8; z++)
518 if (SumBuf == RMCodes[z])
519 AdrMode = z;
520 if (DispAcc == 0)
521 {
522 if (SumBuf == 20)
523 {
524 AdrMode += 0x40;
525 AdrVals[0] = 0;
526 AdrCnt = 1;
527 }
528 }
529 else if (AbleToSign(DispAcc))
530 {
531 AdrMode += 0x40;
532 AdrVals[0] = DispAcc & 0xff;
533 AdrCnt = 1;
534 }
535 else
536 {
537 AdrMode += 0x80;
538 AdrVals[0] = Lo(DispAcc);
539 AdrVals[1] = Hi(DispAcc);
540 AdrCnt = 2;
541 }
542 ChkSpaces(SegBuffer, MomSegment);
543 if (FoundSize != -1)
544 ChkOpSize(FoundSize);
545 }
546 }
547
AddFWait(Word * pCode)548 static void AddFWait(Word *pCode)
549 {
550 if (*pCode & NO_FWAIT_FLAG)
551 *pCode &= ~NO_FWAIT_FLAG;
552 else
553 AddPrefix(0x9b);
554 }
555
FPUEntry(Word * pCode)556 static Boolean FPUEntry(Word *pCode)
557 {
558 if (!FPUAvail)
559 {
560 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
561 return FALSE;
562 }
563
564 AddFWait(pCode);
565 return TRUE;
566 }
567
568 /*---------------------------------------------------------------------------*/
569
DecodeMOV(Word Index)570 static void DecodeMOV(Word Index)
571 {
572 Byte AdrByte;
573 UNUSED(Index);
574
575 if (ChkArgCnt(2, 2))
576 {
577 DecodeAdr(&ArgStr[1]);
578 switch (AdrType)
579 {
580 case TypeReg8:
581 case TypeReg16:
582 AdrByte = AdrMode;
583 DecodeAdr(&ArgStr[2]);
584 switch (AdrType)
585 {
586 case TypeReg8:
587 case TypeReg16:
588 BAsmCode[CodeLen++] = 0x8a | OpSize;
589 BAsmCode[CodeLen++] = 0xc0 | (AdrByte << 3) | AdrMode;
590 break;
591 case TypeMem:
592 if ((AdrByte == 0) && (AdrMode == 6))
593 {
594 BAsmCode[CodeLen] = 0xa0 | OpSize;
595 MoveAdr(1);
596 CodeLen += 1 + AdrCnt;
597 }
598 else
599 {
600 BAsmCode[CodeLen++] = 0x8a | OpSize;
601 BAsmCode[CodeLen++] = AdrMode | (AdrByte << 3);
602 MoveAdr(0);
603 CodeLen += AdrCnt;
604 }
605 break;
606 case TypeRegSeg:
607 if (OpSize == 0) WrError(ErrNum_ConfOpSizes);
608 else
609 {
610 BAsmCode[CodeLen++] = 0x8c;
611 BAsmCode[CodeLen++] = 0xc0 | (AdrMode << 3) | AdrByte;
612 }
613 break;
614 case TypeImm:
615 BAsmCode[CodeLen++] = 0xb0 | (OpSize << 3) | AdrByte;
616 MoveAdr(0);
617 CodeLen += AdrCnt;
618 break;
619 default:
620 if (AdrType != TypeNone)
621 WrError(ErrNum_InvAddrMode);
622 }
623 break;
624 case TypeMem:
625 BAsmCode[CodeLen + 1] = AdrMode;
626 MoveAdr(2);
627 AdrByte = AdrCnt;
628 DecodeAdr(&ArgStr[2]);
629 switch (AdrType)
630 {
631 case TypeReg8:
632 case TypeReg16:
633 if ((AdrMode == 0) && (BAsmCode[CodeLen + 1] == 6))
634 {
635 BAsmCode[CodeLen] = 0xa2 | OpSize;
636 memmove(BAsmCode + CodeLen + 1, BAsmCode + CodeLen + 2, AdrByte);
637 CodeLen += 1 + AdrByte;
638 }
639 else
640 {
641 BAsmCode[CodeLen] = 0x88 | OpSize;
642 BAsmCode[CodeLen + 1] |= AdrMode << 3;
643 CodeLen += 2 + AdrByte;
644 }
645 break;
646 case TypeRegSeg:
647 BAsmCode[CodeLen] = 0x8c;
648 BAsmCode[CodeLen + 1] |= AdrMode << 3;
649 CodeLen += 2 + AdrByte;
650 break;
651 case TypeImm:
652 BAsmCode[CodeLen] = 0xc6 | OpSize;
653 MoveAdr(2 + AdrByte);
654 CodeLen += 2 + AdrByte + AdrCnt;
655 break;
656 default:
657 if (AdrType != TypeNone)
658 WrError(ErrNum_InvAddrMode);
659 }
660 break;
661 case TypeRegSeg:
662 BAsmCode[CodeLen + 1] = AdrMode << 3;
663 DecodeAdr(&ArgStr[2]);
664 switch (AdrType)
665 {
666 case TypeReg16:
667 BAsmCode[CodeLen++] = 0x8e;
668 BAsmCode[CodeLen++] |= 0xc0 + AdrMode;
669 break;
670 case TypeMem:
671 BAsmCode[CodeLen] = 0x8e;
672 BAsmCode[CodeLen + 1] |= AdrMode;
673 MoveAdr(2);
674 CodeLen += 2 + AdrCnt;
675 break;
676 default:
677 if (AdrType != TypeNone)
678 WrError(ErrNum_InvAddrMode);
679 }
680 break;
681 default:
682 if (AdrType != TypeNone)
683 WrError(ErrNum_InvAddrMode);
684 }
685 }
686 AddPrefixes();
687 }
688
DecodeINCDEC(Word Index)689 static void DecodeINCDEC(Word Index)
690 {
691 if (ChkArgCnt(1, 1))
692 {
693 DecodeAdr(&ArgStr[1]);
694 switch (AdrType)
695 {
696 case TypeReg16:
697 BAsmCode[CodeLen] = 0x40 | AdrMode | Index;
698 CodeLen++;
699 break;
700 case TypeReg8:
701 BAsmCode[CodeLen] = 0xfe;
702 BAsmCode[CodeLen + 1] = 0xc0 | AdrMode | Index;
703 CodeLen += 2;
704 break;
705 case TypeMem:
706 MinOneIs0();
707 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
708 else
709 {
710 BAsmCode[CodeLen] = 0xfe | OpSize; /* ANSI :-0 */
711 BAsmCode[CodeLen + 1] = AdrMode | Index;
712 MoveAdr(2);
713 CodeLen += 2 + AdrCnt;
714 }
715 break;
716 default:
717 if (AdrType != TypeNone)
718 WrError(ErrNum_InvAddrMode);
719 }
720 }
721 AddPrefixes();
722 }
723
DecodeINT(Word Index)724 static void DecodeINT(Word Index)
725 {
726 Boolean OK;
727 UNUSED(Index);
728
729 if (ChkArgCnt(1, 1))
730 {
731 BAsmCode[CodeLen + 1] = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
732 if (OK)
733 {
734 if (BAsmCode[1] == 3)
735 BAsmCode[CodeLen++] = 0xcc;
736 else
737 {
738 BAsmCode[CodeLen] = 0xcd;
739 CodeLen += 2;
740 }
741 }
742 }
743 AddPrefixes();
744 }
745
DecodeINOUT(Word Index)746 static void DecodeINOUT(Word Index)
747 {
748 if (ChkArgCnt(2, 2))
749 {
750 tStrComp *pPortArg = Index ? &ArgStr[1] : &ArgStr[2],
751 *pRegArg = Index ? &ArgStr[2] : &ArgStr[1];
752
753 DecodeAdr(pRegArg);
754 switch (AdrType)
755 {
756 case TypeReg8:
757 case TypeReg16:
758 if (AdrMode != 0) WrError(ErrNum_InvAddrMode);
759 else if (!as_strcasecmp(pPortArg->Str, "DX"))
760 BAsmCode[CodeLen++] = 0xec | OpSize | Index;
761 else
762 {
763 tEvalResult EvalResult;
764
765 BAsmCode[CodeLen + 1] = EvalStrIntExpressionWithResult(pPortArg, UInt8, &EvalResult);
766 if (EvalResult.OK)
767 {
768 ChkSpace(SegIO, EvalResult.AddrSpaceMask);
769 BAsmCode[CodeLen] = 0xe4 | OpSize | Index;
770 CodeLen += 2;
771 }
772 }
773 break;
774 default:
775 if (AdrType != TypeNone)
776 WrError(ErrNum_InvAddrMode);
777 }
778 }
779 AddPrefixes();
780 }
781
DecodeCALLJMP(Word Index)782 static void DecodeCALLJMP(Word Index)
783 {
784 Byte AdrByte;
785 Word AdrWord;
786 Boolean OK;
787
788 if (ChkArgCnt(1, 1))
789 {
790 char *pAdr = ArgStr[1].Str;
791
792 if (!strncmp(pAdr, "SHORT ", 6))
793 {
794 AdrByte = 2;
795 pAdr += 6;
796 KillPrefBlanks(pAdr);
797 }
798 else if ((!strncmp(pAdr, "LONG ", 5)) || (!strncmp(pAdr, "NEAR ", 5)))
799 {
800 AdrByte = 1;
801 pAdr += 5;
802 KillPrefBlanks(pAdr);
803 }
804 else
805 AdrByte = 0;
806 OK = True;
807 if (Index == 0)
808 {
809 if (AdrByte == 2)
810 {
811 WrError(ErrNum_InvAddrMode);
812 OK = False;
813 }
814 else
815 AdrByte = 1;
816 }
817
818 if (OK)
819 {
820 OpSize = 1;
821 DecodeAdr(&ArgStr[1]);
822 switch (AdrType)
823 {
824 case TypeReg16:
825 BAsmCode[0] = 0xff;
826 BAsmCode[1] = AdrMode | (0xd0 + (Index << 4));
827 CodeLen = 2;
828 break;
829 case TypeMem:
830 BAsmCode[0] = 0xff;
831 BAsmCode[1] = AdrMode | (0x10 + (Index << 4));
832 MoveAdr(2);
833 CodeLen = 2 + AdrCnt;
834 break;
835 case TypeImm:
836 ChkSpace(SegCode, ImmAddrSpaceMask);
837 AdrWord = (((Word) AdrVals[1]) << 8) | AdrVals[0];
838 if ((AdrByte == 2) || ((AdrByte == 0) && (AbleToSign(AdrWord - EProgCounter() - 2))))
839 {
840 AdrWord -= EProgCounter() + 2;
841 if (!AbleToSign(AdrWord)) WrError(ErrNum_DistTooBig);
842 else
843 {
844 BAsmCode[0] = 0xeb;
845 BAsmCode[1] = Lo(AdrWord);
846 CodeLen = 2;
847 }
848 }
849 else
850 {
851 AdrWord -= EProgCounter() + 3;
852 BAsmCode[0] = 0xe8 | Index;
853 BAsmCode[1] = Lo(AdrWord);
854 BAsmCode[2] = Hi(AdrWord);
855 CodeLen = 3;
856 AdrWord++;
857 }
858 break;
859 default:
860 if (AdrType != TypeNone)
861 WrError(ErrNum_InvAddrMode);
862 }
863 }
864 }
865 AddPrefixes();
866 }
867
DecodePUSHPOP(Word Index)868 static void DecodePUSHPOP(Word Index)
869 {
870 if (ChkArgCnt(1, 1))
871 {
872 OpSize = 1; DecodeAdr(&ArgStr[1]);
873 switch (AdrType)
874 {
875 case TypeReg16:
876 BAsmCode[CodeLen] = 0x50 | AdrMode | (Index << 3);
877 CodeLen++;
878 break;
879 case TypeRegSeg:
880 BAsmCode[CodeLen] = 0x06 | (AdrMode << 3) | Index;
881 CodeLen++;
882 break;
883 case TypeMem:
884 BAsmCode[CodeLen] = 0x8f;
885 BAsmCode[CodeLen + 1] = AdrMode;
886 if (Index == 0)
887 {
888 BAsmCode[CodeLen] += 0x70;
889 BAsmCode[CodeLen + 1] += 0x30;
890 }
891 MoveAdr(2);
892 CodeLen += 2 + AdrCnt;
893 break;
894 case TypeImm:
895 if (!ChkMinCPU(CPU80186));
896 else if (Index == 1) WrError(ErrNum_InvAddrMode);
897 else
898 {
899 BAsmCode[CodeLen] = 0x68;
900 BAsmCode[CodeLen + 1] = AdrVals[0];
901 if (Sgn(AdrVals[0]) == AdrVals[1])
902 {
903 BAsmCode[CodeLen] += 2;
904 CodeLen += 2;
905 }
906 else
907 {
908 BAsmCode[CodeLen + 2] = AdrVals[1];
909 CodeLen += 3;
910 }
911 }
912 break;
913 default:
914 if (AdrType != TypeNone)
915 WrError(ErrNum_InvAddrMode);
916 }
917 }
918 AddPrefixes();
919 }
920
DecodeNOTNEG(Word Index)921 static void DecodeNOTNEG(Word Index)
922 {
923 if (ChkArgCnt(1, 1))
924 {
925 DecodeAdr(&ArgStr[1]);
926 MinOneIs0();
927 BAsmCode[CodeLen] = 0xf6 | OpSize;
928 BAsmCode[CodeLen + 1] = 0x10 | Index;
929 switch (AdrType)
930 {
931 case TypeReg8:
932 case TypeReg16:
933 BAsmCode[CodeLen + 1] |= 0xc0 | AdrMode;
934 CodeLen += 2;
935 break;
936 case TypeMem:
937 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
938 else
939 {
940 BAsmCode[CodeLen + 1] |= AdrMode;
941 MoveAdr(2);
942 CodeLen += 2 + AdrCnt;
943 }
944 break;
945 default:
946 if (AdrType != TypeNone)
947 WrError(ErrNum_InvAddrMode);
948 }
949 }
950 AddPrefixes();
951 }
952
DecodeRET(Word Index)953 static void DecodeRET(Word Index)
954 {
955 Word AdrWord;
956 Boolean OK;
957
958 if (!ChkArgCnt(0, 1));
959 else if (ArgCnt == 0)
960 BAsmCode[CodeLen++] = 0xc3 | Index;
961 else
962 {
963 AdrWord = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
964 if (OK)
965 {
966 BAsmCode[CodeLen++] = 0xc2 | Index;
967 BAsmCode[CodeLen++] = Lo(AdrWord);
968 BAsmCode[CodeLen++] = Hi(AdrWord);
969 }
970 }
971 }
972
DecodeTEST(Word Index)973 static void DecodeTEST(Word Index)
974 {
975 Byte AdrByte;
976 UNUSED(Index);
977
978 if (ChkArgCnt(2, 2))
979 {
980 DecodeAdr(&ArgStr[1]);
981 switch (AdrType)
982 {
983 case TypeReg8:
984 case TypeReg16:
985 BAsmCode[CodeLen + 1] = (AdrMode << 3);
986 DecodeAdr(&ArgStr[2]);
987 switch (AdrType)
988 {
989 case TypeReg8:
990 case TypeReg16:
991 BAsmCode[CodeLen + 1] += 0xc0 | AdrMode;
992 BAsmCode[CodeLen] = 0x84 | OpSize;
993 CodeLen += 2;
994 break;
995 case TypeMem:
996 BAsmCode[CodeLen + 1] |= AdrMode;
997 BAsmCode[CodeLen] = 0x84 | OpSize;
998 MoveAdr(2);
999 CodeLen += 2 + AdrCnt;
1000 break;
1001 case TypeImm:
1002 if (((BAsmCode[CodeLen+1] >> 3) & 7) == 0)
1003 {
1004 BAsmCode[CodeLen] = 0xa8 | OpSize;
1005 MoveAdr(1);
1006 CodeLen += 1 + AdrCnt;
1007 }
1008 else
1009 {
1010 BAsmCode[CodeLen] = OpSize | 0xf6;
1011 BAsmCode[CodeLen + 1] = (BAsmCode[CodeLen + 1] >> 3) | 0xc0;
1012 MoveAdr(2);
1013 CodeLen += 2 + AdrCnt;
1014 }
1015 break;
1016 default:
1017 if (AdrType != TypeNone) WrError(ErrNum_InvAddrMode);
1018 }
1019 break;
1020 case TypeMem:
1021 BAsmCode[CodeLen + 1] = AdrMode;
1022 AdrByte = AdrCnt;
1023 MoveAdr(2);
1024 DecodeAdr(&ArgStr[2]);
1025 switch (AdrType)
1026 {
1027 case TypeReg8:
1028 case TypeReg16:
1029 BAsmCode[CodeLen] = 0x84 | OpSize;
1030 BAsmCode[CodeLen + 1] += (AdrMode << 3);
1031 CodeLen += 2 + AdrByte;
1032 break;
1033 case TypeImm:
1034 BAsmCode[CodeLen] = OpSize | 0xf6;
1035 MoveAdr(2 + AdrByte);
1036 CodeLen += 2 + AdrCnt + AdrByte;
1037 break;
1038 default:
1039 if (AdrType != TypeNone)
1040 WrError(ErrNum_InvAddrMode);
1041 }
1042 break;
1043 default:
1044 if (AdrType != TypeNone)
1045 WrError(ErrNum_InvAddrMode);
1046 }
1047 }
1048 AddPrefixes();
1049 }
1050
DecodeXCHG(Word Index)1051 static void DecodeXCHG(Word Index)
1052 {
1053 Byte AdrByte;
1054 UNUSED(Index);
1055
1056 if (ChkArgCnt(2, 2))
1057 {
1058 DecodeAdr(&ArgStr[1]);
1059 switch (AdrType)
1060 {
1061 case TypeReg8:
1062 case TypeReg16:
1063 AdrByte = AdrMode;
1064 DecodeAdr(&ArgStr[2]);
1065 switch (AdrType)
1066 {
1067 case TypeReg8:
1068 case TypeReg16:
1069 if ((OpSize == 1) && ((AdrMode == 0) || (AdrByte == 0)))
1070 {
1071 BAsmCode[CodeLen] = 0x90 | AdrMode | AdrByte;
1072 CodeLen++;
1073 }
1074 else
1075 {
1076 BAsmCode[CodeLen] = 0x86 | OpSize;
1077 BAsmCode[CodeLen+1] = AdrMode | 0xc0 | (AdrByte << 3);
1078 CodeLen += 2;
1079 }
1080 break;
1081 case TypeMem:
1082 BAsmCode[CodeLen] = 0x86 | OpSize;
1083 BAsmCode[CodeLen+1] = AdrMode | (AdrByte << 3);
1084 MoveAdr(2);
1085 CodeLen += AdrCnt + 2;
1086 break;
1087 default:
1088 if (AdrType != TypeNone)
1089 WrError(ErrNum_InvAddrMode);
1090 }
1091 break;
1092 case TypeMem:
1093 BAsmCode[CodeLen + 1] = AdrMode;
1094 MoveAdr(2);
1095 AdrByte = AdrCnt;
1096 DecodeAdr(&ArgStr[2]);
1097 switch (AdrType)
1098 {
1099 case TypeReg8:
1100 case TypeReg16:
1101 BAsmCode[CodeLen] = 0x86 | OpSize;
1102 BAsmCode[CodeLen+1] |= (AdrMode << 3);
1103 CodeLen += AdrByte + 2;
1104 break;
1105 default:
1106 if (AdrType != TypeNone)
1107 WrError(ErrNum_InvAddrMode);
1108 }
1109 break;
1110 default:
1111 if (AdrType != TypeNone)
1112 WrError(ErrNum_InvAddrMode);
1113 }
1114 }
1115 AddPrefixes();
1116 }
1117
DecodeCALLJMPF(Word Index)1118 static void DecodeCALLJMPF(Word Index)
1119 {
1120 char *p;
1121 Word AdrWord;
1122 Boolean OK;
1123
1124 if (ChkArgCnt(1, 1))
1125 {
1126 p = QuotPos(ArgStr[1].Str, ':');
1127 if (!p)
1128 {
1129 DecodeAdr(&ArgStr[1]);
1130 switch (AdrType)
1131 {
1132 case TypeMem:
1133 BAsmCode[CodeLen] = 0xff;
1134 BAsmCode[CodeLen + 1] = AdrMode | Hi(Index);
1135 MoveAdr(2);
1136 CodeLen += 2 + AdrCnt;
1137 break;
1138 default:
1139 if (AdrType != TypeNone)
1140 WrError(ErrNum_InvAddrMode);
1141 }
1142 }
1143 else
1144 {
1145 tStrComp SegArg, OffsArg;
1146
1147 StrCompSplitRef(&SegArg, &OffsArg, &ArgStr[1], p);
1148 AdrWord = EvalStrIntExpression(&SegArg, UInt16, &OK);
1149 if (OK)
1150 {
1151 BAsmCode[CodeLen + 3] = Lo(AdrWord);
1152 BAsmCode[CodeLen + 4] = Hi(AdrWord);
1153 AdrWord = EvalStrIntExpression(&OffsArg, UInt16, &OK);
1154 if (OK)
1155 {
1156 BAsmCode[CodeLen + 1] = Lo(AdrWord);
1157 BAsmCode[CodeLen + 2] = Hi(AdrWord);
1158 BAsmCode[CodeLen] = Lo(Index);
1159 CodeLen += 5;
1160 }
1161 }
1162 }
1163 }
1164 AddPrefixes();
1165 }
1166
DecodeENTER(Word Index)1167 static void DecodeENTER(Word Index)
1168 {
1169 Word AdrWord;
1170 Boolean OK;
1171 UNUSED(Index);
1172
1173 if (!ChkArgCnt(2, 2));
1174 else if (ChkMinCPU(CPU80186))
1175 {
1176 AdrWord = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
1177 if (OK)
1178 {
1179 BAsmCode[CodeLen + 1] = Lo(AdrWord);
1180 BAsmCode[CodeLen + 2] = Hi(AdrWord);
1181 BAsmCode[CodeLen + 3] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
1182 if (OK)
1183 {
1184 BAsmCode[CodeLen] = 0xc8;
1185 CodeLen += 4;
1186 }
1187 }
1188 }
1189 AddPrefixes();
1190 }
1191
DecodeFixed(Word Index)1192 static void DecodeFixed(Word Index)
1193 {
1194 const FixedOrder *pOrder = FixedOrders + Index;
1195
1196 if (ChkArgCnt(0, 0)
1197 && ChkMinCPU(pOrder->MinCPU))
1198 PutCode(pOrder->Code);
1199 AddPrefixes();
1200 }
1201
DecodeALU2(Word Index)1202 static void DecodeALU2(Word Index)
1203 {
1204 Byte AdrByte;
1205
1206 if (ChkArgCnt(2, 2))
1207 {
1208 DecodeAdr(&ArgStr[1]);
1209 switch (AdrType)
1210 {
1211 case TypeReg8:
1212 case TypeReg16:
1213 BAsmCode[CodeLen + 1] = AdrMode << 3;
1214 DecodeAdr(&ArgStr[2]);
1215 switch (AdrType)
1216 {
1217 case TypeReg8:
1218 case TypeReg16:
1219 BAsmCode[CodeLen + 1] |= 0xc0 | AdrMode;
1220 BAsmCode[CodeLen] = (Index << 3) | 2 | OpSize;
1221 CodeLen += 2;
1222 break;
1223 case TypeMem:
1224 BAsmCode[CodeLen + 1] |= AdrMode;
1225 BAsmCode[CodeLen] = (Index << 3) | 2 | OpSize;
1226 MoveAdr(2);
1227 CodeLen += 2 + AdrCnt;
1228 break;
1229 case TypeImm:
1230 if (((BAsmCode[CodeLen+1] >> 3) & 7) == 0)
1231 {
1232 BAsmCode[CodeLen] = (Index << 3) | 4 | OpSize;
1233 MoveAdr(1);
1234 CodeLen += 1 + AdrCnt;
1235 }
1236 else
1237 {
1238 BAsmCode[CodeLen] = OpSize | 0x80;
1239 if ((OpSize == 1) && (Sgn(AdrVals[0]) == AdrVals[1]))
1240 {
1241 AdrCnt = 1;
1242 BAsmCode[CodeLen] |= 2;
1243 }
1244 BAsmCode[CodeLen + 1] = (BAsmCode[CodeLen + 1] >> 3) + 0xc0 + (Index << 3);
1245 MoveAdr(2);
1246 CodeLen += 2 + AdrCnt;
1247 }
1248 break;
1249 default:
1250 if (AdrType != TypeNone) WrError(ErrNum_InvAddrMode);
1251 }
1252 break;
1253 case TypeMem:
1254 BAsmCode[CodeLen + 1] = AdrMode;
1255 AdrByte = AdrCnt;
1256 MoveAdr(2);
1257 DecodeAdr(&ArgStr[2]);
1258 switch (AdrType)
1259 {
1260 case TypeReg8:
1261 case TypeReg16:
1262 BAsmCode[CodeLen] = (Index << 3) | OpSize;
1263 BAsmCode[CodeLen + 1] |= (AdrMode << 3);
1264 CodeLen += 2 + AdrByte;
1265 break;
1266 case TypeImm:
1267 BAsmCode[CodeLen] = OpSize | 0x80;
1268 if ((OpSize == 1) && (Sgn(AdrVals[0]) == AdrVals[1]))
1269 {
1270 AdrCnt = 1;
1271 BAsmCode[CodeLen] += 2;
1272 }
1273 BAsmCode[CodeLen + 1] += (Index << 3);
1274 MoveAdr(2 + AdrByte);
1275 CodeLen += 2 + AdrCnt + AdrByte;
1276 break;
1277 default:
1278 if (AdrType != TypeNone)
1279 WrError(ErrNum_InvAddrMode);
1280 }
1281 break;
1282 default:
1283 if (AdrType != TypeNone)
1284 WrError(ErrNum_InvAddrMode);
1285 }
1286 }
1287 AddPrefixes();
1288 }
1289
DecodeRel(Word Index)1290 static void DecodeRel(Word Index)
1291 {
1292 const FixedOrder *pOrder = RelOrders + Index;
1293
1294 if (ChkArgCnt(1, 1)
1295 && ChkMinCPU(pOrder->MinCPU))
1296 {
1297 tEvalResult EvalResult;
1298 Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], Int16, &EvalResult);
1299
1300 if (EvalResult.OK)
1301 {
1302 ChkSpace(SegCode, EvalResult.AddrSpaceMask);
1303 AdrWord -= EProgCounter() + 2;
1304 if (Hi(pOrder->Code) != 0)
1305 AdrWord--;
1306 if ((AdrWord >= 0x80) && (AdrWord < 0xff80) && !mSymbolQuestionable(EvalResult.Flags)) WrError(ErrNum_JmpDistTooBig);
1307 else
1308 {
1309 PutCode(pOrder->Code);
1310 BAsmCode[CodeLen++] = Lo(AdrWord);
1311 }
1312 }
1313 }
1314 }
1315
DecodeASSUME(void)1316 static void DecodeASSUME(void)
1317 {
1318 Boolean OK;
1319 int z, z2, z3;
1320 char *p;
1321 String SegPart, ValPart;
1322
1323 if (ChkArgCnt(1, ArgCntMax))
1324 {
1325 z = 1 ; OK = True;
1326 while ((z <= ArgCnt) && (OK))
1327 {
1328 OK = False; p = QuotPos(ArgStr[z].Str, ':');
1329 if (p)
1330 {
1331 *p = '\0';
1332 strmaxcpy(SegPart, ArgStr[z].Str, STRINGSIZE);
1333 strmaxcpy(ValPart, p + 1, STRINGSIZE);
1334 }
1335 else
1336 {
1337 strmaxcpy(SegPart, ArgStr[z].Str, STRINGSIZE);
1338 *ValPart = '\0';
1339 }
1340 z2 = 0;
1341 while ((z2 <= SegRegCnt) && (as_strcasecmp(SegPart, SegRegNames[z2])))
1342 z2++;
1343 if (z2 > SegRegCnt) WrXError(ErrNum_UnknownSegReg, SegPart);
1344 else
1345 {
1346 z3 = 0;
1347 while ((z3 <= PCMax) && (as_strcasecmp(ValPart, SegNames[z3])))
1348 z3++;
1349 if (z3 > PCMax) WrXError(ErrNum_UnknownSegment, ValPart);
1350 else if ((z3 != SegCode) && (z3 != SegData) && (z3 != SegXData) && (z3 != SegNone)) WrError(ErrNum_InvSegment);
1351 else
1352 {
1353 SegAssumes[z2] = z3;
1354 OK = True;
1355 }
1356 }
1357 z++;
1358 }
1359 }
1360 }
1361
DecodePORT(Word Code)1362 static void DecodePORT(Word Code)
1363 {
1364 UNUSED(Code);
1365
1366 CodeEquate(SegIO, 0, 0xffff);
1367 }
1368
DecodeFPUFixed(Word Code)1369 static void DecodeFPUFixed(Word Code)
1370 {
1371 if (!FPUEntry(&Code))
1372 return;
1373
1374 if (ChkArgCnt(0, 0))
1375 {
1376 PutCode(Code);
1377 AddPrefixes();
1378 }
1379 }
1380
DecodeFPUSt(Word Code)1381 static void DecodeFPUSt(Word Code)
1382 {
1383 if (!FPUEntry(&Code))
1384 return;
1385
1386 if (ChkArgCnt(1, 1))
1387 {
1388 DecodeAdr(&ArgStr[1]);
1389 if (AdrType == TypeFReg)
1390 {
1391 PutCode(Code);
1392 BAsmCode[CodeLen-1] |= AdrMode;
1393 AddPrefixes();
1394 }
1395 else if (AdrType != TypeNone)
1396 WrError(ErrNum_InvAddrMode);
1397 }
1398 }
1399
DecodeFLD(Word Code)1400 static void DecodeFLD(Word Code)
1401 {
1402 if (!FPUEntry(&Code))
1403 return;
1404
1405 if (ChkArgCnt(1, 1))
1406 {
1407 DecodeAdr(&ArgStr[1]);
1408 switch (AdrType)
1409 {
1410 case TypeFReg:
1411 BAsmCode[CodeLen] = 0xd9;
1412 BAsmCode[CodeLen + 1] = 0xc0 | AdrMode;
1413 CodeLen += 2;
1414 break;
1415 case TypeMem:
1416 if ((OpSize == -1) && (UnknownFlag))
1417 OpSize = 2;
1418 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1419 else if (OpSize < 2) WrError(ErrNum_InvOpSize);
1420 else
1421 {
1422 MoveAdr(2);
1423 BAsmCode[CodeLen + 1] = AdrMode;
1424 switch (OpSize)
1425 {
1426 case 2:
1427 BAsmCode[CodeLen] = 0xd9;
1428 break;
1429 case 3:
1430 BAsmCode[CodeLen] = 0xdd;
1431 break;
1432 case 4:
1433 BAsmCode[CodeLen] = 0xdb;
1434 BAsmCode[CodeLen + 1] += 0x28;
1435 break;
1436 }
1437 CodeLen += 2+AdrCnt;
1438 }
1439 break;
1440 default:
1441 if (AdrType != TypeNone) WrError(ErrNum_InvAddrMode);
1442 }
1443 }
1444 AddPrefixes();
1445 }
1446
DecodeFILD(Word Code)1447 static void DecodeFILD(Word Code)
1448 {
1449 if (!FPUEntry(&Code))
1450 return;
1451
1452 if (ChkArgCnt(1, 1))
1453 {
1454 DecodeAdr(&ArgStr[1]);
1455 switch (AdrType)
1456 {
1457 case TypeMem:
1458 if ((OpSize == -1) && (UnknownFlag)) OpSize = 1;
1459 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1460 else if ((OpSize < 1) || (OpSize > 3)) WrError(ErrNum_InvOpSize);
1461 else
1462 {
1463 MoveAdr(2);
1464 BAsmCode[CodeLen + 1] = AdrMode;
1465 switch (OpSize)
1466 {
1467 case 1:
1468 BAsmCode[CodeLen] = 0xdf;
1469 break;
1470 case 2:
1471 BAsmCode[CodeLen] = 0xdb;
1472 break;
1473 case 3:
1474 BAsmCode[CodeLen] = 0xdf;
1475 BAsmCode[CodeLen + 1] |= 0x28;
1476 break;
1477 }
1478 CodeLen += 2 + AdrCnt;
1479 }
1480 break;
1481 default:
1482 if (AdrType != TypeNone) WrError(ErrNum_InvAddrMode);
1483 }
1484 }
1485 AddPrefixes();
1486 }
1487
DecodeFBLD(Word Code)1488 static void DecodeFBLD(Word Code)
1489 {
1490 if (!FPUEntry(&Code))
1491 return;
1492
1493 if (ChkArgCnt(1, 1))
1494 {
1495 DecodeAdr(&ArgStr[1]);
1496 switch (AdrType)
1497 {
1498 case TypeMem:
1499 if ((OpSize == -1) && (UnknownFlag))
1500 OpSize = 4;
1501 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1502 else if (OpSize != 4) WrError(ErrNum_InvOpSize);
1503 else
1504 {
1505 BAsmCode[CodeLen] = 0xdf;
1506 MoveAdr(2);
1507 BAsmCode[CodeLen+1] = AdrMode+0x20;
1508 CodeLen += 2+AdrCnt;
1509 }
1510 break;
1511 default:
1512 if (AdrType != TypeNone) WrError(ErrNum_InvAddrMode);
1513 }
1514 }
1515 AddPrefixes();
1516 }
1517
DecodeFST_FSTP(Word Code)1518 static void DecodeFST_FSTP(Word Code)
1519 {
1520 if (!FPUEntry(&Code))
1521 return;
1522
1523 if (ChkArgCnt(1, 1))
1524 {
1525 DecodeAdr(&ArgStr[1]);
1526 switch (AdrType)
1527 {
1528 case TypeFReg:
1529 BAsmCode[CodeLen] = 0xdd;
1530 BAsmCode[CodeLen + 1] = Code | AdrMode;
1531 CodeLen += 2;
1532 break;
1533 case TypeMem:
1534 if ((OpSize == -1) && (UnknownFlag))
1535 OpSize = 2;
1536 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1537 else if ((OpSize < 2) || ((OpSize == 4) && (Code == 0xd0))) WrError(ErrNum_InvOpSize);
1538 else
1539 {
1540 MoveAdr(2);
1541 BAsmCode[CodeLen + 1] = AdrMode | 0x10 | (Code & 8);
1542 switch (OpSize)
1543 {
1544 case 2:
1545 BAsmCode[CodeLen] = 0xd9;
1546 break;
1547 case 3:
1548 BAsmCode[CodeLen] = 0xdd;
1549 break;
1550 case 4:
1551 BAsmCode[CodeLen] = 0xdb;
1552 BAsmCode[CodeLen + 1] |= 0x20;
1553 break;
1554 }
1555 CodeLen += 2 + AdrCnt;
1556 }
1557 break;
1558 default:
1559 if (AdrType != TypeNone) WrError(ErrNum_InvAddrMode);
1560 }
1561 }
1562 AddPrefixes();
1563 }
1564
DecodeFIST_FISTP(Word Code)1565 static void DecodeFIST_FISTP(Word Code)
1566 {
1567 if (!FPUEntry(&Code))
1568 return;
1569
1570 if (ChkArgCnt(1, 1))
1571 {
1572 DecodeAdr(&ArgStr[1]);
1573 switch (AdrType)
1574 {
1575 case TypeMem:
1576 if ((OpSize == -1) && (UnknownFlag)) OpSize = 1;
1577 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1578 else if ((OpSize < 1) || (OpSize == 4) || ((OpSize == 3) && (Code == 0x10))) WrError(ErrNum_InvOpSize);
1579 else
1580 {
1581 MoveAdr(2);
1582 BAsmCode[CodeLen + 1] = AdrMode | Code;
1583 switch (OpSize)
1584 {
1585 case 1:
1586 BAsmCode[CodeLen] = 0xdf;
1587 break;
1588 case 2:
1589 BAsmCode[CodeLen] = 0xdb;
1590 break;
1591 case 3:
1592 BAsmCode[CodeLen] = 0xdf;
1593 BAsmCode[CodeLen + 1] = 0x20;
1594 break;
1595 }
1596 CodeLen += 2 + AdrCnt;
1597 }
1598 break;
1599 default:
1600 if (AdrType != TypeNone) WrError(ErrNum_InvAddrMode);
1601 }
1602 }
1603 AddPrefixes();
1604 }
1605
DecodeFBSTP(Word Code)1606 static void DecodeFBSTP(Word Code)
1607 {
1608 if (!FPUEntry(&Code))
1609 return;
1610
1611 if (ChkArgCnt(1, 1))
1612 {
1613 DecodeAdr(&ArgStr[1]);
1614 switch (AdrType)
1615 {
1616 case TypeMem:
1617 if ((OpSize == -1) && (UnknownFlag))
1618 OpSize = 1;
1619 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1620 else if (OpSize != 4) WrError(ErrNum_InvOpSize);
1621 else
1622 {
1623 BAsmCode[CodeLen] = 0xdf;
1624 BAsmCode[CodeLen + 1] = AdrMode | 0x30;
1625 MoveAdr(2);
1626 CodeLen += 2 + AdrCnt;
1627 }
1628 break;
1629 default:
1630 if (AdrType != TypeNone)
1631 WrError(ErrNum_InvAddrMode);
1632 }
1633 }
1634 AddPrefixes();
1635 }
1636
DecodeFCOM_FCOMP(Word Code)1637 static void DecodeFCOM_FCOMP(Word Code)
1638 {
1639 if (!FPUEntry(&Code))
1640 return;
1641
1642 if (ChkArgCnt(1, 1))
1643 {
1644 DecodeAdr(&ArgStr[1]);
1645 switch (AdrType)
1646 {
1647 case TypeFReg:
1648 BAsmCode[CodeLen] = 0xd8;
1649 BAsmCode[CodeLen+1] = Code | AdrMode;
1650 CodeLen += 2;
1651 break;
1652 case TypeMem:
1653 if ((OpSize == -1) && (UnknownFlag))
1654 OpSize = 1;
1655 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1656 else if ((OpSize != 2) && (OpSize != 3)) WrError(ErrNum_InvOpSize);
1657 else
1658 {
1659 BAsmCode[CodeLen] = (OpSize == 2) ? 0xd8 : 0xdc;
1660 BAsmCode[CodeLen + 1] = AdrMode | 0x10 | (Code & 8);
1661 MoveAdr(2);
1662 CodeLen += 2 + AdrCnt;
1663 }
1664 break;
1665 default:
1666 if (AdrType != TypeNone)
1667 WrError(ErrNum_InvAddrMode);
1668 }
1669 }
1670 AddPrefixes();
1671 }
1672
DecodeFICOM_FICOMP(Word Code)1673 static void DecodeFICOM_FICOMP(Word Code)
1674 {
1675 if (!FPUEntry(&Code))
1676 return;
1677
1678 if (ChkArgCnt(1, 1))
1679 {
1680 DecodeAdr(&ArgStr[1]);
1681 switch (AdrType)
1682 {
1683 case TypeMem:
1684 if ((OpSize == -1) && (UnknownFlag))
1685 OpSize = 1;
1686 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1687 else if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
1688 else
1689 {
1690 BAsmCode[CodeLen] = (OpSize == 1) ? 0xde : 0xda;
1691 BAsmCode[CodeLen+1] = AdrMode | Code;
1692 MoveAdr(2);
1693 CodeLen += 2 + AdrCnt;
1694 }
1695 break;
1696 default:
1697 if (AdrType != TypeNone) WrError(ErrNum_InvAddrMode);
1698 }
1699 }
1700 AddPrefixes();
1701 }
1702
DecodeFADD_FMUL(Word Code)1703 static void DecodeFADD_FMUL(Word Code)
1704 {
1705 if (!FPUEntry(&Code))
1706 return;
1707
1708 if (ArgCnt == 0)
1709 {
1710 BAsmCode[CodeLen] = 0xde;
1711 BAsmCode[CodeLen + 1] = 0xc1 + Code;
1712 CodeLen += 2;
1713 }
1714 else if (ChkArgCnt(0, 2))
1715 {
1716 const tStrComp *pArg1 = &ArgStr[1],
1717 *pArg2 = &ArgStr[2];
1718
1719 if (ArgCnt == 1)
1720 {
1721 pArg2 = &ArgStr[1];
1722 pArg1 = &ArgST;
1723 }
1724
1725 DecodeAdr(pArg1);
1726 OpSize = -1;
1727 switch (AdrType)
1728 {
1729 case TypeFReg:
1730 if (AdrMode != 0) /* ST(i) ist Ziel */
1731 {
1732 BAsmCode[CodeLen + 1] = AdrMode;
1733 DecodeAdr(pArg2);
1734 if ((AdrType != TypeFReg) || (AdrMode != 0)) WrError(ErrNum_InvAddrMode);
1735 else
1736 {
1737 BAsmCode[CodeLen] = 0xdc;
1738 BAsmCode[CodeLen + 1] += 0xc0 + Code;
1739 CodeLen += 2;
1740 }
1741 }
1742 else /* ST ist Ziel */
1743 {
1744 DecodeAdr(pArg2);
1745 switch (AdrType)
1746 {
1747 case TypeFReg:
1748 BAsmCode[CodeLen] = 0xd8;
1749 BAsmCode[CodeLen + 1] = 0xc0 + AdrMode + Code;
1750 CodeLen += 2;
1751 break;
1752 case TypeMem:
1753 if ((OpSize == -1) && (UnknownFlag)) OpSize = 2;
1754 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1755 else if ((OpSize != 2) && (OpSize != 3)) WrError(ErrNum_InvOpSize);
1756 else
1757 {
1758 BAsmCode[CodeLen] = (OpSize == 2) ? 0xd8 : 0xdc;
1759 BAsmCode[CodeLen + 1] = AdrMode + Code;
1760 MoveAdr(2);
1761 CodeLen += AdrCnt + 2;
1762 }
1763 break;
1764 default:
1765 if (AdrType != TypeNone)
1766 WrError(ErrNum_InvAddrMode);
1767 }
1768 }
1769 break;
1770 default:
1771 if (AdrType != TypeNone)
1772 WrError(ErrNum_InvAddrMode);
1773 }
1774 }
1775 AddPrefixes();
1776 }
1777
DecodeFIADD_FIMUL(Word Code)1778 static void DecodeFIADD_FIMUL(Word Code)
1779 {
1780 const tStrComp *pArg1 = &ArgStr[1],
1781 *pArg2 = &ArgStr[2];
1782
1783 if (!FPUEntry(&Code))
1784 return;
1785
1786 if (ArgCnt == 1)
1787 {
1788 pArg2 = &ArgStr[1];
1789 pArg1 = &ArgST;
1790 }
1791 else if (ChkArgCnt(1, 2))
1792 {
1793 DecodeAdr(pArg1);
1794 switch (AdrType)
1795 {
1796 case TypeFReg:
1797 if (AdrMode != 0) WrError(ErrNum_InvAddrMode);
1798 else
1799 {
1800 OpSize = -1;
1801 DecodeAdr(pArg2);
1802 if ((AdrType != TypeMem) && (AdrType != TypeNone)) WrError(ErrNum_InvAddrMode);
1803 else if (AdrType != TypeNone)
1804 {
1805 if ((OpSize == -1) && (UnknownFlag)) OpSize = 1;
1806 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1807 else if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
1808 else
1809 {
1810 BAsmCode[CodeLen] = (OpSize == 1) ? 0xde : 0xda;
1811 BAsmCode[CodeLen+1] = AdrMode + Code;
1812 MoveAdr(2);
1813 CodeLen += 2 + AdrCnt;
1814 }
1815 }
1816 }
1817 break;
1818 default:
1819 if (AdrType != TypeNone)
1820 WrError(ErrNum_InvAddrMode);
1821 }
1822 }
1823 AddPrefixes();
1824 }
1825
DecodeFADDP_FMULP(Word Code)1826 static void DecodeFADDP_FMULP(Word Code)
1827 {
1828 if (!FPUEntry(&Code))
1829 return;
1830
1831 if (ChkArgCnt(2, 2))
1832 {
1833 DecodeAdr(&ArgStr[2]);
1834 switch (AdrType)
1835 {
1836 case TypeFReg:
1837 if (AdrMode != 0) WrError(ErrNum_InvAddrMode);
1838 else
1839 {
1840 DecodeAdr(&ArgStr[1]);
1841 if ((AdrType != TypeFReg) && (AdrType != TypeNone)) WrError(ErrNum_InvAddrMode);
1842 else if (AdrType != TypeNone)
1843 {
1844 BAsmCode[CodeLen] = 0xde;
1845 BAsmCode[CodeLen + 1] = 0xc0 + AdrMode + Code;
1846 CodeLen += 2;
1847 }
1848 }
1849 break;
1850 default:
1851 if (AdrType != TypeNone)
1852 WrError(ErrNum_InvAddrMode);
1853 }
1854 }
1855 AddPrefixes();
1856 }
1857
DecodeFSUB_FSUBR_FDIV_FDIVR(Word Code)1858 static void DecodeFSUB_FSUBR_FDIV_FDIVR(Word Code)
1859 {
1860 if (!FPUEntry(&Code))
1861 return;
1862
1863 if (ArgCnt == 0)
1864 {
1865 BAsmCode[CodeLen] = 0xde;
1866 BAsmCode[CodeLen + 1] = 0xe1 + (Code ^ 8);
1867 CodeLen += 2;
1868 }
1869 else if (ChkArgCnt(0, 2))
1870 {
1871 const tStrComp *pArg1 = &ArgStr[1],
1872 *pArg2 = &ArgStr[2];
1873
1874 if (ArgCnt == 1)
1875 {
1876 pArg1 = &ArgST;
1877 pArg2 = &ArgStr[1];
1878 }
1879
1880 DecodeAdr(pArg1);
1881 OpSize = -1;
1882 switch (AdrType)
1883 {
1884 case TypeFReg:
1885 if (AdrMode != 0) /* ST(i) ist Ziel */
1886 {
1887 BAsmCode[CodeLen + 1] = AdrMode;
1888 DecodeAdr(pArg2);
1889 switch (AdrType)
1890 {
1891 case TypeFReg:
1892 if (AdrMode != 0) WrError(ErrNum_InvAddrMode);
1893 else
1894 {
1895 BAsmCode[CodeLen] = 0xdc;
1896 BAsmCode[CodeLen + 1] += 0xe0 + (Code ^ 8);
1897 CodeLen += 2;
1898 }
1899 break;
1900 default:
1901 if (AdrType != TypeNone)
1902 WrError(ErrNum_InvAddrMode);
1903 }
1904 }
1905 else /* ST ist Ziel */
1906 {
1907 DecodeAdr(pArg2);
1908 switch (AdrType)
1909 {
1910 case TypeFReg:
1911 BAsmCode[CodeLen] = 0xd8;
1912 BAsmCode[CodeLen + 1] = 0xe0 + AdrMode + Code;
1913 CodeLen += 2;
1914 break;
1915 case TypeMem:
1916 if ((OpSize == -1) && (UnknownFlag))
1917 OpSize = 2;
1918 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1919 else if ((OpSize != 2) && (OpSize != 3)) WrError(ErrNum_InvOpSize);
1920 else
1921 {
1922 BAsmCode[CodeLen] = (OpSize == 2) ? 0xd8 : 0xdc;
1923 BAsmCode[CodeLen + 1] = AdrMode + 0x20 + Code;
1924 MoveAdr(2);
1925 CodeLen += AdrCnt + 2;
1926 }
1927 break;
1928 default:
1929 if (AdrType != TypeNone)
1930 WrError(ErrNum_InvAddrMode);
1931 }
1932 }
1933 break;
1934 default:
1935 if (AdrType != TypeNone)
1936 WrError(ErrNum_InvAddrMode);
1937 }
1938 }
1939 AddPrefixes();
1940 }
1941
DecodeFISUB_FISUBR_FIDIV_FIDIVR(Word Code)1942 static void DecodeFISUB_FISUBR_FIDIV_FIDIVR(Word Code)
1943 {
1944 if (!FPUEntry(&Code))
1945 return;
1946
1947 if (ChkArgCnt(1, 2))
1948 {
1949 const tStrComp *pArg1 = &ArgStr[1],
1950 *pArg2 = &ArgStr[2];
1951
1952 if (ArgCnt == 1)
1953 {
1954 pArg1 = &ArgST;
1955 pArg2 = &ArgStr[1];
1956 }
1957
1958 DecodeAdr(pArg1);
1959 switch (AdrType)
1960 {
1961 case TypeFReg:
1962 if (AdrMode != 0) WrError(ErrNum_InvAddrMode);
1963 else
1964 {
1965 OpSize = -1;
1966 DecodeAdr(pArg2);
1967 switch (AdrType)
1968 {
1969 case TypeMem:
1970 if ((OpSize == -1) && (UnknownFlag))
1971 OpSize = 1;
1972 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1973 else if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
1974 else
1975 {
1976 BAsmCode[CodeLen] = (OpSize == 1) ? 0xde : 0xda;
1977 BAsmCode[CodeLen + 1] = AdrMode + 0x20 + Code;
1978 MoveAdr(2);
1979 CodeLen += 2 + AdrCnt;
1980 }
1981 break;
1982 default:
1983 if (AdrType != TypeNone)
1984 WrError(ErrNum_InvAddrMode);
1985 }
1986 }
1987 break;
1988 default:
1989 if (AdrType != TypeNone)
1990 WrError(ErrNum_InvAddrMode);
1991 }
1992 }
1993 AddPrefixes();
1994 }
1995
DecodeFSUBP_FSUBRP_FDIVP_FDIVRP(Word Code)1996 static void DecodeFSUBP_FSUBRP_FDIVP_FDIVRP(Word Code)
1997 {
1998 if (!FPUEntry(&Code))
1999 return;
2000
2001 if (ChkArgCnt(2, 2))
2002 {
2003 DecodeAdr(&ArgStr[2]);
2004 switch (AdrType)
2005 {
2006 case TypeFReg:
2007 if (AdrMode != 0) WrError(ErrNum_InvAddrMode);
2008 else
2009 {
2010 DecodeAdr(&ArgStr[1]);
2011 switch (AdrType)
2012 {
2013 case TypeFReg:
2014 BAsmCode[CodeLen] = 0xde;
2015 BAsmCode[CodeLen+1] = 0xe0 + AdrMode + (Code ^ 8);
2016 CodeLen += 2;
2017 break;
2018 default:
2019 if (AdrType != TypeNone)
2020 WrError(ErrNum_InvAddrMode);
2021 }
2022 }
2023 break;
2024 default:
2025 if (AdrType != TypeNone)
2026 WrError(ErrNum_InvAddrMode);
2027 }
2028 }
2029 AddPrefixes();
2030 }
2031
DecodeFPU16(Word Code)2032 static void DecodeFPU16(Word Code)
2033 {
2034 if (!FPUEntry(&Code))
2035 return;
2036
2037 if (ChkArgCnt(1, 1))
2038 {
2039 OpSize = 1;
2040 DecodeAdr(&ArgStr[1]);
2041 switch (AdrType)
2042 {
2043 case TypeMem:
2044 PutCode(Code);
2045 BAsmCode[CodeLen - 1] += AdrMode;
2046 MoveAdr(0);
2047 CodeLen += AdrCnt;
2048 break;
2049 default:
2050 if (AdrType != TypeNone) WrError(ErrNum_InvAddrMode);
2051 }
2052 }
2053 AddPrefixes();
2054 }
2055
DecodeFSAVE_FRSTOR(Word Code)2056 static void DecodeFSAVE_FRSTOR(Word Code)
2057 {
2058 if (!FPUEntry(&Code))
2059 return;
2060
2061 if (ChkArgCnt(1, 1))
2062 {
2063 DecodeAdr(&ArgStr[1]);
2064 switch (AdrType)
2065 {
2066 case TypeMem:
2067 BAsmCode[CodeLen] = 0xdd;
2068 BAsmCode[CodeLen + 1] = AdrMode + Code;
2069 MoveAdr(2);
2070 CodeLen += 2 + AdrCnt;
2071 break;
2072 default:
2073 if (AdrType != TypeNone)
2074 WrError(ErrNum_InvAddrMode);
2075 }
2076 }
2077 AddPrefixes();
2078 }
2079
DecodeRept(Word Index)2080 static void DecodeRept(Word Index)
2081 {
2082 const FixedOrder *pOrder = ReptOrders + Index;
2083
2084 if (ChkArgCnt(1, 1)
2085 && ChkMinCPU(pOrder->MinCPU))
2086 {
2087 int z2;
2088
2089 for (z2 = 0; z2 < StringOrderCnt; z2++)
2090 if (!as_strcasecmp(StringOrders[z2].Name,ArgStr[1].Str))
2091 break;
2092 if (z2 >= StringOrderCnt) WrError(ErrNum_InvArg);
2093 else if (ChkMinCPU(StringOrders[z2].MinCPU))
2094 {
2095 PutCode(pOrder->Code);
2096 PutCode(StringOrders[z2].Code);
2097 }
2098 }
2099 AddPrefixes();
2100 }
2101
DecodeMul(Word Index)2102 static void DecodeMul(Word Index)
2103 {
2104 Boolean OK;
2105 Word AdrWord;
2106
2107 if (!ChkArgCnt(1, (1 == Index) ? 3 : 1)) /* IMUL only 2/3 ops */
2108 return;
2109
2110 switch (ArgCnt)
2111 {
2112 case 1:
2113 DecodeAdr(&ArgStr[1]);
2114 switch (AdrType)
2115 {
2116 case TypeReg8:
2117 case TypeReg16:
2118 BAsmCode[CodeLen] = 0xf6 + OpSize;
2119 BAsmCode[CodeLen + 1] = 0xe0 + (Index << 3) + AdrMode;
2120 CodeLen += 2;
2121 break;
2122 case TypeMem:
2123 MinOneIs0();
2124 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
2125 else
2126 {
2127 BAsmCode[CodeLen] = 0xf6 + OpSize;
2128 BAsmCode[CodeLen+1] = 0x20 + (Index << 3) + AdrMode;
2129 MoveAdr(2);
2130 CodeLen += 2 + AdrCnt;
2131 }
2132 break;
2133 default:
2134 if (AdrType != TypeNone) WrError(ErrNum_InvAddrMode);
2135 }
2136 break;
2137 case 2:
2138 case 3:
2139 if (ChkMinCPU(CPU80186))
2140 {
2141 tStrComp *pArg1 = &ArgStr[1],
2142 *pArg2 = (ArgCnt == 2) ? &ArgStr[1] : &ArgStr[2],
2143 *pArg3 = (ArgCnt == 2) ? &ArgStr[2] : &ArgStr[3];
2144
2145 BAsmCode[CodeLen] = 0x69;
2146 DecodeAdr(pArg1);
2147 switch (AdrType)
2148 {
2149 case TypeReg16:
2150 BAsmCode[CodeLen + 1] = (AdrMode << 3);
2151 DecodeAdr(pArg2);
2152 if (AdrType == TypeReg16)
2153 {
2154 AdrType = TypeMem;
2155 AdrMode += 0xc0;
2156 }
2157 switch (AdrType)
2158 {
2159 case TypeMem:
2160 BAsmCode[CodeLen + 1] += AdrMode;
2161 MoveAdr(2);
2162 AdrWord = EvalStrIntExpression(pArg3, Int16, &OK);
2163 if (OK)
2164 {
2165 BAsmCode[CodeLen + 2 + AdrCnt] = Lo(AdrWord);
2166 BAsmCode[CodeLen + 3 + AdrCnt] = Hi(AdrWord);
2167 CodeLen += 2 + AdrCnt + 2;
2168 if ((AdrWord >= 0xff80) || (AdrWord < 0x80))
2169 {
2170 CodeLen--;
2171 BAsmCode[CodeLen-AdrCnt - 2 - 1] += 2;
2172 }
2173 }
2174 break;
2175 default:
2176 if (AdrType != TypeNone)
2177 WrError(ErrNum_InvAddrMode);
2178 }
2179 break;
2180 default:
2181 if (AdrType != TypeNone)
2182 WrError(ErrNum_InvAddrMode);
2183 }
2184 }
2185 break;
2186 }
2187 AddPrefixes();
2188 }
2189
DecodeModReg(Word Index)2190 static void DecodeModReg(Word Index)
2191 {
2192 Byte AdrByte;
2193 const FixedOrder *pOrder = ModRegOrders + Index;
2194
2195 NoSegCheck = Hi(pOrder->Code) != 0;
2196 if (ChkArgCnt(2, 2)
2197 && ChkMinCPU(pOrder->MinCPU))
2198 {
2199 DecodeAdr(&ArgStr[1]);
2200 switch (AdrType)
2201 {
2202 case TypeReg16:
2203 OpSize = Hi(pOrder->Code) ? -1 : 2;
2204 AdrByte = (AdrMode << 3);
2205 DecodeAdr(&ArgStr[2]);
2206 switch (AdrType)
2207 {
2208 case TypeMem:
2209 PutCode(Lo(pOrder->Code));
2210 BAsmCode[CodeLen] = AdrByte + AdrMode;
2211 MoveAdr(1);
2212 CodeLen += 1 + AdrCnt;
2213 break;
2214 default:
2215 if (AdrType != TypeNone)
2216 WrError(ErrNum_InvAddrMode);
2217 }
2218 break;
2219 default:
2220 if (AdrType != TypeNone)
2221 WrError(ErrNum_InvAddrMode);
2222 }
2223 }
2224 AddPrefixes();
2225 }
2226
DecodeShift(Word Index)2227 static void DecodeShift(Word Index)
2228 {
2229 const FixedOrder *pOrder = ShiftOrders + Index;
2230
2231 if (ChkArgCnt(2, 2)
2232 && ChkMinCPU(pOrder->MinCPU))
2233 {
2234 DecodeAdr(&ArgStr[1]);
2235 MinOneIs0();
2236 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
2237 else switch (AdrType)
2238 {
2239 case TypeReg8:
2240 case TypeReg16:
2241 case TypeMem:
2242 BAsmCode[CodeLen] = OpSize;
2243 BAsmCode[CodeLen + 1] = AdrMode + (pOrder->Code << 3);
2244 if (AdrType != TypeMem)
2245 BAsmCode[CodeLen + 1] += 0xc0;
2246 MoveAdr(2);
2247 if (!as_strcasecmp(ArgStr[2].Str, "CL"))
2248 {
2249 BAsmCode[CodeLen] += 0xd2;
2250 CodeLen += 2 + AdrCnt;
2251 }
2252 else
2253 {
2254 Boolean OK;
2255
2256 BAsmCode[CodeLen + 2 + AdrCnt] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
2257 if (OK)
2258 {
2259 if (BAsmCode[CodeLen + 2 + AdrCnt] == 1)
2260 {
2261 BAsmCode[CodeLen] += 0xd0;
2262 CodeLen += 2 + AdrCnt;
2263 }
2264 else if (ChkMinCPU(CPU80186))
2265 {
2266 BAsmCode[CodeLen] += 0xc0;
2267 CodeLen += 3 + AdrCnt;
2268 }
2269 }
2270 }
2271 break;
2272 default:
2273 if (AdrType != TypeNone)
2274 WrError(ErrNum_InvAddrMode);
2275 }
2276 }
2277 AddPrefixes();
2278 }
2279
DecodeROL4_ROR4(Word Code)2280 static void DecodeROL4_ROR4(Word Code)
2281 {
2282 if (ChkArgCnt(1, 1)
2283 && ChkMinCPU(CPUV30))
2284 {
2285 DecodeAdr(&ArgStr[1]);
2286 BAsmCode[CodeLen ] = 0x0f;
2287 BAsmCode[CodeLen + 1] = Code;
2288 switch (AdrType)
2289 {
2290 case TypeReg8:
2291 BAsmCode[CodeLen+2] = 0xc0 + AdrMode;
2292 CodeLen += 3;
2293 break;
2294 case TypeMem:
2295 BAsmCode[CodeLen+2] = AdrMode;
2296 MoveAdr(3);
2297 CodeLen += 3 + AdrCnt;
2298 break;
2299 default:
2300 if (AdrType != TypeNone)
2301 WrError(ErrNum_InvAddrMode);
2302 }
2303 }
2304 AddPrefixes();
2305 }
2306
DecodeBit1(Word Index)2307 static void DecodeBit1(Word Index)
2308 {
2309 if (ChkArgCnt(2, 2)
2310 && ChkMinCPU(CPUV30))
2311 {
2312 DecodeAdr(&ArgStr[1]);
2313 if ((AdrType == TypeReg8) || (AdrType == TypeReg16))
2314 {
2315 AdrMode += 0xc0;
2316 AdrType = TypeMem;
2317 }
2318 MinOneIs0();
2319 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
2320 else switch (AdrType)
2321 {
2322 case TypeMem:
2323 BAsmCode[CodeLen ] = 0x0f;
2324 BAsmCode[CodeLen + 1] = 0x10 + (Index << 1) + OpSize;
2325 BAsmCode[CodeLen + 2] = AdrMode;
2326 MoveAdr(3);
2327 if (!as_strcasecmp(ArgStr[2].Str, "CL"))
2328 CodeLen += 3 + AdrCnt;
2329 else
2330 {
2331 Boolean OK;
2332
2333 BAsmCode[CodeLen + 1] += 8;
2334 BAsmCode[CodeLen + 3 + AdrCnt] = EvalStrIntExpression(&ArgStr[2], Int4, &OK);
2335 if (OK)
2336 CodeLen += 4 + AdrCnt;
2337 }
2338 break;
2339 default:
2340 if (AdrType != TypeNone)
2341 WrError(ErrNum_InvAddrMode);
2342 }
2343 }
2344 AddPrefixes();
2345 }
2346
DecodeINS_EXT(Word Code)2347 static void DecodeINS_EXT(Word Code)
2348 {
2349 if (ChkArgCnt(2, 2)
2350 && ChkMinCPU(CPUV30))
2351 {
2352 DecodeAdr(&ArgStr[1]);
2353 if (AdrType != TypeNone)
2354 {
2355 if (AdrType != TypeReg8) WrError(ErrNum_InvAddrMode);
2356 else
2357 {
2358 BAsmCode[CodeLen ] = 0x0f;
2359 BAsmCode[CodeLen + 1] = Code;
2360 BAsmCode[CodeLen + 2] = 0xc0 + AdrMode;
2361 DecodeAdr(&ArgStr[2]);
2362 switch (AdrType)
2363 {
2364 case TypeReg8:
2365 BAsmCode[CodeLen + 2] += (AdrMode << 3);
2366 CodeLen += 3;
2367 break;
2368 case TypeImm:
2369 if (AdrVals[0] > 15) WrError(ErrNum_OverRange);
2370 else
2371 {
2372 BAsmCode[CodeLen + 1] += 8;
2373 BAsmCode[CodeLen + 3] = AdrVals[1];
2374 CodeLen += 4;
2375 }
2376 break;
2377 default:
2378 if (AdrType != TypeNone)
2379 WrError(ErrNum_InvAddrMode);
2380 }
2381 }
2382 }
2383 }
2384 AddPrefixes();
2385 }
2386
DecodeFPO2(Word Code)2387 static void DecodeFPO2(Word Code)
2388 {
2389 UNUSED(Code);
2390
2391 if (ChkArgCnt(1, 2)
2392 && ChkMinCPU(CPUV30))
2393 {
2394 Byte AdrByte;
2395 Boolean OK;
2396
2397 AdrByte = EvalStrIntExpression(&ArgStr[1], Int4, &OK);
2398 if (OK)
2399 {
2400 BAsmCode[CodeLen ] = 0x66 + (AdrByte >> 3);
2401 BAsmCode[CodeLen + 1] = (AdrByte & 7) << 3;
2402 if (ArgCnt == 1)
2403 {
2404 BAsmCode[CodeLen + 1] += 0xc0;
2405 CodeLen += 2;
2406 }
2407 else
2408 {
2409 DecodeAdr(&ArgStr[2]);
2410 switch (AdrType)
2411 {
2412 case TypeReg8:
2413 BAsmCode[CodeLen + 1] += 0xc0 + AdrMode;
2414 CodeLen += 2;
2415 break;
2416 case TypeMem:
2417 BAsmCode[CodeLen + 1] += AdrMode;
2418 MoveAdr(2);
2419 CodeLen += 2 + AdrCnt;
2420 break;
2421 default:
2422 if (AdrType != TypeNone)
2423 WrError(ErrNum_InvAddrMode);
2424 }
2425 }
2426 }
2427 }
2428 AddPrefixes();
2429 }
2430
DecodeBTCLR(Word Code)2431 static void DecodeBTCLR(Word Code)
2432 {
2433 UNUSED(Code);
2434
2435 if (ChkArgCnt(3, 3)
2436 && ChkMinCPU(CPUV35))
2437 {
2438 Boolean OK;
2439
2440 BAsmCode[CodeLen ] = 0x0f;
2441 BAsmCode[CodeLen + 1] = 0x9c;
2442 BAsmCode[CodeLen + 2] = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
2443 if (OK)
2444 {
2445 BAsmCode[CodeLen + 3] = EvalStrIntExpression(&ArgStr[2], UInt3, &OK);
2446 if (OK)
2447 {
2448 Word AdrWord;
2449 tSymbolFlags Flags;
2450
2451 AdrWord = EvalStrIntExpressionWithFlags(&ArgStr[3], Int16, &OK, & Flags) - (EProgCounter() + 5);
2452 if (OK)
2453 {
2454 if (!mSymbolQuestionable(Flags) && ((AdrWord > 0x7f) && (AdrWord < 0xff80))) WrError(ErrNum_DistTooBig);
2455 else
2456 {
2457 BAsmCode[CodeLen + 4] = Lo(AdrWord);
2458 CodeLen += 5;
2459 }
2460 }
2461 }
2462 }
2463 }
2464 AddPrefixes();
2465 }
2466
DecodeReg16(Word Index)2467 static void DecodeReg16(Word Index)
2468 {
2469 const AddOrder *pOrder = Reg16Orders + Index;
2470
2471 if (ChkArgCnt(1, 1))
2472 {
2473 DecodeAdr(&ArgStr[1]);
2474 switch (AdrType)
2475 {
2476 case TypeReg16:
2477 PutCode(pOrder->Code);
2478 BAsmCode[CodeLen++] = pOrder->Add + AdrMode;
2479 break;
2480 default:
2481 if (AdrType != TypeNone)
2482 WrError(ErrNum_InvAddrMode);
2483 }
2484 }
2485 AddPrefixes();
2486 }
2487
DecodeString(Word Index)2488 static void DecodeString(Word Index)
2489 {
2490 const FixedOrder *pOrder = StringOrders + Index;
2491
2492 if (ChkArgCnt(0, 0)
2493 && ChkMinCPU(pOrder->MinCPU))
2494 PutCode(pOrder->Code);
2495 AddPrefixes();
2496 }
2497
2498 /*---------------------------------------------------------------------------*/
2499
AddFPU(const char * NName,Word NCode,InstProc NProc)2500 static void AddFPU(const char *NName, Word NCode, InstProc NProc)
2501 {
2502 char Instr[30];
2503
2504 AddInstTable(InstTable, NName, NCode, NProc);
2505 as_snprintf(Instr, sizeof(Instr), "%cN%s", *NName, NName + 1);
2506 AddInstTable(InstTable, Instr, NCode | NO_FWAIT_FLAG, NProc);
2507 }
2508
AddFixed(const char * NName,CPUVar NMin,Word NCode)2509 static void AddFixed(const char *NName, CPUVar NMin, Word NCode)
2510 {
2511 if (InstrZ >= FixedOrderCnt) exit(255);
2512 FixedOrders[InstrZ].Code = NCode;
2513 FixedOrders[InstrZ].MinCPU = NMin;
2514 AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
2515 }
2516
AddFPUFixed(const char * NName,Word NCode)2517 static void AddFPUFixed(const char *NName, Word NCode)
2518 {
2519 AddFPU(NName, NCode, DecodeFPUFixed);
2520 }
2521
AddFPUSt(const char * NName,Word NCode)2522 static void AddFPUSt(const char *NName, Word NCode)
2523 {
2524 AddFPU(NName, NCode, DecodeFPUSt);
2525 }
2526
AddFPU16(const char * NName,Word NCode)2527 static void AddFPU16(const char *NName, Word NCode)
2528 {
2529 AddFPU(NName, NCode, DecodeFPU16);
2530 }
2531
AddString(const char * NName,CPUVar NMin,Word NCode)2532 static void AddString(const char *NName, CPUVar NMin, Word NCode)
2533 {
2534 if (InstrZ >= StringOrderCnt) exit(255);
2535 StringOrders[InstrZ].Name = NName;
2536 StringOrders[InstrZ].MinCPU = NMin;
2537 StringOrders[InstrZ].Code = NCode;
2538 AddInstTable(InstTable, NName, InstrZ++, DecodeString);
2539 }
2540
AddRept(const char * NName,CPUVar NMin,Word NCode)2541 static void AddRept(const char *NName, CPUVar NMin, Word NCode)
2542 {
2543 if (InstrZ >= ReptOrderCnt) exit(255);
2544 ReptOrders[InstrZ].Code = NCode;
2545 ReptOrders[InstrZ].MinCPU = NMin;
2546 AddInstTable(InstTable, NName, InstrZ++, DecodeRept);
2547 }
2548
AddRel(const char * NName,CPUVar NMin,Word NCode)2549 static void AddRel(const char *NName, CPUVar NMin, Word NCode)
2550 {
2551 if (InstrZ >= RelOrderCnt) exit(255);
2552 RelOrders[InstrZ].MinCPU = NMin;
2553 RelOrders[InstrZ].Code = NCode;
2554 AddInstTable(InstTable, NName, InstrZ++, DecodeRel);
2555 }
2556
AddModReg(const char * NName,CPUVar NMin,Word NCode)2557 static void AddModReg(const char *NName, CPUVar NMin, Word NCode)
2558 {
2559 if (InstrZ >= ModRegOrderCnt) exit(255);
2560 ModRegOrders[InstrZ].MinCPU = NMin;
2561 ModRegOrders[InstrZ].Code = NCode;
2562 AddInstTable(InstTable, NName, InstrZ++, DecodeModReg);
2563 }
2564
AddShift(const char * NName,CPUVar NMin,Word NCode)2565 static void AddShift(const char *NName, CPUVar NMin, Word NCode)
2566 {
2567 if (InstrZ >= ShiftOrderCnt) exit(255);
2568 ShiftOrders[InstrZ].MinCPU = NMin;
2569 ShiftOrders[InstrZ].Code = NCode;
2570 AddInstTable(InstTable, NName, InstrZ++, DecodeShift);
2571 }
2572
AddReg16(const char * NName,CPUVar NMin,Word NCode,Byte NAdd)2573 static void AddReg16(const char *NName, CPUVar NMin, Word NCode, Byte NAdd)
2574 {
2575 if (InstrZ >= Reg16OrderCnt) exit(255);
2576 Reg16Orders[InstrZ].MinCPU = NMin;
2577 Reg16Orders[InstrZ].Code = NCode;
2578 Reg16Orders[InstrZ].Add = NAdd;
2579 AddInstTable(InstTable, NName, InstrZ++, DecodeReg16);
2580 }
2581
InitFields(void)2582 static void InitFields(void)
2583 {
2584 InstTable = CreateInstTable(403);
2585 SetDynamicInstTable(InstTable);
2586
2587 AddInstTable(InstTable, "MOV" , 0, DecodeMOV);
2588 AddInstTable(InstTable, "INC" , 0, DecodeINCDEC);
2589 AddInstTable(InstTable, "DEC" , 8, DecodeINCDEC);
2590 AddInstTable(InstTable, "INT" , 0, DecodeINT);
2591 AddInstTable(InstTable, "IN" , 0, DecodeINOUT);
2592 AddInstTable(InstTable, "OUT" , 2, DecodeINOUT);
2593 AddInstTable(InstTable, "CALL" , 0, DecodeCALLJMP);
2594 AddInstTable(InstTable, "JMP" , 1, DecodeCALLJMP);
2595 AddInstTable(InstTable, "PUSH" , 0, DecodePUSHPOP);
2596 AddInstTable(InstTable, "POP" , 1, DecodePUSHPOP);
2597 AddInstTable(InstTable, "NOT" , 0, DecodeNOTNEG);
2598 AddInstTable(InstTable, "NEG" , 8, DecodeNOTNEG);
2599 AddInstTable(InstTable, "RET" , 0, DecodeRET);
2600 AddInstTable(InstTable, "RETF" , 8, DecodeRET);
2601 AddInstTable(InstTable, "TEST" , 0, DecodeTEST);
2602 AddInstTable(InstTable, "XCHG" , 0, DecodeXCHG);
2603 AddInstTable(InstTable, "CALLF", 0x189a, DecodeCALLJMPF);
2604 AddInstTable(InstTable, "JMPF" , 0x28ea, DecodeCALLJMPF);
2605 AddInstTable(InstTable, "ENTER", 0, DecodeENTER);
2606 AddInstTable(InstTable, "PORT", 0, DecodePORT);
2607 AddInstTable(InstTable, "ROL4", 0x28, DecodeROL4_ROR4);
2608 AddInstTable(InstTable, "ROR4", 0x2a, DecodeROL4_ROR4);
2609 AddInstTable(InstTable, "INS", 0x31, DecodeINS_EXT);
2610 AddInstTable(InstTable, "EXT", 0x33, DecodeINS_EXT);
2611 AddInstTable(InstTable, "FPO2", 0, DecodeFPO2);
2612 AddInstTable(InstTable, "BTCLR", 0, DecodeBTCLR);
2613 AddFPU("FLD", 0, DecodeFLD);
2614 AddFPU("FILD", 0, DecodeFILD);
2615 AddFPU("FBLD", 0, DecodeFBLD);
2616 AddFPU("FST", 0xd0, DecodeFST_FSTP);
2617 AddFPU("FSTP", 0xd8, DecodeFST_FSTP);
2618 AddFPU("FIST", 0x10, DecodeFIST_FISTP);
2619 AddFPU("FISTP", 0x18, DecodeFIST_FISTP);
2620 AddFPU("FBSTP", 0, DecodeFBSTP);
2621 AddFPU("FCOM", 0xd0, DecodeFCOM_FCOMP);
2622 AddFPU("FCOMP", 0xd8, DecodeFCOM_FCOMP);
2623 AddFPU("FICOM", 0x10, DecodeFICOM_FICOMP);
2624 AddFPU("FICOMP", 0x18, DecodeFICOM_FICOMP);
2625 AddFPU("FADD", 0, DecodeFADD_FMUL);
2626 AddFPU("FMUL", 8, DecodeFADD_FMUL);
2627 AddFPU("FIADD", 0, DecodeFIADD_FIMUL);
2628 AddFPU("FIMUL", 8, DecodeFIADD_FIMUL);
2629 AddFPU("FADDP", 0, DecodeFADDP_FMULP);
2630 AddFPU("FMULP", 8, DecodeFADDP_FMULP);
2631 AddFPU("FDIV" , 16, DecodeFSUB_FSUBR_FDIV_FDIVR);
2632 AddFPU("FDIVR", 24, DecodeFSUB_FSUBR_FDIV_FDIVR);
2633 AddFPU("FSUB" , 0, DecodeFSUB_FSUBR_FDIV_FDIVR);
2634 AddFPU("FSUBR", 8, DecodeFSUB_FSUBR_FDIV_FDIVR);
2635 AddFPU("FIDIV" , 16, DecodeFISUB_FISUBR_FIDIV_FIDIVR);
2636 AddFPU("FIDIVR", 24, DecodeFISUB_FISUBR_FIDIV_FIDIVR);
2637 AddFPU("FISUB" , 0, DecodeFISUB_FISUBR_FIDIV_FIDIVR);
2638 AddFPU("FISUBR", 8, DecodeFISUB_FISUBR_FIDIV_FIDIVR);
2639 AddFPU("FDIVP" , 16, DecodeFSUBP_FSUBRP_FDIVP_FDIVRP);
2640 AddFPU("FDIVRP", 24, DecodeFSUBP_FSUBRP_FDIVP_FDIVRP);
2641 AddFPU("FSUBP" , 0, DecodeFSUBP_FSUBRP_FDIVP_FDIVRP);
2642 AddFPU("FSUBRP", 8, DecodeFSUBP_FSUBRP_FDIVP_FDIVRP);
2643 AddFPU("FSAVE" , 0x30, DecodeFSAVE_FRSTOR);
2644 AddFPU("FRSTOR" , 0x20, DecodeFSAVE_FRSTOR);
2645
2646 FixedOrders = (FixedOrder *) malloc(sizeof(FixedOrder) * FixedOrderCnt); InstrZ = 0;
2647 AddFixed("AAA", CPU8086, 0x0037); AddFixed("AAS", CPU8086, 0x003f);
2648 AddFixed("AAM", CPU8086, 0xd40a); AddFixed("AAD", CPU8086, 0xd50a);
2649 AddFixed("CBW", CPU8086, 0x0098); AddFixed("CLC", CPU8086, 0x00f8);
2650 AddFixed("CLD", CPU8086, 0x00fc); AddFixed("CLI", CPU8086, 0x00fa);
2651 AddFixed("CMC", CPU8086, 0x00f5); AddFixed("CWD", CPU8086, 0x0099);
2652 AddFixed("DAA", CPU8086, 0x0027); AddFixed("DAS", CPU8086, 0x002f);
2653 AddFixed("HLT", CPU8086, 0x00f4); AddFixed("INTO", CPU8086, 0x00ce);
2654 AddFixed("IRET", CPU8086, 0x00cf); AddFixed("LAHF", CPU8086, 0x009f);
2655 AddFixed("LOCK", CPU8086, 0x00f0); AddFixed("NOP", CPU8086, 0x0090);
2656 AddFixed("POPF", CPU8086, 0x009d); AddFixed("PUSHF", CPU8086, 0x009c);
2657 AddFixed("SAHF", CPU8086, 0x009e); AddFixed("STC", CPU8086, 0x00f9);
2658 AddFixed("STD", CPU8086, 0x00fd); AddFixed("STI", CPU8086, 0x00fb);
2659 AddFixed("WAIT", CPU8086, 0x009b); AddFixed("XLAT", CPU8086, 0x00d7);
2660 AddFixed("LEAVE", CPU80186, 0x00c9); AddFixed("PUSHA", CPU80186, 0x0060);
2661 AddFixed("POPA", CPU80186, 0x0061); AddFixed("ADD4S", CPUV30, 0x0f20);
2662 AddFixed("SUB4S", CPUV30, 0x0f22); AddFixed("CMP4S", CPUV30, 0x0f26);
2663 AddFixed("STOP", CPUV35, 0x0f9e); AddFixed("RETRBI",CPUV35, 0x0f91);
2664 AddFixed("FINT", CPUV35, 0x0f92); AddFixed("MOVSPA",CPUV35, 0x0f25);
2665 AddFixed("SEGES", CPU8086, 0x0026); AddFixed("SEGCS", CPU8086, 0x002e);
2666 AddFixed("SEGSS", CPU8086, 0x0036); AddFixed("SEGDS", CPU8086, 0x003e);
2667 AddFixed("FWAIT", CPU8086, 0x009b);
2668
2669 AddFPUFixed("FCOMPP", 0xded9); AddFPUFixed("FTST", 0xd9e4);
2670 AddFPUFixed("FXAM", 0xd9e5); AddFPUFixed("FLDZ", 0xd9ee);
2671 AddFPUFixed("FLD1", 0xd9e8); AddFPUFixed("FLDPI", 0xd9eb);
2672 AddFPUFixed("FLDL2T", 0xd9e9); AddFPUFixed("FLDL2E", 0xd9ea);
2673 AddFPUFixed("FLDLG2", 0xd9ec); AddFPUFixed("FLDLN2", 0xd9ed);
2674 AddFPUFixed("FSQRT", 0xd9fa); AddFPUFixed("FSCALE", 0xd9fd);
2675 AddFPUFixed("FPREM", 0xd9f8); AddFPUFixed("FRNDINT",0xd9fc);
2676 AddFPUFixed("FXTRACT",0xd9f4); AddFPUFixed("FABS", 0xd9e1);
2677 AddFPUFixed("FCHS", 0xd9e0); AddFPUFixed("FPTAN", 0xd9f2);
2678 AddFPUFixed("FPATAN", 0xd9f3); AddFPUFixed("F2XM1", 0xd9f0);
2679 AddFPUFixed("FYL2X", 0xd9f1); AddFPUFixed("FYL2XP1",0xd9f9);
2680 AddFPUFixed("FINIT", 0xdbe3); AddFPUFixed("FENI", 0xdbe0);
2681 AddFPUFixed("FDISI", 0xdbe1); AddFPUFixed("FCLEX", 0xdbe2);
2682 AddFPUFixed("FINCSTP",0xd9f7); AddFPUFixed("FDECSTP",0xd9f6);
2683 AddFPUFixed("FNOP", 0xd9d0);
2684
2685 AddFPUSt("FXCH", 0xd9c8);
2686 AddFPUSt("FFREE", 0xddc0);
2687
2688 AddFPU16("FLDCW", 0xd928);
2689 AddFPU16("FSTCW", 0xd938);
2690 AddFPU16("FSTSW", 0xdd38);
2691 AddFPU16("FSTENV", 0xd930);
2692 AddFPU16("FLDENV", 0xd920);
2693
2694 StringOrders = (FixedOrder *) malloc(sizeof(FixedOrder) * StringOrderCnt); InstrZ = 0;
2695 AddString("CMPSB", CPU8086, 0x00a6);
2696 AddString("CMPSW", CPU8086, 0x00a7);
2697 AddString("LODSB", CPU8086, 0x00ac);
2698 AddString("LODSW", CPU8086, 0x00ad);
2699 AddString("MOVSB", CPU8086, 0x00a4);
2700 AddString("MOVSW", CPU8086, 0x00a5);
2701 AddString("SCASB", CPU8086, 0x00ae);
2702 AddString("SCASW", CPU8086, 0x00af);
2703 AddString("STOSB", CPU8086, 0x00aa);
2704 AddString("STOSW", CPU8086, 0x00ab);
2705 AddString("INSB", CPU80186, 0x006c);
2706 AddString("INSW", CPU80186, 0x006d);
2707 AddString("OUTSB", CPU80186, 0x006e);
2708 AddString("OUTSW", CPU80186, 0x006f);
2709
2710 ReptOrders = (FixedOrder *) malloc(sizeof(*ReptOrders) * ReptOrderCnt); InstrZ = 0;
2711 AddRept("REP", CPU8086, 0x00f3);
2712 AddRept("REPE", CPU8086, 0x00f3);
2713 AddRept("REPZ", CPU8086, 0x00f3);
2714 AddRept("REPNE", CPU8086, 0x00f2);
2715 AddRept("REPNZ", CPU8086, 0x00f2);
2716 AddRept("REPC", CPUV30, 0x0065);
2717 AddRept("REPNC", CPUV30, 0x0064);
2718
2719 RelOrders = (FixedOrder *) malloc(sizeof(*RelOrders) * RelOrderCnt); InstrZ = 0;
2720 AddRel("JA", CPU8086, 0x0077); AddRel("JNBE", CPU8086, 0x0077);
2721 AddRel("JAE", CPU8086, 0x0073); AddRel("JNB", CPU8086, 0x0073);
2722 AddRel("JB", CPU8086, 0x0072); AddRel("JNAE", CPU8086, 0x0072);
2723 AddRel("JBE", CPU8086, 0x0076); AddRel("JNA", CPU8086, 0x0076);
2724 AddRel("JC", CPU8086, 0x0072); AddRel("JCXZ", CPU8086, 0x00e3);
2725 AddRel("JE", CPU8086, 0x0074); AddRel("JZ", CPU8086, 0x0074);
2726 AddRel("JG", CPU8086, 0x007f); AddRel("JNLE", CPU8086, 0x007f);
2727 AddRel("JGE", CPU8086, 0x007d); AddRel("JNL", CPU8086, 0x007d);
2728 AddRel("JL", CPU8086, 0x007c); AddRel("JNGE", CPU8086, 0x007c);
2729 AddRel("JLE", CPU8086, 0x007e); AddRel("JNG", CPU8086, 0x007e);
2730 AddRel("JNC", CPU8086, 0x0073); AddRel("JNE", CPU8086, 0x0075);
2731 AddRel("JNZ", CPU8086, 0x0075); AddRel("JNO", CPU8086, 0x0071);
2732 AddRel("JNS", CPU8086, 0x0079); AddRel("JNP", CPU8086, 0x007b);
2733 AddRel("JPO", CPU8086, 0x007b); AddRel("JO", CPU8086, 0x0070);
2734 AddRel("JP", CPU8086, 0x007a); AddRel("JPE", CPU8086, 0x007a);
2735 AddRel("JS", CPU8086, 0x0078); AddRel("LOOP", CPU8086, 0x00e2);
2736 AddRel("LOOPE", CPU8086, 0x00e1); AddRel("LOOPZ", CPU8086, 0x00e1);
2737 AddRel("LOOPNE",CPU8086, 0x00e0); AddRel("LOOPNZ",CPU8086, 0x00e0);
2738
2739 ModRegOrders = (FixedOrder *) malloc(sizeof(*ModRegOrders) * ModRegOrderCnt); InstrZ = 0;
2740 AddModReg("LDS", CPU8086, 0x00c5);
2741 AddModReg("LEA", CPU8086, 0x018d);
2742 AddModReg("LES", CPU8086, 0x00c4);
2743 AddModReg("BOUND", CPU80186, 0x0062);
2744
2745 ShiftOrders = (FixedOrder *) malloc(sizeof(*ShiftOrders) * ShiftOrderCnt); InstrZ = 0;
2746 AddShift("SHL", CPU8086, 4); AddShift("SAL", CPU8086, 4);
2747 AddShift("SHR", CPU8086, 5); AddShift("SAR", CPU8086, 7);
2748 AddShift("ROL", CPU8086, 0); AddShift("ROR", CPU8086, 1);
2749 AddShift("RCL", CPU8086, 2); AddShift("RCR", CPU8086, 3);
2750
2751 Reg16Orders = (AddOrder *) malloc(sizeof(AddOrder) * Reg16OrderCnt); InstrZ = 0;
2752 AddReg16("BRKCS" , CPUV35, 0x0f2d, 0xc0);
2753 AddReg16("TSKSW" , CPUV35, 0x0f94, 0xf8);
2754 AddReg16("MOVSPB", CPUV35, 0x0f95, 0xf8);
2755
2756 InstrZ = 0;
2757 AddInstTable(InstTable, "ADD", InstrZ++, DecodeALU2);
2758 AddInstTable(InstTable, "OR" , InstrZ++, DecodeALU2);
2759 AddInstTable(InstTable, "ADC", InstrZ++, DecodeALU2);
2760 AddInstTable(InstTable, "SBB", InstrZ++, DecodeALU2);
2761 AddInstTable(InstTable, "AND", InstrZ++, DecodeALU2);
2762 AddInstTable(InstTable, "SUB", InstrZ++, DecodeALU2);
2763 AddInstTable(InstTable, "XOR", InstrZ++, DecodeALU2);
2764 AddInstTable(InstTable, "CMP", InstrZ++, DecodeALU2);
2765
2766 InstrZ = 0;
2767 AddInstTable(InstTable, "MUL" , InstrZ++, DecodeMul);
2768 AddInstTable(InstTable, "IMUL", InstrZ++, DecodeMul);
2769 AddInstTable(InstTable, "DIV" , InstrZ++, DecodeMul);
2770 AddInstTable(InstTable, "IDIV", InstrZ++, DecodeMul);
2771
2772 InstrZ = 0;
2773 AddInstTable(InstTable, "TEST1", InstrZ++, DecodeBit1);
2774 AddInstTable(InstTable, "CLR1" , InstrZ++, DecodeBit1);
2775 AddInstTable(InstTable, "SET1" , InstrZ++, DecodeBit1);
2776 AddInstTable(InstTable, "NOT1" , InstrZ++, DecodeBit1);
2777 }
2778
DeinitFields(void)2779 static void DeinitFields(void)
2780 {
2781 DestroyInstTable(InstTable);
2782 free(FixedOrders);
2783 free(ReptOrders);
2784 free(ShiftOrders);
2785 free(StringOrders);
2786 free(ModRegOrders);
2787 free(Reg16Orders);
2788 free(RelOrders);
2789 }
2790
MakeCode_86(void)2791 static void MakeCode_86(void)
2792 {
2793 CodeLen = 0;
2794 DontPrint = False;
2795 OpSize = -1;
2796 PrefixLen = 0;
2797 NoSegCheck = False;
2798 UnknownFlag = False;
2799
2800 /* zu ignorierendes */
2801
2802 if (Memo(""))
2803 return;
2804
2805 /* Pseudoanweisungen */
2806
2807 if (DecodeIntelPseudo(False))
2808 return;
2809
2810 /* vermischtes */
2811
2812 if (!LookupInstTable(InstTable, OpPart.Str))
2813 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2814 }
2815
InitCode_86(void)2816 static void InitCode_86(void)
2817 {
2818 SegAssumes[0] = SegNone; /* ASSUME ES:NOTHING */
2819 SegAssumes[1] = SegCode; /* ASSUME CS:CODE */
2820 SegAssumes[2] = SegNone; /* ASSUME SS:NOTHING */
2821 SegAssumes[3] = SegData; /* ASSUME DS:DATA */
2822 }
2823
IsDef_86(void)2824 static Boolean IsDef_86(void)
2825 {
2826 return (Memo("PORT"));
2827 }
2828
SwitchFrom_86(void)2829 static void SwitchFrom_86(void)
2830 {
2831 DeinitFields();
2832 ClearONOFF();
2833 }
2834
SwitchTo_86(void)2835 static void SwitchTo_86(void)
2836 {
2837 TurnWords = False; ConstMode = ConstModeIntel;
2838
2839 PCSymbol = "$"; HeaderID = 0x42; NOPCode = 0x90;
2840 DivideChars = ","; HasAttrs = False;
2841
2842 ValidSegs = (1 << SegCode) | (1 << SegData) | (1 << SegXData) | (1 << SegIO);
2843 Grans[SegCode ] = 1; ListGrans[SegCode ] = 1; SegInits[SegCode ] = 0;
2844 SegLimits[SegCode ] = 0xffff;
2845 Grans[SegData ] = 1; ListGrans[SegData ] = 1; SegInits[SegData ] = 0;
2846 SegLimits[SegData ] = 0xffff;
2847 Grans[SegXData] = 1; ListGrans[SegXData] = 1; SegInits[SegXData] = 0;
2848 SegLimits[SegXData] = 0xffff;
2849 Grans[SegIO ] = 1; ListGrans[SegIO ] = 1; SegInits[SegIO ] = 0;
2850 SegLimits[SegIO ] = 0xffff;
2851
2852 pASSUMEOverride = DecodeASSUME;
2853
2854 MakeCode = MakeCode_86; IsDef = IsDef_86;
2855 SwitchFrom = SwitchFrom_86; InitFields();
2856 AddONOFF("FPU",&FPUAvail,FPUAvailName,False);
2857 }
2858
code86_init(void)2859 void code86_init(void)
2860 {
2861 CPU8086 = AddCPU("8086" ,SwitchTo_86);
2862 CPU80186 = AddCPU("80186",SwitchTo_86);
2863 CPUV30 = AddCPU("V30" ,SwitchTo_86);
2864 CPUV35 = AddCPU("V35" ,SwitchTo_86);
2865
2866 AddInitPassProc(InitCode_86);
2867 }
2868