1 /* codemn2610.c */
2 /****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                    */
4 /*                                                                          */
5 /* AS, C-Version                                                            */
6 /*                                                                          */
7 /* Code Generator for MN161x Processor - alternate version                  */
8 /*                                                                          */
9 /****************************************************************************/
10 
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14 
15 #include "bpemu.h"
16 #include "endian.h"
17 #include "strutil.h"
18 #include "asmdef.h"
19 #include "asmpars.h"
20 #include "asmsub.h"
21 #include "motpseudo.h"
22 #include "asmitree.h"
23 #include "codevars.h"
24 #include "headids.h"
25 #include "errmsg.h"
26 #include "codepseudo.h"
27 #include "ibmfloat.h"
28 
29 #include "codemn2610.h"
30 
31 /*--------------------------------------------------------------------------*/
32 /* Definitions */
33 
34 typedef struct
35 {
36   const char *pName;
37   Word Code;
38 } tCodeTable;
39 
40 typedef struct
41 {
42   Word Code;
43   CPUVar MinCPU;
44 } tFixedOrder;
45 
46 enum
47 {
48   eAddrRegX0,
49   eAddrRegX1,
50   eAddrRegIC,
51   eAddrRegCnt
52 };
53 
54 static CPUVar CPUMN1610, CPUMN1613;
55 static tSymbolSize OpSize;
56 static LongInt BaseRegVals[4];
57 
58 #define ASSUMEMN1613Count 4
59 static ASSUMERec ASSUMEMN1613[ASSUMEMN1613Count] =
60 {
61   { "CSBR", BaseRegVals + 0, 0, 15, 16, NULL },
62   { "SSBR", BaseRegVals + 1, 0, 15, 16, NULL },
63   { "TSR0", BaseRegVals + 2, 0, 15, 16, NULL },
64   { "TSR1", BaseRegVals + 3, 0, 15, 16, NULL }
65 };
66 
67 #define FixedOrderCnt 6
68 static tFixedOrder *FixedOrders;
69 
70 /*--------------------------------------------------------------------------*/
71 /* Adress Decoders */
72 
DecodeTable(const char * pArg,Word * pResult,const tCodeTable * pTable)73 static Boolean DecodeTable(const char *pArg, Word *pResult, const tCodeTable *pTable)
74 {
75   for (; pTable->pName; pTable++)
76     if (!as_strcasecmp(pArg, pTable->pName))
77     {
78       *pResult = pTable->Code;
79       return True;
80     }
81   return False;
82 }
83 
84 static const tCodeTable RegCodes[] =
85 {
86   { "R0",  0 },
87   { "R1",  1 },
88   { "R2",  2 },
89   { "R3",  3 },
90   { "R4",  4 },
91   { "SP",  5 },
92   { "STR", 6 },
93   { "IC",  7 },
94   { "X0",  3 },
95   { "X1",  4 },
96   { NULL,  0 }
97 };
98 #define DecodeRegCore(pArg, pResult) (DecodeTable((pArg), (pResult), RegCodes))
99 
DecodeReg(const tStrComp * pArg,Word * pResult,Byte Mask)100 static Boolean DecodeReg(const tStrComp *pArg, Word *pResult, Byte Mask)
101 {
102   Boolean Result = DecodeRegCore(pArg->Str, pResult) && (Mask & (1 << *pResult));
103 
104   if (!Result)
105     WrStrErrorPos(ErrNum_InvReg, pArg);
106   return Result;
107 }
108 
109 static const tCodeTable DRegCodes[] =
110 {
111   { "DR0",  0 },
112   { NULL ,  0 }
113 };
114 #define DecodeDRegCore(pArg, pResult) (DecodeTable((pArg), (pResult), DRegCodes))
115 
DecodeDReg(const tStrComp * pArg)116 static Boolean DecodeDReg(const tStrComp *pArg)
117 {
118   Word DummyReg;
119   Boolean Result = DecodeDRegCore(pArg->Str, &DummyReg) && !DummyReg;
120 
121   if (!Result)
122     WrStrErrorPos(ErrNum_InvReg, pArg);
123   return Result;
124 }
125 
126 static const tCodeTable SkipCodes[] =
127 {
128   { ""   ,  0 },
129   { "SKP",  1 },
130   { "M"  ,  2 },
131   { "PZ" ,  3 },
132   { "E"  ,  4 },
133   { "Z"  ,  4 },
134   { "NE" ,  5 },
135   { "NZ" ,  5 },
136   { "MZ" ,  6 },
137   { "P"  ,  7 },
138   { "EZ" ,  8 },
139   { "ENZ",  9 },
140   { "OZ" , 10 },
141   { "ONZ", 11 },
142   { "LMZ", 12 },
143   { "LP" , 13 },
144   { "LPZ", 14 },
145   { "LM" , 15 },
146   { NULL ,  0 }
147 };
148 #define DecodeSkipCore(pArg, pResult) (DecodeTable((pArg), (pResult), SkipCodes))
149 
DecodeSkip(const tStrComp * pArg,Word * pResult)150 static Boolean DecodeSkip(const tStrComp *pArg, Word *pResult)
151 {
152   Boolean Result = DecodeSkipCore(pArg->Str, pResult);
153 
154   if (!Result)
155     WrStrErrorPos(ErrNum_UndefCond, pArg);
156   return Result;
157 }
158 
159 static const tCodeTable AddrRegCodes[] =
160 {
161   { "(X0)", eAddrRegX0 },
162   { "(X1)", eAddrRegX1 },
163   { "(IC)", eAddrRegIC },
164   { NULL  ,  0         }
165 };
166 #define DecodeAddrReg(pArg, pResult) (DecodeTable((pArg), (pResult), AddrRegCodes))
167 
168 static const tCodeTable EECodes[] =
169 {
170   { ""  , 0 },
171   { "RE", 1 },
172   { "SE", 2 },
173   { "CE", 3 },
174   { NULL, 0 }
175 };
176 #define DecodeEECore(pArg, pResult) (DecodeTable((pArg), (pResult), EECodes))
177 
DecodeEE(const tStrComp * pArg,Word * pResult)178 static Boolean DecodeEE(const tStrComp *pArg, Word *pResult)
179 {
180   Boolean Result = DecodeEECore(pArg->Str, pResult);
181 
182   if (!Result)
183     WrStrErrorPos(ErrNum_InvReg, pArg);
184   return Result;
185 }
186 
187 static const tCodeTable AllBRCodes[] =
188 {
189   { "CSBR", 0 },
190   { "SSBR", 1 },
191   { "TSR0", 2 },
192   { "TSR1", 3 },
193   { "OSR0", 4 },
194   { "OSR1", 5 },
195   { "OSR2", 6 },
196   { "OSR3", 7 },
197   { NULL ,  0 }
198 };
199 #define DecodeAllBRCore(pArg, pResult, IsWrite) (DecodeTable((pArg), (pResult), AllBRCodes + IsWrite))
200 
201 static const tCodeTable BRCodes[] =
202 {
203   { "CSBR", 0 },
204   { "SSBR", 1 },
205   { "TSR0", 2 },
206   { "TSR1", 3 },
207   { NULL  , 0 }
208 };
209 #define DecodeBRCore(pArg, pResult) (DecodeTable((pArg), (pResult), BRCodes))
210 
DecodeBR(const tStrComp * pArg,Word * pResult)211 static Boolean DecodeBR(const tStrComp *pArg, Word *pResult)
212 {
213   Boolean Result = DecodeBRCore(pArg->Str, pResult);
214 
215   if (!Result)
216     WrStrErrorPos(ErrNum_UnknownSegReg, pArg);
217   return Result;
218 }
219 
220 
221 static const tCodeTable SRegCodes[] =
222 {
223   { "SBRB", 0 },
224   { "ICB" , 1 },
225   { "NPP" , 2 },
226   { NULL  , 0 }
227 };
228 #define DecodeSRegCore(pArg, pResult) (DecodeTable((pArg), (pResult), SRegCodes))
229 
DecodeSOrAllBReg(const tStrComp * pArg,Word * pResult,unsigned IsS,Boolean IsWrite)230 static Boolean DecodeSOrAllBReg(const tStrComp *pArg, Word *pResult, unsigned IsS, Boolean IsWrite)
231 {
232   Boolean Result = IsS ? DecodeSRegCore(pArg->Str, pResult) : DecodeAllBRCore(pArg->Str, pResult, IsWrite);
233 
234   if (!Result)
235     WrStrErrorPos(ErrNum_InvReg, pArg);
236   return Result;
237 }
238 
239 static tCodeTable HRegCodes[] =
240 {
241   { "TCR" , 0 },
242   { "TIR" , 1 },
243   { "TSR" , 2 },
244   { "SCR" , 3 },
245   { "SSR" , 4 },
246   { NULL  , 5 }, /* filled @ runtime with SOR/SIR */
247   { "IISR", 6 },
248   { NULL  , 0 }
249 };
250 #define DecodeHRegCore(pArg, pResult) (DecodeTable((pArg), (pResult), HRegCodes))
251 
DecodeHReg(const tStrComp * pArg,Word * pResult,Boolean IsWrite)252 static Boolean DecodeHReg(const tStrComp *pArg, Word *pResult, Boolean IsWrite)
253 {
254   Boolean Result;
255 
256   HRegCodes[5].pName = IsWrite ? "SOR" : "SIR";
257   Result = DecodeHRegCore(pArg->Str, pResult);
258 
259   if (!Result)
260     WrStrErrorPos(ErrNum_InvReg, pArg);
261   return Result;
262 }
263 
264 /*!------------------------------------------------------------------------
265  * \fn     Word ChkPage(LongWord Addr, Word Base, const tStrComp *pArg, bool Warn)
266  * \brief  check whether a linear address is reachable via the given segment register, and compute offset
267  * \param  Addr linear address in 64/256K space
268  * \param  Base index of segment register to be used
269  * \param  pArg textual argument for warnings (may be NULL)
270  * \return resulting offset
271  * ------------------------------------------------------------------------ */
272 
ChkPage(LongWord Addr,Word Base,const tStrComp * pArg)273 static Word ChkPage(LongWord Addr, Word Base, const tStrComp *pArg)
274 {
275   Addr -= BaseRegVals[Base] << 14;
276   Addr &= SegLimits[SegCode];
277   if ((Addr >= 0x10000ul) && pArg)
278     WrStrErrorPos(ErrNum_InAccPage, pArg);
279   return Addr & 0xffff;
280 }
281 
282 /*!------------------------------------------------------------------------
283  * \fn     DecodeMem(tStrComp *pArg, Word *pResult)
284  * \brief  parse memory address expression
285  * \param  pArg memory argument in source
286  * \param  pResult resulting code for instruction word (xxMMMxxxDDDDDDDD)
287  * \return True if successfully parsed
288  * ------------------------------------------------------------------------ */
289 
DecodeMem(tStrComp * pArg,Word * pResult)290 static Boolean DecodeMem(tStrComp *pArg, Word *pResult)
291 {
292   tStrComp Arg;
293   Boolean TotIndirect = IsIndirect(pArg->Str), OK;
294   Word R;
295   Integer Disp;
296   int l;
297   tSymbolFlags Flags;
298 
299   if (TotIndirect)
300   {
301     StrCompRefRight(&Arg, pArg, 1);
302     KillPrefBlanksStrCompRef(&Arg);
303     StrCompShorten(&Arg, 1);
304     KillPostBlanksStrComp(&Arg);
305   }
306   else
307     StrCompRefRight(&Arg, pArg, 0);
308 
309   l = strlen(Arg.Str);
310   if ((l >= 4) && DecodeAddrReg(Arg.Str + l - 4, &R))
311   {
312     Boolean DispIndirect;
313 
314     Arg.Str[l - 4] = '\0';
315     KillPostBlanksStrComp(&Arg);
316     DispIndirect = IsIndirect(Arg.Str);
317     Disp = EvalStrIntExpression(&Arg, (R == 2) ? SInt8 : UInt8, &OK);
318     if (!OK)
319       return False;
320     if (R == 2)
321     {
322       if (DispIndirect)  /* ((disp)(IC)), (disp)(IC) not possible */
323       {
324         WrStrErrorPos(ErrNum_InvAddrMode, pArg);
325         return False;
326       }
327       else /* (disp(IC)) */
328       {
329         *pResult = ((TotIndirect ? 3 : 1) << 11) | (Disp & 0xff);
330         return True;
331       }
332     }
333     else if (TotIndirect) /* (disp(Xn)), ((disp)(Xn)) not possible */
334     {
335       WrStrErrorPos(ErrNum_InvAddrMode, pArg);
336       return False;
337     }
338     else /* disp(Xn), (disp)(Xn) */
339     {
340       *pResult = (((DispIndirect ? 6 : 4) + R) << 11) | (Disp & 0xff);
341       return True;
342     }
343   }
344   else if (TotIndirect && DecodeRegCore(Arg.Str, &R)) /* plain (ic) (x0) (x1) without displacement */
345   {
346     switch (R)
347     {
348       case 3:
349         *pResult = (4 << 11);
350         return True;
351       case 4:
352         *pResult = (5 << 11);
353         return True;
354       case 7:
355         *pResult = (1 << 11);
356         return True;
357       default:
358         goto plaindisp;
359     }
360   }
361   else
362   {
363     int ArgOffset, ForceMode;
364     LongWord Addr;
365 
366 plaindisp:
367     /* For (Addr), there is only the 'zero-page' variant: */
368 
369     if (TotIndirect)
370     {
371       ArgOffset = 0;
372       ForceMode = 1;
373     }
374 
375     /* For direct addressing, either zero-page or IC-relative may be used.
376        Check for explicit request: */
377 
378     else switch (*Arg.Str)
379     {
380       case '>':
381         ArgOffset = 1;
382         ForceMode = 2;
383         break;
384       case '<':
385         ArgOffset = 1;
386         ForceMode = 1;
387         break;
388       default:
389         ArgOffset = ForceMode = 0;
390     }
391 
392     /* evaluate expression */
393 
394     Addr = EvalStrIntExpressionOffsWithFlags(&Arg, ArgOffset, (MomCPU == CPUMN1613) ? UInt18 : UInt16, &OK, &Flags);
395     if (!OK)
396       return False;
397 
398     /* now generate mode */
399 
400     switch (ForceMode)
401     {
402       case 0:
403       {
404         if (ChkPage(Addr, 0, NULL) < 256)
405           goto case1;
406         else
407           goto case2;
408       }
409       case 1:
410       case1:
411       {
412         Word Offset = ChkPage(Addr, 0, NULL);
413 
414         if (!mFirstPassUnknownOrQuestionable(Flags) && (Offset > 255))
415         {
416           WrStrErrorPos(ErrNum_OverRange, pArg);
417           return False;
418         }
419         else
420         {
421           *pResult = ((TotIndirect ? 2 : 0) << 11) | (Offset & 0xff);
422           return True;
423         }
424       }
425       case 2:
426       case2:
427       {
428         LongInt Disp = Addr - EProgCounter();
429 
430         if (!mFirstPassUnknownOrQuestionable(Flags) && ((Disp > 127) || (Disp < -128)))
431         {
432           WrStrErrorPos(ErrNum_DistTooBig, pArg);
433           return False;
434         }
435         else
436         {
437           *pResult = (1 << 11) | (Disp & 0xff);
438           return True;
439         }
440       }
441       default:
442         return False;
443     }
444   }
445 }
446 
DecodeIReg(tStrComp * pStrArg,Word * pResult,Word Mask,Word Allowed)447 static Boolean DecodeIReg(tStrComp *pStrArg, Word *pResult, Word Mask, Word Allowed)
448 {
449   char *pArg = pStrArg->Str;
450   int l = strlen(pArg);
451   char *pEnd = pArg + l, Save;
452   Word Reg;
453   Boolean OK;
454 
455   if ((l > 2) && (*pArg == '(') && (*(pEnd - 1) == ')'))
456   {
457     pArg++; pEnd--;
458     *pResult = 1 << 6;
459   }
460   else if ((l > 3) && (*pArg == '(') && (*(pEnd - 2) == ')') && (*(pEnd - 1) == '+'))
461   {
462     pArg++; pEnd -= 2;
463     *pResult = 3 << 6;
464   }
465   else if ((l > 3) && (*pArg == '-') && (pArg[1] == '(') && (*(pEnd - 1) == ')'))
466   {
467     pArg += 2; pEnd--;
468     *pResult = 2 << 6;
469   }
470   else
471     goto error;
472 
473   while ((pArg < pEnd) && isspace(*pArg))
474     pArg++;
475   while ((pEnd > pArg) && isspace(*(pEnd - 1)))
476     pEnd--;
477   Save = *pEnd; *pEnd = '\0';
478 
479   OK = DecodeRegCore(pArg, &Reg);
480   *pEnd = Save;
481   if (!OK || (Reg < 1) || (Reg > 4))
482     goto error;
483 
484   *pResult |= (Reg - 1);
485   if ((*pResult & Mask) != Allowed)
486     goto error;
487   return True;
488 
489 error:
490   WrStrErrorPos(ErrNum_InvAddrMode, pStrArg);
491   return False;
492 }
493 
494 /*--------------------------------------------------------------------------*/
495 /* Instruction Decoders */
496 
DecodeFixed(Word Index)497 static void DecodeFixed(Word Index)
498 {
499   const tFixedOrder *pOrder = FixedOrders + Index;
500 
501   if (ChkArgCnt(0, 0) && ChkMinCPU(pOrder->MinCPU))
502   {
503     WAsmCode[0] = pOrder->Code;
504     CodeLen = 1;
505   }
506 }
507 
DecodeOneReg(Word Code)508 static void DecodeOneReg(Word Code)
509 {
510   Word Reg;
511 
512   if (ChkArgCnt(1, 1)
513    && DecodeReg(&ArgStr[1], &Reg, 0x7f)) /* do not allow IC as register */
514   {
515     WAsmCode[0] = Code | (Reg << 8);
516     CodeLen = 1;
517   }
518 }
519 
DecodeRegImm(Word Code)520 static void DecodeRegImm(Word Code)
521 {
522   Word Reg;
523 
524   if (ChkArgCnt(2, 2)
525    && DecodeReg(&ArgStr[1], &Reg, 0x7f)) /* do not allow IC as register */
526   {
527     tEvalResult EvalResult;
528 
529     WAsmCode[0] = EvalStrIntExpressionWithResult(&ArgStr[2], Int8, &EvalResult) & 0xff;
530     if (EvalResult.OK)
531     {
532       if (Code & 0x1000)
533         ChkSpace(SegIO, EvalResult.AddrSpaceMask);
534       WAsmCode[0] |= Code | (Reg << 8);
535       CodeLen = 1;
536     }
537   }
538 }
539 
DecodeTwoReg(Word Code)540 static void DecodeTwoReg(Word Code)
541 {
542   Word Rd, Rs, Skip = 0;
543 
544   if (ChkArgCnt(2, 3)
545    && DecodeReg(&ArgStr[1], &Rd, 0x7f) /* do not allow IC as register */
546    && DecodeReg(&ArgStr[2], &Rs, 0x7f) /* do not allow IC as register */
547    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
548   {
549     WAsmCode[0] = Code | (Rd << 8) | (Skip << 4) | Rs;
550     CodeLen = 1;
551   }
552 }
553 
DecodeEAReg(Word Code)554 static void DecodeEAReg(Word Code)
555 {
556   Word R, EA;
557 
558   if (ChkArgCnt(2, 2)
559    && DecodeReg(&ArgStr[1], &R, 0x3f)
560    && DecodeMem(&ArgStr[2], &EA))
561   {
562     WAsmCode[0] = Code | EA | (R << 8);
563     CodeLen = 1;
564   }
565 }
566 
DecodeEA(Word Code)567 static void DecodeEA(Word Code)
568 {
569   Word EA;
570 
571   if (ChkArgCnt(1, 1)
572    && DecodeMem(&ArgStr[1], &EA))
573   {
574     WAsmCode[0] = Code | EA;
575     CodeLen = 1;
576   }
577 }
578 
DecodeShift(Word Code)579 static void DecodeShift(Word Code)
580 {
581   Word R, Skip = 0, EE = 0;
582 
583   if (ChkArgCnt(1, 3)
584    && DecodeReg(&ArgStr[1], &R, 0x7f)) /* do not allow IC as register */
585   {
586     Boolean OK;
587 
588     if (ArgCnt == 3)
589       OK = DecodeEE(&ArgStr[2], &EE) && DecodeSkip(&ArgStr[3], &Skip);
590     else if (ArgCnt == 1)
591       OK = True;
592     else
593       OK = DecodeEECore(ArgStr[2].Str, &EE) || DecodeSkip(&ArgStr[2], &Skip);
594     if (OK)
595     {
596       WAsmCode[0] = Code | (R << 8) | (Skip << 4) | EE;
597       CodeLen = 1;
598     }
599   }
600 }
601 
DecodeImm4(Word Code)602 static void DecodeImm4(Word Code)
603 {
604   Word R, Skip = 0;
605 
606   if (ChkArgCnt(2, 3)
607    && DecodeReg(&ArgStr[1], &R, 0x7f)
608    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
609   {
610     Word Num;
611     Boolean OK;
612 
613     Num = EvalStrIntExpression(&ArgStr[2], UInt4, &OK);
614     if (OK)
615     {
616       WAsmCode[0] = Code | (R << 8) | (Skip << 4) | (Num & 15);
617       CodeLen = 1;
618     }
619   }
620 }
621 
DecodeImm2(Word Code)622 static void DecodeImm2(Word Code)
623 {
624   if (ChkArgCnt(1, 1))
625   {
626     Boolean OK;
627 
628     WAsmCode[0] = Code | EvalStrIntExpression(&ArgStr[1], UInt2, &OK);
629     if (OK)
630       CodeLen = 1;
631   }
632 }
633 
DecodeLD_STD(Word Code)634 static void DecodeLD_STD(Word Code)
635 {
636   Word R, Base = 0;
637 
638   if (ChkArgCnt(2, 3)
639    && ChkMinCPU(CPUMN1613)
640    && DecodeReg(&ArgStr[1], &R, 0x3f) /* do not allow IC/STR as register */
641    && ((ArgCnt <= 2) || DecodeBR(&ArgStr[2], &Base)))
642   {
643     Boolean OK;
644     LongWord Addr;
645 
646     Addr = EvalStrIntExpression(&ArgStr[ArgCnt], UInt18, &OK);
647     if (OK)
648     {
649       WAsmCode[0] = Code | R | (Base << 4);
650       WAsmCode[1] = ChkPage(Addr, Base, &ArgStr[ArgCnt]);
651       CodeLen = 2;
652     }
653   }
654 }
655 
DecodeLR_STR(Word Code)656 static void DecodeLR_STR(Word Code)
657 {
658   Word R, IR, Base = 0;
659 
660   if (ChkArgCnt(2, 3)
661    && ChkMinCPU(CPUMN1613)
662    && DecodeReg(&ArgStr[1], &R, 0x3f) /* do not allow STR/IC as register */
663    && ((ArgCnt <= 2) || DecodeBR(&ArgStr[2], &Base))
664    && DecodeIReg(&ArgStr[ArgCnt], &IR, 0x00, 0x00))
665   {
666     WAsmCode[0] = Code | (R << 8) | IR | (Base << 4);
667     CodeLen = 1;
668   }
669 }
670 
DecodeR0RISkip(Word Code)671 static void DecodeR0RISkip(Word Code)
672 {
673   Word R, RI, Skip = 0;
674 
675   if (ChkArgCnt(2, 3)
676    && ChkMinCPU(CPUMN1613)
677    && DecodeReg(&ArgStr[1], &R, 0x01)
678    && DecodeIReg(&ArgStr[2], &RI, 0xc0, 0x40)
679    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
680   {
681     WAsmCode[0] = Code | (Skip << 4) | (RI & 3);
682     CodeLen = 1;
683   }
684 }
685 
DecodeRImmSkip(Word Code)686 static void DecodeRImmSkip(Word Code)
687 {
688   Word R, Skip = 0;
689 
690   if (ChkArgCnt(2, 3)
691    && ChkMinCPU(CPUMN1613)
692    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC as register */
693    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
694   {
695     Boolean OK;
696 
697     WAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
698     if (OK)
699     {
700       WAsmCode[0] = Code | (R << 8) | (Skip << 4);
701       CodeLen = 2;
702     }
703   }
704 }
705 
ChkCarry(int StartIndex,Boolean * pHasCarryArg,Word * pCarryVal)706 static Boolean ChkCarry(int StartIndex, Boolean *pHasCarryArg, Word *pCarryVal)
707 {
708   if (ArgCnt < StartIndex)
709   {
710     *pHasCarryArg = False;
711     *pCarryVal = 0;
712     return True;
713   }
714   else
715   {
716     Boolean Result;
717 
718     *pHasCarryArg = !as_strcasecmp(ArgStr[StartIndex].Str, "C")
719                  || !as_strcasecmp(ArgStr[StartIndex].Str, "0")
720                  || !as_strcasecmp(ArgStr[StartIndex].Str, "1");
721     *pCarryVal = *pHasCarryArg && (ArgStr[StartIndex].Str[0] != '0');
722     Result = (ArgCnt == StartIndex) || *pHasCarryArg;
723     if (!Result)
724       WrStrErrorPos(ErrNum_InvReg, &ArgStr[StartIndex]);
725     return Result;
726   }
727 }
728 
DecodeDR0RISkip(Word Code)729 static void DecodeDR0RISkip(Word Code)
730 {
731   Word Skip = 0, Ri, CarryVal = 0;
732   Boolean OptCarry = !!(Code & 0x10), HasCarryArg = False;
733 
734   Code &= ~0x10;
735   if (ChkArgCnt(2, 3 + OptCarry)
736    && ChkMinCPU(CPUMN1613)
737    && DecodeDReg(&ArgStr[1])
738    && DecodeIReg(&ArgStr[2], &Ri, 0xc0, 0x40)
739    && (!OptCarry || ChkCarry(3, &HasCarryArg, &CarryVal))
740    && ((ArgCnt < 3 + HasCarryArg) || DecodeSkip(&ArgStr[3 + HasCarryArg], &Skip)))
741   {
742     WAsmCode[0] = Code | (Skip << 4) | (Ri & 3) | (CarryVal << 3);
743     CodeLen = 1;
744   }
745 }
746 
DecodeDAA_DAS(Word Code)747 static void DecodeDAA_DAS(Word Code)
748 {
749   Word R, Ri, Skip = 0, CarryVal = 0;
750   Boolean HasCarryArg = False;
751 
752   if (ChkArgCnt(2, 4)
753    && ChkMinCPU(CPUMN1613)
754    && DecodeReg(&ArgStr[1], &R, 0x01)
755    && DecodeIReg(&ArgStr[2], &Ri, 0xc0, 0x40)
756    && ChkCarry(3, &HasCarryArg, &CarryVal)
757    && ((ArgCnt < 3 + HasCarryArg) || DecodeSkip(&ArgStr[3 + HasCarryArg], &Skip)))
758   {
759     WAsmCode[0] = Code | (Skip << 4) | (Ri & 3) | (CarryVal << 3);
760     CodeLen = 1;
761   }
762 }
763 
DecodeNEG(Word Code)764 static void DecodeNEG(Word Code)
765 {
766   Word R, Skip = 0, CarryVal = 0;
767   Boolean HasCarryArg = False;
768 
769   if (ChkArgCnt(1, 3)
770    && ChkMinCPU(CPUMN1613)
771    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC as register */
772    && ChkCarry(2, &HasCarryArg, &CarryVal)
773    && ((ArgCnt < 2 + HasCarryArg) || DecodeSkip(&ArgStr[2 + HasCarryArg], &Skip)))
774   {
775     WAsmCode[0] = Code | (Skip << 4) | R | (CarryVal << 3);
776     CodeLen = 1;
777   }
778 }
779 
DecodeRDR_WTR(Word Code)780 static void DecodeRDR_WTR(Word Code)
781 {
782   Word R, Ri;
783 
784   if (ChkArgCnt(2, 2)
785    && ChkMinCPU(CPUMN1613)
786    && DecodeReg(&ArgStr[1], &R, 0x3f) /* do not allow IC/STR */
787    && DecodeIReg(&ArgStr[2], &Ri, 0xc0, 0x40))
788   {
789     WAsmCode[0] = Code | (R << 8) | (Ri & 3);
790     CodeLen = 1;
791   }
792 }
793 
DecodeBD_BALD(Word Code)794 static void DecodeBD_BALD(Word Code)
795 {
796   if (ChkArgCnt(1, 1)
797    && ChkMinCPU(CPUMN1613))
798   {
799     Boolean OK;
800     LongWord Addr = EvalStrIntExpression(&ArgStr[1], UInt18, &OK);
801 
802     if (OK)
803     {
804       WAsmCode[0] = Code;
805       WAsmCode[1] = ChkPage(Addr, 0, &ArgStr[1]);
806       CodeLen = 2;
807     }
808   }
809 }
810 
DecodeBL_BALL(Word Code)811 static void DecodeBL_BALL(Word Code)
812 {
813   if (!ChkArgCnt(1, 1));
814   else if (!ChkMinCPU(CPUMN1613));
815   else if (!IsIndirect(ArgStr[1].Str)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
816   else
817   {
818     Boolean OK;
819     LongWord Addr = EvalStrIntExpression(&ArgStr[1], UInt18, &OK);
820 
821     if (OK)
822     {
823       WAsmCode[0] = Code;
824       WAsmCode[1] = ChkPage(Addr, 0, &ArgStr[1]);
825       CodeLen = 2;
826     }
827   }
828 }
829 
DecodeBR_BALR(Word Code)830 static void DecodeBR_BALR(Word Code)
831 {
832   Word Ri;
833 
834   if (ChkArgCnt(1, 1)
835    && ChkMinCPU(CPUMN1613)
836    && DecodeIReg(&ArgStr[1], &Ri, 0xc0, 0x40))
837   {
838     WAsmCode[0] = Code | (Ri & 3);
839     CodeLen = 1;
840   }
841 }
842 
DecodeTSET_TRST(Word Code)843 static void DecodeTSET_TRST(Word Code)
844 {
845   Word R, Skip = 0;
846 
847   if (ChkArgCnt(2, 3)
848    && ChkMinCPU(CPUMN1613)
849    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC as register */
850    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
851   {
852     Boolean OK;
853     LongWord Addr = EvalStrIntExpression(&ArgStr[2], UInt18, &OK);
854 
855     if (OK)
856     {
857       WAsmCode[0] = Code | R | (Skip << 4);
858       WAsmCode[1] = ChkPage(Addr, 0, &ArgStr[2]);
859       CodeLen = 2;
860     }
861   }
862 }
863 
DecodeFIX(Word Code)864 static void DecodeFIX(Word Code)
865 {
866   Word Skip = 0, R;
867 
868   if (ChkArgCnt(2, 3)
869    && ChkMinCPU(CPUMN1613)
870    && DecodeReg(&ArgStr[1], &R, 0x01)
871    && DecodeDReg(&ArgStr[2])
872    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
873   {
874     WAsmCode[0] = Code | (Skip << 4);
875     CodeLen = 1;
876   }
877 }
878 
DecodeFLT(Word Code)879 static void DecodeFLT(Word Code)
880 {
881   Word Skip = 0, R;
882 
883   if (ChkArgCnt(2, 3)
884    && ChkMinCPU(CPUMN1613)
885    && DecodeDReg(&ArgStr[1])
886    && DecodeReg(&ArgStr[2], &R, 0x01)
887    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
888   {
889     WAsmCode[0] = Code | (Skip << 4);
890     CodeLen = 1;
891   }
892 }
893 
DecodeSRBT(Word Code)894 static void DecodeSRBT(Word Code)
895 {
896   Word R;
897 
898   if (ChkArgCnt(2, 2)
899    && ChkMinCPU(CPUMN1613)
900    && DecodeReg(&ArgStr[1], &R, 0x01)
901    && DecodeReg(&ArgStr[2], &R, 0x7f))
902   {
903     WAsmCode[0] = Code | R;
904     CodeLen = 1;
905   }
906 }
907 
DecodeDEBP(Word Code)908 static void DecodeDEBP(Word Code)
909 {
910   Word R;
911 
912   if (ChkArgCnt(2, 2)
913    && ChkMinCPU(CPUMN1613)
914    && DecodeReg(&ArgStr[2], &R, 0x01)
915    && DecodeReg(&ArgStr[1], &R, 0x7f))
916   {
917     WAsmCode[0] = Code | R;
918     CodeLen = 1;
919   }
920 }
921 
DecodeBLK(Word Code)922 static void DecodeBLK(Word Code)
923 {
924   Word Ri;
925 
926   if (ChkArgCnt(3, 3)
927    && ChkMinCPU(CPUMN1613)
928    && DecodeIReg(&ArgStr[1], &Ri, 0xff, 0x41)
929    && DecodeIReg(&ArgStr[2], &Ri, 0xff, 0x40)
930    && DecodeReg(&ArgStr[3], &Ri, 0x01))
931   {
932     WAsmCode[0] = Code;
933     CodeLen = 1;
934   }
935 }
936 
DecodeLBS_STBS(Word Code)937 static void DecodeLBS_STBS(Word Code)
938 {
939   Word R;
940 
941   if (ChkArgCnt(2, 2)
942    && ChkMinCPU(CPUMN1613)
943    && DecodeSOrAllBReg(&ArgStr[1], &R, Code & 8, !(Code & 0x80)))
944   {
945     Boolean OK;
946     LongWord Addr = EvalStrIntExpression(&ArgStr[2], UInt18, &OK);
947 
948     if (OK)
949     {
950       WAsmCode[0] = Code | (R << 4);
951       WAsmCode[1] = ChkPage(Addr, 0, &ArgStr[2]);
952       CodeLen = 2;
953     }
954   }
955 }
956 
DecodeCPYBS_SETBS(Word Code)957 static void DecodeCPYBS_SETBS(Word Code)
958 {
959   Word R, BSR;
960 
961   if (ChkArgCnt(2, 2)
962    && ChkMinCPU(CPUMN1613)
963    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC */
964    && DecodeSOrAllBReg(&ArgStr[2], &BSR, Code & 8, !(Code & 0x80)))
965   {
966     WAsmCode[0] = Code | R | (BSR << 4);
967     CodeLen = 1;
968   }
969 }
970 
DecodeCPYH_SETH(Word Code)971 static void DecodeCPYH_SETH(Word Code)
972 {
973   Word R, BSR;
974 
975   if (ChkArgCnt(2, 2)
976    && ChkMinCPU(CPUMN1613)
977    && DecodeReg(&ArgStr[1], &R, 0xff)
978    && DecodeHReg(&ArgStr[2], &BSR, !(Code & 0x80)))
979   {
980     WAsmCode[0] = Code | R | (BSR << 4);
981     CodeLen = 1;
982   }
983 }
984 
DecodeCLR(Word Code)985 static void DecodeCLR(Word Code)
986 {
987   Word R;
988 
989   if (ChkArgCnt(1, 1)
990    && DecodeReg(&ArgStr[1], &R, 0x7f)) /* do not allow IC */
991   {
992     /* == EOR R,R */
993 
994     WAsmCode[0] = Code | (R << 8) | R;
995     CodeLen = 1;
996   }
997 }
998 
DecodeSKIP(Word Code)999 static void DecodeSKIP(Word Code)
1000 {
1001   Word R, Skip;
1002 
1003   if (ChkArgCnt(2, 2)
1004    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC */
1005    && DecodeSkip(&ArgStr[2], &Skip))
1006   {
1007     /* == MV R,R,SKIP */
1008 
1009     WAsmCode[0] = Code | (R << 8) | (Skip << 4) | R;
1010   }
1011 }
1012 
IncMaxCodeLen(unsigned NumWords)1013 void IncMaxCodeLen(unsigned NumWords)
1014 {
1015   SetMaxCodeLen((CodeLen + NumWords) * 2);
1016 }
1017 
AppendWord(Word Data)1018 static void AppendWord(Word Data)
1019 {
1020   IncMaxCodeLen(1);
1021   WAsmCode[CodeLen++] = Data;
1022 }
1023 
DecodeDC(Word Code)1024 static void DecodeDC(Word Code)
1025 {
1026   Boolean OK, HalfFilledWord = False;
1027   int z;
1028   TempResult t;
1029 
1030   UNUSED(Code);
1031 
1032   if (ChkArgCnt(1, ArgCntMax))
1033   {
1034     OK = True;
1035     for (z = 1; z <= ArgCnt; z++)
1036      if (OK)
1037      {
1038        EvalStrExpression(&ArgStr[z], &t);
1039        if (mFirstPassUnknown(t.Flags) && (t.Typ == TempInt)) t.Contents.Int &= 0x7fff;
1040        switch (t.Typ)
1041        {
1042          case TempInt:
1043          ToInt:
1044            if (ChkRange(t.Contents.Int, -32768, 65535))
1045              AppendWord(t.Contents.Int);
1046            else
1047              OK = False;
1048            HalfFilledWord = False;
1049            break;
1050          case TempString:
1051          {
1052            Word Trans;
1053            int z2;
1054 
1055            if (MultiCharToInt(&t, 2))
1056              goto ToInt;
1057 
1058            for (z2 = 0; z2 < (int)t.Contents.Ascii.Length; z2++)
1059            {
1060              Trans = CharTransTable[((usint) t.Contents.Ascii.Contents[z2]) & 0xff];
1061              if (HalfFilledWord)
1062              {
1063                WAsmCode[CodeLen - 1] |= Trans & 0xff;
1064                HalfFilledWord = False;
1065              }
1066              else
1067              {
1068                AppendWord(Trans << 8);
1069                HalfFilledWord = True;
1070              }
1071            }
1072            break;
1073          }
1074          case TempFloat:
1075          {
1076            IncMaxCodeLen(2);
1077            if (Double2IBMFloat(&WAsmCode[CodeLen], t.Contents.Float, False))
1078              CodeLen += 2;
1079            else
1080              OK = False;
1081            HalfFilledWord = False;
1082            break;
1083          }
1084          default:
1085            OK = False;
1086        }
1087      }
1088     if (!OK)
1089        CodeLen = 0;
1090   }
1091 }
1092 
DecodeDS(Word Index)1093 static void DecodeDS(Word Index)
1094 {
1095   Boolean OK;
1096   Word Size;
1097   tSymbolFlags Flags;
1098 
1099   UNUSED(Index);
1100 
1101   Size = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &OK, &Flags);
1102   if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
1103   if (OK && !mFirstPassUnknown(Flags))
1104   {
1105     DontPrint = True;
1106     if (!Size) WrError(ErrNum_NullResMem);
1107     CodeLen = Size;
1108     BookKeeping();
1109   }
1110 }
1111 
1112 /*--------------------------------------------------------------------------*/
1113 /* Codetabellen */
1114 
AddFixed(tFixedOrder * pOrder,const char * pName,Word Code,CPUVar MinCPU)1115 static tFixedOrder *AddFixed(tFixedOrder *pOrder, const char *pName, Word Code, CPUVar MinCPU)
1116 {
1117   Word Index = pOrder - FixedOrders;
1118 
1119   if (Index >= FixedOrderCnt)
1120     exit(255);
1121   pOrder->Code = Code;
1122   pOrder->MinCPU = MinCPU;
1123   AddInstTable(InstTable, pName, Index, DecodeFixed);
1124   return pOrder + 1;
1125 }
1126 
InitFields(void)1127 static void InitFields(void)
1128 {
1129   tFixedOrder *pOrder;
1130 
1131   FixedOrders = pOrder = (tFixedOrder*)malloc(sizeof(*FixedOrders) * FixedOrderCnt);
1132   InstTable = CreateInstTable(201);
1133 
1134   pOrder = AddFixed(pOrder, "H"   , 0x2000 , CPUMN1610);
1135   pOrder = AddFixed(pOrder, "RET" , 0x2003 , CPUMN1610);
1136   pOrder = AddFixed(pOrder, "NOP" , NOPCode, CPUMN1610);
1137   pOrder = AddFixed(pOrder, "PSHM", 0x170f , CPUMN1613);
1138   pOrder = AddFixed(pOrder, "POPM", 0x1707 , CPUMN1613);
1139   pOrder = AddFixed(pOrder, "RETL", 0x3f07 , CPUMN1613);
1140 
1141   AddInstTable(InstTable, "PUSH", 0x2001, DecodeOneReg);
1142   AddInstTable(InstTable, "POP" , 0x2002, DecodeOneReg);
1143 
1144   /* allow WR as alias to WT */
1145 
1146   AddInstTable(InstTable, "RD"  , 0x1800, DecodeRegImm);
1147   AddInstTable(InstTable, "WT"  , 0x1000, DecodeRegImm);
1148   AddInstTable(InstTable, "WR"  , 0x1000, DecodeRegImm);
1149   AddInstTable(InstTable, "MVI" , 0x0800, DecodeRegImm);
1150 
1151   AddInstTable(InstTable, "A"   , 0x5808, DecodeTwoReg);
1152   AddInstTable(InstTable, "S"   , 0x5800, DecodeTwoReg);
1153   AddInstTable(InstTable, "C"   , 0x5008, DecodeTwoReg);
1154   AddInstTable(InstTable, "CB"  , 0x5000, DecodeTwoReg);
1155   AddInstTable(InstTable, "MV"  , 0x7808, DecodeTwoReg);
1156   AddInstTable(InstTable, "MVB" , 0x7800, DecodeTwoReg);
1157   AddInstTable(InstTable, "BSWP", 0x7008, DecodeTwoReg);
1158   AddInstTable(InstTable, "DSWP", 0x7000, DecodeTwoReg);
1159   AddInstTable(InstTable, "LAD" , 0x6800, DecodeTwoReg);
1160   AddInstTable(InstTable, "AND" , 0x6808, DecodeTwoReg);
1161   AddInstTable(InstTable, "OR"  , 0x6008, DecodeTwoReg);
1162   AddInstTable(InstTable, "EOR" , 0x6000, DecodeTwoReg);
1163 
1164   AddInstTable(InstTable, "L"   , 0xc000, DecodeEAReg);
1165   AddInstTable(InstTable, "ST"  , 0x8000, DecodeEAReg);
1166   AddInstTable(InstTable, "B"   , 0xc700, DecodeEA);
1167   AddInstTable(InstTable, "BAL" , 0x8700, DecodeEA);
1168   AddInstTable(InstTable, "IMS" , 0xc600, DecodeEA);
1169   AddInstTable(InstTable, "DMS" , 0x8600, DecodeEA);
1170 
1171   AddInstTable(InstTable, "SL"  , 0x200c, DecodeShift);
1172   AddInstTable(InstTable, "SR"  , 0x2008, DecodeShift);
1173 
1174   AddInstTable(InstTable, "SBIT", 0x3800, DecodeImm4);
1175   AddInstTable(InstTable, "RBIT", 0x3000, DecodeImm4);
1176   AddInstTable(InstTable, "TBIT", 0x2800, DecodeImm4);
1177   AddInstTable(InstTable, "AI"  , 0x4800, DecodeImm4);
1178   AddInstTable(InstTable, "SI"  , 0x4000, DecodeImm4);
1179 
1180   AddInstTable(InstTable, "LPSW", 0x2004, DecodeImm2);
1181 
1182   /* new to MN1613 */
1183 
1184   AddInstTable(InstTable, "LD"  , 0x2708, DecodeLD_STD);
1185   AddInstTable(InstTable, "STD" , 0x2748, DecodeLD_STD);
1186   AddInstTable(InstTable, "LR"  , 0x2000, DecodeLR_STR);
1187   AddInstTable(InstTable, "STR" , 0x2004, DecodeLR_STR);
1188 
1189   AddInstTable(InstTable, "MVWR", 0x7f08, DecodeR0RISkip);
1190   AddInstTable(InstTable, "MVBR", 0x7f00, DecodeR0RISkip);
1191   AddInstTable(InstTable, "BSWR", 0x7708, DecodeR0RISkip);
1192   AddInstTable(InstTable, "DSWR", 0x7700, DecodeR0RISkip);
1193   AddInstTable(InstTable, "AWR" , 0x5f08, DecodeR0RISkip);
1194   AddInstTable(InstTable, "SWR" , 0x5f00, DecodeR0RISkip);
1195   AddInstTable(InstTable, "CWR" , 0x5708, DecodeR0RISkip);
1196   AddInstTable(InstTable, "CBR" , 0x5700, DecodeR0RISkip);
1197   AddInstTable(InstTable, "LADR", 0x6f00, DecodeR0RISkip);
1198   AddInstTable(InstTable, "ANDR", 0x6f08, DecodeR0RISkip);
1199   AddInstTable(InstTable, "ORR" , 0x6708, DecodeR0RISkip);
1200   AddInstTable(InstTable, "EORR", 0x6700, DecodeR0RISkip);
1201 
1202   AddInstTable(InstTable, "MVWI", 0x780f, DecodeRImmSkip);
1203   AddInstTable(InstTable, "AWI" , 0x580f, DecodeRImmSkip);
1204   AddInstTable(InstTable, "SWI" , 0x5807, DecodeRImmSkip);
1205   AddInstTable(InstTable, "CWI" , 0x500f, DecodeRImmSkip);
1206   AddInstTable(InstTable, "CBI" , 0x5007, DecodeRImmSkip);
1207   AddInstTable(InstTable, "LADI", 0x6807, DecodeRImmSkip);
1208   AddInstTable(InstTable, "ANDI", 0x680f, DecodeRImmSkip);
1209   AddInstTable(InstTable, "ORI" , 0x600f, DecodeRImmSkip);
1210   AddInstTable(InstTable, "EORI", 0x6007, DecodeRImmSkip);
1211 
1212   AddInstTable(InstTable, "AD"  , 0x4f14, DecodeDR0RISkip);
1213   AddInstTable(InstTable, "SD"  , 0x4714, DecodeDR0RISkip);
1214   AddInstTable(InstTable, "M"   , 0x7f0c, DecodeDR0RISkip);
1215   AddInstTable(InstTable, "D"   , 0x770c, DecodeDR0RISkip);
1216   AddInstTable(InstTable, "FA"  , 0x6f0c, DecodeDR0RISkip);
1217   AddInstTable(InstTable, "FS"  , 0x6f04, DecodeDR0RISkip);
1218   AddInstTable(InstTable, "FM"  , 0x670c, DecodeDR0RISkip);
1219   AddInstTable(InstTable, "FD"  , 0x6704, DecodeDR0RISkip);
1220 
1221   AddInstTable(InstTable, "DAA" , 0x5f04, DecodeDAA_DAS);
1222   AddInstTable(InstTable, "DAS" , 0x5704, DecodeDAA_DAS);
1223 
1224   AddInstTable(InstTable, "RDR" , 0x2014, DecodeRDR_WTR);
1225   AddInstTable(InstTable, "WTR" , 0x2010, DecodeRDR_WTR);
1226 
1227   AddInstTable(InstTable, "BD"  , 0x2607, DecodeBD_BALD);
1228   AddInstTable(InstTable, "BALD", 0x2617, DecodeBD_BALD);
1229 
1230   AddInstTable(InstTable, "BL"  , 0x270f, DecodeBL_BALL);
1231   AddInstTable(InstTable, "BALL", 0x271f, DecodeBL_BALL);
1232 
1233   AddInstTable(InstTable, "BR"  , 0x2704, DecodeBR_BALR);
1234   AddInstTable(InstTable, "BALR", 0x2714, DecodeBR_BALR);
1235 
1236   AddInstTable(InstTable, "TSET", 0x1708, DecodeTSET_TRST);
1237   AddInstTable(InstTable, "TRST", 0x1700, DecodeTSET_TRST);
1238 
1239   AddInstTable(InstTable, "NEG" , 0x1f00, DecodeNEG);
1240   AddInstTable(InstTable, "FIX" , 0x1f0f, DecodeFIX);
1241   AddInstTable(InstTable, "FLT" , 0x1f07, DecodeFLT);
1242 
1243   AddInstTable(InstTable, "SRBT", 0x3f70, DecodeSRBT);
1244   AddInstTable(InstTable, "DEBP", 0x3ff0, DecodeDEBP);
1245   AddInstTable(InstTable, "BLK" , 0x3f17, DecodeBLK);
1246 
1247   AddInstTable(InstTable, "LB"  , 0x0f07, DecodeLBS_STBS);
1248   AddInstTable(InstTable, "LS"  , 0x0f0f, DecodeLBS_STBS);
1249   AddInstTable(InstTable, "STB" , 0x0f87, DecodeLBS_STBS);
1250   AddInstTable(InstTable, "STS" , 0x0f8f, DecodeLBS_STBS);
1251 
1252   AddInstTable(InstTable, "CPYB", 0x0f80, DecodeCPYBS_SETBS);
1253   AddInstTable(InstTable, "CPYS", 0x0f88, DecodeCPYBS_SETBS);
1254   AddInstTable(InstTable, "SETB", 0x0f00, DecodeCPYBS_SETBS);
1255   AddInstTable(InstTable, "SETS", 0x0f08, DecodeCPYBS_SETBS);
1256 
1257   AddInstTable(InstTable, "CPYH", 0x3f80, DecodeCPYH_SETH);
1258   AddInstTable(InstTable, "SETH", 0x3f00, DecodeCPYH_SETH);
1259 
1260   /* aliases */
1261 
1262   AddInstTable(InstTable, "CLR",   0x6000, DecodeCLR);
1263   AddInstTable(InstTable, "CLEAR", 0x6000, DecodeCLR);
1264   AddInstTable(InstTable, "SKIP",  0x7808, DecodeSKIP);
1265 
1266   /* pseudo instructions */
1267 
1268   AddInstTable(InstTable, "DC"  , 0, DecodeDC);
1269   AddInstTable(InstTable, "DS"  , 0, DecodeDS);
1270 }
1271 
DeinitFields(void)1272 static void DeinitFields(void)
1273 {
1274   DestroyInstTable(InstTable);
1275   free(FixedOrders);
1276 }
1277 
1278 /*--------------------------------------------------------------------------*/
1279 /* Interface to AS */
1280 
DecodeAttrPart_MN1610_Alt(void)1281 static Boolean DecodeAttrPart_MN1610_Alt(void)
1282 {
1283   return DecodeMoto16AttrSize(*AttrPart.Str, &AttrPartOpSize, False);
1284 }
1285 
MakeCode_MN1610_Alt(void)1286 static void MakeCode_MN1610_Alt(void)
1287 {
1288   OpSize = (AttrPartOpSize != eSymbolSizeUnknown) ? AttrPartOpSize : eSymbolSize16Bit;
1289 
1290   /* Ignore empty instruction */
1291 
1292   if (Memo("")) return;
1293 
1294   /* Pseudo Instructions */
1295 
1296   if (!LookupInstTable(InstTable, OpPart.Str))
1297     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
1298 }
1299 
IsDef_MN1610_Alt(void)1300 static Boolean IsDef_MN1610_Alt(void)
1301 {
1302   return FALSE;
1303 }
1304 
SwitchFrom_MN1610_Alt(void)1305 static void SwitchFrom_MN1610_Alt(void)
1306 {
1307   DeinitFields();
1308 }
1309 
SwitchTo_MN1610_Alt(void)1310 static void SwitchTo_MN1610_Alt(void)
1311 {
1312   PFamilyDescr FoundDescr;
1313 
1314   FoundDescr = FindFamilyByName("MN161x");
1315 
1316   TurnWords = True;
1317   ConstMode = ConstModeWeird;
1318 
1319   PCSymbol = "*";
1320   HeaderID = FoundDescr->Id;
1321   NOPCode = 0x7808; /* MV R0,R0 */
1322   DivideChars = ",";
1323   HasAttrs = False;
1324   AttrChars = ".";
1325 
1326   ValidSegs = (1 << SegCode) | (1 << SegIO);
1327   Grans[SegCode]     = Grans[SegIO]     = 2;
1328   ListGrans[SegCode] = ListGrans[SegIO] = 2;
1329   SegInits[SegCode]  = SegInits[SegIO]  = 0;
1330   if (MomCPU == CPUMN1613)
1331   {
1332     SegLimits[SegCode] = 0x3ffff;
1333     SegLimits[SegIO] = 0xffff;
1334     pASSUMERecs = ASSUMEMN1613;
1335     ASSUMERecCnt = ASSUMEMN1613Count;
1336   }
1337   else
1338   {
1339     SegLimits[SegCode] = 0xffff;
1340     SegLimits[SegIO] = 0xff; /* no RDR/WTR insn */
1341   }
1342 
1343   DecodeAttrPart = DecodeAttrPart_MN1610_Alt;
1344   MakeCode = MakeCode_MN1610_Alt;
1345   IsDef = IsDef_MN1610_Alt;
1346   SwitchFrom = SwitchFrom_MN1610_Alt;
1347   InitFields();
1348 }
1349 
1350 /*--------------------------------------------------------------------------*/
1351 /* Initialisierung */
1352 
codemn2610_init(void)1353 void codemn2610_init(void)
1354 {
1355   CPUMN1610 = AddCPU("MN1610ALT", SwitchTo_MN1610_Alt);
1356   CPUMN1613 = AddCPU("MN1613ALT", SwitchTo_MN1610_Alt);
1357 }
1358