1 /* codeh8_5.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS-Portierung                                                             */
6 /*                                                                           */
7 /* AS-Codegenerator H8/500                                                   */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14 
15 #include "nls.h"
16 #include "bpemu.h"
17 #include "strutil.h"
18 #include "asmdef.h"
19 #include "asmsub.h"
20 #include "asmpars.h"
21 #include "asmallg.h"
22 #include "asmitree.h"
23 #include "asmstructs.h"
24 #include "codepseudo.h"
25 #include "motpseudo.h"
26 #include "codevars.h"
27 #include "errmsg.h"
28 
29 #include "codeh8_5.h"
30 
31 #define OneOrderCount 13
32 #define OneRegOrderCount 3
33 #define RegEAOrderCount 9
34 #define TwoRegOrderCount 3
35 
36 #define REG_SP 7
37 #define REG_FP 6
38 #define REG_MARK 8
39 
40 #define ModNone (-1)
41 #define ModReg 0
42 #define MModReg (1 << ModReg)
43 #define ModIReg 1
44 #define MModIReg (1 << ModIReg)
45 #define ModDisp8 2
46 #define MModDisp8 (1 << ModDisp8)
47 #define ModDisp16 3
48 #define MModDisp16 (1 << ModDisp16)
49 #define ModPredec 4
50 #define MModPredec (1 << ModPredec)
51 #define ModPostInc 5
52 #define MModPostInc (1 << ModPostInc)
53 #define ModAbs8 6
54 #define MModAbs8 (1 << ModAbs8)
55 #define ModAbs16 7
56 #define MModAbs16 (1 << ModAbs16)
57 #define ModImm 8
58 #define MModImm (1 << ModImm)
59 #define MModImmVariable (1 << 9)
60 
61 #define MModAll (MModReg|MModIReg|MModDisp8|MModDisp16|MModPredec|MModPostInc|MModAbs8|MModAbs16|MModImm)
62 #define MModNoImm (MModAll & ~MModImm)
63 
64 
65 typedef struct
66 {
67   char *Name;
68   Word Code;
69   Byte SizeMask;
70   tSymbolSize DefSize;
71 } OneOrder;
72 
73 
74 static CPUVar CPU532,CPU534,CPU536,CPU538;
75 
76 static tSymbolSize OpSize;
77 static char *Format;
78 static ShortInt AdrMode;
79 static Byte AdrByte,FormatCode;
80 static Byte AdrVals[3];
81 static Byte AbsBank;
82 static tSymbolSize ImmSize;
83 
84 static ShortInt Adr2Mode;
85 static Byte Adr2Byte, Adr2Cnt;
86 static Byte Adr2Vals[3];
87 static tSymbolSize Imm2Size;
88 
89 static LongInt Reg_DP,Reg_EP,Reg_TP,Reg_BR;
90 
91 static OneOrder *OneOrders;
92 static OneOrder *OneRegOrders;
93 static OneOrder *RegEAOrders;
94 static OneOrder *TwoRegOrders;
95 
96 #define ASSUMEH8_5Count 4
97 static ASSUMERec ASSUMEH8_5s[ASSUMEH8_5Count] =
98 {
99   {"DP", &Reg_DP, 0, 0xff, -1, NULL},
100   {"EP", &Reg_EP, 0, 0xff, -1, NULL},
101   {"TP", &Reg_TP, 0, 0xff, -1, NULL},
102   {"BR", &Reg_BR, 0, 0xff, -1, NULL}
103 };
104 
105 /*-------------------------------------------------------------------------*/
106 /* Adressparsing */
107 
SetOpSize(tSymbolSize NSize)108 static void SetOpSize(tSymbolSize NSize)
109 {
110   if (OpSize == eSymbolSizeUnknown) OpSize = NSize;
111   else if (OpSize != NSize) WrError(ErrNum_ConfOpSizes);
112 }
113 
114 /*!------------------------------------------------------------------------
115  * \fn     DecodeRegCore(const char *pArg, Byte *pResult)
116  * \brief  check whether argument is a CPU register
117  * \param  pArg source argument
118  * \param  pResult register # if yes
119  * \return True if yes
120  * ------------------------------------------------------------------------ */
121 
DecodeRegCore(const char * pArg,Byte * pResult)122 static Boolean DecodeRegCore(const char *pArg, Byte *pResult)
123 {
124   if (!as_strcasecmp(pArg, "SP")) *pResult = REG_SP | REG_MARK;
125   else if (!as_strcasecmp(pArg, "FP")) *pResult = REG_FP | REG_MARK;
126   else if ((strlen(pArg) == 2) && (as_toupper(*pArg) == 'R') && (pArg[1] >= '0') && (pArg[1] <= '7'))
127     *pResult = pArg[1] - '0';
128   else
129     return False;
130   return True;
131 }
132 
133 /*!------------------------------------------------------------------------
134  * \fn     DissectReg_H8_5(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
135  * \brief  dissect register symbols - H8/500 variant
136  * \param  pDest destination buffer
137  * \param  DestSize destination buffer size
138  * \param  Value numeric register value
139  * \param  InpSize register size
140  * ------------------------------------------------------------------------ */
141 
DissectReg_H8_5(char * pDest,size_t DestSize,tRegInt Value,tSymbolSize InpSize)142 static void DissectReg_H8_5(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
143 {
144   switch (InpSize)
145   {
146     case eSymbolSize16Bit:
147       if (Value == (REG_SP | REG_MARK))
148         as_snprintf(pDest, DestSize, "SP");
149       else if (Value == (REG_FP | REG_MARK))
150         as_snprintf(pDest, DestSize, "FP");
151       else
152         as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
153       break;
154     default:
155       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
156   }
157 }
158 
159 
160 /*!------------------------------------------------------------------------
161  * \fn     DecodeReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
162  * \brief  check whether argument is a CPU register or CPU alias
163  * \param  pArg source argument
164  * \param  pResult register # if yes
165  * \param  MustBeReg True if argument must be a register
166  * \return EvalResult
167  * ------------------------------------------------------------------------ */
168 
DecodeReg(const tStrComp * pArg,Byte * pResult,Boolean MustBeReg)169 static tRegEvalResult DecodeReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
170 {
171   tRegDescr RegDescr;
172   tEvalResult EvalResult;
173   tRegEvalResult RegEvalResult;
174 
175   if (DecodeRegCore(pArg->Str, pResult))
176   {
177     *pResult &= ~REG_MARK;
178     return eIsReg;
179   }
180 
181   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize16Bit, MustBeReg);
182   *pResult = RegDescr.Reg;
183   return RegEvalResult;
184 }
185 
DecodeRegList(tStrComp * pArg,Byte * pResult)186 static Boolean DecodeRegList(tStrComp *pArg, Byte *pResult)
187 {
188   tStrComp Arg, Remainder;
189   Byte Reg1, Reg2, z;
190   char *p, *p2;
191 
192   Arg = *pArg;
193   if (IsIndirect(Arg.Str))
194   {
195     StrCompIncRefLeft(&Arg, 1);
196     StrCompShorten(&Arg, 1);
197     KillPrefBlanksStrCompRef(&Arg);
198     KillPostBlanksStrComp(&Arg);
199   }
200 
201   *pResult = 0;
202   do
203   {
204     p = QuotPos(Arg.Str, ',');
205     if (p)
206       StrCompSplitRef(&Arg, &Remainder, &Arg, p);
207     p2 = strchr(Arg.Str, '-');
208     if (p2)
209     {
210       tStrComp Left, Right;
211 
212       StrCompSplitRef(&Left, &Right, &Arg, p2);
213       if (DecodeReg(&Left, &Reg1, True) != eIsReg) return False;
214       if (DecodeReg(&Right, &Reg2, True) != eIsReg) return False;
215       if (Reg1 > Reg2) Reg2 += 8;
216       for (z = Reg1; z <= Reg2; z++) *pResult |= (1 << (z & 7));
217     }
218     else
219     {
220       if (DecodeReg(&Arg, &Reg1, True) != eIsReg) return False;
221       *pResult |= (1 << Reg1);
222     }
223     if (p)
224       Arg = Remainder;
225   }
226   while (p);
227 
228   return True;
229 }
230 
DecodeCReg(char * Asc,Byte * pErg)231 static Boolean DecodeCReg(char *Asc, Byte *pErg)
232 {
233   if (!as_strcasecmp(Asc, "SR"))
234   {
235     *pErg = 0; SetOpSize(eSymbolSize16Bit);
236   }
237   else if (!as_strcasecmp(Asc, "CCR"))
238   {
239     *pErg = 1; SetOpSize(eSymbolSize8Bit);
240   }
241   else if (!as_strcasecmp(Asc, "BR"))
242   {
243     *pErg = 3; SetOpSize(eSymbolSize8Bit);
244   }
245   else if (!as_strcasecmp(Asc, "EP"))
246   {
247     *pErg = 4; SetOpSize(eSymbolSize8Bit);
248   }
249   else if (!as_strcasecmp(Asc, "DP"))
250   {
251     *pErg = 5; SetOpSize(eSymbolSize8Bit);
252   }
253   else if (!as_strcasecmp(Asc, "TP"))
254   {
255     *pErg = 7; SetOpSize(eSymbolSize8Bit);
256   }
257   else
258     return False;
259   return True;
260 }
261 
SplitDisp(tStrComp * pArg,tSymbolSize * pSize)262 static void SplitDisp(tStrComp *pArg, tSymbolSize *pSize)
263 {
264   int l = strlen(pArg->Str);
265 
266   if ((l > 2) && !strcmp(pArg->Str + l - 2, ":8"))
267   {
268     StrCompShorten(pArg, 2);
269     *pSize = eSymbolSize8Bit;
270   }
271   else if ((l > 3) && !strcmp(pArg->Str + l - 3, ":16"))
272   {
273     StrCompShorten(pArg, 3);
274     *pSize = eSymbolSize16Bit;
275   }
276 }
277 
DecideAbsolute(LongInt Value,tSymbolSize Size,Boolean Unknown,Word Mask)278 static void DecideAbsolute(LongInt Value, tSymbolSize Size, Boolean Unknown, Word Mask)
279 {
280   LongInt Base;
281 
282   if (Size == eSymbolSizeUnknown)
283   {
284     if (((Value >> 8) == Reg_BR) && (Mask & MModAbs8)) Size = eSymbolSize8Bit;
285     else Size = eSymbolSize16Bit;
286   }
287 
288   AdrMode = ModNone;
289   AdrCnt = 0;
290 
291   switch (Size)
292   {
293     case eSymbolSize8Bit:
294       if (Unknown) Value = (Value & 0xff) | (Reg_BR << 8);
295       if ((Value >> 8) != Reg_BR) WrError(ErrNum_InAccPage);
296       AdrMode = ModAbs8; AdrByte = 0x05;
297       AdrVals[0] = Value & 0xff; AdrCnt = 1;
298       break;
299     case eSymbolSize16Bit:
300       if (Maximum)
301       {
302         Base = AbsBank;
303         Base <<= 16;
304       }
305       else
306         Base = 0;
307       if (Unknown) Value = (Value & 0xffff) | Base;
308       if ((Value >> 16) != (Base >> 16)) WrError(ErrNum_InAccPage);
309       AdrMode = ModAbs16; AdrByte = 0x15;
310       AdrVals[0] = (Value >> 8) & 0xff;
311       AdrVals[1] = Value & 0xff;
312       AdrCnt = 2;
313       break;
314     default:
315       break;
316   }
317 }
318 
ChkAdr(Word Mask)319 static void ChkAdr(Word Mask)
320 {
321   if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
322   {
323     WrError(ErrNum_InvAddrMode); AdrMode = ModNone; AdrCnt = 0;
324   }
325 }
326 
DecodeAdr(tStrComp * pArg,Word Mask)327 static void DecodeAdr(tStrComp *pArg, Word Mask)
328 {
329   Word AdrWord;
330   Boolean OK, Unknown;
331   tSymbolFlags Flags;
332   LongInt DispAcc;
333   Byte HReg;
334   tSymbolSize DispSize;
335   ShortInt RegPart;
336   char *p;
337 
338   AdrMode = ModNone; AdrCnt = 0;
339   ImmSize = eSymbolSizeUnknown;
340 
341   /* einfaches Register ? */
342 
343   switch (DecodeReg(pArg, &AdrByte, False))
344   {
345     case eIsReg:
346       AdrMode = ModReg; AdrByte |= 0xa0;
347       ChkAdr(Mask); return;
348     case eRegAbort:
349       return;
350     case eIsNoReg:
351       break;
352   }
353 
354   /* immediate ? */
355 
356   if (*pArg->Str == '#')
357   {
358     SplitDisp(pArg, &ImmSize);
359     if (ImmSize == eSymbolSizeUnknown)
360     {
361       if (!(Mask & MModImmVariable))
362         ImmSize = OpSize;
363     }
364     else if ((ImmSize != OpSize) && !(Mask & MModImmVariable))
365     {
366       WrStrErrorPos(ErrNum_ConfOpSizes, pArg);
367       return;
368     }
369     switch (OpSize)
370     {
371       case eSymbolSizeUnknown:
372         OK = False; WrError(ErrNum_UndefOpSizes);
373         break;
374       case eSymbolSize8Bit:
375         AdrVals[0] = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
376         break;
377       case eSymbolSize16Bit:
378         AdrWord = EvalStrIntExpressionOffs(pArg, 1, Int16, &OK);
379         AdrVals[0] = Hi(AdrWord); AdrVals[1] = Lo(AdrWord);
380         break;
381       default:
382         OK = False;
383         break;
384     }
385     if (OK)
386     {
387       AdrMode = ModImm; AdrByte = 0x04; AdrCnt = OpSize + 1;
388     }
389     ChkAdr(Mask); return;
390   }
391 
392   /* indirekt ? */
393 
394   if (*pArg->Str == '@')
395   {
396     tStrComp Arg, Remainder;
397 
398     StrCompRefRight(&Arg, pArg, 1);
399     if (IsIndirect(Arg.Str))
400     {
401       StrCompIncRefLeft(&Arg, 1);
402       StrCompShorten(&Arg, 1);
403     }
404 
405     /* Predekrement ? */
406 
407     if (*Arg.Str == '-')
408     {
409       tStrComp RegArg;
410 
411       StrCompRefRight(&RegArg, &Arg, 1);
412       if (DecodeReg(&RegArg, &AdrByte, True) == eIsReg)
413       {
414         AdrMode = ModPredec; AdrByte |= 0xb0;
415         ChkAdr(Mask); return;
416       }
417     }
418 
419     /* Postinkrement ? */
420 
421     if ((*Arg.Str) && (Arg.Str[strlen(Arg.Str) - 1] == '+'))
422     {
423       StrCompShorten(&Arg, 1);
424       if (DecodeReg(&Arg, &AdrByte, True) == eIsReg)
425       {
426         AdrMode = ModPostInc; AdrByte |= 0xc0;
427         ChkAdr(Mask); return;
428       }
429     }
430 
431     /* zusammengesetzt */
432 
433     DispAcc = 0; DispSize = eSymbolSizeUnknown; RegPart = -1; OK = True; Unknown = False;
434     do
435     {
436       p = QuotPos(Arg.Str, ',');
437       if (p)
438         StrCompSplitRef(&Arg, &Remainder, &Arg, p);
439       switch (DecodeReg(&Arg, &HReg, False))
440       {
441         case eIsReg:
442           if (RegPart != -1)
443           {
444             WrStrErrorPos(ErrNum_InvAddrMode, &Arg); OK = False;
445           }
446           else
447             RegPart = HReg;
448           break;
449         case eIsNoReg:
450           SplitDisp(&Arg, &DispSize);
451           DispAcc += EvalStrIntExpressionOffsWithFlags(&Arg, !!(*Arg.Str == '#'), Int32, &OK, &Flags);
452           if (mFirstPassUnknown(Flags)) Unknown = True;
453           break;
454         default:
455           OK = False;
456       }
457       if (p)
458         Arg = Remainder;
459     }
460     while (p && OK);
461     if (OK)
462     {
463       if (RegPart == -1) DecideAbsolute(DispAcc, DispSize, Unknown, Mask);
464       else if (DispAcc == 0)
465       {
466         switch (DispSize)
467         {
468           case eSymbolSizeUnknown:
469             AdrMode = ModIReg; AdrByte = 0xd0 | RegPart;
470             break;
471           case eSymbolSize8Bit:
472             AdrMode = ModDisp8; AdrByte = 0xe0 | RegPart;
473             AdrVals[0] = 0; AdrCnt = 1;
474             break;
475           case eSymbolSize16Bit:
476             AdrMode = ModDisp16; AdrByte = 0xf0 | RegPart;
477             AdrVals[0] = 0; AdrVals[1] = 0; AdrCnt = 2;
478             break;
479           default:
480             break;
481         }
482       }
483       else
484       {
485         if (DispSize == eSymbolSizeUnknown)
486         {
487           if ((DispAcc >= -128) && (DispAcc < 127)) DispSize = eSymbolSize8Bit;
488           else DispSize = eSymbolSize16Bit;
489         }
490         switch (DispSize)
491         {
492           case eSymbolSize8Bit:
493             if (Unknown) DispAcc &= 0x7f;
494             if (ChkRange(DispAcc, -128, 127))
495             {
496               AdrMode = ModDisp8; AdrByte = 0xe0 | RegPart;
497               AdrVals[0] = DispAcc & 0xff; AdrCnt = 1;
498             }
499             break;
500           case eSymbolSize16Bit:
501             if (Unknown) DispAcc &= 0x7fff;
502             if (ChkRange(DispAcc, -0x8000l, 0xffffl))
503             {
504               AdrMode = ModDisp16; AdrByte = 0xf0 | RegPart;
505               AdrVals[1] = DispAcc & 0xff;
506               AdrVals[0] = (DispAcc >> 8) & 0xff;
507               AdrCnt = 2;
508             }
509             break;
510           default:
511             break;
512         }
513       }
514     }
515 
516     ChkAdr(Mask); return;
517   }
518 
519   /* absolut */
520 
521   DispSize = eSymbolSizeUnknown; SplitDisp(pArg, &DispSize);
522   DispAcc = EvalStrIntExpressionWithFlags(pArg, UInt24, &OK, &Flags);
523   DecideAbsolute(DispAcc, DispSize, mFirstPassUnknown(Flags), Mask);
524 
525   ChkAdr(Mask);
526 }
527 
ImmVal(void)528 static LongInt ImmVal(void)
529 {
530   LongInt t;
531 
532   switch (OpSize)
533   {
534     case eSymbolSize8Bit:
535       t = AdrVals[0]; if (t > 127) t -= 256;
536       break;
537     case eSymbolSize16Bit:
538       t = (((Word)AdrVals[0]) << 8) + AdrVals[1];
539       if (t > 0x7fff) t -= 0x10000;
540       break;
541     default:
542       t = 0; WrError(ErrNum_InternalError);
543   }
544   return t;
545 }
546 
547 /*!------------------------------------------------------------------------
548  * \fn     AdaptImmSize(const tStrComp *pArg)
549  * \brief  necessary post-processing if immediate operand size may differ from insn size
550  * \param  pArg immediate argument
551  * \return True if adaption succeeded
552  * ------------------------------------------------------------------------ */
553 
AdaptImmSize(const tStrComp * pArg)554 static Boolean AdaptImmSize(const tStrComp *pArg)
555 {
556   LongInt ImmV = ImmVal();
557   Boolean ImmValShort = (ImmV >= -128) && (ImmV < 127);
558 
559   switch (OpSize)
560   {
561     /* no AdrVals adaptions needed for pure 8 bit: */
562 
563     case eSymbolSize8Bit:
564       if (ImmSize == eSymbolSize16Bit)
565       {
566         WrStrErrorPos(ErrNum_ConfOpSizes, pArg);
567         return False;
568       }
569       else
570       {
571         ImmSize = eSymbolSize8Bit;
572         return True;
573       }
574 
575     case eSymbolSize16Bit:
576       switch (ImmSize)
577       {
578         case eSymbolSize16Bit:
579           return True;
580         case eSymbolSize8Bit:
581           if (!ImmValShort)
582           {
583             WrStrErrorPos(ErrNum_OverRange, pArg);
584             return False;
585           }
586           else
587             goto Make8;
588         case eSymbolSizeUnknown:
589           if (ImmValShort)
590           {
591             ImmSize = eSymbolSize8Bit;
592             goto Make8;
593           }
594           else
595           {
596             ImmSize = eSymbolSize16Bit;
597             return True;
598           }
599         default:
600           WrStrErrorPos(ErrNum_InternalError, pArg);
601           return False;
602         Make8:
603           AdrVals[0] = AdrVals[1];
604           AdrCnt--;
605           return True;
606       }
607 
608     default:
609       WrStrErrorPos(ErrNum_InternalError, pArg);
610       return False;
611   }
612 }
613 
614 /*--------------------------------------------------------------------------*/
615 /* Bit Symbol Handling */
616 
617 /*
618  * Compact representation of bits in symbol table:
619  * Bit 31/30: Operand size (00 = unknown, 10=8, 11=16 bits)
620  * Bit 29/28: address field size (00 = unknown, 10=8, 11=16 bits)
621  * Bits 27...4 or 26..3: Absolute address
622  * Bits 0..2 or 0..3: Bit position
623  */
624 
CodeOpSize(tSymbolSize Size)625 static LongWord CodeOpSize(tSymbolSize Size)
626 {
627   return (Size == eSymbolSizeUnknown)
628        ? 0
629        : ((Size == eSymbolSize16Bit) ? 3 : 2);
630 }
631 
DecodeOpSize(Byte SizeCode)632 static tSymbolSize DecodeOpSize(Byte SizeCode)
633 {
634   return (SizeCode & 2)
635        ? ((SizeCode & 1) ? eSymbolSize16Bit : eSymbolSize8Bit)
636        : eSymbolSizeUnknown;
637 }
638 
639 /*!------------------------------------------------------------------------
640  * \fn     EvalBitPosition(const tStrComp *pArg, tSymbolSize Size, Boolean *pOK)
641  * \brief  evaluate bit position
642  * \param  bit position argument (with or without #)
643  * \param  Size operand size (8/16/unknown)
644  * \param  pOK parsing OK?
645  * \return numeric bit position
646  * ------------------------------------------------------------------------ */
647 
EvalBitPosition(const tStrComp * pArg,tSymbolSize Size,Boolean * pOK)648 static LongWord EvalBitPosition(const tStrComp *pArg, tSymbolSize Size, Boolean *pOK)
649 {
650   return EvalStrIntExpressionOffs(pArg, !!(*pArg->Str == '#'), (Size == eSymbolSize16Bit) ? UInt4 : UInt3, pOK);
651 }
652 
653 /*!------------------------------------------------------------------------
654  * \fn     AssembleBitSymbol(Byte BitPos, LongWord Address, tSymbolSize OpSize, tSymbolSize AddrSize)
655  * \brief  build the compact internal representation of a bit symbol
656  * \param  BitPos bit position in word
657  * \param  Address register address
658  * \param  OpSize memory operand size
659  * \param  AddrSize address length
660  * \return compact representation
661  * ------------------------------------------------------------------------ */
662 
AssembleBitSymbol(Byte BitPos,Word Address,tSymbolSize OpSize,tSymbolSize AddrSize)663 static LongWord AssembleBitSymbol(Byte BitPos, Word Address, tSymbolSize OpSize, tSymbolSize AddrSize)
664 {
665   return
666     (CodeOpSize(OpSize) << 30)
667   | (CodeOpSize(AddrSize) << 28)
668   | (Address << ((OpSize == eSymbolSize8Bit) ? 3 : 4))
669   | (BitPos << 0);
670 }
671 
672 /*!------------------------------------------------------------------------
673  * \fn     DecodeBitArg2(LongWord *pResult, const tStrComp *pBitArg, tStrComp *pRegArg)
674  * \brief  encode a bit symbol, address & bit position separated
675  * \param  pResult resulting encoded bit
676  * \param  pRegArg register argument
677  * \param  pBitArg bit argument
678  * \return True if success
679  * ------------------------------------------------------------------------ */
680 
DecodeBitArg2(LongWord * pResult,const tStrComp * pBitArg,tStrComp * pRegArg)681 static Boolean DecodeBitArg2(LongWord *pResult, const tStrComp *pBitArg, tStrComp *pRegArg)
682 {
683   Boolean OK;
684   LongWord Addr, BitPos;
685   tSymbolSize AddrSize = eSymbolSizeUnknown;
686 
687   BitPos = EvalBitPosition(pBitArg, (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize, &OK);
688   if (!OK)
689     return False;
690 
691   SplitDisp(pRegArg, &AddrSize);
692   Addr = EvalStrIntExpression(pRegArg, UInt24, &OK);
693   if (!OK)
694     return False;
695 
696   *pResult = AssembleBitSymbol(BitPos, Addr, OpSize, AddrSize);
697 
698   return True;
699 }
700 
701 /*!------------------------------------------------------------------------
702  * \fn     DecodeBitArg(LongWord *pResult, int Start, int Stop)
703  * \brief  encode a bit symbol from instruction argument(s)
704  * \param  pResult resulting encoded bit
705  * \param  Start first argument
706  * \param  Stop last argument
707  * \return True if success
708  * ------------------------------------------------------------------------ */
709 
DecodeBitArg(LongWord * pResult,int Start,int Stop)710 static Boolean DecodeBitArg(LongWord *pResult, int Start, int Stop)
711 {
712   *pResult = 0;
713 
714   /* Just one argument -> parse as bit argument */
715 
716   if (Start == Stop)
717   {
718     tEvalResult EvalResult;
719 
720     *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], UInt32, &EvalResult);
721     if (EvalResult.OK)
722       ChkSpace(SegBData, EvalResult.AddrSpaceMask);
723     return EvalResult.OK;
724   }
725 
726   /* register & bit position are given as separate arguments */
727 
728   else if (Stop == Start + 1)
729     return DecodeBitArg2(pResult, &ArgStr[Start], &ArgStr[Stop]);
730 
731   /* other # of arguments not allowed */
732 
733   else
734   {
735     WrError(ErrNum_WrongArgCnt);
736     return False;
737   }
738 }
739 
740 /*!------------------------------------------------------------------------
741  * \fn     DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos, tSymbolSize *pOpSize, tSymbolSize *pAddrSize)
742  * \brief  transform compact representation of bit (field) symbol into components
743  * \param  BitSymbol compact storage
744  * \param  pAddress register address
745  * \param  pBitPos bit position
746  * \param  pOpSize operand size
747  * \param  pAddrSize address length
748  * \return constant True
749  * ------------------------------------------------------------------------ */
750 
DissectBitSymbol(LongWord BitSymbol,LongWord * pAddress,Byte * pBitPos,tSymbolSize * pOpSize,tSymbolSize * pAddrSize)751 static Boolean DissectBitSymbol(LongWord BitSymbol, LongWord *pAddress, Byte *pBitPos, tSymbolSize *pOpSize, tSymbolSize *pAddrSize)
752 {
753   *pOpSize = DecodeOpSize(BitSymbol >> 30);
754   *pAddrSize = DecodeOpSize(BitSymbol >> 28);
755   *pAddress = (BitSymbol >> ((*pOpSize == eSymbolSize8Bit) ? 3 : 4)) & 0xfffffful;
756   *pBitPos = BitSymbol & (*pOpSize ? 15 : 7);
757   return True;
758 }
759 
760 /*!------------------------------------------------------------------------
761  * \fn     DissectBit_H8_5(char *pDest, size_t DestSize, LargeWord Inp)
762  * \brief  dissect compact storage of bit (field) into readable form for listing
763  * \param  pDest destination for ASCII representation
764  * \param  DestSize destination buffer size
765  * \param  Inp compact storage
766  * ------------------------------------------------------------------------ */
767 
DissectBit_H8_5(char * pDest,size_t DestSize,LargeWord Inp)768 static void DissectBit_H8_5(char *pDest, size_t DestSize, LargeWord Inp)
769 {
770   Byte BitPos;
771   LongWord Address;
772   tSymbolSize OpSize, AddrSize;
773 
774   DissectBitSymbol(Inp, &Address, &BitPos, &OpSize, &AddrSize);
775 
776   as_snprintf(pDest, DestSize, "#%u,$%llx", BitPos, (LargeWord)Address);
777   if (AddrSize != eSymbolSizeUnknown)
778     as_snprcatf(pDest, DestSize, ":%u", AddrSize ? 16 : 8);
779   if (OpSize != eSymbolSizeUnknown)
780     as_snprcatf(pDest, DestSize, ".%c", "BW"[OpSize]);
781 }
782 
783 /*!------------------------------------------------------------------------
784  * \fn     ExpandBit_H8_5(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
785  * \brief  expands bit definition when a structure is instantiated
786  * \param  pVarName desired symbol name
787  * \param  pStructElem element definition
788  * \param  Base base address of instantiated structure
789  * ------------------------------------------------------------------------ */
790 
ExpandBit_H8_5(const tStrComp * pVarName,const struct sStructElem * pStructElem,LargeWord Base)791 static void ExpandBit_H8_5(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
792 {
793   tSymbolSize OpSize = (pStructElem->OpSize < 0) ? eSymbolSize8Bit : pStructElem->OpSize;
794   LongWord Address = Base + pStructElem->Offset;
795 
796   if (!ChkRange(Address, 0, 0xffffff)
797    || !ChkRange(pStructElem->BitPos, 0, (8 << OpSize) - 1))
798     return;
799 
800   PushLocHandle(-1);
801   EnterIntSymbol(pVarName, AssembleBitSymbol(pStructElem->BitPos, Address, OpSize, eSymbolSizeUnknown), SegBData, False);
802   PopLocHandle();
803   /* TODO: MakeUseList? */
804 }
805 
806 /*-------------------------------------------------------------------------*/
807 
CheckFormat(const char * FSet)808 static Boolean CheckFormat(const char *FSet)
809 {
810   const char *p;
811 
812   if (!strcmp(Format, " "))
813     FormatCode = 0;
814   else
815   {
816     p = strchr(FSet, *Format);
817     if (!p)
818     {
819       WrError(ErrNum_InvFormat);
820       return False;
821     }
822     else
823       FormatCode = p - FSet + 1;
824   }
825   return True;
826 }
827 
FormatToBranchSize(const char * pFormat,tSymbolSize * pOpSize)828 static Boolean FormatToBranchSize(const char *pFormat, tSymbolSize *pOpSize)
829 {
830   if (!strcmp(pFormat, " "));
831 
832   else if (!strcmp(pFormat, "16")) /* treat like .L */
833   {
834     if (*pOpSize == eSymbolSizeUnknown) *pOpSize = eSymbolSize32Bit;
835     else if (*pOpSize != eSymbolSize32Bit)
836     {
837       WrXError(ErrNum_ConfOpSizes, Format);
838       return False;
839     }
840   }
841   else if (!strcmp(pFormat, "8")) /* treat like .S */
842   {
843     if (*pOpSize == eSymbolSizeUnknown) *pOpSize = eSymbolSizeFloat32Bit;
844     else if (*pOpSize != eSymbolSizeFloat32Bit)
845     {
846       WrXError(ErrNum_ConfOpSizes, Format);
847       return False;
848     }
849   }
850   else
851   {
852     WrXError(ErrNum_InvFormat, Format);
853     return False;
854   }
855   return True;
856 }
857 
CopyAdr(void)858 static void CopyAdr(void)
859 {
860   Adr2Mode = AdrMode;
861   Adr2Byte = AdrByte;
862   Adr2Cnt = AdrCnt;
863   Imm2Size = ImmSize;
864   memcpy(Adr2Vals, AdrVals, AdrCnt);
865 }
866 
867 /*-------------------------------------------------------------------------*/
868 /* Instruction Decoders */
869 
DecodeFixed(Word Code)870 static void DecodeFixed(Word Code)
871 {
872   if (!ChkArgCnt(0, 0));
873   else if (OpSize != eSymbolSizeUnknown) WrError(ErrNum_UseLessAttr);
874   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
875   else
876   {
877     CodeLen = 0;
878     if (Hi(Code) != 0)
879       BAsmCode[CodeLen++] = Hi(Code);
880     BAsmCode[CodeLen++] = Lo(Code);
881   }
882 }
883 
DecodeMOV(Word Dummy)884 static void DecodeMOV(Word Dummy)
885 {
886   UNUSED(Dummy);
887 
888   if (!ChkArgCnt(2, 2));
889   else if (CheckFormat("GEIFLS"))
890   {
891     if (OpSize == eSymbolSizeUnknown)
892       SetOpSize((FormatCode == 2) ? eSymbolSize8Bit : eSymbolSize16Bit);
893     if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
894     else
895     {
896       DecodeAdr(&ArgStr[2], MModNoImm);
897       if (AdrMode != ModNone)
898       {
899         CopyAdr();
900         DecodeAdr(&ArgStr[1], MModAll | MModImmVariable);
901         if (AdrMode != ModNone)
902         {
903           if (FormatCode == 0)
904           {
905             if ((AdrMode == ModImm) && ((ImmSize == OpSize) || (ImmSize == eSymbolSizeUnknown)) && (Adr2Mode == ModReg)) FormatCode = 2 + OpSize;
906             else if ((AdrMode == ModReg) && (Adr2Byte == 0xe6)) FormatCode = 4;
907             else if ((Adr2Mode == ModReg) && (AdrByte == 0xe6)) FormatCode = 4;
908             else if ((AdrMode == ModReg) && (Adr2Mode == ModAbs8)) FormatCode = 6;
909             else if ((AdrMode == ModAbs8) && (Adr2Mode == ModReg)) FormatCode = 5;
910             else FormatCode = 1;
911           }
912           switch (FormatCode)
913           {
914             case 1:
915               if ((AdrMode == ModReg) && (Adr2Mode == ModReg))
916               {
917                 BAsmCode[0] = AdrByte | (OpSize << 3);
918                 BAsmCode[1] = 0x80 | (Adr2Byte & 7);
919                 CodeLen = 2;
920               }
921               else if (AdrMode == ModReg)
922               {
923                 BAsmCode[0] = Adr2Byte | (OpSize << 3);
924                 memcpy(BAsmCode + 1, Adr2Vals, Adr2Cnt);
925                 BAsmCode[1 + Adr2Cnt] = 0x90 | (AdrByte & 7);
926                 CodeLen = 2 + Adr2Cnt;
927               }
928               else if (Adr2Mode == ModReg)
929               {
930                 BAsmCode[0] = AdrByte | (OpSize << 3);
931                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
932                 BAsmCode[1 + AdrCnt] = 0x80 | (Adr2Byte & 7);
933                 CodeLen = 2 + AdrCnt;
934               }
935               else if (AdrMode == ModImm)
936               {
937                 BAsmCode[0] = Adr2Byte | (OpSize << 3);
938                 memcpy(BAsmCode + 1, Adr2Vals, Adr2Cnt);
939                 if (AdaptImmSize(&ArgStr[1]))
940                 {
941                   BAsmCode[1 + Adr2Cnt] = 0x06 + ImmSize;
942                   memcpy(BAsmCode + 1 + Adr2Cnt + 1, AdrVals, AdrCnt);
943                   CodeLen = 1 + Adr2Cnt + 1 + AdrCnt;
944                 }
945               }
946               else WrError(ErrNum_InvAddrMode);
947               break;
948             case 2:
949               if ((AdrMode != ModImm) || (Adr2Mode != ModReg)) WrError(ErrNum_InvAddrMode);
950               else if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
951               else
952               {
953                 BAsmCode[0] = 0x50 | (Adr2Byte & 7);
954                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
955                 CodeLen = 1 + AdrCnt;
956               }
957               break;
958             case 3:
959               if ((AdrMode != ModImm) || (Adr2Mode != ModReg)) WrError(ErrNum_InvAddrMode);
960               else if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
961               else
962               {
963                 BAsmCode[0] = 0x58 | (Adr2Byte & 7);
964                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
965                 CodeLen = 1 + AdrCnt;
966               }
967               break;
968             case 4:
969               if ((AdrMode == ModReg) && (Adr2Byte == 0xe6))
970               {
971                 BAsmCode[0] = 0x90 | (OpSize << 3) | (AdrByte & 7);
972                 memcpy(BAsmCode + 1, Adr2Vals, Adr2Cnt);
973                 CodeLen =1 + Adr2Cnt;
974               }
975               else if ((Adr2Mode == ModReg) && (AdrByte == 0xe6))
976               {
977                 BAsmCode[0] = 0x80 | (OpSize << 3) | (Adr2Byte & 7);
978                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
979                 CodeLen = 1 + AdrCnt;
980               }
981               else WrError(ErrNum_InvAddrMode);
982               break;
983             case 5:
984               if ((AdrMode != ModAbs8) || (Adr2Mode != ModReg)) WrError(ErrNum_InvAddrMode);
985               else
986               {
987                 BAsmCode[0] = 0x60 | (OpSize << 3) | (Adr2Byte & 7);
988                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
989                 CodeLen = 1 + AdrCnt;
990               }
991               break;
992             case 6:
993               if ((Adr2Mode != ModAbs8) || (AdrMode != ModReg)) WrError(ErrNum_InvAddrMode);
994               else
995               {
996                 BAsmCode[0] = 0x70 | (OpSize << 3) | (AdrByte & 7);
997                 memcpy(BAsmCode + 1, Adr2Vals, Adr2Cnt);
998                 CodeLen = 1 + Adr2Cnt;
999               }
1000               break;
1001           }
1002         }
1003       }
1004     }
1005   }
1006 }
1007 
DecodeLDC_STC(Word IsSTC_16)1008 static void DecodeLDC_STC(Word IsSTC_16)
1009 {
1010   Byte HReg;
1011   int CRegIdx = 2, AdrIdx = 1;
1012 
1013   if (!ChkArgCnt(2, 2));
1014   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
1015   else
1016   {
1017     if (IsSTC_16)
1018     {
1019       CRegIdx = 1;
1020       AdrIdx = 2;
1021     }
1022     if (!DecodeCReg(ArgStr[CRegIdx].Str, &HReg)) WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]);
1023     else
1024     {
1025       DecodeAdr(&ArgStr[AdrIdx], IsSTC_16 ? MModNoImm : MModAll);
1026       if (AdrMode != ModNone)
1027       {
1028         BAsmCode[0] = AdrByte | (OpSize << 3);
1029         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1030         BAsmCode[1 + AdrCnt] = 0x88 | IsSTC_16 | HReg;
1031         CodeLen = 2 + AdrCnt;
1032       }
1033     }
1034   }
1035 }
1036 
DecodeLDM(Word Dummy)1037 static void DecodeLDM(Word Dummy)
1038 {
1039   UNUSED(Dummy);
1040 
1041   if (OpSize == eSymbolSizeUnknown) OpSize = eSymbolSize16Bit;
1042   if (!ChkArgCnt(2, 2));
1043   else if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
1044   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
1045   else if (!DecodeRegList(&ArgStr[2], BAsmCode + 1)) WrError(ErrNum_InvRegList);
1046   else
1047   {
1048     DecodeAdr(&ArgStr[1], MModPostInc);
1049     if (AdrMode != ModNone)
1050     {
1051       if ((AdrByte & 7) != 7) WrError(ErrNum_InvAddrMode);
1052       else
1053       {
1054         BAsmCode[0] = 0x02; CodeLen = 2;
1055       }
1056     }
1057   }
1058 }
1059 
DecodeSTM(Word Dummy)1060 static void DecodeSTM(Word Dummy)
1061 {
1062   UNUSED(Dummy);
1063 
1064   if (OpSize == eSymbolSizeUnknown) OpSize = eSymbolSize16Bit;
1065   if (!ChkArgCnt(2, 2));
1066   else if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
1067   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
1068   else if (!DecodeRegList(&ArgStr[1], BAsmCode + 1)) WrError(ErrNum_InvRegList);
1069   else
1070   {
1071     DecodeAdr(&ArgStr[2], MModPredec);
1072     if (AdrMode != ModNone)
1073     {
1074       if ((AdrByte & 7) != 7) WrError(ErrNum_InvAddrMode);
1075       else
1076       {
1077         BAsmCode[0] = 0x12; CodeLen = 2;
1078       }
1079     }
1080   }
1081 }
1082 
DecodeMOVTPE_MOVFPE(Word IsMOVTPE_16)1083 static void DecodeMOVTPE_MOVFPE(Word IsMOVTPE_16)
1084 {
1085   Byte HReg;
1086   int RegIdx = 2, AdrIdx = 1;
1087 
1088   if (ChkArgCnt(2, 2)
1089    && CheckFormat("G"))
1090   {
1091     if (IsMOVTPE_16)
1092     {
1093       RegIdx = 1;
1094       AdrIdx = 2;
1095     }
1096     if (OpSize == eSymbolSizeUnknown) SetOpSize(eSymbolSize8Bit);
1097     if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
1098     else if (DecodeReg(&ArgStr[RegIdx], &HReg, True))
1099     {
1100       DecodeAdr(&ArgStr[AdrIdx], MModNoImm & (~MModReg));
1101       if (AdrMode != ModNone)
1102       {
1103         BAsmCode[0] = AdrByte | (OpSize << 3);
1104         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1105         BAsmCode[1 + AdrCnt] = 0;
1106         BAsmCode[2 + AdrCnt] = 0x80 | HReg | IsMOVTPE_16;
1107         CodeLen =3 + AdrCnt;
1108       }
1109     }
1110   }
1111 }
1112 
DecodeADD_SUB(Word IsSUB_16)1113 static void DecodeADD_SUB(Word IsSUB_16)
1114 {
1115   LongInt AdrLong;
1116 
1117   if (ChkArgCnt(2, 2)
1118    && CheckFormat("GQ"))
1119   {
1120     if (OpSize == eSymbolSizeUnknown) SetOpSize(eSymbolSize16Bit);
1121     if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
1122     else
1123     {
1124       DecodeAdr(&ArgStr[2], MModNoImm);
1125       if (AdrMode != ModNone)
1126       {
1127         CopyAdr();
1128         DecodeAdr(&ArgStr[1], MModAll);
1129         if (AdrMode != ModNone)
1130         {
1131           AdrLong = ImmVal();
1132           if (FormatCode == 0)
1133           {
1134             if ((AdrMode == ModImm) && (abs(AdrLong) >= 1) && (abs(AdrLong) <= 2)) FormatCode = 2;
1135             else FormatCode = 1;
1136           }
1137           switch (FormatCode)
1138           {
1139             case 1:
1140               if (Adr2Mode != ModReg) WrError(ErrNum_InvAddrMode);
1141               else
1142               {
1143                 BAsmCode[0] = AdrByte | (OpSize << 3);
1144                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1145                 BAsmCode[1 + AdrCnt] = 0x20 | IsSUB_16 | (Adr2Byte & 7);
1146                 CodeLen = 2 + AdrCnt;
1147               }
1148               break;
1149             case 2:
1150               if (ChkRange(AdrLong, -2, 2))
1151               {
1152                 if (AdrLong == 0) WrError(ErrNum_UnderRange);
1153                 else
1154                 {
1155                   if (IsSUB_16) AdrLong = (-AdrLong);
1156                   BAsmCode[0] = Adr2Byte | (OpSize << 3);
1157                   memcpy(BAsmCode + 1, Adr2Vals, Adr2Cnt);
1158                   BAsmCode[1 + Adr2Cnt] = 0x08 | (abs(AdrLong) - 1);
1159                   if (AdrLong < 0) BAsmCode[1 + Adr2Cnt] |= 4;
1160                   CodeLen = 2 + Adr2Cnt;
1161                 }
1162               }
1163               break;
1164           }
1165         }
1166       }
1167     }
1168   }
1169 }
1170 
1171 /* NOTE: though the length of immediate data im G format is explicitly
1172    coded and independent of the operand size, the manual seems to suggest
1173    that it is not allowed for CMP to use an 8-bit immediate value with a
1174    16-bit operand, assuming the immediate value will be sign-extended.
1175    This mechanism is described e.g. for MOV:G, but not for CMP:G.  So
1176    we omit this optimization here: */
1177 
1178 #define CMP_IMMVARIABLE 0
1179 
DecodeCMP(Word Dummy)1180 static void DecodeCMP(Word Dummy)
1181 {
1182   UNUSED(Dummy);
1183 
1184   if (ChkArgCnt(2, 2)
1185    && CheckFormat("GEI"))
1186   {
1187     if (OpSize == eSymbolSizeUnknown)
1188       SetOpSize((FormatCode == 2) ? eSymbolSize8Bit : eSymbolSize16Bit);
1189     if ((OpSize != 0) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
1190     else
1191     {
1192       DecodeAdr(&ArgStr[2], MModNoImm);
1193       if (AdrMode != ModNone)
1194       {
1195         CopyAdr();
1196 
1197 
1198         DecodeAdr(&ArgStr[1], MModAll
1199 #if CMP_IMMVARIABLE
1200                             | MModImmVariable
1201 #endif
1202                  );
1203         if (AdrMode != ModNone)
1204         {
1205           if (FormatCode == 0)
1206           {
1207             if ((AdrMode == ModImm) && ((ImmSize == OpSize) || (ImmSize == eSymbolSizeUnknown)) && (Adr2Mode == ModReg)) FormatCode = 2 + OpSize;
1208             else FormatCode = 1;
1209           }
1210           switch (FormatCode)
1211           {
1212             case 1:
1213               if (Adr2Mode == ModReg)
1214               {
1215                 BAsmCode[0] = AdrByte | (OpSize << 3);
1216                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1217                 BAsmCode[1 + AdrCnt] = 0x70 | (Adr2Byte & 7);
1218                 CodeLen = 2 + AdrCnt;
1219               }
1220               else if (AdrMode == ModImm)
1221               {
1222 #if CMP_IMMVARIABLE
1223                 if (AdaptImmSize(&ArgStr[1]))
1224 #endif
1225                 {
1226                   BAsmCode[0] = Adr2Byte | (OpSize << 3);
1227                   memcpy(BAsmCode + 1, Adr2Vals, Adr2Cnt);
1228                   BAsmCode[1 + Adr2Cnt] = 0x04 | ImmSize;
1229                   memcpy(BAsmCode + 2 + Adr2Cnt, AdrVals, AdrCnt);
1230                   CodeLen = 2 + AdrCnt + Adr2Cnt;
1231                 }
1232               }
1233               else WrError(ErrNum_InvAddrMode);
1234               break;
1235             case 2:
1236               if ((AdrMode != ModImm) || (Adr2Mode != ModReg)) WrError(ErrNum_InvAddrMode);
1237               else if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
1238               else
1239               {
1240                 BAsmCode[0] = 0x40 | (Adr2Byte & 7);
1241                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1242                 CodeLen = 1 + AdrCnt;
1243               }
1244               break;
1245              case 3:
1246                if ((AdrMode != ModImm) || (Adr2Mode != ModReg)) WrError(ErrNum_InvAddrMode);
1247                else if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
1248                else
1249                {
1250                  BAsmCode[0] = 0x48 + (Adr2Byte & 7);
1251                  memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1252                  CodeLen = 1 + AdrCnt;
1253                }
1254                break;
1255           }
1256         }
1257       }
1258     }
1259   }
1260 }
1261 
DecodeRegEA(Word Index)1262 static void DecodeRegEA(Word Index)
1263 {
1264   Byte HReg;
1265   OneOrder *pOrder = RegEAOrders + Index;
1266 
1267   if (ChkArgCnt(2, 2)
1268    && CheckFormat("G"))
1269   {
1270     if (OpSize == eSymbolSizeUnknown) SetOpSize(pOrder->DefSize);
1271     if (!((1 << OpSize) & pOrder->SizeMask)) WrError(ErrNum_InvOpSize);
1272     else if (DecodeReg(&ArgStr[2], &HReg, True))
1273     {
1274       DecodeAdr(&ArgStr[1], MModAll);
1275       if (AdrMode != ModNone)
1276       {
1277         BAsmCode[0] = AdrByte | (OpSize << 3);
1278         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1279         BAsmCode[1 + AdrCnt] = pOrder->Code | HReg;
1280         CodeLen = 2 + AdrCnt;
1281       }
1282     }
1283   }
1284 }
1285 
DecodeTwoReg(Word Index)1286 static void DecodeTwoReg(Word Index)
1287 {
1288   Byte HReg;
1289   OneOrder *pOrder = TwoRegOrders + Index;
1290 
1291   if (!ChkArgCnt(2, 2));
1292   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
1293   else if (DecodeReg(&ArgStr[1], &HReg, True)
1294        &&  DecodeReg(&ArgStr[2], &AdrByte, True))
1295   {
1296     if (OpSize == eSymbolSizeUnknown) SetOpSize(pOrder->DefSize);
1297     if (!((1 << OpSize) & pOrder->SizeMask)) WrError(ErrNum_InvOpSize);
1298     else
1299     {
1300       BAsmCode[0] = 0xa0 | HReg | (OpSize << 3);
1301       if (Hi(pOrder->Code))
1302       {
1303         BAsmCode[1] = Lo(pOrder->Code);
1304         BAsmCode[2] = Hi(pOrder->Code) | AdrByte;
1305         CodeLen = 3;
1306       }
1307       else
1308       {
1309         BAsmCode[1] = pOrder->Code | AdrByte;
1310         CodeLen = 2;
1311       }
1312     }
1313   }
1314 }
1315 
DecodeLog(Word Code)1316 static void DecodeLog(Word Code)
1317 {
1318   Byte HReg;
1319 
1320   if (!ChkArgCnt(2, 2));
1321   else if (!DecodeCReg(ArgStr[2].Str, &HReg)) WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]);
1322   else
1323   {
1324     DecodeAdr(&ArgStr[1], MModImm);
1325     if (AdrMode != ModNone)
1326     {
1327       BAsmCode[0] = AdrByte | (OpSize << 3);
1328       memcpy(BAsmCode + 1,AdrVals, AdrCnt);
1329       BAsmCode[1 + AdrCnt] = Code | HReg;
1330       CodeLen = 2 + AdrCnt;
1331     }
1332   }
1333 }
1334 
DecodeOne(Word Index)1335 static void DecodeOne(Word Index)
1336 {
1337   OneOrder *pOrder = OneOrders + Index;
1338 
1339   if (!ChkArgCnt(1, 1));
1340   else if (CheckFormat("G"))
1341   {
1342     if (OpSize == eSymbolSizeUnknown) SetOpSize(pOrder->DefSize);
1343     if (!((1 << OpSize) & pOrder->SizeMask)) WrError(ErrNum_InvOpSize);
1344     else
1345     {
1346       DecodeAdr(&ArgStr[1], MModNoImm);
1347       if (AdrMode != ModNone)
1348       {
1349         BAsmCode[0] = AdrByte | (OpSize << 3);
1350         memcpy(BAsmCode+1, AdrVals, AdrCnt);
1351         BAsmCode[1 + AdrCnt] = pOrder->Code;
1352         CodeLen = 2 + AdrCnt;
1353       }
1354     }
1355   }
1356 }
1357 
DecodeOneReg(Word Index)1358 static void DecodeOneReg(Word Index)
1359 {
1360   Byte HReg;
1361   OneOrder *pOrder = OneRegOrders + Index;
1362 
1363   if (!ChkArgCnt(1, 1));
1364   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
1365   else if (DecodeReg(&ArgStr[1], &HReg, True))
1366   {
1367     if (OpSize == -1) SetOpSize(pOrder->DefSize);
1368     if (!((1 << OpSize) & pOrder->SizeMask)) WrError(ErrNum_InvOpSize);
1369     else
1370     {
1371       BAsmCode[0] = 0xa0 | HReg | (OpSize << 3);
1372       BAsmCode[1] = pOrder->Code;
1373       CodeLen = 2;
1374     }
1375   }
1376 }
1377 
DecodeBit(Word Code)1378 static void DecodeBit(Word Code)
1379 {
1380   Boolean OK;
1381   Byte BitPos;
1382 
1383   switch (ArgCnt)
1384   {
1385     case 1:
1386     {
1387       LongWord BitSpec;
1388 
1389       if (DecodeBitArg(&BitSpec, 1, 1))
1390       {
1391         LongWord Addr;
1392         tSymbolSize ThisOpSize, ThisAddrSize;
1393 
1394         DissectBitSymbol(BitSpec, &Addr, &BitPos, &ThisOpSize, &ThisAddrSize);
1395         if (OpSize == eSymbolSizeUnknown)
1396           OpSize = ThisOpSize;
1397         else if (OpSize != ThisOpSize)
1398         {
1399           WrStrErrorPos(ErrNum_ConfOpSizes, &ArgStr[1]);
1400           return;
1401         }
1402         if (OpSize == eSymbolSizeUnknown)
1403           OpSize = eSymbolSize8Bit;
1404         BitPos |= 0x80;
1405         DecideAbsolute(Addr, ThisAddrSize, False, MModAbs8 | MModAbs16);
1406         if (AdrMode != ModNone)
1407           goto common;
1408       }
1409       break;
1410     }
1411     case 2:
1412     {
1413       DecodeAdr(&ArgStr[2], MModNoImm);
1414       if (AdrMode != ModNone)
1415       {
1416         if (OpSize == eSymbolSizeUnknown)
1417           OpSize = (AdrMode == ModReg) ? eSymbolSize16Bit : eSymbolSize8Bit;
1418         if ((OpSize != 0) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
1419         else
1420         {
1421           switch (DecodeReg(&ArgStr[1], &BitPos, False))
1422           {
1423             case eIsReg:
1424               OK = True; BitPos += 8;
1425               break;
1426             case eIsNoReg:
1427               BitPos = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].Str == '#'), (OpSize == eSymbolSize8Bit) ? UInt3 : UInt4, &OK);
1428               if (OK) BitPos |= 0x80;
1429               break;
1430             default:
1431               OK = False;
1432           }
1433           if (OK)
1434             goto common;
1435         }
1436       }
1437       break;
1438     }
1439     common:
1440       BAsmCode[0] = AdrByte | (OpSize << 3);
1441       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1442       BAsmCode[1 + AdrCnt] = Code | BitPos;
1443       CodeLen = 2 + AdrCnt;
1444       break;
1445     default:
1446       (void)ChkArgCnt(1, 2);
1447   }
1448 }
1449 
DecodeRel(Word Code)1450 static void DecodeRel(Word Code)
1451 {
1452   Boolean OK;
1453   tSymbolFlags Flags;
1454   LongInt AdrLong;
1455 
1456   if (ChkArgCnt(1, 1)
1457    && FormatToBranchSize(Format, &OpSize))
1458   {
1459     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags);
1460     if (OK)
1461     {
1462       if (!ChkSamePage(AdrLong, EProgCounter(), 16, Flags));
1463       else if ((EProgCounter() & 0xffff) >= 0xfffc) WrError(ErrNum_NotFromThisAddress);
1464       else
1465       {
1466         AdrLong -= EProgCounter() + 2;
1467         if (AdrLong > 0x7fff) AdrLong -= 0x10000;
1468         else if (AdrLong < -0x8000l) AdrLong += 0x10000;
1469         if (OpSize == eSymbolSizeUnknown)
1470         {
1471           if ((AdrLong <= 127) && (AdrLong >= -128)) OpSize = eSymbolSizeFloat32Bit;
1472           else OpSize = eSymbolSize32Bit;
1473         }
1474         switch (OpSize)
1475         {
1476           case eSymbolSize32Bit:
1477             AdrLong--;
1478             BAsmCode[0] = Code | 0x10;
1479             BAsmCode[1] = (AdrLong >> 8) & 0xff;
1480             BAsmCode[2] = AdrLong & 0xff;
1481             CodeLen = 3;
1482             break;
1483           case eSymbolSizeFloat32Bit:
1484             if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
1485             else
1486             {
1487               BAsmCode[0] = Code;
1488               BAsmCode[1] = AdrLong & 0xff;
1489               CodeLen = 2;
1490             }
1491             break;
1492           default:
1493            WrError(ErrNum_InvOpSize);
1494         }
1495       }
1496     }
1497   }
1498 }
1499 
DecodeJMP_JSR(Word IsJSR_8)1500 static void DecodeJMP_JSR(Word IsJSR_8)
1501 {
1502   if (ChkArgCnt(1, 1)
1503    && CheckFormat("G"))
1504   {
1505     AbsBank = EProgCounter() >> 16;
1506     DecodeAdr(&ArgStr[1], MModIReg | MModReg | MModDisp8 | MModDisp16 | MModAbs16);
1507     switch (AdrMode)
1508     {
1509       case ModReg:
1510       case ModIReg:
1511         BAsmCode[0] = 0x11; BAsmCode[1] = 0xd0 | IsJSR_8 | (AdrByte & 7);
1512         CodeLen = 2;
1513         break;
1514       case ModDisp8:
1515       case ModDisp16:
1516         BAsmCode[0] = 0x11; BAsmCode[1] = AdrByte | IsJSR_8;
1517         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1518         CodeLen = 2 + AdrCnt;
1519         break;
1520       case ModAbs16:
1521         BAsmCode[0] = 0x10 | IsJSR_8; memcpy(BAsmCode + 1, AdrVals, AdrCnt);
1522         CodeLen = 1 + AdrCnt;
1523         break;
1524     }
1525   }
1526 }
1527 
DecodePJMP_PJSR(Word IsPJMP)1528 static void DecodePJMP_PJSR(Word IsPJMP)
1529 {
1530   if (!ChkArgCnt(1, 1));
1531   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1532   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
1533   else if (!Maximum) WrError(ErrNum_OnlyInMaxmode);
1534   else
1535   {
1536     tStrComp *pArg = &ArgStr[1], Arg;
1537     unsigned ArgOffs = !!(*pArg->Str == '@');
1538     Byte HReg;
1539 
1540     StrCompRefRight(&Arg, pArg, ArgOffs);
1541     switch (DecodeReg(&Arg, &HReg, False))
1542     {
1543       case eIsReg:
1544         BAsmCode[0] = 0x11; BAsmCode[1] = 0xc0 | ((1 - IsPJMP) << 3) | HReg;
1545         CodeLen = 2;
1546         break;
1547       case eIsNoReg:
1548       {
1549         Boolean OK;
1550         LongInt AdrLong = EvalStrIntExpressionOffs(pArg, ArgOffs, UInt24, &OK);
1551 
1552         if (OK)
1553         {
1554           BAsmCode[0] = 0x03 | (IsPJMP << 4);
1555           BAsmCode[1] = (AdrLong >> 16) & 0xff;
1556           BAsmCode[2] = (AdrLong >> 8) & 0xff;
1557           BAsmCode[3] = AdrLong & 0xff;
1558           CodeLen = 4;
1559         }
1560         break;
1561       }
1562       default:
1563         break;
1564     }
1565   }
1566 }
1567 
DecodeSCB(Word Code)1568 static void DecodeSCB(Word Code)
1569 {
1570   Byte HReg;
1571   LongInt AdrLong;
1572   Boolean OK;
1573   tSymbolFlags Flags;
1574 
1575   if (!ChkArgCnt(2, 2));
1576   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1577   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
1578   else if (DecodeReg(&ArgStr[1], &HReg, True))
1579   {
1580     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt24, &OK, &Flags);
1581     if (OK)
1582     {
1583       if (!ChkSamePage(AdrLong, EProgCounter(), 16, Flags));
1584       else if ((EProgCounter() & 0xffff) >= 0xfffc) WrError(ErrNum_NotFromThisAddress);
1585       else
1586       {
1587         AdrLong -= EProgCounter() + 3;
1588         if (!mSymbolQuestionable(Flags) && ((AdrLong > 127) || (AdrLong < -128))) WrError(ErrNum_JmpDistTooBig);
1589         else
1590         {
1591           BAsmCode[0] = Code;
1592           BAsmCode[1] = 0xb8 | HReg;
1593           BAsmCode[2] = AdrLong & 0xff;
1594           CodeLen = 3;
1595         }
1596       }
1597     }
1598   }
1599 }
1600 
DecodePRTD_RTD(Word IsPRTD)1601 static void DecodePRTD_RTD(Word IsPRTD)
1602 {
1603   tSymbolSize HSize;
1604   Integer AdrInt;
1605 
1606   if (!ChkArgCnt(1, 1));
1607   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
1608   else if (*ArgStr[1].Str != '#') WrError(ErrNum_OnlyImmAddr);
1609   else
1610   {
1611     tStrComp Arg;
1612     Boolean OK;
1613     tSymbolFlags Flags;
1614 
1615     StrCompRefRight(&Arg, &ArgStr[1], 1);
1616     HSize = eSymbolSizeUnknown; SplitDisp(&Arg, &HSize);
1617     if (HSize != eSymbolSizeUnknown) SetOpSize(HSize);
1618     AdrInt = EvalStrIntExpressionWithFlags(&Arg, SInt16, &OK, &Flags);
1619     if (mFirstPassUnknown(Flags)) AdrInt &= 127;
1620     if (OK)
1621     {
1622       if (OpSize == eSymbolSizeUnknown)
1623       {
1624         if ((AdrInt < 127) && (AdrInt > -128)) OpSize = eSymbolSize8Bit;
1625         else OpSize = eSymbolSize16Bit;
1626       }
1627       if (IsPRTD) BAsmCode[0] = 0x11;
1628       switch (OpSize)
1629       {
1630         case eSymbolSize8Bit:
1631           if (ChkRange(AdrInt, -128, 127))
1632           {
1633             BAsmCode[IsPRTD] = 0x14;
1634             BAsmCode[1 + IsPRTD] = AdrInt & 0xff;
1635             CodeLen = 2 + IsPRTD;
1636           }
1637           break;
1638         case eSymbolSize16Bit:
1639           BAsmCode[IsPRTD] = 0x1c;
1640           BAsmCode[1 + IsPRTD] = (AdrInt >> 8) & 0xff;
1641           BAsmCode[2 + IsPRTD] = AdrInt & 0xff;
1642           CodeLen = 3 + IsPRTD;
1643           break;
1644         default:
1645           WrError(ErrNum_InvOpSize);
1646       }
1647     }
1648   }
1649 }
1650 
DecodeLINK(Word Dummy)1651 static void DecodeLINK(Word Dummy)
1652 {
1653   UNUSED(Dummy);
1654 
1655   if (!ChkArgCnt(2, 2));
1656   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
1657   else
1658   {
1659     DecodeAdr(&ArgStr[1], MModReg);
1660     if (AdrMode != ModNone)
1661     {
1662       if ((AdrByte & 7) != 6) WrError(ErrNum_InvAddrMode);
1663       else if (*ArgStr[2].Str != '#') WrError(ErrNum_OnlyImmAddr);
1664       else
1665       {
1666         tStrComp Arg;
1667         tSymbolSize HSize;
1668         Integer AdrInt;
1669         Boolean OK;
1670         tSymbolFlags Flags;
1671 
1672         StrCompRefRight(&Arg, &ArgStr[2], 1);
1673         HSize = eSymbolSizeUnknown; SplitDisp(&Arg, &HSize);
1674         if (HSize != eSymbolSizeUnknown) SetOpSize(HSize);
1675         AdrInt = EvalStrIntExpressionWithFlags(&Arg, SInt16, &OK, &Flags);
1676         if (mFirstPassUnknown(Flags)) AdrInt &= 127;
1677         if (OK)
1678         {
1679           if (OpSize == eSymbolSizeUnknown)
1680           {
1681             if ((AdrInt < 127) && (AdrInt > -128)) OpSize = eSymbolSize8Bit;
1682             else OpSize = eSymbolSize16Bit;
1683           }
1684           switch (OpSize)
1685           {
1686             case eSymbolSize8Bit:
1687               if (ChkRange(AdrInt, -128, 127))
1688               {
1689                 BAsmCode[0] = 0x17;
1690                 BAsmCode[1] = AdrInt & 0xff;
1691                 CodeLen = 2;
1692               }
1693               break;
1694             case eSymbolSize16Bit:
1695               BAsmCode[0] = 0x1f;
1696               BAsmCode[1] = (AdrInt >> 8) & 0xff;
1697               BAsmCode[2] = AdrInt & 0xff;
1698               CodeLen = 3;
1699               break;
1700             default:
1701               WrError(ErrNum_InvOpSize);
1702           }
1703         }
1704       }
1705     }
1706   }
1707 }
1708 
DecodeUNLK(Word Dummy)1709 static void DecodeUNLK(Word Dummy)
1710 {
1711   UNUSED(Dummy);
1712 
1713   if (!ChkArgCnt(1, 1));
1714   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1715   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
1716   else
1717   {
1718     DecodeAdr(&ArgStr[1], MModReg);
1719     if (AdrMode != ModNone)
1720     {
1721       if ((AdrByte & 7) != 6) WrError(ErrNum_InvAddrMode);
1722       else
1723       {
1724         BAsmCode[0] = 0x0f; CodeLen = 1;
1725       }
1726     }
1727   }
1728 }
1729 
DecodeTRAPA(Word Dummy)1730 static void DecodeTRAPA(Word Dummy)
1731 {
1732   UNUSED(Dummy);
1733 
1734   if (!ChkArgCnt(1, 1));
1735   else if (*AttrPart.Str) WrError(ErrNum_UseLessAttr);
1736   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
1737   else if (*ArgStr[1].Str != '#') WrError(ErrNum_OnlyImmAddr);
1738   else
1739   {
1740     Boolean OK;
1741 
1742     BAsmCode[1] = 0x10 | EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt4, &OK);
1743     if (OK)
1744     {
1745       BAsmCode[0] = 0x08; CodeLen = 2;
1746     }
1747   }
1748 }
1749 
DecodeDATA(Word Dummy)1750 static void DecodeDATA(Word Dummy)
1751 {
1752   UNUSED(Dummy);
1753 
1754   DecodeMotoDC(OpSize, True);
1755 }
1756 
DecodeBIT(Word Code)1757 static void DecodeBIT(Word Code)
1758 {
1759   UNUSED(Code);
1760 
1761   /* if in structure definition, add special element to structure */
1762 
1763   if (OpSize > eSymbolSize16Bit)
1764   {
1765     WrError(ErrNum_InvOpSize);
1766     return;
1767   }
1768   if (ActPC == StructSeg)
1769   {
1770     Boolean OK;
1771     Byte BitPos;
1772     PStructElem pElement;
1773 
1774     if (!ChkArgCnt(2, 2))
1775       return;
1776     BitPos = EvalBitPosition(&ArgStr[1], OpSize, &OK);
1777     if (!OK)
1778       return;
1779     pElement = CreateStructElem(LabPart.Str);
1780     pElement->pRefElemName = as_strdup(ArgStr[2].Str);
1781     pElement->OpSize = OpSize;
1782     pElement->BitPos = BitPos;
1783     pElement->ExpandFnc = ExpandBit_H8_5;
1784     AddStructElem(pInnermostNamedStruct->StructRec, pElement);
1785   }
1786   else
1787   {
1788     LongWord BitSpec;
1789 
1790     if (DecodeBitArg(&BitSpec, 1, ArgCnt))
1791     {
1792       *ListLine = '=';
1793       DissectBit_H8_5(ListLine + 1, STRINGSIZE - 3, BitSpec);
1794       PushLocHandle(-1);
1795       EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
1796       PopLocHandle();
1797       /* TODO: MakeUseList? */
1798     }
1799   }
1800 }
1801 
1802 /*-------------------------------------------------------------------------*/
1803 /* dynamische Belegung/Freigabe Codetabellen */
1804 
AddFixed(const char * NName,Word NCode)1805 static void AddFixed(const char *NName, Word NCode)
1806 {
1807   AddInstTable(InstTable, NName, NCode, DecodeFixed);
1808 }
1809 
AddRel(const char * NName,Word NCode)1810 static void AddRel(const char *NName, Word NCode)
1811 {
1812   AddInstTable(InstTable, NName, NCode, DecodeRel);
1813 }
1814 
AddOne(const char * NName,Word NCode,Byte NMask,tSymbolSize NDef)1815 static void AddOne(const char *NName, Word NCode, Byte NMask, tSymbolSize NDef)
1816 {
1817   if (InstrZ>=OneOrderCount) exit(255);
1818   OneOrders[InstrZ].Code = NCode;
1819   OneOrders[InstrZ].SizeMask = NMask;
1820   OneOrders[InstrZ].DefSize = NDef;
1821   AddInstTable(InstTable, NName, InstrZ++, DecodeOne);
1822 }
1823 
AddOneReg(const char * NName,Word NCode,Byte NMask,tSymbolSize NDef)1824 static void AddOneReg(const char *NName, Word NCode, Byte NMask, tSymbolSize NDef)
1825 {
1826   if (InstrZ>=OneRegOrderCount) exit(255);
1827   OneRegOrders[InstrZ].Code=NCode;
1828   OneRegOrders[InstrZ].SizeMask = NMask;
1829   OneRegOrders[InstrZ].DefSize = NDef;
1830   AddInstTable(InstTable, NName, InstrZ++, DecodeOneReg);
1831 }
1832 
AddRegEA(const char * NName,Word NCode,Byte NMask,tSymbolSize NDef)1833 static void AddRegEA(const char *NName, Word NCode, Byte NMask, tSymbolSize NDef)
1834 {
1835   if (InstrZ >= RegEAOrderCount) exit(255);
1836   RegEAOrders[InstrZ].Code = NCode;
1837   RegEAOrders[InstrZ].SizeMask = NMask;
1838   RegEAOrders[InstrZ].DefSize = NDef;
1839   AddInstTable(InstTable, NName, InstrZ++, DecodeRegEA);
1840 }
1841 
AddTwoReg(const char * NName,Word NCode,Byte NMask,tSymbolSize NDef)1842 static void AddTwoReg(const char *NName, Word NCode, Byte NMask, tSymbolSize NDef)
1843 {
1844   if (InstrZ >= TwoRegOrderCount) exit(255);
1845   TwoRegOrders[InstrZ].Code = NCode;
1846   TwoRegOrders[InstrZ].SizeMask = NMask;
1847   TwoRegOrders[InstrZ].DefSize = NDef;
1848   AddInstTable(InstTable, NName, InstrZ++, DecodeTwoReg);
1849 }
1850 
AddLog(const char * NName,Word NCode)1851 static void AddLog(const char *NName, Word NCode)
1852 {
1853   AddInstTable(InstTable, NName, NCode, DecodeLog);
1854 }
1855 
AddBit(const char * NName,Word NCode)1856 static void AddBit(const char *NName, Word NCode)
1857 {
1858   AddInstTable(InstTable, NName, NCode, DecodeBit);
1859 }
1860 
InitFields(void)1861 static void InitFields(void)
1862 {
1863   Format = (char*)malloc(sizeof(char) * STRINGSIZE);
1864 
1865   InstTable = CreateInstTable(302);
1866 
1867   AddFixed("NOP"  , 0x0000); AddFixed("PRTS"   , 0x1119);
1868   AddFixed("RTE"  , 0x000a); AddFixed("RTS"    , 0x0019);
1869   AddFixed("SLEEP", 0x001a); AddFixed("TRAP/VS", 0x0009);
1870 
1871   AddInstTable(InstTable, "MOV"   , 0   , DecodeMOV);
1872   AddInstTable(InstTable, "LDC"   , 0   , DecodeLDC_STC);
1873   AddInstTable(InstTable, "STC"   , 16  , DecodeLDC_STC);
1874   AddInstTable(InstTable, "LDM"   , 0   , DecodeLDM);
1875   AddInstTable(InstTable, "STM"   , 0   , DecodeSTM);
1876   AddInstTable(InstTable, "MOVTPE", 16  , DecodeMOVTPE_MOVFPE);
1877   AddInstTable(InstTable, "MOVFPE", 0   , DecodeMOVTPE_MOVFPE);
1878   AddInstTable(InstTable, "ADD"   , 0   , DecodeADD_SUB);
1879   AddInstTable(InstTable, "SUB"   , 16  , DecodeADD_SUB);
1880   AddInstTable(InstTable, "CMP"   , 0   , DecodeCMP);
1881   AddInstTable(InstTable, "JMP"   , 0   , DecodeJMP_JSR);
1882   AddInstTable(InstTable, "JSR"   , 8   , DecodeJMP_JSR);
1883   AddInstTable(InstTable, "PJMP"  , 1   , DecodePJMP_PJSR);
1884   AddInstTable(InstTable, "PJSR"  , 0   , DecodePJMP_PJSR);
1885   AddInstTable(InstTable, "SCB/F" , 0x01, DecodeSCB);
1886   AddInstTable(InstTable, "SCB/NE", 0x06, DecodeSCB);
1887   AddInstTable(InstTable, "SCB/EQ", 0x07, DecodeSCB);
1888   AddInstTable(InstTable, "RTD"   , 0   , DecodePRTD_RTD);
1889   AddInstTable(InstTable, "PRTD"  , 1   , DecodePRTD_RTD);
1890   AddInstTable(InstTable, "LINK"  , 0   , DecodeLINK);
1891   AddInstTable(InstTable, "UNLK"  , 0   , DecodeUNLK);
1892   AddInstTable(InstTable, "TRAPA" , 0   , DecodeTRAPA);
1893 
1894   AddRel("BRA", 0x20); AddRel("BT" , 0x20); AddRel("BRN", 0x21);
1895   AddRel("BF" , 0x21); AddRel("BHI", 0x22); AddRel("BLS", 0x23);
1896   AddRel("BCC", 0x24); AddRel("BHS", 0x24); AddRel("BCS", 0x25);
1897   AddRel("BLO", 0x25); AddRel("BNE", 0x26); AddRel("BEQ", 0x27);
1898   AddRel("BVC", 0x28); AddRel("BVS", 0x29); AddRel("BPL", 0x2a);
1899   AddRel("BMI", 0x2b); AddRel("BGE", 0x2c); AddRel("BLT", 0x2d);
1900   AddRel("BGT", 0x2e); AddRel("BLE", 0x2f); AddRel("BSR", 0x0e);
1901 
1902   InstrZ = 0; OneOrders = (OneOrder *) malloc(sizeof(OneOrder) * OneOrderCount);
1903   AddOne("CLR"  , 0x13, 3, eSymbolSize16Bit); AddOne("NEG"  , 0x14, 3, eSymbolSize16Bit);
1904   AddOne("NOT"  , 0x15, 3, eSymbolSize16Bit); AddOne("ROTL" , 0x1c, 3, eSymbolSize16Bit);
1905   AddOne("ROTR" , 0x1d, 3, eSymbolSize16Bit); AddOne("ROTXL", 0x1e, 3, eSymbolSize16Bit);
1906   AddOne("ROTXR", 0x1f, 3, eSymbolSize16Bit); AddOne("SHAL" , 0x18, 3, eSymbolSize16Bit);
1907   AddOne("SHAR" , 0x19, 3, eSymbolSize16Bit); AddOne("SHLL" , 0x1a, 3, eSymbolSize16Bit);
1908   AddOne("SHLR" , 0x1b, 3, eSymbolSize16Bit); AddOne("TAS"  , 0x17, 1, eSymbolSize8Bit);
1909   AddOne("TST"  , 0x16, 3, eSymbolSize16Bit);
1910 
1911   InstrZ = 0; OneRegOrders = (OneOrder *) malloc(sizeof(OneOrder) * OneRegOrderCount);
1912   AddOneReg("EXTS", 0x11, 1, eSymbolSize8Bit);
1913   AddOneReg("EXTU", 0x12, 1, eSymbolSize8Bit);
1914   AddOneReg("SWAP", 0x10, 1, eSymbolSize8Bit);
1915 
1916   InstrZ = 0; RegEAOrders = (OneOrder *) malloc(sizeof(OneOrder) * RegEAOrderCount);
1917   AddRegEA("ADDS" , 0x28, 3, eSymbolSize16Bit); AddRegEA("ADDX" , 0xa0, 3, eSymbolSize16Bit);
1918   AddRegEA("AND"  , 0x50, 3, eSymbolSize16Bit); AddRegEA("DIVXU", 0xb8, 3, eSymbolSize16Bit);
1919   AddRegEA("MULXU", 0xa8, 3, eSymbolSize16Bit); AddRegEA("OR"   , 0x40, 3, eSymbolSize16Bit);
1920   AddRegEA("SUBS" , 0x38, 3, eSymbolSize16Bit); AddRegEA("SUBX" , 0xb0, 3, eSymbolSize16Bit);
1921   AddRegEA("XOR"  , 0x60, 3, eSymbolSize16Bit);
1922 
1923   InstrZ = 0; TwoRegOrders = (OneOrder *) malloc(sizeof(OneOrder) * TwoRegOrderCount);
1924   AddTwoReg("DADD", 0xa000, 1, eSymbolSize8Bit);
1925   AddTwoReg("DSUB", 0xb000, 1, eSymbolSize8Bit);
1926   AddTwoReg("XCH" ,   0x90, 2, eSymbolSize16Bit);
1927 
1928   AddLog("ANDC", 0x58); AddLog("ORC", 0x48); AddLog("XORC", 0x68);
1929 
1930   AddBit("BCLR", 0x50); AddBit("BNOT", 0x60);
1931   AddBit("BSET", 0x40); AddBit("BTST", 0x70);
1932 
1933   AddInstTable(InstTable, "REG", 0, CodeREG);
1934   AddInstTable(InstTable, "DATA", 0, DecodeDATA);
1935   AddInstTable(InstTable, "BIT", 0, DecodeBIT);
1936 }
1937 
DeinitFields(void)1938 static void DeinitFields(void)
1939 {
1940   free(Format);
1941   free(OneOrders);
1942   free(OneRegOrders);
1943   free(RegEAOrders);
1944   free(TwoRegOrders);
1945   DestroyInstTable(InstTable);
1946 }
1947 
1948 /*!------------------------------------------------------------------------
1949  * \fn     InternSymbol_H8_5(char *pArg, TempResult *pResult)
1950  * \brief  handle built-in symbols on H8/500
1951  * \param  pArg source argument
1952  * \param  pResult result buffer
1953  * ------------------------------------------------------------------------ */
1954 
InternSymbol_H8_5(char * pArg,TempResult * pResult)1955 static void InternSymbol_H8_5(char *pArg, TempResult *pResult)
1956 {
1957   Byte Erg;
1958 
1959   if (DecodeRegCore(pArg, &Erg))
1960   {
1961     pResult->Typ = TempReg;
1962     pResult->DataSize = eSymbolSize16Bit;
1963     pResult->Contents.RegDescr.Reg = Erg;
1964     pResult->Contents.RegDescr.Dissect = DissectReg_H8_5;
1965   }
1966 }
1967 
DecodeAttrPart_H8_5(void)1968 static Boolean DecodeAttrPart_H8_5(void)
1969 {
1970   char *p;
1971 
1972   /* Formatangabe abspalten */
1973 
1974   switch (AttrSplit)
1975   {
1976     case '.':
1977       p = strchr(AttrPart.Str, ':');
1978       if (p)
1979       {
1980         if (p < AttrPart.Str + strlen(AttrPart.Str) - 1)
1981           strmaxcpy(Format, p + 1, STRINGSIZE - 1);
1982         else
1983           strcpy(Format, " ");
1984         *p = '\0';
1985       }
1986       else
1987         strcpy(Format, " ");
1988       break;
1989     case ':':
1990       p = strchr(AttrPart.Str, '.');
1991       if (!p)
1992       {
1993         strmaxcpy(Format, AttrPart.Str, STRINGSIZE - 1);
1994         *AttrPart.Str = '\0';
1995       }
1996       else
1997       {
1998         *p = '\0';
1999         if (p == AttrPart.Str)
2000           strcpy(Format, " ");
2001         else
2002           strmaxcpy(Format, AttrPart.Str, STRINGSIZE - 1);
2003         strcpy(AttrPart.Str, p + 1);
2004       }
2005       break;
2006     default:
2007       strcpy(Format, " ");
2008   }
2009 
2010   NLS_UpString(Format);
2011 
2012   if (*AttrPart.Str)
2013   {
2014     if (!DecodeMoto16AttrSize(*AttrPart.Str, &AttrPartOpSize, False))
2015       return False;
2016   }
2017   return True;
2018 }
2019 
MakeCode_H8_5(void)2020 static void MakeCode_H8_5(void)
2021 {
2022   CodeLen = 0; DontPrint = False; AbsBank = Reg_DP;
2023 
2024   /* to be ignored */
2025 
2026   if (Memo("")) return;
2027 
2028   OpSize = eSymbolSizeUnknown;
2029   if (*AttrPart.Str)
2030     SetOpSize(AttrPartOpSize);
2031 
2032   if (DecodeMoto16Pseudo(OpSize, True)) return;
2033 
2034   /* Sonderfaelle */
2035 
2036   if (!LookupInstTable(InstTable, OpPart.Str))
2037     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2038 }
2039 
ChkPC_H8_5(LargeWord Addr)2040 static Boolean ChkPC_H8_5(LargeWord Addr)
2041 {
2042   if (ActPC == SegCode)
2043     return (Addr < (Maximum ? 0x1000000u : 0x10000u));
2044   else
2045     return False;
2046 }
2047 
IsDef_H8_5(void)2048 static Boolean IsDef_H8_5(void)
2049 {
2050   return Memo("REG")
2051       || Memo("BIT");
2052 }
2053 
SwitchFrom_H8_5(void)2054 static void SwitchFrom_H8_5(void)
2055 {
2056   DeinitFields(); ClearONOFF();
2057 }
2058 
InitCode_H8_5(void)2059 static void InitCode_H8_5(void)
2060 {
2061   Reg_DP = -1;
2062   Reg_EP = -1;
2063   Reg_TP = -1;
2064   Reg_BR = -1;
2065 }
2066 
SwitchTo_H8_5(void)2067 static void SwitchTo_H8_5(void)
2068 {
2069   TurnWords = True; ConstMode = ConstModeMoto;
2070 
2071   PCSymbol = "*"; HeaderID = 0x69; NOPCode = 0x00;
2072   DivideChars = ","; HasAttrs = True; AttrChars = ".:";
2073 
2074   ValidSegs = 1 << SegCode;
2075   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
2076 
2077   DecodeAttrPart = DecodeAttrPart_H8_5;
2078   MakeCode = MakeCode_H8_5;
2079   ChkPC = ChkPC_H8_5;
2080   IsDef = IsDef_H8_5;
2081   SwitchFrom = SwitchFrom_H8_5;
2082   InternSymbol = InternSymbol_H8_5;
2083   DissectReg = DissectReg_H8_5;
2084   DissectBit = DissectBit_H8_5;
2085   QualifyQuote = QualifyQuote_SingleQuoteConstant;
2086   ConstModeWeirdNoTerm = True;
2087   InitFields();
2088   AddONOFF("MAXMODE", &Maximum, MaximumName, False);
2089   AddMoto16PseudoONOFF();
2090 
2091   pASSUMERecs = ASSUMEH8_5s;
2092   ASSUMERecCnt = ASSUMEH8_5Count;
2093 
2094   SetFlag(&DoPadding, DoPaddingName, False);
2095 }
2096 
codeh8_5_init(void)2097 void codeh8_5_init(void)
2098 {
2099   CPU532 = AddCPU("HD6475328", SwitchTo_H8_5);
2100   CPU534 = AddCPU("HD6475348", SwitchTo_H8_5);
2101   CPU536 = AddCPU("HD6475368", SwitchTo_H8_5);
2102   CPU538 = AddCPU("HD6475388", SwitchTo_H8_5);
2103 
2104   AddInitPassProc(InitCode_H8_5);
2105 }
2106