1 /* code90c141.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* Codegenerator Toshiba TLCS-90 */
8 /* */
9 /*****************************************************************************/
10
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14
15 #include "nls.h"
16 #include "bpemu.h"
17 #include "strutil.h"
18 #include "asmdef.h"
19 #include "asmsub.h"
20 #include "asmpars.h"
21 #include "asmitree.h"
22 #include "codepseudo.h"
23 #include "intpseudo.h"
24 #include "codevars.h"
25 #include "errmsg.h"
26
27 #include "code90c141.h"
28
29 typedef struct
30 {
31 const char *Name;
32 Byte Code;
33 } Condition;
34
35 #define AccReg 6
36 #define HLReg 2
37
38 #define ConditionCnt 24
39
40 enum
41 {
42 ModNone = -1,
43 ModReg8 = 0,
44 ModReg16 = 1,
45 ModIReg16 = 2,
46 ModIndReg = 3,
47 ModIdxReg = 4,
48 ModDir = 5,
49 ModMem = 6,
50 ModImm = 7
51 };
52
53 #define MModReg8 (1 << ModReg8)
54 #define MModReg16 (1 << ModReg16)
55 #define MModIReg16 (1 << ModIReg16)
56 #define MModIndReg (1 << ModIndReg)
57 #define MModIdxReg (1 << ModIdxReg)
58 #define MModDir (1 << ModDir)
59 #define MModMem (1 << ModMem)
60 #define MModImm (1 << ModImm)
61
62 static unsigned DefaultCondition;
63
64 static ShortInt AdrType;
65 static Byte AdrMode;
66 static ShortInt OpSize;
67 static Byte AdrVals[10];
68 static Boolean MinOneIs0;
69
70 static Condition *Conditions;
71
72 static CPUVar CPU90C141;
73
74 /*---------------------------------------------------------------------------*/
75
SetOpSize(ShortInt New)76 static void SetOpSize(ShortInt New)
77 {
78 if (OpSize == -1)
79 OpSize = New;
80 else if (OpSize != New)
81 {
82 WrError(ErrNum_ConfOpSizes);
83 AdrType = ModNone;
84 AdrCnt = 0;
85 }
86 }
87
DecodeAdr(const tStrComp * pArg,Byte Erl)88 static void DecodeAdr(const tStrComp *pArg, Byte Erl)
89 {
90 static const char Reg8Names[][2] = { "B", "C", "D", "E", "H", "L", "A" };
91 static const int Reg8Cnt = sizeof(Reg8Names) / sizeof(*Reg8Names);
92 static const char Reg16Names[][3] = { "BC", "DE", "HL", "\0", "IX", "IY", "SP" };
93 static const int Reg16Cnt = sizeof(Reg16Names) / sizeof(*Reg16Names);
94 static const char IReg16Names[][3] = {"IX", "IY", "SP" };
95 static const int IReg16Cnt = sizeof(IReg16Names) / sizeof(*IReg16Names);
96
97 int z;
98 char *p;
99 LongInt DispAcc, DispVal;
100 Byte OccFlag, BaseReg;
101 Boolean ok, fnd, NegFlag, NNegFlag, Unknown;
102
103 AdrType = ModNone; AdrCnt = 0;
104
105 /* 1. 8-Bit-Register */
106
107 for (z = 0; z < Reg8Cnt; z++)
108 if (!as_strcasecmp(pArg->Str, Reg8Names[z]))
109 {
110 AdrType = ModReg8;
111 AdrMode = z;
112 SetOpSize(0);
113 goto chk;
114 }
115
116 /* 2. 16-Bit-Register, indiziert */
117
118 if (Erl & MModIReg16)
119 {
120 for (z = 0; z < IReg16Cnt; z++)
121 if (!as_strcasecmp(pArg->Str, IReg16Names[z]))
122 {
123 AdrType = ModIReg16;
124 AdrMode = z;
125 SetOpSize(1);
126 goto chk;
127 }
128 }
129
130 /* 3. 16-Bit-Register, normal */
131
132 for (z = 0; z < Reg16Cnt; z++)
133 if (!as_strcasecmp(pArg->Str, Reg16Names[z]))
134 {
135 AdrType = ModReg16;
136 AdrMode = z;
137 SetOpSize(1);
138 goto chk;
139 }
140
141 /* Speicheradresse */
142
143 if (IsIndirect(pArg->Str))
144 {
145 tStrComp Arg, Remainder;
146
147 OccFlag = 0;
148 BaseReg = 0;
149 DispAcc = 0;
150 ok = True;
151 NegFlag = False;
152 Unknown = False;
153 StrCompRefRight(&Arg, pArg, 1);
154 StrCompShorten(&Arg, 1);
155
156 do
157 {
158 p = QuotMultPos(Arg.Str, "+-");
159 NNegFlag = p && (*p == '-');
160 if (p)
161 StrCompSplitRef(&Arg, &Remainder, &Arg, p);
162
163 KillPrefBlanksStrComp(&Arg);
164 KillPostBlanksStrComp(&Arg);
165 fnd = False;
166
167 if (!as_strcasecmp(Arg.Str, "A"))
168 {
169 fnd = True;
170 ok = ((!NegFlag) && (!(OccFlag & 1)));
171 if (ok)
172 OccFlag += 1;
173 else
174 WrError(ErrNum_InvAddrMode);
175 }
176
177 if (!fnd)
178 {
179 for (z = 0; z < Reg16Cnt; z++)
180 {
181 if (!as_strcasecmp(Arg.Str, Reg16Names[z]))
182 {
183 fnd = True;
184 BaseReg = z;
185 ok = ((!NegFlag) && (!(OccFlag & 2)));
186 if (ok)
187 OccFlag += 2;
188 else
189 WrError(ErrNum_InvAddrMode);
190 }
191 }
192 }
193
194 if (!fnd)
195 {
196 tSymbolFlags Flags;
197
198 DispVal = EvalStrIntExpressionWithFlags(&Arg, Int32, &ok, &Flags);
199 if (ok)
200 {
201 DispAcc = NegFlag ? DispAcc - DispVal : DispAcc + DispVal;
202 if (mFirstPassUnknown(Flags))
203 Unknown = True;
204 }
205 }
206
207 NegFlag = NNegFlag;
208 if (p)
209 Arg = Remainder;
210 }
211 while (p && ok);
212
213 if (!ok)
214 return;
215 if (Unknown)
216 DispAcc &= 0x7f;
217
218 switch (OccFlag)
219 {
220 case 1:
221 WrError(ErrNum_InvAddrMode);
222 break;
223 case 3:
224 if ((BaseReg != 2) || (DispAcc!=0)) WrError(ErrNum_InvAddrMode);
225 else
226 {
227 AdrType = ModIdxReg;
228 AdrMode = 3;
229 }
230 break;
231 case 2:
232 if ((DispAcc > 127) || (DispAcc < -128)) WrError(ErrNum_OverRange);
233 else if (DispAcc == 0)
234 {
235 AdrType = ModIndReg;
236 AdrMode = BaseReg;
237 }
238 else if (BaseReg < 4) WrError(ErrNum_InvAddrMode);
239 else
240 {
241 AdrType = ModIdxReg;
242 AdrMode = BaseReg - 4;
243 AdrCnt = 1;
244 AdrVals[0] = DispAcc & 0xff;
245 }
246 break;
247 case 0:
248 if (DispAcc > 0xffff) WrError(ErrNum_AdrOverflow);
249 else if ((Hi(DispAcc) == 0xff) && (Erl & MModDir))
250 {
251 AdrType = ModDir;
252 AdrCnt = 1;
253 AdrVals[0] = Lo(DispAcc);
254 }
255 else
256 {
257 AdrType = ModMem;
258 AdrCnt = 2;
259 AdrVals[0] = Lo(DispAcc);
260 AdrVals[1] = Hi(DispAcc);
261 }
262 break;
263 }
264 }
265
266 /* immediate */
267
268 else
269 {
270 if ((OpSize == -1) && (MinOneIs0))
271 OpSize = 0;
272 switch (OpSize)
273 {
274 case -1:
275 WrError(ErrNum_InvOpSize);
276 break;
277 case 0:
278 AdrVals[0] = EvalStrIntExpression(pArg, Int8, &ok);
279 if (ok)
280 {
281 AdrType = ModImm;
282 AdrCnt = 1;
283 }
284 break;
285 case 1:
286 DispVal = EvalStrIntExpression(pArg, Int16, &ok);
287 if (ok)
288 {
289 AdrType = ModImm;
290 AdrCnt = 2;
291 AdrVals[0] = Lo(DispVal);
292 AdrVals[1] = Hi(DispVal);
293 }
294 break;
295 }
296 }
297
298 /* gefunden */
299
300 chk:
301 if ((AdrType != ModNone) && (!((1 << AdrType) & Erl)))
302 {
303 WrError(ErrNum_InvAddrMode);
304 AdrType = ModNone;
305 AdrCnt = 0;
306 }
307 }
308
ArgPair(const char * Arg1,const char * Arg2)309 static Boolean ArgPair(const char *Arg1, const char *Arg2)
310 {
311 return (((!as_strcasecmp(ArgStr[1].Str, Arg1)) && (!as_strcasecmp(ArgStr[2].Str, Arg2)))
312 || ((!as_strcasecmp(ArgStr[1].Str, Arg2)) && (!as_strcasecmp(ArgStr[2].Str, Arg1))));
313 }
314
DecodeCondition(char * pCondStr)315 static unsigned DecodeCondition(char *pCondStr)
316 {
317 int z;
318
319 NLS_UpString(pCondStr);
320 for (z = 0; z < ConditionCnt; z++)
321 if (!strcmp(pCondStr, Conditions[z].Name))
322 break;
323 return z;
324 }
325
326 /*-------------------------------------------------------------------------*/
327
328 /* ohne Argument */
329
DecodeFixed(Word Code)330 static void DecodeFixed(Word Code)
331 {
332 if (ChkArgCnt(0, 0))
333 {
334 CodeLen = 1;
335 BAsmCode[0] = Code;
336 }
337 }
338
DecodeMove(Word Code)339 static void DecodeMove(Word Code)
340 {
341 if (ChkArgCnt(0, 0))
342 {
343 CodeLen = 2;
344 BAsmCode[0] = 0xfe;
345 BAsmCode[1] = Code;
346 }
347 }
348
DecodeShift(Word Code)349 static void DecodeShift(Word Code)
350 {
351 if (ChkArgCnt(1, 1))
352 {
353 DecodeAdr(&ArgStr[1], (Hi(Code) ? MModReg8 : 0) | MModIndReg | MModIdxReg | MModMem | MModDir);
354 switch (AdrType)
355 {
356 case ModReg8:
357 CodeLen = 2;
358 BAsmCode[0] = 0xf8 + AdrMode;
359 BAsmCode[1] = Lo(Code);
360 if (AdrMode == AccReg)
361 WrError(ErrNum_ShortAddrPossible);
362 break;
363 case ModIndReg:
364 CodeLen = 2;
365 BAsmCode[0] = 0xe0 + AdrMode;
366 BAsmCode[1] = Lo(Code);
367 break;
368 case ModIdxReg:
369 CodeLen = 2 + AdrCnt;
370 BAsmCode[0] = 0xf0 + AdrMode;
371 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
372 BAsmCode[1 + AdrCnt] = Lo(Code);
373 break;
374 case ModDir:
375 CodeLen = 3;
376 BAsmCode[0] = 0xe7;
377 BAsmCode[1] = AdrVals[0];
378 BAsmCode[2] = Lo(Code);
379 break;
380 case ModMem:
381 CodeLen = 4;
382 BAsmCode[0] = 0xe3;
383 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
384 BAsmCode[3] = Lo(Code);
385 break;
386 }
387 }
388 }
389
390 /* Logik */
391
DecodeBit(Word Code)392 static void DecodeBit(Word Code)
393 {
394 Byte BitPos;
395 Boolean OK;
396
397 if (ChkArgCnt(2, 2))
398 {
399 BitPos = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
400 if (OK)
401 {
402 DecodeAdr(&ArgStr[2], MModReg8 | MModIndReg | MModIdxReg | MModMem | MModDir);
403 switch (AdrType)
404 {
405 case ModReg8:
406 CodeLen = 2;
407 BAsmCode[0] = 0xf8 + AdrMode;
408 BAsmCode[1] = Code + BitPos;
409 break;
410 case ModIndReg:
411 CodeLen = 2;
412 BAsmCode[0] = 0xe0 + AdrMode;
413 BAsmCode[1] = Code + BitPos;
414 break;
415 case ModIdxReg:
416 CodeLen = 2 + AdrCnt;
417 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
418 BAsmCode[0] = 0xf0 + AdrMode;
419 BAsmCode[1 + AdrCnt] = Code + BitPos;
420 break;
421 case ModMem:
422 CodeLen = 4;
423 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
424 BAsmCode[0] = 0xe3;
425 BAsmCode[1 + AdrCnt] = Code + BitPos;
426 break;
427 case ModDir:
428 BAsmCode[1] = AdrVals[0];
429 if (Code == 0x18)
430 {
431 BAsmCode[0] = 0xe7;
432 BAsmCode[2] = Code + BitPos;
433 CodeLen = 3;
434 }
435 else
436 {
437 BAsmCode[0] = Code + BitPos;
438 CodeLen = 2;
439 }
440 break;
441 }
442 }
443 }
444 }
445
DecodeAcc(Word Code)446 static void DecodeAcc(Word Code)
447 {
448 if (!ChkArgCnt(1, 1));
449 else if (as_strcasecmp(ArgStr[1].Str, "A")) WrError(ErrNum_InvAddrMode);
450 else
451 {
452 CodeLen = 1;
453 BAsmCode[0] = Code;
454 }
455 }
456
DecodeALU2(Word Code)457 static void DecodeALU2(Word Code)
458 {
459 Byte HReg;
460
461 if (ChkArgCnt(2, 2))
462 {
463 DecodeAdr(&ArgStr[1], MModReg8 | MModReg16 | MModIdxReg | MModIndReg | MModDir | MModMem);
464 switch (AdrType)
465 {
466 case ModReg8:
467 DecodeAdr(&ArgStr[2], MModImm | (((HReg = AdrMode) == AccReg) ? MModReg8 | MModIndReg | MModIdxReg | MModDir | MModMem:0));
468 switch(AdrType)
469 {
470 case ModReg8:
471 CodeLen = 2;
472 BAsmCode[0] = 0xf8 | AdrMode;
473 BAsmCode[1] = 0x60 | Code;
474 break;
475 case ModIndReg:
476 CodeLen = 2;
477 BAsmCode[0] = 0xe0 | AdrMode; BAsmCode[1] = 0x60 | Code;
478 break;
479 case ModIdxReg:
480 CodeLen = 2 + AdrCnt;
481 BAsmCode[0] = 0xf0 | AdrMode;
482 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
483 BAsmCode[1 + AdrCnt] = 0x60 | Code;
484 break;
485 case ModDir:
486 CodeLen = 2;
487 BAsmCode[0] = 0x60 | Code;
488 BAsmCode[1] = AdrVals[0];
489 break;
490 case ModMem:
491 CodeLen = 4;
492 BAsmCode[0] = 0xe3;
493 BAsmCode[3] = 0x60 | Code;
494 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
495 break;
496 case ModImm:
497 if (HReg == AccReg)
498 {
499 CodeLen = 2;
500 BAsmCode[0] = 0x68 | Code;
501 BAsmCode[1] = AdrVals[0];
502 }
503 else
504 {
505 CodeLen = 3;
506 BAsmCode[0] = 0xf8 | HReg;
507 BAsmCode[1] = 0x68 | Code;
508 BAsmCode[2] = AdrVals[0];
509 }
510 break;
511 }
512 break;
513 case ModReg16:
514 if ((AdrMode == 2) || ((Code == 0) && (AdrMode >= 4)))
515 {
516 HReg = AdrMode;
517 DecodeAdr(&ArgStr[2], MModReg16 | MModIndReg | MModIdxReg | MModDir | MModMem | MModImm);
518 switch (AdrType)
519 {
520 case ModReg16:
521 CodeLen = 2;
522 BAsmCode[0] = 0xf8 | AdrMode;
523 BAsmCode[1] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x70 + Code;
524 break;
525 case ModIndReg:
526 CodeLen = 2;
527 BAsmCode[0] = 0xe0 | AdrMode;
528 BAsmCode[1] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x70 + Code;
529 break;
530 case ModIdxReg:
531 CodeLen = 2 + AdrCnt;
532 BAsmCode[0] = 0xf0 | AdrMode;
533 memcpy(BAsmCode + 1,AdrVals, AdrCnt);
534 BAsmCode[1 + AdrCnt] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x70 + Code;
535 break;
536 case ModDir:
537 if (HReg >= 4)
538 {
539 CodeLen = 3;
540 BAsmCode[0] = 0xe7;
541 BAsmCode[1] = AdrVals[0];
542 BAsmCode[2] = 0x10 | HReg;
543 }
544 else
545 {
546 CodeLen = 2;
547 BAsmCode[0] = 0x70 | Code;
548 BAsmCode[1] = AdrVals[0];
549 }
550 break;
551 case ModMem:
552 CodeLen = 4;
553 BAsmCode[0] = 0xe3;
554 memcpy(BAsmCode + 1, AdrVals, 2);
555 BAsmCode[3] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x70 + Code;
556 break;
557 case ModImm:
558 CodeLen = 3;
559 BAsmCode[0] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x78 + Code;
560 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
561 break;
562 }
563 }
564 else WrError(ErrNum_InvAddrMode);
565 break;
566 case ModIndReg:
567 case ModIdxReg:
568 case ModDir:
569 case ModMem:
570 OpSize = 0;
571 switch (AdrType)
572 {
573 case ModIndReg:
574 HReg = 3;
575 BAsmCode[0] = 0xe8 | AdrMode;
576 BAsmCode[1] = 0x68 | Code;
577 break;
578 case ModIdxReg:
579 HReg = 3 + AdrCnt;
580 BAsmCode[0] = 0xf4 | AdrMode;
581 BAsmCode[1 + AdrCnt] = 0x68 | Code;
582 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
583 break;
584 case ModDir:
585 HReg = 4;
586 BAsmCode[0] = 0xef;
587 BAsmCode[1] = AdrVals[0];
588 BAsmCode[2] = 0x68 | Code;
589 break;
590 case ModMem:
591 HReg = 5;
592 BAsmCode[0] = 0xeb;
593 memcpy(BAsmCode + 1, AdrVals, 2);
594 BAsmCode[3] = 0x68 | Code;
595 break;
596 default:
597 HReg = 0;
598 }
599 DecodeAdr(&ArgStr[2], MModImm);
600 if (AdrType == ModImm)
601 {
602 BAsmCode[HReg-1] = AdrVals[0];
603 CodeLen = HReg;
604 }
605 break;
606 }
607 }
608 }
609
DecodeLD(Word Code)610 static void DecodeLD(Word Code)
611 {
612 Byte HReg;
613
614 if (Hi(Code))
615 SetOpSize(1);
616
617 if (ChkArgCnt(2, 2))
618 {
619 DecodeAdr(&ArgStr[1], MModReg8 | MModReg16 | MModIndReg | MModIdxReg | MModDir | MModMem);
620 switch (AdrType)
621 {
622 case ModReg8:
623 HReg = AdrMode;
624 DecodeAdr(&ArgStr[2], MModReg8 | MModIndReg | MModIdxReg | MModDir | MModMem | MModImm);
625 switch (AdrType)
626 {
627 case ModReg8:
628 if (HReg == AccReg)
629 {
630 CodeLen = 1;
631 BAsmCode[0] = 0x20 | AdrMode;
632 }
633 else if (AdrMode == AccReg)
634 {
635 CodeLen = 1;
636 BAsmCode[0] = 0x28 | HReg;
637 }
638 else
639 {
640 CodeLen = 2;
641 BAsmCode[0] = 0xf8 | AdrMode;
642 BAsmCode[1] = 0x30 | HReg;
643 }
644 break;
645 case ModIndReg:
646 CodeLen = 2;
647 BAsmCode[0] = 0xe0 | AdrMode;
648 BAsmCode[1] = 0x28 | HReg;
649 break;
650 case ModIdxReg:
651 CodeLen = 2 + AdrCnt;
652 BAsmCode[0] = 0xf0 | AdrMode;
653 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
654 BAsmCode[1 + AdrCnt] = 0x28 | HReg;
655 break;
656 case ModDir:
657 if (HReg == AccReg)
658 {
659 CodeLen = 2;
660 BAsmCode[0] = 0x27;
661 BAsmCode[1] = AdrVals[0];
662 }
663 else
664 {
665 CodeLen = 3;
666 BAsmCode[0] = 0xe7;
667 BAsmCode[1] = AdrVals[0];
668 BAsmCode[2] = 0x28 | HReg;
669 }
670 break;
671 case ModMem:
672 CodeLen = 4;
673 BAsmCode[0] = 0xe3;
674 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
675 BAsmCode[3] = 0x28 | HReg;
676 break;
677 case ModImm:
678 CodeLen = 2;
679 BAsmCode[0] = 0x30 | HReg;
680 BAsmCode[1] = AdrVals[0];
681 break;
682 }
683 break;
684 case ModReg16:
685 HReg = AdrMode;
686 DecodeAdr(&ArgStr[2], MModReg16 | MModIndReg | MModIdxReg | MModDir | MModMem | MModImm);
687 switch (AdrType)
688 {
689 case ModReg16:
690 if (HReg == HLReg)
691 {
692 CodeLen = 1;
693 BAsmCode[0] = 0x40 | AdrMode;
694 }
695 else if (AdrMode == HLReg)
696 {
697 CodeLen = 1;
698 BAsmCode[0] = 0x48 | HReg;
699 }
700 else
701 {
702 CodeLen = 2;
703 BAsmCode[0] = 0xf8 | AdrMode;
704 BAsmCode[1] = 0x38 | HReg;
705 }
706 break;
707 case ModIndReg:
708 CodeLen = 2;
709 BAsmCode[0] = 0xe0 | AdrMode;
710 BAsmCode[1] = 0x48 | HReg;
711 break;
712 case ModIdxReg:
713 CodeLen = 2 + AdrCnt;
714 BAsmCode[0] = 0xf0 | AdrMode;
715 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
716 BAsmCode[1 + AdrCnt] = 0x48 | HReg;
717 break;
718 case ModDir:
719 if (HReg == HLReg)
720 {
721 CodeLen = 2;
722 BAsmCode[0] = 0x47;
723 BAsmCode[1] = AdrVals[0];
724 }
725 else
726 {
727 CodeLen = 3;
728 BAsmCode[0] = 0xe7;
729 BAsmCode[1] = AdrVals[0];
730 BAsmCode[2] = 0x48 | HReg;
731 }
732 break;
733 case ModMem:
734 CodeLen = 4;
735 BAsmCode[0] = 0xe3;
736 BAsmCode[3] = 0x48 | HReg;
737 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
738 break;
739 case ModImm:
740 CodeLen = 3;
741 BAsmCode[0] = 0x38 | HReg;
742 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
743 break;
744 }
745 break;
746 case ModIndReg:
747 case ModIdxReg:
748 case ModDir:
749 case ModMem:
750 MinOneIs0 = True;
751 HReg = AdrCnt;
752 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
753 switch (AdrType)
754 {
755 case ModIndReg:
756 BAsmCode[0] = 0xe8 | AdrMode;
757 break;
758 case ModIdxReg:
759 BAsmCode[0] = 0xf4 | AdrMode;
760 break;
761 case ModMem:
762 BAsmCode[0] = 0xeb;
763 break;
764 case ModDir:
765 BAsmCode[0] = 0x0f;
766 break;
767 }
768 DecodeAdr(&ArgStr[2], MModReg16 | MModReg8 | MModImm);
769 if (BAsmCode[0] == 0x0f)
770 switch (AdrType)
771 {
772 case ModReg8:
773 if (AdrMode == AccReg)
774 {
775 CodeLen = 2;
776 BAsmCode[0] = 0x2f;
777 }
778 else
779 {
780 CodeLen = 3;
781 BAsmCode[0] = 0xef;
782 BAsmCode[2] = 0x20 | AdrMode;
783 }
784 break;
785 case ModReg16:
786 if (AdrMode == HLReg)
787 {
788 CodeLen = 2;
789 BAsmCode[0] = 0x4f;
790 }
791 else
792 {
793 CodeLen = 3;
794 BAsmCode[0] = 0xef;
795 BAsmCode[2] = 0x40 | AdrMode;
796 }
797 break;
798 case ModImm:
799 CodeLen = 3 + OpSize;
800 BAsmCode[0] = 0x37 | (OpSize << 3);
801 memcpy(BAsmCode + 2, AdrVals, AdrCnt);
802 break;
803 }
804 else
805 {
806 switch (AdrType)
807 {
808 case ModReg8:
809 BAsmCode[1 + HReg] = 0x20 | AdrMode;
810 break;
811 case ModReg16:
812 BAsmCode[1 + HReg] = 0x40 | AdrMode;
813 break;
814 case ModImm:
815 BAsmCode[1 + HReg] = 0x37 | (OpSize << 3);
816 break;
817 }
818 memcpy(BAsmCode + 2 + HReg, AdrVals, AdrCnt);
819 CodeLen = 1 + HReg + 1 + AdrCnt;
820 }
821 break;
822 }
823 }
824 }
825
DecodePUSH_POP(Word Code)826 static void DecodePUSH_POP(Word Code)
827 {
828 if (ChkArgCnt(1, 1))
829 {
830 if (!as_strcasecmp(ArgStr[1].Str, "AF"))
831 {
832 CodeLen = 1;
833 BAsmCode[0] = 0x56 | Code;
834 }
835 else
836 {
837 DecodeAdr(&ArgStr[1], MModReg16);
838 if (AdrType == ModReg16)
839 {
840 if (AdrMode == 6) WrError(ErrNum_InvAddrMode);
841 else
842 {
843 CodeLen = 1;
844 BAsmCode[0] = 0x50 | Code | AdrMode;
845 }
846 }
847 }
848 }
849 }
850
DecodeLDA(Word Code)851 static void DecodeLDA(Word Code)
852 {
853 Byte HReg;
854
855 UNUSED(Code);
856
857 if (ChkArgCnt(2, 2))
858 {
859 DecodeAdr(&ArgStr[1], MModReg16);
860 if (AdrType == ModReg16)
861 {
862 HReg = 0x38 + AdrMode;
863 DecodeAdr(&ArgStr[2], MModIndReg | MModIdxReg);
864 switch (AdrType)
865 {
866 case ModIndReg:
867 if (AdrMode < 4) WrError(ErrNum_InvAddrMode);
868 else
869 {
870 CodeLen = 3;
871 BAsmCode[0] = 0xf0 | AdrMode;
872 BAsmCode[1] = 0;
873 BAsmCode[2] = HReg;
874 }
875 break;
876 case ModIdxReg:
877 CodeLen = 2 + AdrCnt;
878 BAsmCode[0] = 0xf4 + AdrMode;
879 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
880 BAsmCode[1 + AdrCnt] = HReg;
881 break;
882 }
883 }
884 }
885 }
886
DecodeLDAR(Word Code)887 static void DecodeLDAR(Word Code)
888 {
889 UNUSED(Code);
890
891 if (!ChkArgCnt(2, 2));
892 else if (as_strcasecmp(ArgStr[1].Str, "HL")) WrError(ErrNum_InvAddrMode);
893 else
894 {
895 Boolean OK;
896 Integer AdrInt = EvalStrIntExpression(&ArgStr[2], Int16, &OK) - (EProgCounter() + 2);
897 if (OK)
898 {
899 CodeLen = 3;
900 BAsmCode[0] = 0x17;
901 BAsmCode[1] = Lo(AdrInt);
902 BAsmCode[2] = Hi(AdrInt);
903 }
904 }
905 }
906
DecodeEX(Word Code)907 static void DecodeEX(Word Code)
908 {
909 Byte HReg;
910
911 UNUSED(Code);
912
913 /* work around the parser problem related to the ' character */
914
915 if (!as_strncasecmp(ArgStr[2].Str, "AF\'", 3))
916 ArgStr[2].Str[3] = '\0';
917
918 if (!ChkArgCnt(2, 2));
919 else if (ArgPair("DE", "HL"))
920 {
921 CodeLen = 1;
922 BAsmCode[0] = 0x08;
923 }
924 else if ((ArgPair("AF", "AF\'")) || (ArgPair("AF", "AF`")))
925 {
926 CodeLen = 1;
927 BAsmCode[0] = 0x09;
928 }
929 else
930 {
931 DecodeAdr(&ArgStr[1], MModReg16 | MModIndReg | MModIdxReg | MModMem | MModDir);
932 switch (AdrType)
933 {
934 case ModReg16:
935 HReg = 0x50 | AdrMode;
936 DecodeAdr(&ArgStr[2], MModIndReg | MModIdxReg | MModMem | MModDir);
937 switch (AdrType)
938 {
939 case ModIndReg:
940 CodeLen = 2;
941 BAsmCode[0] = 0xe0 | AdrMode;
942 BAsmCode[1] = HReg;
943 break;
944 case ModIdxReg:
945 CodeLen = 2 + AdrCnt;
946 BAsmCode[0] = 0xf0 | AdrMode;
947 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
948 BAsmCode[1 + AdrCnt] = HReg;
949 break;
950 case ModDir:
951 CodeLen = 3;
952 BAsmCode[0] = 0xe7;
953 BAsmCode[1] = AdrVals[0];
954 BAsmCode[2] = HReg;
955 break;
956 case ModMem:
957 CodeLen = 4;
958 BAsmCode[0] = 0xe3;
959 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
960 BAsmCode[3] = HReg;
961 break;
962 }
963 break;
964 case ModIndReg:
965 case ModIdxReg:
966 case ModDir:
967 case ModMem:
968 switch (AdrType)
969 {
970 case ModIndReg:
971 BAsmCode[0] = 0xe0 | AdrMode;
972 break;
973 case ModIdxReg:
974 BAsmCode[0] = 0xf0 | AdrMode;
975 break;
976 case ModDir:
977 BAsmCode[0] = 0xe7;
978 break;
979 case ModMem:
980 BAsmCode[0] = 0xe3;
981 break;
982 }
983 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
984 HReg = 2 + AdrCnt;
985 DecodeAdr(&ArgStr[2], MModReg16);
986 if (AdrType == ModReg16)
987 {
988 BAsmCode[HReg - 1] = 0x50 | AdrMode;
989 CodeLen = HReg;
990 }
991 break;
992 }
993 }
994 }
995
DecodeINC_DEC(Word Code)996 static void DecodeINC_DEC(Word Code)
997 {
998 if (Hi(Code))
999 SetOpSize(1);
1000
1001 if (ChkArgCnt(1, 1))
1002 {
1003 DecodeAdr(&ArgStr[1], MModReg8 | MModReg16 | MModIndReg | MModIdxReg | MModDir | MModMem);
1004 if (OpSize==-1)
1005 OpSize = 0;
1006 switch (AdrType)
1007 {
1008 case ModReg8:
1009 CodeLen = 1;
1010 BAsmCode[0] = 0x80 | Lo(Code) | AdrMode;
1011 break;
1012 case ModReg16:
1013 CodeLen = 1;
1014 BAsmCode[0] = 0x90 | Lo(Code) | AdrMode;
1015 break;
1016 case ModIndReg:
1017 CodeLen = 2;
1018 BAsmCode[0] = 0xe0 | AdrMode;
1019 BAsmCode[1] = 0x87 | (OpSize << 4) | Lo(Code);
1020 break;
1021 case ModIdxReg:
1022 CodeLen = 2 + AdrCnt;
1023 BAsmCode[0] = 0xf0 | AdrMode;
1024 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1025 BAsmCode[1 + AdrCnt] = 0x87 | (OpSize << 4) | Lo(Code);
1026 break;
1027 case ModDir:
1028 CodeLen = 2;
1029 BAsmCode[0] = 0x87 | (OpSize << 4) | Lo(Code);
1030 BAsmCode[1] = AdrVals[0];
1031 break;
1032 case ModMem:
1033 CodeLen = 4;
1034 BAsmCode[0] = 0xe3;
1035 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1036 BAsmCode[3] = 0x87 | (OpSize << 4) | Lo(Code);
1037 BAsmCode[1] = AdrVals[0];
1038 break;
1039 }
1040 }
1041 }
1042
DecodeINCX_DECX(Word Code)1043 static void DecodeINCX_DECX(Word Code)
1044 {
1045 if (ChkArgCnt(1, 1))
1046 {
1047 DecodeAdr(&ArgStr[1], MModDir);
1048 if (AdrType == ModDir)
1049 {
1050 CodeLen = 2;
1051 BAsmCode[0] = Code;
1052 BAsmCode[1] = AdrVals[0];
1053 }
1054 }
1055 }
1056
DecodeMUL_DIV(Word Code)1057 static void DecodeMUL_DIV(Word Code)
1058 {
1059 if (!ChkArgCnt(2, 2));
1060 else if (as_strcasecmp(ArgStr[1].Str, "HL")) WrError(ErrNum_InvAddrMode);
1061 else
1062 {
1063 OpSize = 0;
1064 DecodeAdr(&ArgStr[2], MModReg8 | MModIndReg | MModIdxReg | MModDir | MModMem | MModImm);
1065 switch (AdrType)
1066 {
1067 case ModReg8:
1068 CodeLen = 2;
1069 BAsmCode[0] = 0xf8 + AdrMode;
1070 BAsmCode[1] = Code;
1071 break;
1072 case ModIndReg:
1073 CodeLen = 2;
1074 BAsmCode[0] = 0xe0 + AdrMode;
1075 BAsmCode[1] = Code;
1076 break;
1077 case ModIdxReg:
1078 CodeLen = 2 + AdrCnt;
1079 BAsmCode[0] = 0xf0 + AdrMode;
1080 BAsmCode[1 + AdrCnt] = Code;
1081 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1082 break;
1083 case ModDir:
1084 CodeLen = 3;
1085 BAsmCode[0] = 0xe7;
1086 BAsmCode[1] = AdrVals[0];
1087 BAsmCode[2] = Code;
1088 break;
1089 case ModMem:
1090 CodeLen = 4;
1091 BAsmCode[0] = 0xe3;
1092 BAsmCode[3] = Code;
1093 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1094 break;
1095 case ModImm:
1096 CodeLen = 2;
1097 BAsmCode[0] = Code;
1098 BAsmCode[1] = AdrVals[0];
1099 break;
1100 }
1101 }
1102 }
1103
DecodeJR(Word Code)1104 static void DecodeJR(Word Code)
1105 {
1106 UNUSED(Code);
1107
1108 if (ChkArgCnt(1, 2))
1109 {
1110 int Cond = (ArgCnt == 1) ? DefaultCondition : DecodeCondition(ArgStr[1].Str);
1111 if (Cond >= ConditionCnt) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1112 else
1113 {
1114 Boolean OK;
1115 tSymbolFlags Flags;
1116 Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int16, &OK, &Flags) - (EProgCounter() + 2);
1117
1118 if (OK)
1119 {
1120 if (!mSymbolQuestionable(Flags) && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
1121 else
1122 {
1123 CodeLen = 2;
1124 BAsmCode[0] = 0xc0 | Conditions[Cond].Code;
1125 BAsmCode[1] = AdrInt & 0xff;
1126 }
1127 }
1128 }
1129 }
1130 }
1131
DecodeCALL_JP(Word Code)1132 static void DecodeCALL_JP(Word Code)
1133 {
1134 if (ChkArgCnt(1, 2))
1135 {
1136 unsigned Cond = (ArgCnt == 1) ? DefaultCondition : DecodeCondition(ArgStr[1].Str);
1137
1138 if (Cond >= ConditionCnt) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1139 else
1140 {
1141 OpSize = 1;
1142 DecodeAdr(&ArgStr[ArgCnt], MModIndReg | MModIdxReg | MModMem |MModImm);
1143 if (AdrType == ModImm)
1144 AdrType = ModMem;
1145 switch (AdrType)
1146 {
1147 case ModIndReg:
1148 CodeLen = 2;
1149 BAsmCode[0] = 0xe8 | AdrMode;
1150 BAsmCode[1] = 0xc0 | (Code << 4) | Conditions[Cond].Code;
1151 break;
1152 case ModIdxReg:
1153 CodeLen = 2 + AdrCnt;
1154 BAsmCode[0] = 0xf4 | AdrMode;
1155 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1156 BAsmCode[1 + AdrCnt] = 0xc0 | (Code << 4) | Conditions[Cond].Code;
1157 break;
1158 case ModMem:
1159 if (Cond == DefaultCondition)
1160 {
1161 CodeLen = 3;
1162 BAsmCode[0] = 0x1a + (Code << 1);
1163 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1164 }
1165 else
1166 {
1167 CodeLen = 4;
1168 BAsmCode[0] = 0xeb;
1169 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1170 BAsmCode[3] = 0xc0 | (Code << 4) | Conditions[Cond].Code;
1171 }
1172 break;
1173 }
1174 }
1175 }
1176 }
1177
DecodeRET(Word Code)1178 static void DecodeRET(Word Code)
1179 {
1180 UNUSED(Code);
1181
1182 if (ChkArgCnt(0, 1))
1183 {
1184 unsigned Cond = (ArgCnt == 0) ? DefaultCondition : DecodeCondition(ArgStr[1].Str);
1185
1186 if (Cond == DefaultCondition)
1187 {
1188 CodeLen = 1;
1189 BAsmCode[0] = 0x1e;
1190 }
1191 else if (Cond >= ConditionCnt) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
1192 else
1193 {
1194 CodeLen = 2;
1195 BAsmCode[0] = 0xfe;
1196 BAsmCode[1] = 0xd0 | Conditions[Cond].Code;
1197 }
1198 }
1199 }
1200
DecodeDJNZ(Word Code)1201 static void DecodeDJNZ(Word Code)
1202 {
1203 UNUSED(Code);
1204
1205 if (ChkArgCnt(1, 2))
1206 {
1207 if (ArgCnt == 1)
1208 {
1209 AdrType = ModReg8;
1210 AdrMode = 0;
1211 OpSize = 0;
1212 }
1213 else
1214 DecodeAdr(&ArgStr[1], MModReg8 | MModReg16);
1215 if (AdrType != ModNone)
1216 {
1217 if (AdrMode != 0) WrError(ErrNum_InvAddrMode);
1218 else
1219 {
1220 Boolean OK;
1221 tSymbolFlags Flags;
1222 Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int16, &OK, &Flags) - (EProgCounter() + 2);
1223
1224 if (OK)
1225 {
1226 if (!mSymbolQuestionable(Flags) && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
1227 else
1228 {
1229 CodeLen = 2;
1230 BAsmCode[0] = 0x18 | OpSize;
1231 BAsmCode[1] = AdrInt & 0xff;
1232 }
1233 }
1234 }
1235 }
1236 }
1237 }
1238
DecodeJRL_CALR(Word Code)1239 static void DecodeJRL_CALR(Word Code)
1240 {
1241 if (ChkArgCnt(1, 1))
1242 {
1243 Boolean OK;
1244 Integer AdrInt = EvalStrIntExpression(&ArgStr[1], Int16, &OK) - (EProgCounter() + 2);
1245 if (OK)
1246 {
1247 CodeLen = 3;
1248 BAsmCode[0] = Code;
1249 if ((Code == 0x1b)
1250 && (AdrInt >= -128)
1251 && (AdrInt <= 127))
1252 WrError(ErrNum_ShortJumpPossible);
1253 BAsmCode[1] = Lo(AdrInt);
1254 BAsmCode[2] = Hi(AdrInt);
1255 }
1256 }
1257 }
1258
1259 /*-------------------------------------------------------------------------*/
1260
AddW(const char * Name,Word Code,InstProc Proc)1261 static void AddW(const char *Name, Word Code, InstProc Proc)
1262 {
1263 char Str[20];
1264
1265 AddInstTable(InstTable, Name, Code, Proc);
1266 as_snprintf(Str, sizeof(Str), "%sW", Name);
1267 AddInstTable(InstTable, Str, Code | 0x100, Proc);
1268 }
1269
AddFixed(const char * NName,Byte NCode)1270 static void AddFixed(const char *NName, Byte NCode)
1271 {
1272 AddInstTable(InstTable, NName, NCode, DecodeFixed);
1273 }
1274
AddMove(const char * NName,Byte NCode)1275 static void AddMove(const char *NName, Byte NCode)
1276 {
1277 AddInstTable(InstTable, NName, NCode, DecodeMove);
1278 }
1279
AddShift(const char * NName,Word NCode,Boolean NMay)1280 static void AddShift(const char *NName, Word NCode, Boolean NMay)
1281 {
1282 AddInstTable(InstTable, NName, NCode | (NMay ? 0x100 : 0), DecodeShift);
1283 }
1284
AddBit(const char * NName,Byte NCode)1285 static void AddBit(const char *NName, Byte NCode)
1286 {
1287 AddInstTable(InstTable, NName, NCode, DecodeBit);
1288 }
1289
AddAcc(const char * NName,Byte NCode)1290 static void AddAcc(const char *NName, Byte NCode)
1291 {
1292 AddInstTable(InstTable, NName, NCode, DecodeAcc);
1293 }
1294
AddCondition(const char * NName,Byte NCode)1295 static void AddCondition(const char *NName, Byte NCode)
1296 {
1297 if (InstrZ >= ConditionCnt) exit(255);
1298 Conditions[InstrZ].Name = NName;
1299 Conditions[InstrZ++].Code = NCode;
1300 }
1301
InitFields(void)1302 static void InitFields(void)
1303 {
1304 InstTable = CreateInstTable(207);
1305 SetDynamicInstTable(InstTable);
1306 AddW("LD", 0, DecodeLD);
1307 AddInstTable(InstTable, "PUSH", 0, DecodePUSH_POP);
1308 AddInstTable(InstTable, "POP" , 8, DecodePUSH_POP);
1309 AddInstTable(InstTable, "LDA", 0, DecodeLDA);
1310 AddInstTable(InstTable, "LDAR", 0, DecodeLDAR);
1311 AddInstTable(InstTable, "EX", 0, DecodeEX);
1312 AddW("INC", 0, DecodeINC_DEC);
1313 AddW("DEC", 8, DecodeINC_DEC);
1314 AddInstTable(InstTable, "INCX", 0x07, DecodeINCX_DECX);
1315 AddInstTable(InstTable, "DECX", 0x0f, DecodeINCX_DECX);
1316 AddInstTable(InstTable, "MUL", 0x12, DecodeMUL_DIV);
1317 AddInstTable(InstTable, "DIV", 0x13, DecodeMUL_DIV);
1318 AddInstTable(InstTable, "JR", 0, DecodeJR);
1319 AddInstTable(InstTable, "CALL", 1, DecodeCALL_JP);
1320 AddInstTable(InstTable, "JP", 0, DecodeCALL_JP);
1321 AddInstTable(InstTable, "RET", 0, DecodeRET);
1322 AddInstTable(InstTable, "DJNZ", 0, DecodeDJNZ);
1323 AddInstTable(InstTable, "JRL", 0x1b, DecodeJRL_CALR);
1324 AddInstTable(InstTable, "CALR", 0x1d, DecodeJRL_CALR);
1325
1326 AddFixed("EXX" , 0x0a); AddFixed("CCF" , 0x0e);
1327 AddFixed("SCF" , 0x0d); AddFixed("RCF" , 0x0c);
1328 AddFixed("NOP" , 0x00); AddFixed("HALT", 0x01);
1329 AddFixed("DI" , 0x02); AddFixed("EI" , 0x03);
1330 AddFixed("SWI" , 0xff); AddFixed("RLCA", 0xa0);
1331 AddFixed("RRCA", 0xa1); AddFixed("RLA" , 0xa2);
1332 AddFixed("RRA" , 0xa3); AddFixed("SLAA", 0xa4);
1333 AddFixed("SRAA", 0xa5); AddFixed("SLLA", 0xa6);
1334 AddFixed("SRLA", 0xa7); AddFixed("RETI", 0x1f);
1335
1336 AddMove("LDI" , 0x58);
1337 AddMove("LDIR", 0x59);
1338 AddMove("LDD" , 0x5a);
1339 AddMove("LDDR", 0x5b);
1340 AddMove("CPI" , 0x5c);
1341 AddMove("CPIR", 0x5d);
1342 AddMove("CPD" , 0x5e);
1343 AddMove("CPDR", 0x5f);
1344
1345 AddShift("RLC", 0xa0, True );
1346 AddShift("RRC", 0xa1, True );
1347 AddShift("RL" , 0xa2, True );
1348 AddShift("RR" , 0xa3, True );
1349 AddShift("SLA", 0xa4, True );
1350 AddShift("SRA", 0xa5, True );
1351 AddShift("SLL", 0xa6, True );
1352 AddShift("SRL", 0xa7, True );
1353 AddShift("RLD", 0x10, False);
1354 AddShift("RRD", 0x11, False);
1355
1356 AddBit("BIT" , 0xa8);
1357 AddBit("SET" , 0xb8);
1358 AddBit("RES" , 0xb0);
1359 AddBit("TSET", 0x18);
1360
1361 AddAcc("DAA", 0x0b);
1362 AddAcc("CPL", 0x10);
1363 AddAcc("NEG", 0x11);
1364
1365 InstrZ = 0;
1366 AddInstTable(InstTable, "ADD", InstrZ++, DecodeALU2);
1367 AddInstTable(InstTable, "ADC", InstrZ++, DecodeALU2);
1368 AddInstTable(InstTable, "SUB", InstrZ++, DecodeALU2);
1369 AddInstTable(InstTable, "SBC", InstrZ++, DecodeALU2);
1370 AddInstTable(InstTable, "AND", InstrZ++, DecodeALU2);
1371 AddInstTable(InstTable, "XOR", InstrZ++, DecodeALU2);
1372 AddInstTable(InstTable, "OR" , InstrZ++, DecodeALU2);
1373 AddInstTable(InstTable, "CP" , InstrZ++, DecodeALU2);
1374
1375 Conditions = (Condition *) malloc(sizeof(Condition) * ConditionCnt); InstrZ = 0;
1376 AddCondition("F" , 0); DefaultCondition = InstrZ; AddCondition("T" , 8);
1377 AddCondition("Z" , 6); AddCondition("NZ" , 14);
1378 AddCondition("C" , 7); AddCondition("NC" , 15);
1379 AddCondition("PL" , 13); AddCondition("MI" , 5);
1380 AddCondition("P" , 13); AddCondition("M" , 5);
1381 AddCondition("NE" , 14); AddCondition("EQ" , 6);
1382 AddCondition("OV" , 4); AddCondition("NOV", 12);
1383 AddCondition("PE" , 4); AddCondition("PO" , 12);
1384 AddCondition("GE" , 9); AddCondition("LT" , 1);
1385 AddCondition("GT" , 10); AddCondition("LE" , 2);
1386 AddCondition("UGE", 15); AddCondition("ULT", 7);
1387 AddCondition("UGT", 11); AddCondition("ULE", 3);
1388 }
1389
DeinitFields(void)1390 static void DeinitFields(void)
1391 {
1392 DestroyInstTable(InstTable);
1393
1394 free(Conditions);
1395 }
1396
MakeCode_90C141(void)1397 static void MakeCode_90C141(void)
1398 {
1399 CodeLen = 0; DontPrint = False; OpSize = -1;
1400
1401 /* zu ignorierendes */
1402
1403 if (Memo("")) return;
1404
1405 /* Pseudoanweisungen */
1406
1407 if (DecodeIntelPseudo(False)) return;
1408
1409 if (!LookupInstTable(InstTable, OpPart.Str))
1410 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
1411 }
1412
1413 /*-------------------------------------------------------------------------*/
1414
IsDef_90C141(void)1415 static Boolean IsDef_90C141(void)
1416 {
1417 return False;
1418 }
1419
SwitchFrom_90C141(void)1420 static void SwitchFrom_90C141(void)
1421 {
1422 DeinitFields();
1423 }
1424
ChkMoreOneArg(void)1425 static Boolean ChkMoreOneArg(void)
1426 {
1427 return (ArgCnt > 1);
1428 }
1429
SwitchTo_90C141(void)1430 static void SwitchTo_90C141(void)
1431 {
1432 TurnWords = False;
1433 ConstMode = ConstModeIntel;
1434 SetIsOccupiedFnc = ChkMoreOneArg;
1435
1436 PCSymbol = "$";
1437 HeaderID = 0x53;
1438 NOPCode = 0x00;
1439 DivideChars = ",";
1440 HasAttrs = False;
1441
1442 ValidSegs = 1 << SegCode;
1443 Grans[SegCode] = 1;
1444 ListGrans[SegCode] = 1;
1445 SegInits[SegCode] = 0;
1446 SegLimits[SegCode] = 0xffff;
1447
1448 MakeCode = MakeCode_90C141;
1449 IsDef = IsDef_90C141;
1450 SwitchFrom = SwitchFrom_90C141;
1451 InitFields();
1452 }
1453
code90c141_init(void)1454 void code90c141_init(void)
1455 {
1456 CPU90C141 = AddCPU("90C141", SwitchTo_90C141);
1457 }
1458