1 /* code97c241.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* Codegenerator TLCS-9000 */
8 /* */
9 /*****************************************************************************/
10
11 #include "stdinc.h"
12
13 #include <string.h>
14 #include <ctype.h>
15 #include <assert.h>
16
17 #include "nls.h"
18 #include "strutil.h"
19 #include "bpemu.h"
20 #include "asmdef.h"
21 #include "asmsub.h"
22 #include "asmpars.h"
23 #include "asmallg.h"
24 #include "asmitree.h"
25 #include "codepseudo.h"
26 #include "intpseudo.h"
27 #include "codevars.h"
28 #include "errmsg.h"
29
30 #include "code97c241.h"
31
32 typedef struct
33 {
34 Byte Code;
35 Byte Mask; /* B0..2=OpSizes, B4=-MayImm, B5=-MayReg */
36 } RMWOrder;
37
38 typedef struct
39 {
40 const char *Name;
41 Byte Code;
42 Byte Mask; /* B7: DD in A-Format gedreht */
43 enum { Equal, FirstCounts, SecondCounts, Op2Half } SizeType;
44 Boolean ImmKorr, ImmErl, RegErl;
45 } GAOrder;
46
47
48 #define ConditionCount 20
49 #define RMWOrderCount 14
50
51
52 static CPUVar CPU97C241;
53
54 static int OpSize, OpSize2;
55 static Integer LowLim4, LowLim8;
56
57 static Boolean AdrOK;
58 static Word AdrMode, AdrMode2;
59 static Byte AdrCnt2;
60 static Word AdrVals[2], AdrVals2[2];
61 static int AdrInc;
62 static Word Prefs[2];
63 static Boolean PrefUsed[2];
64 static char Format;
65 static Boolean MinOneIs0;
66
67 static RMWOrder *RMWOrders;
68 static const char **Conditions;
69
70 /*--------------------------------------------------------------------------*/
71
CheckForcePrefix(const char * pArg,Boolean * pForce)72 static int CheckForcePrefix(const char *pArg, Boolean *pForce)
73 {
74 if (*pArg == '>')
75 {
76 *pForce = True;
77 return 1;
78 }
79 return 0;
80 }
81
AddSignedPrefix(Byte Index,Byte MaxBits,LongInt Value,Boolean Force)82 static void AddSignedPrefix(Byte Index, Byte MaxBits, LongInt Value, Boolean Force)
83 {
84 LongInt Max;
85
86 Max = 1l << (MaxBits -1);
87 if (Force || ((Value < -Max) || (Value >= Max)))
88 {
89 PrefUsed[Index] = True;
90 Prefs[Index] = (Value >> MaxBits) & 0x7ff;
91 }
92 }
93
AddRelPrefix(Byte Index,Byte MaxBits,LongInt * Value,Boolean Force)94 static Boolean AddRelPrefix(Byte Index, Byte MaxBits, LongInt *Value, Boolean Force)
95 {
96 LongInt Max1,Max2;
97
98 Max1 = 1l << (MaxBits - 1);
99 Max2 = 1l << (MaxBits + 10);
100 if ((*Value < -Max2) || (*Value >= Max2)) WrError(ErrNum_JmpDistTooBig);
101 else
102 {
103 if (Force || ((*Value < -Max1) || (*Value >= Max1)))
104 {
105 PrefUsed[Index] = True;
106 Prefs[Index] = ((*Value) >> MaxBits) & 0x7ff;
107 }
108 return True;
109 }
110 return False;
111 }
112
AddAbsPrefix(Byte Index,Byte MaxBits,LongInt Value,Boolean Force)113 static void AddAbsPrefix(Byte Index, Byte MaxBits, LongInt Value, Boolean Force)
114 {
115 LongInt Dist;
116
117 Dist = 1l << (MaxBits - 1);
118 if (Force || ((Value >= Dist) && (Value < 0x1000000 - Dist)))
119 {
120 PrefUsed[Index] = True;
121 Prefs[Index] = (Value >> MaxBits) & 0x7ff;
122 }
123 }
124
InsertSinglePrefix(Byte Index)125 static void InsertSinglePrefix(Byte Index)
126 {
127 if (PrefUsed[Index])
128 {
129 memmove(WAsmCode + 1, WAsmCode + 0, CodeLen);
130 WAsmCode[0] = Prefs[Index] + 0xd000 + (((Word)Index) << 11);
131 CodeLen += 2;
132 }
133 }
134
135 /*!------------------------------------------------------------------------
136 * \fn DecodeRegCore(const char *pArg, Byte *pResult, tSymbolSize *pSize)
137 * \brief check whether argument is a CPU register
138 * \param pArg source argument
139 * \param pResult register number if yes
140 * \param pSize register size if yes
141 * \return True if yes
142 * ------------------------------------------------------------------------ */
143
DecodeRegCore(const char * pArg,Byte * pResult,tSymbolSize * pSize)144 static Boolean DecodeRegCore(const char *pArg, Byte *pResult, tSymbolSize *pSize)
145 {
146 Boolean OK;
147 int l = strlen(pArg);
148
149 if (as_toupper(*pArg) != 'R')
150 return False;
151 l = strlen(pArg);
152 if ((l > 4) || (l < 3))
153 return False;
154
155 switch (as_toupper(pArg[1]))
156 {
157 case 'B':
158 *pSize = eSymbolSize8Bit;
159 break;
160 case 'W':
161 *pSize = eSymbolSize16Bit;
162 break;
163 case 'D':
164 *pSize = eSymbolSize32Bit;
165 break;
166 default:
167 return False;
168 }
169 *pResult = ConstLongInt(pArg + 2, &OK, 10);
170 if (!OK || (*pResult > 15))
171 return False;
172 if ((*pSize == eSymbolSize32Bit) && Odd(*pResult))
173 return False;
174 return True;
175 }
176
177 /*!------------------------------------------------------------------------
178 * \fn DissectReg_97C241(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
179 * \brief dissect register symbols - TLCS-9000 variant
180 * \param pDest destination buffer
181 * \param DestSize destination buffer size
182 * \param Value numeric register value
183 * \param InpSize register size
184 * ------------------------------------------------------------------------ */
185
DissectReg_97C241(char * pDest,size_t DestSize,tRegInt Value,tSymbolSize InpSize)186 static void DissectReg_97C241(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
187 {
188 switch (InpSize)
189 {
190 case eSymbolSize8Bit:
191 as_snprintf(pDest, DestSize, "RB%u", (unsigned)Value);
192 break;
193 case eSymbolSize16Bit:
194 as_snprintf(pDest, DestSize, "RW%u", (unsigned)Value);
195 break;
196 case eSymbolSize32Bit:
197 as_snprintf(pDest, DestSize, "RD%u", (unsigned)Value);
198 break;
199 default:
200 as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
201 }
202 }
203
204 /*!------------------------------------------------------------------------
205 * \fn tRegEvalResult DecodeReg(const tStrComp *pArg, Byte *pResult, tSymbolSize *pSize, Boolean MustBeReg)
206 * \brief check whether argument is a CPU register or register alias
207 * \param pArg source argument
208 * \param pResult register number if yes
209 * \param pSize register size if yes
210 * \param MustBeReg True if register is expected
211 * \return True if yes
212 * ------------------------------------------------------------------------ */
213
DecodeReg(const tStrComp * pArg,Byte * pResult,tSymbolSize * pSize,Boolean MustBeReg)214 static tRegEvalResult DecodeReg(const tStrComp *pArg, Byte *pResult, tSymbolSize *pSize, Boolean MustBeReg)
215 {
216 tRegEvalResult RegEvalResult;
217 tEvalResult EvalResult;
218 tRegDescr RegDescr;
219
220 if (DecodeRegCore(pArg->Str, pResult, pSize))
221 return eIsReg;
222
223 RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
224 if (eIsReg == RegEvalResult)
225 {
226 *pResult = RegDescr.Reg;
227 *pSize = EvalResult.DataSize;
228 }
229 return RegEvalResult;
230 }
231
DecodeSpecReg(char * Asc,Byte * Result)232 static Boolean DecodeSpecReg(char *Asc, Byte *Result)
233 {
234 if (!as_strcasecmp(Asc, "SP")) *Result = 0x8c;
235 else if (!as_strcasecmp(Asc, "ISP")) *Result = 0x81;
236 else if (!as_strcasecmp(Asc, "ESP")) *Result = 0x83;
237 else if (!as_strcasecmp(Asc, "PBP")) *Result = 0x05;
238 else if (!as_strcasecmp(Asc, "CBP")) *Result = 0x07;
239 else if (!as_strcasecmp(Asc, "PSW")) *Result = 0x89;
240 else if (!as_strcasecmp(Asc, "IMC")) *Result = 0x0b;
241 else if (!as_strcasecmp(Asc, "CC")) *Result = 0x0e;
242 else return False;
243 return True;
244 }
245
DecodeRegAdr(const tStrComp * pArg,Byte * pResult)246 static Boolean DecodeRegAdr(const tStrComp *pArg, Byte *pResult)
247 {
248 tSymbolSize Size;
249
250 if (DecodeReg(pArg, pResult, &Size, True) != eIsReg)
251 return False;
252 if (OpSize == eSymbolSizeUnknown)
253 OpSize = Size;
254 if (Size != OpSize)
255 {
256 WrError(ErrNum_ConfOpSizes);
257 return False;
258 }
259 *pResult &= 0x3f;
260 return True;
261 }
262
DecodeAdr(const tStrComp * pArg,Byte PrefInd,Boolean MayImm,Boolean MayReg)263 static void DecodeAdr(const tStrComp *pArg, Byte PrefInd, Boolean MayImm, Boolean MayReg)
264 {
265 #define FreeReg 0xff
266 #define SPReg 0xfe
267 #define PCReg 0xfd
268
269 Byte Reg;
270 String AdrPartStr;
271 tStrComp AdrPart, Remainder;
272 Boolean OK;
273 int ArgLen;
274 tSymbolSize Size;
275 tRegEvalResult RegEvalResult;
276
277 AdrCnt = 0; AdrOK = False;
278 StrCompMkTemp(&AdrPart, AdrPartStr);
279
280 /* I. Speicheradresse */
281
282 if (IsIndirect(pArg->Str))
283 {
284 Boolean ForcePrefix = False, MinFlag, NMinFlag;
285 tStrComp Arg, TmpComp;
286 String Tmp;
287 char *PMPos, *EPos;
288 Byte BaseReg, IndReg, ScaleFact;
289 tSymbolSize BaseRegSize, IndRegSize;
290 LongInt DispAcc;
291
292 StrCompMkTemp(&TmpComp, Tmp);
293
294 /* I.1. vorkonditionieren */
295
296 StrCompRefRight(&Arg, pArg, 1);
297 StrCompShorten(&Arg, 1);
298 KillPrefBlanksStrCompRef(&Arg);
299 KillPostBlanksStrComp(&Arg);
300
301 /* I.2. Predekrement */
302
303 if ((*Arg.Str == '-') && (Arg.Str[1] == '-'))
304 {
305 tStrComp RegComp;
306
307 StrCompRefRight(&RegComp, &Arg, 2);
308 if (DecodeReg(&RegComp, &Reg, &Size, True) == eIsReg)
309 {
310 switch (Size)
311 {
312 case eSymbolSize16Bit:
313 AdrMode = 0x50 + (Reg & 15);
314 AdrOK = True;
315 break;
316 case eSymbolSize32Bit:
317 AdrMode = 0x71 + (Reg & 14);
318 AdrOK = True;
319 break;
320 default:
321 WrStrErrorPos(ErrNum_InvAddrMode, &Arg);
322 break;
323 }
324 }
325 return;
326 }
327
328 /* I.3. Postinkrement */
329
330 ArgLen = strlen(Arg.Str);
331 if ((Arg.Str[ArgLen - 1] == '+') && (Arg.Str[ArgLen - 2] == '+'))
332 {
333 StrCompCopy(&AdrPart, &Arg);
334 StrCompShorten(&AdrPart, 2);
335 if (DecodeReg(&AdrPart, &Reg, &Size, True) == eIsReg)
336 {
337 switch (Size)
338 {
339 case eSymbolSize16Bit:
340 AdrMode = 0x40 + (Reg & 15);
341 AdrOK = True;
342 break;
343 case eSymbolSize32Bit:
344 AdrMode = 0x70 + (Reg & 14);
345 AdrOK = True;
346 break;
347 default:
348 WrError(ErrNum_InvAddrMode);
349 break;
350 }
351 return;
352 }
353 }
354
355 /* I.4. Adresskomponenten zerlegen */
356
357 BaseReg = IndReg = FreeReg;
358 BaseRegSize = IndRegSize = eSymbolSizeUnknown;
359 ScaleFact = 0;
360 DispAcc = AdrInc;
361 MinFlag = False;
362 do
363 {
364 /* I.4.a. Trennzeichen suchen */
365
366 PMPos = QuotMultPos(Arg.Str, "-+");
367 NMinFlag = (PMPos && (*PMPos == '-'));
368 if (PMPos)
369 {
370 StrCompSplitRef(&Arg, &Remainder, &Arg, PMPos);
371 KillPostBlanksStrComp(&Arg);
372 KillPrefBlanksStrCompRef(&Remainder);
373 }
374
375 /* I.4.b. Indexregister mit Skalierung */
376
377 EPos = QuotPos(Arg.Str, '*');
378 if (EPos)
379 {
380 StrCompCopy(&TmpComp, &Arg);
381 TmpComp.Str[EPos - Arg.Str] = '\0';
382 KillPostBlanksStrComp(&TmpComp);
383 }
384 ArgLen = strlen(Arg.Str);
385 if ((EPos == Arg.Str + ArgLen - 2)
386 && ((Arg.Str[ArgLen - 1] == '1') || (Arg.Str[ArgLen - 1] == '2') || (Arg.Str[ArgLen - 1] == '4') || (Arg.Str[ArgLen - 1] == '8'))
387 && ((RegEvalResult = DecodeReg(&TmpComp, &Reg, &Size, False)) != eIsNoReg))
388 {
389 if (RegEvalResult == eRegAbort)
390 return;
391 if ((Size == eSymbolSize8Bit) || MinFlag || (IndReg != FreeReg))
392 {
393 WrError(ErrNum_InvAddrMode);
394 return;
395 }
396 IndReg = Reg;
397 IndRegSize = Size;
398 switch (Arg.Str[ArgLen - 1])
399 {
400 case '1':
401 ScaleFact = 0;
402 break;
403 case '2':
404 ScaleFact = 1;
405 break;
406 case '4':
407 ScaleFact = 2;
408 break;
409 case '8':
410 ScaleFact = 3;
411 break;
412 }
413 }
414
415 /* I.4.c. Basisregister */
416
417 else if ((RegEvalResult = DecodeReg(&Arg, &Reg, &Size, False)) != eIsNoReg)
418 {
419 if (RegEvalResult == eRegAbort)
420 return;
421 if ((Size == eSymbolSize8Bit) || (MinFlag))
422 {
423 WrError(ErrNum_InvAddrMode);
424 return;
425 }
426 if (BaseReg == FreeReg)
427 {
428 BaseReg = Reg;
429 BaseRegSize = Size;
430 }
431 else if (IndReg == FreeReg)
432 {
433 IndReg = Reg;
434 IndRegSize = Size;
435 ScaleFact = 0;
436 }
437 else
438 {
439 WrStrErrorPos(ErrNum_InvAddrMode, &Arg);
440 return;
441 }
442 }
443
444 /* I.4.d. Sonderregister */
445
446 else if ((!as_strcasecmp(Arg.Str, "PC")) || (!as_strcasecmp(Arg.Str, "SP")))
447 {
448 if ((BaseReg != FreeReg) && (IndReg == FreeReg))
449 {
450 IndReg = BaseReg;
451 IndRegSize = BaseRegSize;
452 BaseReg = FreeReg;
453 ScaleFact = 0;
454 };
455 if ((BaseReg != FreeReg) || (MinFlag))
456 {
457 WrError(ErrNum_InvAddrMode);
458 return;
459 }
460 /*#warning here*/
461 BaseReg = as_strcasecmp(Arg.Str, "SP") ? PCReg : SPReg;
462 }
463
464 /* I.4.e. Displacement */
465
466 else
467 {
468 LongInt DispPart;
469 tSymbolFlags Flags;
470
471 DispPart = EvalStrIntExpressionOffsWithFlags(&Arg, CheckForcePrefix(Arg.Str, &ForcePrefix), Int32, &OK, &Flags);
472 if (!OK)
473 return;
474 if (mFirstPassUnknown(Flags))
475 DispPart = 1;
476 DispAcc = MinFlag ? DispAcc - DispPart : DispAcc + DispPart;
477 }
478
479 if (PMPos)
480 Arg = Remainder;
481 MinFlag = NMinFlag;
482 }
483 while (PMPos);
484
485 /* I.5. Indexregister mit Skalierung 1 als Basis behandeln */
486
487 if ((BaseReg == FreeReg) && (IndReg != FreeReg) && (ScaleFact == 0))
488 {
489 BaseReg = IndReg;
490 BaseRegSize = IndRegSize;
491 IndReg = FreeReg;
492 }
493
494 /* I.6. absolut */
495
496 if ((BaseReg == FreeReg) && (IndReg == FreeReg))
497 {
498 AdrMode = 0x20; /* 0x60 should be equivalent: adding 0 as RW0 or RD0 is irrelvant */
499 AdrVals[0] = 0xe000 + (DispAcc & 0x1fff); AdrCnt = 2;
500 AddAbsPrefix(PrefInd, 13, DispAcc, ForcePrefix);
501 AdrOK = True;
502 return;
503 }
504
505 /* I.7. Basis [mit Displacement] */
506
507 if ((BaseReg != FreeReg) && (IndReg == FreeReg))
508 {
509 /* I.7.a. Basis ohne Displacement */
510
511 if (DispAcc == 0)
512 {
513 if (BaseRegSize == eSymbolSize16Bit)
514 AdrMode = 0x10 + (BaseReg & 15);
515 else
516 AdrMode = 0x61 + (BaseReg & 14);
517 AdrOK = True;
518 return;
519 }
520
521 /* I.7.b. Nullregister mit Displacement muss in Erweiterungswort */
522
523 else if (BaseReg == 0)
524 {
525 if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
526 else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
527 else
528 {
529 AdrMode = 0x20;
530 if (BaseRegSize == eSymbolSize16Bit)
531 AdrVals[0] = ((Word)BaseReg & 15) << 11;
532 else
533 AdrVals[0] = (((Word)BaseReg & 14) << 11) + 0x8000;
534 AdrVals[0] += DispAcc & 0x1ff;
535 AdrCnt = 2;
536 AddSignedPrefix(PrefInd, 9, DispAcc, ForcePrefix);
537 AdrOK = True;
538 }
539 return;
540 }
541
542 /* I.7.c. Stack mit Displacement: Optimierung moeglich */
543
544 else if (BaseReg == SPReg)
545 {
546 if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
547 else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
548 else if ((DispAcc >= 0) && (DispAcc <= 127))
549 {
550 AdrMode = 0x80 + (DispAcc & 0x7f);
551 AdrOK = True;
552 }
553 else
554 {
555 AdrMode = 0x20;
556 AdrVals[0] = 0xd000 + (DispAcc & 0x1ff); AdrCnt = 2;
557 AddSignedPrefix(PrefInd, 9, DispAcc, ForcePrefix);
558 AdrOK = True;
559 }
560 return;
561 }
562
563 /* I.7.d. Programmzaehler mit Displacement: keine Optimierung */
564
565 else if (BaseReg == PCReg)
566 {
567 if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
568 else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
569 else
570 {
571 AdrMode = 0x20;
572 AdrVals[0] = 0xd800 + (DispAcc & 0x1ff);
573 AdrCnt = 2;
574 AddSignedPrefix(PrefInd, 9, DispAcc, ForcePrefix);
575 AdrOK = True;
576 }
577 return;
578 }
579
580 /* I.7.e. einfaches Basisregister mit Displacement */
581
582 else
583 {
584 if (DispAcc > 0x7fffff) WrError(ErrNum_OverRange);
585 else if (DispAcc < -0x800000) WrError(ErrNum_UnderRange);
586 else
587 {
588 if (BaseRegSize == eSymbolSize16Bit)
589 AdrMode = 0x20 + (BaseReg & 15);
590 else
591 AdrMode = 0x60 + (BaseReg & 14);
592 AdrVals[0] = 0xe000 + (DispAcc & 0x1fff);
593 AdrCnt = 2;
594 AddSignedPrefix(PrefInd, 13, DispAcc, ForcePrefix);
595 AdrOK = True;
596 }
597 return;
598 }
599 }
600
601 /* I.8. Index- [und Basisregister] */
602
603 else
604 {
605 if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
606 else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
607 else if ((IndReg & 15) == 0) WrError(ErrNum_InvAddrMode);
608 else
609 {
610 if (IndRegSize == eSymbolSize16Bit)
611 AdrMode = 0x20 + (IndReg & 15);
612 else
613 AdrMode = 0x60 + (IndReg & 14);
614 switch (BaseReg)
615 {
616 case FreeReg:
617 AdrVals[0] = 0xc000; break;
618 case SPReg:
619 AdrVals[0] = 0xd000; break;
620 case PCReg:
621 AdrVals[0] = 0xd800; break;
622 default:
623 if (BaseRegSize == eSymbolSize16Bit)
624 AdrVals[0] = ((Word)BaseReg & 15) << 11;
625 else
626 AdrVals[0] = 0x8000 + (((Word)BaseReg & 14) << 10);
627 }
628 AdrVals[0] += (((Word)ScaleFact) << 9) + (DispAcc & 0x1ff);
629 AdrCnt = 2;
630 AddSignedPrefix(PrefInd, 9, DispAcc, ForcePrefix);
631 AdrOK = True;
632 }
633 return;
634 }
635 }
636
637 /* II. Arbeitsregister */
638
639 else if ((RegEvalResult = DecodeReg(pArg, &Reg, &Size, False)) != eIsNoReg)
640 {
641 if (RegEvalResult == eRegAbort)
642 return;
643 if (!MayReg) WrStrErrorPos(ErrNum_InvAddrMode, pArg);
644 else
645 {
646 if (OpSize == eSymbolSizeUnknown)
647 OpSize = Size;
648 if (Size != OpSize) WrError(ErrNum_ConfOpSizes);
649 else
650 {
651 AdrMode = Reg & 15;
652 AdrOK = True;
653 }
654 }
655 return;
656 }
657
658 /* III. Spezialregister */
659
660 else if (DecodeSpecReg(pArg->Str, &Reg))
661 {
662 if (!MayReg) WrError(ErrNum_InvAddrMode);
663 else
664 {
665 if (OpSize == -1)
666 OpSize=Reg >> 6;
667 if ((Reg >> 6) != OpSize) WrError(ErrNum_ConfOpSizes);
668 else
669 {
670 AdrMode = 0x30 + (Reg & 15);
671 AdrOK = True;
672 }
673 }
674 return;
675 }
676
677 else if (!MayImm) WrError(ErrNum_InvAddrMode);
678 else
679 {
680 if ((OpSize == -1) && (MinOneIs0))
681 OpSize = 0;
682 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
683 else
684 {
685 AdrMode = 0x30;
686 switch (OpSize)
687 {
688 case 0:
689 AdrVals[0] = EvalStrIntExpression(pArg, Int8, &OK) & 0xff;
690 if (OK)
691 {
692 AdrCnt = 2;
693 AdrOK = True;
694 }
695 break;
696 case 1:
697 AdrVals[0] = EvalStrIntExpression(pArg, Int16, &OK);
698 if (OK)
699 {
700 AdrCnt = 2;
701 AdrOK = True;
702 }
703 break;
704 case 2:
705 {
706 LongInt DispAcc = EvalStrIntExpression(pArg, Int32, &OK);
707
708 if (OK)
709 {
710 AdrVals[0] = DispAcc & 0xffff;
711 AdrVals[1] = DispAcc >> 16;
712 AdrCnt = 4;
713 AdrOK = True;
714 }
715 break;
716 }
717 }
718 }
719 }
720 }
721
CopyAdr(void)722 static void CopyAdr(void)
723 {
724 OpSize2 = OpSize;
725 AdrMode2 = AdrMode;
726 AdrCnt2 = AdrCnt;
727 memcpy(AdrVals2, AdrVals, AdrCnt);
728 }
729
IsReg(void)730 static Boolean IsReg(void)
731 {
732 return (AdrMode <= 15);
733 }
734
Is2Reg(void)735 static Boolean Is2Reg(void)
736 {
737 return (AdrMode2 <= 15);
738 }
739
IsImmediate(void)740 static Boolean IsImmediate(void)
741 {
742 return (AdrMode == 0x30);
743 }
744
Is2Immediate(void)745 static Boolean Is2Immediate(void)
746 {
747 return (AdrMode2 == 0x30);
748 }
749
ImmVal(void)750 static LongInt ImmVal(void)
751 {
752 LongInt Tmp1;
753 Integer Tmp2;
754 ShortInt Tmp3;
755
756 switch (OpSize)
757 {
758 case 0:
759 Tmp3 = AdrVals[0] & 0xff;
760 return Tmp3;
761 case 1:
762 Tmp2 = AdrVals[0];
763 return Tmp2;
764 case 2:
765 Tmp1 = (((LongInt)AdrVals[1]) << 16) + AdrVals[0];
766 return Tmp1;
767 default:
768 WrError(ErrNum_InternalError);
769 return 0;
770 }
771 }
772
ImmVal2(void)773 static LongInt ImmVal2(void)
774 {
775 LongInt Tmp1;
776 Integer Tmp2;
777 ShortInt Tmp3;
778
779 switch (OpSize)
780 {
781 case 0:
782 Tmp3 = AdrVals2[0] & 0xff;
783 return Tmp3;
784 case 1:
785 Tmp2 = AdrVals2[0];
786 return Tmp2;
787 case 2:
788 Tmp1 = (((LongInt)AdrVals2[1]) << 16) + AdrVals2[0];
789 return Tmp1;
790 default:
791 WrError(ErrNum_InternalError);
792 return 0;
793 }
794 }
795
IsAbsolute(void)796 static Boolean IsAbsolute(void)
797 {
798 return (((AdrMode == 0x20) || (AdrMode == 0x60))
799 && (AdrCnt == 2)
800 && ((AdrVals[0] & 0xe000) == 0xe000));
801 }
802
Is2Absolute(void)803 static Boolean Is2Absolute(void)
804 {
805 return (((AdrMode2 == 0x20) || (AdrMode2 == 0x60))
806 && (AdrCnt2 == 2)
807 && ((AdrVals2[0] & 0xe000) == 0xe000));
808 }
809
IsShort(void)810 static Boolean IsShort(void)
811 {
812 if (AdrMode < 0x30)
813 return True;
814 else if (AdrMode == 0x30)
815 {
816 LongInt ImmValue = ImmVal();
817
818 return ((ImmValue >= LowLim4) && (ImmValue <= 7));
819 }
820 else
821 return False;
822 }
823
Is2Short(void)824 static Boolean Is2Short(void)
825 {
826 if (AdrMode2 < 0x30)
827 return True;
828 else if (AdrMode2 == 0x30)
829 {
830 LongInt ImmValue = ImmVal2();
831
832 return ((ImmValue >= LowLim4) && (ImmValue <= 7));
833 }
834 else
835 return False;
836 }
837
ConvertShort(void)838 static void ConvertShort(void)
839 {
840 if (AdrMode == 0x30)
841 {
842 AdrMode += ImmVal() & 15;
843 AdrCnt = 0;
844 }
845 }
846
Convert2Short(void)847 static void Convert2Short(void)
848 {
849 if (AdrMode2 == 0x30)
850 {
851 AdrMode2 += ImmVal2() & 15;
852 AdrCnt2 = 0;
853 }
854 }
855
SetULowLims(void)856 static void SetULowLims(void)
857 {
858 LowLim4 = 0;
859 LowLim8 = 0;
860 }
861
DecodePseudo(void)862 static Boolean DecodePseudo(void)
863 {
864 return False;
865 }
866
AddPrefixes(void)867 static void AddPrefixes(void)
868 {
869 if (CodeLen != 0)
870 {
871 InsertSinglePrefix(1);
872 InsertSinglePrefix(0);
873 }
874 }
875
DecodeCondition(const char * pAsc,Word * pCondition)876 static Boolean DecodeCondition(const char *pAsc, Word *pCondition)
877 {
878 int z;
879
880 for (z = 0; z < ConditionCount; z++)
881 if (!as_strcasecmp(pAsc, Conditions[z]))
882 {
883 *pCondition = z;
884 return True;
885 }
886 return False;
887 }
888
DecideGA(void)889 static char DecideGA(void)
890 {
891 if (((IsShort()) && (Is2Absolute()))
892 || ((Is2Short()) && (IsAbsolute())))
893 return 'A';
894 else
895 return 'G';
896 }
897
898 /*--------------------------------------------------------------------------*/
899
DecodeFixed(Word Code)900 static void DecodeFixed(Word Code)
901 {
902 if (!ChkArgCnt(0, 0));
903 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
904 else
905 {
906 WAsmCode[0] = Code;
907 CodeLen = 2;
908 }
909 }
910
DecodeRMW(Word Index)911 static void DecodeRMW(Word Index)
912 {
913 const RMWOrder *pOrder = RMWOrders + Index;
914
915 if ((OpSize == -1) && (pOrder->Mask & 0x20))
916 OpSize = 2;
917 if (ChkArgCnt(1, 1))
918 {
919 tStrComp *pArg = &ArgStr[1];
920
921 if ((!IsIndirect(ArgStr[1].Str)) && (pOrder->Mask & 0x20))
922 {
923 StrCompReset(&ArgStr[2]);
924 as_snprintf(ArgStr[2].Str, STRINGSIZE, "(%s)", ArgStr[1].Str);
925 pArg = &ArgStr[2];
926 }
927 DecodeAdr(pArg, 0, !(pOrder->Mask & 0x10), !(pOrder->Mask & 0x20));
928 if (AdrOK)
929 {
930 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
931 else if (!(pOrder->Mask & (1 << OpSize))) WrError(ErrNum_InvOpSize);
932 else
933 {
934 WAsmCode[0] = (((Word)OpSize + 1) << 14) + (((Word)pOrder->Code) << 8) + AdrMode;
935 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
936 CodeLen = 2 + AdrCnt;
937 }
938 }
939 }
940 }
941
DecodeGASI1(Word Code)942 static void DecodeGASI1(Word Code)
943 {
944 if (ChkArgCnt(2, 2))
945 {
946 DecodeAdr(&ArgStr[1], 1, False, True);
947 if (AdrOK)
948 {
949 CopyAdr();
950 DecodeAdr(&ArgStr[2], 0, True, True);
951 if (AdrOK)
952 {
953 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
954 else
955 {
956 LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
957
958 if (Format == ' ')
959 {
960 if (((IsReg()) && (Is2Short()))
961 || ((Is2Reg()) && (IsShort())))
962 Format = 'S';
963 else if ((IsImmediate()) && (OpSize > 0) && ((ImmValue > 127) || (ImmValue < -128)))
964 Format = 'I';
965 else
966 Format = DecideGA();
967 }
968 switch (Format)
969 {
970 case 'G':
971 WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
972 if ((IsImmediate()) && (ImmValue <= 127) && (ImmValue >= -128))
973 {
974 AdrMode = ImmValue & 0xff;
975 AdrCnt = 0;
976 }
977 else
978 WAsmCode[0] += 0x800;
979 WAsmCode[0] += AdrMode;
980 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
981 WAsmCode[1 + (AdrCnt >> 1)] = 0x8400 + (Code << 8) + AdrMode2;
982 memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
983 CodeLen = 4 + AdrCnt + AdrCnt2;
984 break;
985 case 'A':
986 if ((IsShort()) && (Is2Absolute()))
987 {
988 ConvertShort();
989 WAsmCode[0] = 0x3900
990 + (((Word)OpSize + 1) << 14)
991 + ((AdrMode & 0xf0) << 5)
992 + (AdrMode & 15);
993 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
994 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff) + (Code << 13);
995 CodeLen = 4 + AdrCnt;
996 }
997 else if ((Is2Short()) && (IsAbsolute()))
998 {
999 Convert2Short();
1000 WAsmCode[0] = 0x3980
1001 + (((Word)OpSize + 1) << 14)
1002 + ((AdrMode2 & 0xf0) << 5)
1003 + (AdrMode2 & 15);
1004 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1005 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
1006 CodeLen = 4 + AdrCnt2;
1007 }
1008 else WrError(ErrNum_InvAddrMode);
1009 break;
1010 case 'S':
1011 if ((IsShort()) && (Is2Reg()))
1012 {
1013 ConvertShort();
1014 WAsmCode[0] = 0x0000
1015 + (((Word)OpSize + 1) << 14)
1016 + (AdrMode & 15)
1017 + ((AdrMode & 0xf0) << 5)
1018 + ((AdrMode2 & 1) << 12)
1019 + ((AdrMode2 & 14) << 4)
1020 + ((Code & 1) << 4)
1021 + ((Code & 2) << 10);
1022 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1023 CodeLen = 2 + AdrCnt;
1024 }
1025 else if ((Is2Short()) && (IsReg()))
1026 {
1027 Convert2Short();
1028 WAsmCode[0] = 0x0100
1029 + (((Word)OpSize + 1) << 14)
1030 + (AdrMode2 & 15)
1031 + ((AdrMode2 & 0xf0) << 5)
1032 + ((AdrMode & 1) << 12)
1033 + ((AdrMode & 14) << 4)
1034 + ((Code & 1) << 4)
1035 + ((Code & 2) << 11);
1036 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1037 CodeLen = 2 + AdrCnt2;
1038 }
1039 else WrError(ErrNum_InvAddrMode);
1040 break;
1041 case 'I':
1042 if ((!IsImmediate()) || (OpSize == 0)) WrError(ErrNum_InvAddrMode);
1043 else
1044 {
1045 WAsmCode[0] = AdrMode2 + (((Word)OpSize-1) << 11) + (Code << 8);
1046 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1047 memcpy(WAsmCode + 1 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
1048 CodeLen = 2 + AdrCnt + AdrCnt2;
1049 }
1050 break;
1051 default:
1052 WrError(ErrNum_InvFormat);
1053 }
1054 }
1055 }
1056 }
1057 }
1058 }
1059
DecodeGASI2(Word Code)1060 static void DecodeGASI2(Word Code)
1061 {
1062 if (ChkArgCnt(2, 2))
1063 {
1064 DecodeAdr(&ArgStr[1], 1, False, True);
1065 if (AdrOK)
1066 {
1067 CopyAdr();
1068 DecodeAdr(&ArgStr[2], 0, True, True);
1069 if (AdrOK)
1070 {
1071 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1072 else
1073 {
1074 LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1075
1076 if (Format == ' ')
1077 {
1078 if ((IsReg()) && (Is2Reg()))
1079 Format = 'S';
1080 else if ((IsImmediate()) && (OpSize > 0) && ((ImmValue > 127) || (ImmValue < -128)))
1081 Format = 'I';
1082 else
1083 Format = DecideGA();
1084 }
1085 switch (Format)
1086 {
1087 case 'G':
1088 WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1089 if ((IsImmediate()) && (ImmValue <= 127) && (ImmValue >= -128))
1090 {
1091 AdrMode = ImmValue & 0xff;
1092 AdrCnt = 0;
1093 }
1094 else
1095 WAsmCode[0] += 0x800;
1096 WAsmCode[0] += AdrMode;
1097 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1098 WAsmCode[1 + (AdrCnt >> 1)] = 0xc400 + (Code << 8) + AdrMode2;
1099 memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1100 CodeLen = 4 + AdrCnt + AdrCnt2;
1101 break;
1102 case 'A':
1103 if ((IsShort()) && (Is2Absolute()))
1104 {
1105 ConvertShort();
1106 WAsmCode[0] = 0x3940
1107 + (((Word)OpSize+1) << 14)
1108 + ((AdrMode & 0xf0) << 5)
1109 + (AdrMode & 15);
1110 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1111 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff) + (Code << 13);
1112 CodeLen = 4 + AdrCnt;
1113 }
1114 else if ((Is2Short()) && (IsAbsolute()))
1115 {
1116 Convert2Short();
1117 WAsmCode[0] = 0x39c0
1118 + (((Word)OpSize+1) << 14)
1119 + ((AdrMode2 & 0xf0) << 5)
1120 + (AdrMode2 & 15);
1121 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1122 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
1123 CodeLen = 4 + AdrCnt2;
1124 }
1125 else WrError(ErrNum_InvAddrMode);
1126 break;
1127 case 'S':
1128 if ((IsReg()) && (Is2Reg()))
1129 {
1130 WAsmCode[0] = 0x3800
1131 + (((Word)OpSize+1) << 14)
1132 + (AdrMode & 15)
1133 + (AdrMode2 << 4)
1134 + (Code << 9);
1135 CodeLen = 2;
1136 }
1137 else WrError(ErrNum_InvAddrMode);
1138 break;
1139 case 'I':
1140 if ((!IsImmediate()) || (OpSize == 0)) WrError(ErrNum_InvAddrMode);
1141 else
1142 {
1143 WAsmCode[0] = 0x400 + AdrMode2 + (((Word)OpSize-1) << 11) + (Code << 8);
1144 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1145 memcpy(WAsmCode + 1 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
1146 CodeLen = 2 + AdrCnt + AdrCnt2;
1147 }
1148 break;
1149 default:
1150 WrError(ErrNum_InvFormat);
1151 }
1152 }
1153 }
1154 }
1155 }
1156 }
1157
DecodeTrinom(Word Code)1158 static void DecodeTrinom(Word Code)
1159 {
1160 int Cnt;
1161 Byte Reg;
1162
1163 if (Code == 2) /* MAC */
1164 LowLim8 = 0;
1165 if (!ChkArgCnt(3, 3));
1166 else if (DecodeRegAdr(&ArgStr[1], &Reg))
1167 {
1168 if (Code >= 2)
1169 OpSize--;
1170 if (OpSize < 0) WrError(ErrNum_InvOpSize);
1171 else
1172 {
1173 DecodeAdr(&ArgStr[3], 0, True, True);
1174 if (AdrOK)
1175 {
1176 LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1177
1178 WAsmCode[0] = 0x700;
1179 if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1180 {
1181 AdrMode = ImmValue & 0xff;
1182 AdrCnt = 0;
1183 }
1184 else
1185 WAsmCode[0] += 0x800;
1186 WAsmCode[0] += (((Word)OpSize + 1) << 14) + AdrMode;
1187 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1188 Cnt = AdrCnt;
1189 DecodeAdr(&ArgStr[2], 1, False, True);
1190 if (AdrOK)
1191 {
1192 WAsmCode[1 + (Cnt >> 1)] = AdrMode + (Code << 8) + (((Word)Reg) << 11);
1193 memcpy(WAsmCode + 2 + (Cnt >> 1), AdrVals, AdrCnt);
1194 CodeLen = 4 + Cnt + AdrCnt;
1195 }
1196 }
1197 }
1198 }
1199 }
1200
DecodeRLM_RRM(Word Code)1201 static void DecodeRLM_RRM(Word Code)
1202 {
1203 int Cnt;
1204 Byte Reg;
1205 tSymbolSize Size;
1206
1207 if (!ChkArgCnt(3, 3));
1208 else if (!DecodeReg(&ArgStr[2], &Reg, &Size, True));
1209 else if (Size != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[2]);
1210 else
1211 {
1212 Reg &= 0x3f;
1213 DecodeAdr(&ArgStr[3], 0, True, True);
1214 if (AdrOK)
1215 {
1216 LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1217
1218 WAsmCode[0] = 0x700;
1219 if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > -128))
1220 {
1221 AdrMode = ImmValue & 0xff; AdrCnt = 0;
1222 }
1223 else
1224 WAsmCode[0] += 0x800;
1225 WAsmCode[0] += AdrMode;
1226 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1227 Cnt = AdrCnt;
1228 DecodeAdr(&ArgStr[1], 1, False, True);
1229 if (AdrOK)
1230 {
1231 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1232 else
1233 {
1234 WAsmCode[0] += ((Word)OpSize + 1) << 14;
1235 WAsmCode[1 + (Cnt >> 1)] = Code + (((Word)Reg) << 11)+AdrMode;
1236 memcpy(WAsmCode + 2 + (Cnt >> 1), AdrVals, AdrCnt);
1237 CodeLen = 4 + AdrCnt + Cnt;
1238 }
1239 }
1240 }
1241 }
1242 }
1243
DecodeBit(Word Code)1244 static void DecodeBit(Word Code)
1245 {
1246 if (ChkArgCnt(2, 2))
1247 {
1248 DecodeAdr(&ArgStr[1], 1, False, True);
1249 if (AdrOK)
1250 {
1251 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1252 else
1253 {
1254 CopyAdr();
1255 OpSize = -1;
1256 MinOneIs0 = True;
1257 DecodeAdr(&ArgStr[2], 0, True, True);
1258 if (AdrOK)
1259 {
1260 LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1261
1262 OpSize = OpSize2;
1263 if (Format==' ')
1264 {
1265 if ((Is2Reg()) && (IsImmediate())
1266 && (ImmValue > 0)
1267 && (ImmValue < (1 << (OpSize + 3))))
1268 Format = 'S';
1269 else
1270 Format = DecideGA();
1271 }
1272 switch (Format)
1273 {
1274 case 'G':
1275 WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1276 if ((IsImmediate()) && (ImmValue >= LowLim8) && (ImmValue < 127))
1277 {
1278 AdrMode = ImmValue & 0xff;
1279 AdrCnt = 0;
1280 }
1281 else
1282 WAsmCode[0] += 0x800;
1283 WAsmCode[0] += AdrMode;
1284 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1285 WAsmCode[1 + (AdrCnt >> 1)] = 0xd400 + (Code << 8) + AdrMode2;
1286 memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1287 CodeLen = 4 + AdrCnt + AdrCnt2;
1288 break;
1289 case 'A':
1290 if ((IsAbsolute()) && (Is2Short()))
1291 {
1292 Convert2Short();
1293 WAsmCode[0] = 0x39d0
1294 + (((Word)OpSize+1) << 14)
1295 + ((AdrMode2 & 0xf0) << 5)
1296 + (AdrMode2 & 15);
1297 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1298 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
1299 CodeLen = 4 + AdrCnt2;
1300 }
1301 else if ((Is2Absolute()) && (IsShort()))
1302 {
1303 ConvertShort();
1304 WAsmCode[0] = 0x3950
1305 + (((Word)OpSize+1) << 14)
1306 + ((AdrMode & 0xf0) << 5)
1307 + (AdrMode & 15);
1308 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1309 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff) + (Code << 13);
1310 CodeLen = 4 + AdrCnt;
1311 }
1312 else WrError(ErrNum_InvAddrMode);
1313 break;
1314 case 'S':
1315 if ((Is2Reg())
1316 && (IsImmediate())
1317 && (ImmVal() >= 0)
1318 && (ImmVal() < (1 << (3 + OpSize))))
1319 {
1320 if (OpSize == 2)
1321 {
1322 if (ImmVal() >= 16)
1323 {
1324 AdrVals[0] -= 16;
1325 AdrMode2++;
1326 }
1327 OpSize = 1;
1328 }
1329 if (OpSize == 1)
1330 {
1331 if (ImmVal() < 8)
1332 OpSize=0;
1333 else
1334 AdrVals[0] -= 8;
1335 }
1336 WAsmCode[0] = 0x1700
1337 + (((Word)OpSize + 1) << 14)
1338 + ((Code & 1) << 7)
1339 + ((Code & 2) << 10)
1340 + (ImmVal() << 4)
1341 + AdrMode2;
1342 CodeLen = 2;
1343 }
1344 else WrError(ErrNum_InvAddrMode);
1345 break;
1346 default:
1347 WrError(ErrNum_InvFormat);
1348 }
1349 }
1350 }
1351 }
1352 }
1353 }
1354
DecodeShift(Word Code)1355 static void DecodeShift(Word Code)
1356 {
1357 if (ChkArgCnt(2, 2))
1358 {
1359 DecodeAdr(&ArgStr[1], 1, False, True);
1360 if (AdrOK)
1361 {
1362 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1363 else
1364 {
1365 CopyAdr();
1366 OpSize = -1;
1367 MinOneIs0 = True;
1368 DecodeAdr(&ArgStr[2], 0, True, True);
1369 if (AdrOK)
1370 {
1371 LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1372
1373 OpSize = OpSize2;
1374 if (Format==' ')
1375 {
1376 if ((IsImmediate()) && (ImmValue == 1))
1377 Format = 'S';
1378 else
1379 Format = DecideGA();
1380 }
1381 switch (Format)
1382 {
1383 case 'G':
1384 WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1385 if ((IsImmediate()) && (ImmValue >= LowLim8) && (ImmVal() < 127))
1386 {
1387 AdrMode = ImmValue & 0xff;
1388 AdrCnt = 0;
1389 }
1390 else
1391 WAsmCode[0] += 0x800;
1392 WAsmCode[0] += AdrMode;
1393 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1394 WAsmCode[1 + (AdrCnt >> 1)] = 0xb400
1395 + ((Code & 3) << 8)
1396 + ((Code & 4) << 9)
1397 + AdrMode2;
1398 memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1399 CodeLen = 4 + AdrCnt + AdrCnt2;
1400 break;
1401 case 'A':
1402 if ((IsAbsolute()) && (Is2Short()))
1403 {
1404 Convert2Short();
1405 WAsmCode[0] = 0x39b0
1406 + (((Word)OpSize+1) << 14)
1407 + ((AdrMode2 & 0xf0) << 5)
1408 + (AdrMode2 & 15);
1409 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1410 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
1411 CodeLen = 4 + AdrCnt2;
1412 }
1413 else if ((Is2Absolute()) && (IsShort()))
1414 {
1415 ConvertShort();
1416 WAsmCode[0] = 0x3930
1417 + (((Word)OpSize+1) << 14)
1418 + ((AdrMode & 0xf0) << 5)
1419 + (AdrMode & 15);
1420 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1421 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)+ (Code << 13);
1422 CodeLen = 4 + AdrCnt;
1423 }
1424 else WrError(ErrNum_InvAddrMode);
1425 break;
1426 case 'S':
1427 if ((IsImmediate()) && (ImmValue == 1))
1428 {
1429 WAsmCode[0] = 0x2400
1430 + (((Word)OpSize+1) << 14)
1431 + AdrMode2
1432 + ((Code & 3) << 8)
1433 + ((Code & 4) << 9);
1434 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1435 CodeLen =2 + AdrCnt2;
1436 }
1437 else WrError(ErrNum_InvAddrMode);
1438 break;
1439 default:
1440 WrError(ErrNum_InvFormat);
1441 }
1442 }
1443 }
1444 }
1445 }
1446 }
1447
DecodeBField(Word Code)1448 static void DecodeBField(Word Code)
1449 {
1450 Byte Reg, Num1, Num2;
1451 Boolean OK;
1452 tSymbolFlags Flags;
1453 tSymbolSize Size;
1454
1455 if (ChkArgCnt(4, 4))
1456 {
1457 tStrComp *pArg1 = (Code == 2) ? &ArgStr[2] : &ArgStr[1],
1458 *pArg2 = (Code == 2) ? &ArgStr[1] : &ArgStr[2];
1459
1460 if (!DecodeReg(pArg1, &Reg, &Size, True));
1461 else if (Size != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, pArg1);
1462 else
1463 {
1464 Reg &= 0x3f;
1465 Num2 = EvalStrIntExpressionWithFlags(&ArgStr[4], Int5, &OK, &Flags);
1466 if (OK)
1467 {
1468 if (mFirstPassUnknown(Flags))
1469 Num2 &= 15;
1470 Num2--;
1471 if (Num2 > 15) WrError(ErrNum_OverRange);
1472 else if ((OpSize == -1) && (!DecodeRegAdr(pArg2, &Num1)));
1473 else
1474 {
1475 switch (OpSize)
1476 {
1477 case 0: Num1 = EvalStrIntExpression(&ArgStr[3], UInt3, &OK) & 7; break;
1478 case 1: Num1 = EvalStrIntExpression(&ArgStr[3], Int4, &OK) & 15; break;
1479 case 2: Num1 = EvalStrIntExpression(&ArgStr[3], Int5, &OK) & 31; break;
1480 default: assert(0);
1481 }
1482 if (OK)
1483 {
1484 if ((OpSize == 2) && (Num1 > 15))
1485 AdrInc = 2;
1486 DecodeAdr(pArg2, 1, False, True);
1487 if (AdrOK)
1488 {
1489 if ((OpSize == 2) && (Num1 > 15))
1490 {
1491 Num1 -= 16;
1492 OpSize--;
1493 if (!(AdrMode & 0xf0))
1494 AdrMode++;
1495 }
1496 WAsmCode[0] = 0x7000 + (((Word)OpSize + 1) << 8) + AdrMode;
1497 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1498 WAsmCode[1 + (AdrCnt >> 1)] = (((Word)Reg) << 11)
1499 + Num2
1500 + (((Word)Num1) << 5)
1501 + ((Code & 1) << 10)
1502 + ((Code & 2) << 14);
1503 CodeLen = 4 + AdrCnt;
1504 }
1505 }
1506 }
1507 }
1508 }
1509 }
1510 }
1511
DecodeGAEq(Word Code)1512 static void DecodeGAEq(Word Code)
1513 {
1514 if (Hi(Code))
1515 SetULowLims();
1516 if (ChkArgCnt(2, 2))
1517 {
1518 DecodeAdr(&ArgStr[1], 1, False, True);
1519 if (AdrOK)
1520 {
1521 CopyAdr();
1522 DecodeAdr(&ArgStr[2], 0, True, True);
1523 if (AdrOK)
1524 {
1525 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1526 else
1527 {
1528 if (OpSize == 0)
1529 LowLim8 = -128;
1530 if (Format == ' ')
1531 Format = DecideGA();
1532 switch (Format)
1533 {
1534 case 'G':
1535 {
1536 LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1537
1538 WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1539 if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1540 {
1541 AdrMode = ImmValue & 0xff;
1542 AdrCnt = 0;
1543 }
1544 else
1545 WAsmCode[0] += 0x800;
1546 WAsmCode[0] += AdrMode;
1547 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1548 WAsmCode[1 + (AdrCnt >> 1)] = 0x8400
1549 + AdrMode2
1550 + ((Code & 0xf0) << 8)
1551 + ((Code & 4) << 9)
1552 + ((Code & 3) << 8);
1553 memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1554 CodeLen = 4 + AdrCnt + AdrCnt2;
1555 break;
1556 }
1557 case 'A':
1558 if ((IsAbsolute()) && (Is2Short()))
1559 {
1560 Convert2Short();
1561 WAsmCode[0] = 0x3980
1562 + (((Word)OpSize + 1) << 14)
1563 + ((AdrMode2 & 0xf0) << 5)
1564 + (AdrMode2 & 15)
1565 + (Code & 0xf0);
1566 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1567 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
1568 + ((Code & 15) << 13);
1569 CodeLen = 4 + AdrCnt2;
1570 }
1571 else if ((Is2Absolute()) && (IsShort()))
1572 {
1573 ConvertShort();
1574 WAsmCode[0] = 0x3900
1575 + (((Word)OpSize + 1) << 14)
1576 + ((AdrMode & 0xf0) << 5)
1577 + (AdrMode & 15)
1578 + (Code & 0xf0);
1579 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1580 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
1581 + ((Code & 15) << 13);
1582 CodeLen = 4 + AdrCnt;
1583 }
1584 else WrError(ErrNum_InvAddrMode);
1585 break;
1586 default:
1587 WrError(ErrNum_InvFormat);
1588 }
1589 }
1590 }
1591 }
1592 }
1593 }
1594
DecodeGAHalf(Word Code)1595 static void DecodeGAHalf(Word Code)
1596 {
1597 if (ChkArgCnt(2, 2))
1598 {
1599 DecodeAdr(&ArgStr[1], 1, False, True);
1600 if (AdrOK)
1601 {
1602 if (OpSize == 0) WrError(ErrNum_InvOpSize);
1603 else
1604 {
1605 if (OpSize != -1)
1606 OpSize--;
1607 CopyAdr();
1608 DecodeAdr(&ArgStr[2], 0, True, True);
1609 if (AdrOK)
1610 {
1611 if (OpSize == 2) WrError(ErrNum_InvOpSize);
1612 else if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1613 else
1614 {
1615 if (Format == ' ')
1616 Format = DecideGA();
1617 switch (Format)
1618 {
1619 case 'G':
1620 {
1621 LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1622
1623 WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1624 if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1625 {
1626 AdrMode = ImmValue & 0xff;
1627 AdrCnt = 0;
1628 }
1629 else
1630 WAsmCode[0] += 0x800;
1631 WAsmCode[0] += AdrMode;
1632 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1633 WAsmCode[1 + (AdrCnt >> 1)] = 0x8400
1634 + AdrMode2
1635 + ((Code & 0xf0) << 8)
1636 + ((Code & 4) << 9)
1637 + ((Code & 3) << 8);
1638 memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1639 CodeLen = 4 + AdrCnt + AdrCnt2;
1640 break;
1641 }
1642 case 'A':
1643 if ((IsAbsolute()) && (Is2Short()))
1644 {
1645 Convert2Short();
1646 WAsmCode[0] = 0x3980
1647 + (((Word)OpSize + 1) << 14)
1648 + ((AdrMode2 & 0xf0) << 5)
1649 + (AdrMode2 & 15)
1650 + (Code & 0xf0);
1651 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1652 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
1653 + ((Code & 15) << 13);
1654 CodeLen = 4 + AdrCnt2;
1655 }
1656 else if ((Is2Absolute()) && (IsShort()))
1657 {
1658 ConvertShort();
1659 WAsmCode[0] = 0x3900
1660 + (((Word)OpSize + 1) << 14)
1661 + ((AdrMode & 0xf0) << 5)
1662 + (AdrMode & 15)
1663 + (Code & 0xf0);
1664 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1665 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
1666 + ((Code & 15) << 13);
1667 CodeLen = 4 + AdrCnt;
1668 }
1669 else WrError(ErrNum_InvAddrMode);
1670 break;
1671 default:
1672 WrError(ErrNum_InvFormat);
1673 }
1674 }
1675 }
1676 }
1677 }
1678 }
1679 }
1680
DecodeGAFirst(Word Code)1681 static void DecodeGAFirst(Word Code)
1682 {
1683 if (ChkArgCnt(2, 2))
1684 {
1685 DecodeAdr(&ArgStr[1], 1, !(Memo("STCF") || Memo("TSET")), True);
1686 if (AdrOK)
1687 {
1688 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1689 else
1690 {
1691 CopyAdr();
1692 OpSize = -1;
1693 MinOneIs0 = True;
1694 DecodeAdr(&ArgStr[2], 0, True, True);
1695 OpSize = OpSize2;
1696 if (AdrOK)
1697 {
1698 if (Format == ' ')
1699 Format = DecideGA();
1700 switch (Format)
1701 {
1702 case 'G':
1703 {
1704 LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1705
1706 WAsmCode[0] = 0x700
1707 + (((Word)OpSize + 1) << 14);
1708 if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1709 {
1710 AdrMode = ImmValue & 0xff;
1711 AdrCnt = 0;
1712 }
1713 else WAsmCode[0] += 0x800;
1714 WAsmCode[0] += AdrMode;
1715 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1716 WAsmCode[1 + (AdrCnt >> 1)] = 0x8400
1717 + AdrMode2
1718 + ((Code & 0xf0) << 8)
1719 + ((Code & 4) << 9)
1720 + ((Code & 3) << 8);
1721 memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1722 CodeLen = 4 + AdrCnt + AdrCnt2;
1723 break;
1724 }
1725 case 'A':
1726 if ((IsAbsolute()) && (Is2Short()))
1727 {
1728 Convert2Short();
1729 WAsmCode[0] = 0x3980
1730 + (((Word)OpSize + 1) << 14)
1731 + ((AdrMode2 & 0xf0) << 5)
1732 + (AdrMode2 & 15)
1733 + (Code & 0xf0);
1734 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1735 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
1736 + ((Code & 15) << 13);
1737 CodeLen = 4 + AdrCnt2;
1738 }
1739 else if ((Is2Absolute()) && (IsShort()))
1740 {
1741 ConvertShort();
1742 WAsmCode[0] = 0x3900
1743 + (((Word)OpSize + 1) << 14)
1744 + ((AdrMode & 0xf0) << 5)
1745 + (AdrMode & 15)
1746 + (Code & 0xf0);
1747 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1748 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
1749 + ((Code & 15) << 13);
1750 CodeLen = 4 + AdrCnt;
1751 }
1752 else WrError(ErrNum_InvAddrMode);
1753 break;
1754 default:
1755 WrError(ErrNum_InvFormat);
1756 }
1757 }
1758 }
1759 }
1760 }
1761 }
1762
DecodeGASecond(Word Code)1763 static void DecodeGASecond(Word Code)
1764 {
1765 if (ChkArgCnt(2, 2))
1766 {
1767 DecodeAdr(&ArgStr[2], 0, True, True);
1768 if (AdrOK)
1769 {
1770 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1771 else
1772 {
1773 CopyAdr();
1774 OpSize = -1;
1775 DecodeAdr(&ArgStr[1], 1, False, True);
1776 OpSize = OpSize2;
1777 if (AdrOK)
1778 {
1779 if (Format == ' ')
1780 Format = DecideGA();
1781 switch (Format)
1782 {
1783 case 'G':
1784 WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1785 if ((Is2Immediate()) && (ImmVal2() < 127) && (ImmVal2() > LowLim8))
1786 {
1787 AdrMode2 = ImmVal2() & 0xff;
1788 AdrCnt = 0;
1789 }
1790 else
1791 WAsmCode[0] += 0x800;
1792 WAsmCode[0] += AdrMode2;
1793 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1794 WAsmCode[1 + (AdrCnt2 >> 1)] = 0x8400
1795 + AdrMode
1796 + ((Code & 0xf0) << 8)
1797 + ((Code & 4) << 9)
1798 + ((Code & 3) << 8);
1799 memcpy(WAsmCode + 2 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
1800 CodeLen = 4 + AdrCnt + AdrCnt2;
1801 break;
1802 case 'A':
1803 if ((IsAbsolute()) && (Is2Short()))
1804 {
1805 Convert2Short();
1806 WAsmCode[0] = 0x3900
1807 + (((Word)OpSize + 1) << 14)
1808 + ((AdrMode2 & 0xf0) << 5)
1809 + (AdrMode2 & 15)
1810 + (Code & 0xf0);
1811 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1812 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
1813 + ((Code & 15) << 13);
1814 CodeLen = 4 + AdrCnt2;
1815 }
1816 else if ((Is2Absolute()) && (IsShort()))
1817 {
1818 ConvertShort();
1819 WAsmCode[0] = 0x3980 + (((Word)OpSize + 1) << 14)
1820 + ((AdrMode & 0xf0) << 5)
1821 + (AdrMode & 15)
1822 + (Code & 0xf0);
1823 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1824 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
1825 + ((Code & 15) << 13);
1826 CodeLen = 4 + AdrCnt;
1827 }
1828 else WrError(ErrNum_InvAddrMode);
1829 break;
1830 default:
1831 WrError(ErrNum_InvFormat);
1832 }
1833 }
1834 }
1835 }
1836 }
1837 }
1838
DecodeCHK_CHKS(Word IsSigned)1839 static void DecodeCHK_CHKS(Word IsSigned)
1840 {
1841 if (!IsSigned)
1842 SetULowLims();
1843 if (ChkArgCnt(2, 2))
1844 {
1845 DecodeAdr(&ArgStr[2], 1, False, True);
1846 if (AdrOK)
1847 {
1848 if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
1849 else if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1850 else
1851 {
1852 CopyAdr();
1853 DecodeAdr(&ArgStr[1], 0, False, False);
1854 if (AdrOK)
1855 {
1856 if (OpSize == 0)
1857 LowLim8 = -128;
1858 if (Format == ' ')
1859 Format = DecideGA();
1860 switch (Format)
1861 {
1862 case 'G':
1863 WAsmCode[0] = 0xf00 + (((Word)OpSize + 1) << 14) + AdrMode2;
1864 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1865 WAsmCode[1 + (AdrCnt2 >> 1)] = 0xa600 + AdrMode
1866 + (IsSigned << 8);
1867 memcpy(WAsmCode + 2 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
1868 CodeLen = 4 + AdrCnt + AdrCnt2;
1869 break;
1870 case 'A':
1871 if ((IsAbsolute()) && (Is2Short()))
1872 {
1873 Convert2Short();
1874 WAsmCode[0] = 0x3920
1875 + (((Word)OpSize + 1) << 14)
1876 + ((AdrMode2 & 0xf0) << 5)
1877 + (AdrMode2 & 15);
1878 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1879 WAsmCode[1 + (AdrCnt2 >> 1)] = 0x4000
1880 + (AdrVals[0] & 0x1fff)
1881 + (IsSigned << 13);
1882 CodeLen = 4 + AdrCnt2;
1883 }
1884 else if ((Is2Absolute()) && (IsShort()))
1885 {
1886 ConvertShort();
1887 WAsmCode[0] = 0x39a0
1888 + (((Word)OpSize + 1) << 14)
1889 + ((AdrMode & 0xf0) << 5)
1890 + (AdrMode & 15);
1891 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1892 WAsmCode[1 + (AdrCnt >> 1)] = 0x4000
1893 + (AdrVals2[0] & 0x1fff)
1894 + (IsSigned << 13);
1895 CodeLen = 4 + AdrCnt;
1896 }
1897 else WrError(ErrNum_InvAddrMode);
1898 break;
1899 default:
1900 WrError(ErrNum_InvFormat);
1901 }
1902 }
1903 }
1904 }
1905 }
1906 }
1907
DecodeString(Word Code)1908 static void DecodeString(Word Code)
1909 {
1910 Byte Reg;
1911 int Cnt;
1912 tSymbolSize Size;
1913
1914 if (!ChkArgCnt(3, 3));
1915 else if (!DecodeReg(&ArgStr[3], &Reg, &Size, True));
1916 else if (Size != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[3]);
1917 else
1918 {
1919 Reg &= 0x3f;
1920 DecodeAdr(&ArgStr[2], 0, True, True);
1921 if (AdrOK)
1922 {
1923 LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1924
1925 WAsmCode[0] = 0x700;
1926 if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1927 {
1928 AdrMode = ImmValue & 0xff;
1929 AdrCnt = 0;
1930 }
1931 else
1932 WAsmCode[0] += 0x800;
1933 WAsmCode[0] += AdrMode;
1934 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1935 Cnt = AdrCnt;
1936 DecodeAdr(&ArgStr[1], 1, True, True);
1937 if (AdrOK)
1938 {
1939 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1940 else
1941 {
1942 WAsmCode[0] += ((Word)OpSize + 1) << 14;
1943 WAsmCode[1 + (Cnt >> 1)] = 0x8000 + AdrMode + (Code << 8) + (((Word)Reg) << 11);
1944 memcpy(WAsmCode + 2 + (Cnt >> 1), AdrVals, AdrCnt);
1945 CodeLen = 4 + AdrCnt + Cnt;
1946 }
1947 }
1948 }
1949 }
1950 }
1951
DecodeEX(Word Code)1952 static void DecodeEX(Word Code)
1953 {
1954 UNUSED(Code);
1955
1956 if (ChkArgCnt(2, 2))
1957 {
1958 DecodeAdr(&ArgStr[1], 1, False, True);
1959 if (AdrOK)
1960 {
1961 CopyAdr();
1962 DecodeAdr(&ArgStr[2], 0, False, True);
1963 if (AdrOK)
1964 {
1965 if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1966 else
1967 {
1968 if (Format == ' ')
1969 {
1970 if ((IsReg()) && (Is2Reg()))
1971 Format = 'S';
1972 else
1973 Format = DecideGA();
1974 }
1975 switch (Format)
1976 {
1977 case 'G':
1978 WAsmCode[0] = 0x0f00 + (((Word)OpSize + 1) << 14) + AdrMode;
1979 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1980 WAsmCode[1 + (AdrCnt >> 1)] = 0x8f00 + AdrMode2;
1981 memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1982 CodeLen = 4 + AdrCnt + AdrCnt2;
1983 break;
1984 case 'A':
1985 if ((IsAbsolute()) && (Is2Short()))
1986 {
1987 Convert2Short();
1988 WAsmCode[0] = 0x3980
1989 + (((Word)OpSize + 1) << 14)
1990 + ((AdrMode2 & 0xf0) << 5)
1991 + (AdrMode2 & 15);
1992 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1993 WAsmCode[1 + (AdrCnt2 >> 1)] = AdrVals[0];
1994 CodeLen = 4 + AdrCnt2;
1995 }
1996 else if ((Is2Absolute()) && (IsShort()))
1997 {
1998 ConvertShort();
1999 WAsmCode[0] = 0x3900
2000 + (((Word)OpSize + 1) << 14)
2001 + ((AdrMode & 0xf0) << 5)
2002 + (AdrMode & 15);
2003 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
2004 WAsmCode[1 + (AdrCnt >> 1)] = AdrVals2[0];
2005 CodeLen = 4 + AdrCnt;
2006 }
2007 else WrError(ErrNum_InvAddrMode);
2008 break;
2009 case 'S':
2010 if ((IsReg()) && (Is2Reg()))
2011 {
2012 WAsmCode[0] = 0x3e00
2013 + (((Word)OpSize + 1) << 14)
2014 + (AdrMode2 << 4)
2015 + AdrMode;
2016 CodeLen = 2;
2017 }
2018 else WrError(ErrNum_InvAddrMode);
2019 break;
2020 default:
2021 WrError(ErrNum_InvFormat);
2022 }
2023 }
2024 }
2025 }
2026 }
2027 }
2028
DecodeCALR_JR(Word Code)2029 static void DecodeCALR_JR(Word Code)
2030 {
2031 if (!ChkArgCnt(1, 1));
2032 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
2033 else
2034 {
2035 LongInt AdrInt;
2036 Boolean OK, ForcePrefix = False;
2037
2038 AdrInt = EvalStrIntExpressionOffs(&ArgStr[1], CheckForcePrefix(ArgStr[1].Str, &ForcePrefix), Int32, &OK) - EProgCounter();
2039 if ((OK) && (AddRelPrefix(0, 13, &AdrInt, ForcePrefix)))
2040 {
2041 if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2042 else
2043 {
2044 WAsmCode[0] = Code + (AdrInt & 0x1ffe);
2045 CodeLen = 2;
2046 }
2047 }
2048 }
2049 }
2050
DecodeJRC(Word Code)2051 static void DecodeJRC(Word Code)
2052 {
2053 UNUSED(Code);
2054
2055 if (!ChkArgCnt(2, 2));
2056 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
2057 else
2058 {
2059 Word Condition;
2060
2061 if (!DecodeCondition(ArgStr[1].Str, &Condition)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
2062 else
2063 {
2064 LongInt AdrInt;
2065 Boolean OK, ForcePrefix = False;
2066
2067 Condition %= 16;
2068 AdrInt = EvalStrIntExpressionOffs(&ArgStr[2], CheckForcePrefix(ArgStr[2].Str, &ForcePrefix), Int32, &OK) - EProgCounter();
2069 if ((OK) && (AddRelPrefix(0, 9, &AdrInt, ForcePrefix)))
2070 {
2071 if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2072 else
2073 {
2074 WAsmCode[0] = 0x1000 + ((Condition & 14) << 8) + (AdrInt & 0x1fe) + (Condition & 1);
2075 CodeLen = 2;
2076 }
2077 }
2078 }
2079 }
2080 }
2081
DecodeJRBC_JRBS(Word Code)2082 static void DecodeJRBC_JRBS(Word Code)
2083 {
2084 if (!ChkArgCnt(3, 3));
2085 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
2086 else
2087 {
2088 int z;
2089 Boolean OK;
2090
2091 z = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
2092 if (OK)
2093 {
2094 Boolean AdrLongPrefix = False;
2095 LongInt AdrLong;
2096
2097 AdrLong = EvalStrIntExpressionOffs(&ArgStr[2], CheckForcePrefix(ArgStr[2].Str, &AdrLongPrefix), Int24, &OK);
2098 if (OK)
2099 {
2100 LongInt AdrInt;
2101 Boolean AdrIntPrefix = False;
2102
2103 AddAbsPrefix(1, 13, AdrLong, AdrLongPrefix);
2104 AdrInt = EvalStrIntExpressionOffs(&ArgStr[3], CheckForcePrefix(ArgStr[3].Str, &AdrIntPrefix), Int32, &OK) - EProgCounter();
2105 if ((OK) && (AddRelPrefix(0, 9, &AdrInt, AdrIntPrefix)))
2106 {
2107 if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2108 else
2109 {
2110 CodeLen = 4;
2111 WAsmCode[1] = (z << 13) + (AdrLong & 0x1fff);
2112 WAsmCode[0] = Code + (AdrInt & 0x1fe);
2113 }
2114 }
2115 }
2116 }
2117 }
2118 }
2119
DecodeDJNZ(Word Code)2120 static void DecodeDJNZ(Word Code)
2121 {
2122 UNUSED(Code);
2123
2124 if (ChkArgCnt(2, 2))
2125 {
2126 DecodeAdr(&ArgStr[1], 0, False, True);
2127 if (AdrOK)
2128 {
2129 if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
2130 else
2131 {
2132 LongInt AdrInt;
2133 Boolean OK, ForcePrefix = False;
2134
2135 AdrInt = EvalStrIntExpressionOffs(&ArgStr[2], CheckForcePrefix(ArgStr[2].Str, &ForcePrefix), Int32, &OK) - (EProgCounter() + 4 + AdrCnt +2 * Ord(PrefUsed[0]));
2136 if ((OK) && (AddRelPrefix(1, 13, &AdrInt, ForcePrefix)))
2137 {
2138 if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2139 else
2140 {
2141 WAsmCode[0] = 0x3700 + (((Word)OpSize + 1) << 14) + AdrMode;
2142 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
2143 WAsmCode[1 + (AdrCnt >> 1)] = 0xe000 + (AdrInt & 0x1ffe);
2144 CodeLen = 4 + AdrCnt;
2145 }
2146 }
2147 }
2148 }
2149 }
2150 }
2151
DecodeDJNZC(Word Code)2152 static void DecodeDJNZC(Word Code)
2153 {
2154 UNUSED(Code);
2155
2156 if (ChkArgCnt(3, 3))
2157 {
2158 Word Condition;
2159
2160 if (!DecodeCondition(ArgStr[2].Str, &Condition)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[2]);
2161 else
2162 {
2163 Condition %= 16;
2164 DecodeAdr(&ArgStr[1], 0, False, True);
2165 if (AdrOK)
2166 {
2167 if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
2168 else
2169 {
2170 Boolean OK, ForcePrefix = False;
2171 LongInt AdrInt;
2172
2173 AdrInt = EvalStrIntExpressionOffs(&ArgStr[3], CheckForcePrefix(ArgStr[3].Str, &ForcePrefix), Int32, &OK) - EProgCounter();
2174 if ((OK) && (AddRelPrefix(1, 13, &AdrInt, ForcePrefix)))
2175 {
2176 if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2177 else
2178 {
2179 WAsmCode[0] = 0x3700 + (((Word)OpSize+1) << 14) + AdrMode;
2180 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
2181 WAsmCode[1 + (AdrCnt >> 1)] = ((Condition & 14) << 12) + (AdrInt & 0x1ffe) + (Condition & 1);
2182 CodeLen =4 + AdrCnt;
2183 }
2184 }
2185 }
2186 }
2187 }
2188 }
2189 }
2190
DecodeLINK_RETD(Word Code)2191 static void DecodeLINK_RETD(Word Code)
2192 {
2193 if (!ChkArgCnt(1, 1));
2194 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
2195 else
2196 {
2197 LongInt AdrInt;
2198 Boolean OK, ForcePrefix = False;
2199 tSymbolFlags Flags;
2200
2201 AdrInt = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], CheckForcePrefix(ArgStr[1].Str, &ForcePrefix), Int32, &OK, &Flags);
2202 if (mFirstPassUnknown(Flags))
2203 AdrInt &= 0x1fe;
2204 if (ChkRange(AdrInt, -0x80000, 0x7ffff))
2205 {
2206 if (Odd(AdrInt)) WrError(ErrNum_NotAligned);
2207 else
2208 {
2209 WAsmCode[0] = Code + (AdrInt & 0x1fe);
2210 AddSignedPrefix(0, 9, AdrInt, ForcePrefix);
2211 CodeLen = 2;
2212 }
2213 }
2214 }
2215 }
2216
DecodeSWI(Word Code)2217 static void DecodeSWI(Word Code)
2218 {
2219 UNUSED(Code);
2220
2221 if (!ChkArgCnt(1, 1));
2222 else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
2223 else
2224 {
2225 Boolean OK;
2226
2227 WAsmCode[0] = EvalStrIntExpression(&ArgStr[1], Int4, &OK) + 0x7f90;
2228 if (OK)
2229 CodeLen = 2;
2230 }
2231 }
2232
DecodeLDA(Word Code)2233 static void DecodeLDA(Word Code)
2234 {
2235 UNUSED(Code);
2236
2237 if (ChkArgCnt(2, 2))
2238 {
2239 DecodeAdr(&ArgStr[2], 0, False, False);
2240 if (AdrOK)
2241 {
2242 int z;
2243
2244 WAsmCode[0] = 0x3000 + AdrMode;
2245 z = AdrCnt;
2246 memcpy(WAsmCode + 1, AdrVals, z);
2247 DecodeAdr(&ArgStr[1], 1, False, True);
2248 if (AdrOK)
2249 {
2250 if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
2251 else
2252 {
2253 WAsmCode[0] += ((Word)OpSize) << 14;
2254 WAsmCode[1 + (z >> 1)] = 0x9700 + AdrMode;
2255 memcpy(WAsmCode + 2 + (z >> 1), AdrVals, AdrCnt);
2256 CodeLen = 4 + z + AdrCnt;
2257 }
2258 }
2259 }
2260 }
2261 }
2262
2263 /*--------------------------------------------------------------------------*/
2264
AddFixed(const char * NName,Word NCode)2265 static void AddFixed(const char *NName, Word NCode)
2266 {
2267 AddInstTable(InstTable, NName, NCode, DecodeFixed);
2268 }
2269
AddRMW(const char * NName,Byte NCode,Byte NMask)2270 static void AddRMW(const char *NName, Byte NCode, Byte NMask)
2271 {
2272 if (InstrZ >= RMWOrderCount) exit(255);
2273 RMWOrders[InstrZ].Mask = NMask;
2274 RMWOrders[InstrZ].Code = NCode;
2275 AddInstTable(InstTable, NName, InstrZ++, DecodeRMW);
2276 }
2277
AddGAEq(const char * NName,Word NCode)2278 static void AddGAEq(const char *NName, Word NCode)
2279 {
2280 AddInstTable(InstTable, NName, NCode, DecodeGAEq);
2281 }
2282
AddGAHalf(const char * NName,Word NCode)2283 static void AddGAHalf(const char *NName, Word NCode)
2284 {
2285 AddInstTable(InstTable, NName, NCode, DecodeGAHalf);
2286 }
2287
AddGAFirst(const char * NName,Word NCode)2288 static void AddGAFirst(const char *NName, Word NCode)
2289 {
2290 AddInstTable(InstTable, NName, NCode, DecodeGAFirst);
2291 }
2292
AddGASecond(const char * NName,Word NCode)2293 static void AddGASecond(const char *NName, Word NCode)
2294 {
2295 AddInstTable(InstTable, NName, NCode, DecodeGASecond);
2296 }
2297
InitFields(void)2298 static void InitFields(void)
2299 {
2300 InstTable = CreateInstTable(301);
2301 AddInstTable(InstTable, "RLM", 0x0400, DecodeRLM_RRM);
2302 AddInstTable(InstTable, "RRM", 0x0500, DecodeRLM_RRM);
2303 AddInstTable(InstTable, "CHK", 0, DecodeCHK_CHKS);
2304 AddInstTable(InstTable, "CHKS", 1, DecodeCHK_CHKS);
2305 AddInstTable(InstTable, "EX", 0, DecodeEX);
2306 AddInstTable(InstTable, "CALR", 0x2001, DecodeCALR_JR);
2307 AddInstTable(InstTable, "JR", 0x2000, DecodeCALR_JR);
2308 AddInstTable(InstTable, "JRC", 0, DecodeJRC);
2309 AddInstTable(InstTable, "JRBC", 0x1e00, DecodeJRBC_JRBS);
2310 AddInstTable(InstTable, "JRBS", 0x1e01, DecodeJRBC_JRBS);
2311 AddInstTable(InstTable, "DJNZ", 0, DecodeDJNZ);
2312 AddInstTable(InstTable, "DJNZC", 0, DecodeDJNZC);
2313 AddInstTable(InstTable, "LINK", 0xc001, DecodeLINK_RETD);
2314 AddInstTable(InstTable, "RETD", 0xc801, DecodeLINK_RETD);
2315 AddInstTable(InstTable, "SWI", 0, DecodeSWI);
2316 AddInstTable(InstTable, "LDA", 0, DecodeLDA);
2317 AddInstTable(InstTable, "REG", 0, CodeREG);
2318
2319 AddFixed("CCF" , 0x7f82);
2320 AddFixed("CSF" , 0x7f8a);
2321 AddFixed("CVF" , 0x7f86);
2322 AddFixed("CZF" , 0x7f8e);
2323 AddFixed("DI" , 0x7fa1);
2324 AddFixed("EI" , 0x7fa3);
2325 AddFixed("HALT", 0x7fa5);
2326 AddFixed("NOP" , 0x7fa0);
2327 AddFixed("RCF" , 0x7f80);
2328 AddFixed("RET" , 0x7fa4);
2329 AddFixed("RETI", 0x7fa9);
2330 AddFixed("RETS", 0x7fab);
2331 AddFixed("RSF" , 0x7f88);
2332 AddFixed("RVF" , 0x7f84);
2333 AddFixed("RZF" , 0x7f8c);
2334 AddFixed("SCF" , 0x7f81);
2335 AddFixed("SSF" , 0x7f89);
2336 AddFixed("SVF" , 0x7f85);
2337 AddFixed("SZF" , 0x7f8b);
2338 AddFixed("UNLK", 0x7fa2);
2339
2340 RMWOrders = (RMWOrder *) malloc(sizeof(RMWOrder) * RMWOrderCount); InstrZ = 0;
2341 AddRMW("CALL" , 0x35, 0x36);
2342 AddRMW("CLR" , 0x2b, 0x17);
2343 AddRMW("CPL" , 0x28, 0x17);
2344 AddRMW("EXTS" , 0x33, 0x16);
2345 AddRMW("EXTZ" , 0x32, 0x16);
2346 AddRMW("JP" , 0x34, 0x36);
2347 AddRMW("MIRR" , 0x23, 0x17);
2348 AddRMW("NEG" , 0x29, 0x17);
2349 AddRMW("POP" , 0x20, 0x17);
2350 AddRMW("PUSH" , 0x21, 0x07);
2351 AddRMW("PUSHA", 0x31, 0x36);
2352 AddRMW("RVBY" , 0x22, 0x17);
2353 AddRMW("TJP" , 0x36, 0x16);
2354 AddRMW("TST" , 0x2a, 0x17);
2355
2356 InstrZ = 0;
2357 AddInstTable(InstTable, "ADD", InstrZ++, DecodeGASI1);
2358 AddInstTable(InstTable, "SUB", InstrZ++, DecodeGASI1);
2359 AddInstTable(InstTable, "CP" , InstrZ++, DecodeGASI1);
2360 AddInstTable(InstTable, "LD" , InstrZ++, DecodeGASI1);
2361
2362 InstrZ = 0;
2363 AddInstTable(InstTable, "AND", InstrZ++, DecodeGASI2);
2364 AddInstTable(InstTable, "OR" , InstrZ++, DecodeGASI2);
2365 AddInstTable(InstTable, "XOR", InstrZ++, DecodeGASI2);
2366
2367 InstrZ = 0;
2368 AddInstTable(InstTable, "ADD3", InstrZ++, DecodeTrinom);
2369 AddInstTable(InstTable, "SUB3", InstrZ++, DecodeTrinom);
2370 AddInstTable(InstTable, "MAC" , InstrZ++, DecodeTrinom);
2371 AddInstTable(InstTable, "MACS", InstrZ++, DecodeTrinom);
2372
2373 InstrZ = 0;
2374 AddInstTable(InstTable, "BRES", InstrZ++, DecodeBit);
2375 AddInstTable(InstTable, "BSET", InstrZ++, DecodeBit);
2376 AddInstTable(InstTable, "BCHG", InstrZ++, DecodeBit);
2377 AddInstTable(InstTable, "BTST", InstrZ++, DecodeBit);
2378
2379 InstrZ = 0;
2380 AddInstTable(InstTable, "SLL", InstrZ++, DecodeShift);
2381 AddInstTable(InstTable, "SRL", InstrZ++, DecodeShift);
2382 AddInstTable(InstTable, "SLA", InstrZ++, DecodeShift);
2383 AddInstTable(InstTable, "SRA", InstrZ++, DecodeShift);
2384 AddInstTable(InstTable, "RL" , InstrZ++, DecodeShift);
2385 AddInstTable(InstTable, "RR" , InstrZ++, DecodeShift);
2386 AddInstTable(InstTable, "RLC", InstrZ++, DecodeShift);
2387 AddInstTable(InstTable, "RRC", InstrZ++, DecodeShift);
2388
2389 InstrZ = 0;
2390 AddInstTable(InstTable, "BFEX" , InstrZ++, DecodeBField);
2391 AddInstTable(InstTable, "BFEXS", InstrZ++, DecodeBField);
2392 AddInstTable(InstTable, "BFIN" , InstrZ++, DecodeBField);
2393
2394 AddGAEq("ABCD" , 0x0110);
2395 AddGAEq("ADC" , 0x0004);
2396 AddGAEq("CBCD" , 0x0112);
2397 AddGAEq("CPC" , 0x0006);
2398 AddGAEq("MAX" , 0x0116);
2399 AddGAEq("MAXS" , 0x0017);
2400 AddGAEq("MIN" , 0x0114);
2401 AddGAEq("MINS" , 0x0015);
2402 AddGAEq("SBC" , 0x0105);
2403 AddGAEq("SBCD" , 0x0111);
2404
2405 AddGAHalf("DIV" , 0x26);
2406 AddGAHalf("DIVS" , 0x27);
2407 AddGAHalf("MUL" , 0x24);
2408 AddGAHalf("MULS" , 0x25);
2409
2410 AddGAFirst("ANDCF", 0x44);
2411 AddGAFirst("LDCF" , 0x47);
2412 AddGAFirst("ORCF" , 0x45);
2413 AddGAFirst("STCF" , 0x43);
2414 AddGAFirst("TSET" , 0x70);
2415 AddGAFirst("XORCF", 0x46);
2416
2417 AddGASecond("BS0B" , 0x54);
2418 AddGASecond("BS0F" , 0x55);
2419 AddGASecond("BS1B" , 0x56);
2420 AddGASecond("BS1F" , 0x57);
2421
2422 AddInstTable(InstTable, "CPSZ", 0, DecodeString);
2423 AddInstTable(InstTable, "CPSN", 1, DecodeString);
2424 AddInstTable(InstTable, "LDS" , 3, DecodeString);
2425
2426 Conditions = (const char **) malloc(sizeof(char *)*ConditionCount); InstrZ = 0;
2427 Conditions[InstrZ++] = "C"; Conditions[InstrZ++] = "NC";
2428 Conditions[InstrZ++] = "Z"; Conditions[InstrZ++] = "NZ";
2429 Conditions[InstrZ++] = "OV"; Conditions[InstrZ++] = "NOV";
2430 Conditions[InstrZ++] = "MI"; Conditions[InstrZ++] = "PL";
2431 Conditions[InstrZ++] = "LE"; Conditions[InstrZ++] = "GT";
2432 Conditions[InstrZ++] = "LT"; Conditions[InstrZ++] = "GE";
2433 Conditions[InstrZ++] = "ULE"; Conditions[InstrZ++] = "UGT";
2434 Conditions[InstrZ++] = "N"; Conditions[InstrZ++] = "A";
2435 Conditions[InstrZ++] = "ULT"; Conditions[InstrZ++] = "UGE";
2436 Conditions[InstrZ++] = "EQ"; Conditions[InstrZ++] = "NE";
2437 }
2438
DeinitFields(void)2439 static void DeinitFields(void)
2440 {
2441 DestroyInstTable(InstTable);
2442
2443 free(RMWOrders);
2444 free(Conditions);
2445 }
2446
DecodeAttrPart_97C241(void)2447 static Boolean DecodeAttrPart_97C241(void)
2448 {
2449 char *p;
2450
2451 switch (AttrSplit)
2452 {
2453 case '.':
2454 p = strchr(AttrPart.Str, ':');
2455 if (p)
2456 {
2457 Format = (p < AttrPart.Str + strlen(AttrPart.Str) - 1) ? p[1] : ' ';
2458 *p = '\0';
2459 }
2460 else
2461 Format = ' ';
2462 break;
2463 case ':':
2464 p = strchr(AttrPart.Str, '.');
2465 if (!p)
2466 {
2467 Format = (*AttrPart.Str);
2468 *AttrPart.Str = '\0';
2469 }
2470 else
2471 {
2472 Format = (p == AttrPart.Str) ? ' ' : *AttrPart.Str;
2473 strmov(AttrPart.Str, p + 1);
2474 }
2475 break;
2476 default:
2477 Format = ' ';
2478 }
2479 Format = as_toupper(Format);
2480
2481 if (*AttrPart.Str)
2482 switch (as_toupper(*AttrPart.Str))
2483 {
2484 case 'B':
2485 AttrPartOpSize = eSymbolSize8Bit;
2486 break;
2487 case 'W':
2488 AttrPartOpSize = eSymbolSize16Bit;
2489 break;
2490 case 'D':
2491 AttrPartOpSize = eSymbolSize32Bit;
2492 break;
2493 default:
2494 WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
2495 return False;
2496 }
2497 return True;
2498 }
2499
MakeCode_97C241(void)2500 static void MakeCode_97C241(void)
2501 {
2502 CodeLen = 0;
2503 DontPrint = False;
2504 PrefUsed[0] = False;
2505 PrefUsed[1] = False;
2506 AdrInc = 0;
2507 MinOneIs0 = False;
2508 LowLim4 = -8; LowLim8 = -128;
2509
2510 /* zu ignorierendes */
2511
2512 if (Memo(""))
2513 return;
2514
2515 OpSize = AttrPartOpSize;
2516
2517 /* Pseudoanweisungen */
2518
2519 if (DecodePseudo()) return;
2520
2521 if (DecodeIntelPseudo(False)) return;
2522
2523 if (LookupInstTable(InstTable, OpPart.Str))
2524 {
2525 AddPrefixes();
2526 return;
2527 }
2528
2529 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2530 }
2531
2532 /*!------------------------------------------------------------------------
2533 * \fn InternSymbol_97C241(char *pArg, TempResult *pResult)
2534 * \brief handle built-in symbols on TLCS-9000
2535 * \param pArg source argument
2536 * \param pResult result buffer
2537 * ------------------------------------------------------------------------ */
2538
InternSymbol_97C241(char * pArg,TempResult * pResult)2539 static void InternSymbol_97C241(char *pArg, TempResult *pResult)
2540 {
2541 Byte Reg;
2542 tSymbolSize Size;
2543
2544 if (DecodeRegCore(pArg, &Reg, &Size))
2545 {
2546 pResult->Typ = TempReg;
2547 pResult->DataSize = Size;
2548 pResult->Contents.RegDescr.Reg = Reg;
2549 pResult->Contents.RegDescr.Dissect = DissectReg_97C241;
2550 }
2551 }
2552
IsDef_97C241(void)2553 static Boolean IsDef_97C241(void)
2554 {
2555 return Memo("REG");
2556 }
2557
SwitchFrom_97C241(void)2558 static void SwitchFrom_97C241(void)
2559 {
2560 DeinitFields();
2561 }
2562
SwitchTo_97C241(void)2563 static void SwitchTo_97C241(void)
2564 {
2565 TurnWords = False;
2566 ConstMode = ConstModeIntel;
2567
2568 PCSymbol = "$";
2569 HeaderID = 0x56;
2570 NOPCode = 0x7fa0;
2571 DivideChars = ",";
2572 HasAttrs = True;
2573 AttrChars = ".:";
2574
2575 ValidSegs = 1 << SegCode;
2576 Grans[SegCode] = 1;
2577 ListGrans[SegCode] = 2;
2578 SegInits[SegCode] = 0;
2579 SegLimits[SegCode] = 0xffffffl;
2580
2581 DecodeAttrPart = DecodeAttrPart_97C241;
2582 MakeCode = MakeCode_97C241;
2583 IsDef = IsDef_97C241;
2584 InternSymbol = InternSymbol_97C241;
2585 DissectReg = DissectReg_97C241;
2586 SwitchFrom = SwitchFrom_97C241;
2587 InitFields();
2588 }
2589
code97c241_init(void)2590 void code97c241_init(void)
2591 {
2592 CPU97C241 = AddCPU("97C241", SwitchTo_97C241);
2593 }
2594