1 /* code78c10.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS-Portierung                                                             */
6 /*                                                                           */
7 /* Codegenerator NEC uPD78(C)1x                                              */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 #include "stdinc.h"
12 #include <ctype.h>
13 #include <string.h>
14 
15 #include "bpemu.h"
16 #include "strutil.h"
17 #include "asmdef.h"
18 #include "asmsub.h"
19 #include "asmpars.h"
20 #include "asmitree.h"
21 #include "codepseudo.h"
22 #include "intpseudo.h"
23 #include "codevars.h"
24 #include "errmsg.h"
25 
26 #include "code78c10.h"
27 
28 /*---------------------------------------------------------------------------*/
29 
30 typedef struct
31 {
32   const char *Name;
33   Byte Code;
34 } SReg;
35 
36 typedef struct
37 {
38   const char *pName;
39   Byte Code;
40   Byte MayIndirect;
41 } tAdrMode;
42 
43 #define SRegCnt 28
44 
45 
46 static LongInt WorkArea;
47 
48 static CPUVar CPU7810, CPU78C10;
49 
50 static SReg *SRegs;
51 
52 static ASSUMERec ASSUME78C10s[] =
53 {
54   {"V" , &WorkArea, 0, 0xff, 0x100, NULL}
55 };
56 
57 /*--------------------------------------------------------------------------------*/
58 
Decode_r(char * Asc,ShortInt * Erg)59 static Boolean Decode_r(char *Asc, ShortInt *Erg)
60 {
61   static const char Names[] = "VABCDEHL";
62   const char *p;
63 
64   if (strlen(Asc) != 1) return False;
65   p = strchr(Names, as_toupper(*Asc));
66   if (!p) return False;
67   *Erg = p - Names;
68   return True;
69 }
70 
Decode_r1(char * Asc,ShortInt * Erg)71 static Boolean Decode_r1(char *Asc, ShortInt *Erg)
72 {
73   if (!as_strcasecmp(Asc, "EAL")) *Erg = 1;
74   else if (!as_strcasecmp(Asc, "EAH")) *Erg = 0;
75   else
76   {
77     if (!Decode_r(Asc, Erg)) return False;
78     return (*Erg > 1);
79   }
80   return True;
81 }
82 
Decode_r2(char * Asc,ShortInt * Erg)83 static Boolean Decode_r2(char *Asc, ShortInt *Erg)
84 {
85   if (!Decode_r(Asc, Erg)) return False;
86   return ((*Erg > 0) && (*Erg < 4));
87 }
88 
Decode_rp2(char * Asc,ShortInt * Erg)89 static Boolean Decode_rp2(char *Asc, ShortInt *Erg)
90 {
91   static const SReg Regs[] =
92   {
93     { "SP" , 0 },
94     { "B"  , 1 },
95     { "BC" , 1 },
96     { "D"  , 2 },
97     { "DE" , 2 },
98     { "H"  , 3 },
99     { "HL" , 3 },
100     { "EA" , 4 },
101     { NULL , 0 },
102   };
103 
104   for (*Erg = 0; Regs[*Erg].Name; (*Erg)++)
105     if (!as_strcasecmp(Asc, Regs[*Erg].Name))
106     {
107       *Erg = Regs[*Erg].Code;
108       return True;
109     }
110   return False;
111 }
112 
Decode_rp(char * Asc,ShortInt * Erg)113 static Boolean Decode_rp(char *Asc, ShortInt *Erg)
114 {
115   if (!Decode_rp2(Asc, Erg)) return False;
116   return (*Erg < 4);
117 }
118 
Decode_rp1(char * Asc,ShortInt * Erg)119 static Boolean Decode_rp1(char *Asc, ShortInt *Erg)
120 {
121   if (!as_strcasecmp(Asc, "V")) *Erg = 0;
122   else
123   {
124     if (!Decode_rp2(Asc, Erg)) return False;
125     return (*Erg != 0);
126   }
127   return True;
128 }
129 
Decode_rp3(char * Asc,ShortInt * Erg)130 static Boolean Decode_rp3(char *Asc, ShortInt *Erg)
131 {
132   if (!Decode_rp2(Asc, Erg)) return False;
133   return ((*Erg < 4) && (*Erg > 0));
134 }
135 
DecodeAdrMode(char * pAsc,const tAdrMode pModes[],ShortInt * pErg,Boolean * pWasIndirect)136 static Boolean DecodeAdrMode(char *pAsc, const tAdrMode pModes[],
137                              ShortInt *pErg, Boolean *pWasIndirect)
138 {
139   int z;
140 
141   if (!*pWasIndirect && (IsIndirect(pAsc)))
142   {
143     strmov(pAsc, pAsc + 1);
144     pAsc[strlen(pAsc) - 1] = '\0';
145     *pWasIndirect = True;
146   }
147 
148   for (z = 0; pModes[z].pName; z++)
149   {
150     if (*pWasIndirect && !pModes[z].MayIndirect)
151       continue;
152     if (!as_strcasecmp(pAsc, pModes[z].pName))
153     {
154       *pErg = pModes[z].Code;
155       return True;
156     }
157   }
158   return False;
159 }
160 
Decode_rpa2(const tStrComp * pArg,Boolean * pWasIndirect,ShortInt * Erg,ShortInt * Disp)161 static Boolean Decode_rpa2(const tStrComp *pArg, Boolean *pWasIndirect, ShortInt *Erg, ShortInt *Disp)
162 {
163   static const tAdrMode AdrModes[] =
164   {
165     { "B"   ,  1  , True  },
166     { "BC"  ,  1  , True  },
167     { "D"   ,  2  , True  },
168     { "DE"  ,  2  , True  },
169     { "H"   ,  3  , True  },
170     { "HL"  ,  3  , True  },
171     { "D+"  ,  4  , True  },
172     { "DE+" ,  4  , True  },
173     { "(DE)+", 4  , False },
174     { "H+"   , 5  , True  },
175     { "HL+"  , 5  , True  },
176     { "(HL)+", 5  , False },
177     { "D-"   , 6  , True  },
178     { "DE-"  , 6  , True  },
179     { "(DE)-", 6  , False },
180     { "H-"   , 7  , True  },
181     { "HL-"  , 7  , True  },
182     { "(HL)-", 7  , False },
183     { "H+A"  , 12 , True  },
184     { "HL+A" , 12 , True  },
185     { "A+H"  , 12 , True  },
186     { "A+HL" , 12 , True  },
187     { "H+B"  , 13 , True  },
188     { "HL+B" , 13 , True  },
189     { "B+H"  , 13 , True  },
190     { "B+HL" , 13 , True  },
191     { "H+EA" , 14 , True  },
192     { "HL+EA", 14 , True  },
193     { "EA+H" , 14 , True  },
194     { "EA+HL", 14 , True  },
195     { NULL  , 0   , False },
196   };
197 
198   char *p, Save;
199   Boolean OK;
200   ShortInt BaseReg;
201   tStrComp Left, Right;
202 
203   if (DecodeAdrMode(pArg->Str, AdrModes, Erg, pWasIndirect))
204   {
205     *Disp = 0;
206     return True;
207   }
208 
209   p = QuotMultPos(pArg->Str, "+-");
210   if (!p) return False;
211 
212   Save = StrCompSplitRef(&Left, &Right, pArg, p);
213   OK = (Decode_rp2(Left.Str, &BaseReg));
214   *p = Save;
215   if (!OK || ((BaseReg != 2) && (BaseReg != 3)))
216     return False;
217   *Erg = (BaseReg == 3) ? 15 : 11;
218   *Disp = EvalStrIntExpressionOffs(pArg, p - pArg->Str, SInt8, &OK);
219   return OK;
220 }
221 
Decode_rpa(const tStrComp * pArg,ShortInt * Erg)222 static Boolean Decode_rpa(const tStrComp *pArg, ShortInt *Erg)
223 {
224   ShortInt Dummy;
225   Boolean WasIndirect = False;
226 
227   if (!Decode_rpa2(pArg, &WasIndirect, Erg, &Dummy)) return False;
228   return (*Erg <= 7);
229 }
230 
Decode_rpa1(const tStrComp * pArg,ShortInt * Erg)231 static Boolean Decode_rpa1(const tStrComp *pArg, ShortInt *Erg)
232 {
233   ShortInt Dummy;
234   Boolean WasIndirect = False;
235 
236   if (!Decode_rpa2(pArg, &WasIndirect, Erg, &Dummy)) return False;
237   return (*Erg <= 3);
238 }
239 
Decode_rpa3(const tStrComp * pArg,ShortInt * Erg,ShortInt * Disp)240 static Boolean Decode_rpa3(const tStrComp *pArg, ShortInt *Erg, ShortInt *Disp)
241 {
242   static const tAdrMode AdrModes[] =
243   {
244     { "D++"   , 4 , True  },
245     { "DE++"  , 4 , True  },
246     { "(DE)++", 4 , False },
247     { "H++"   , 5 , True  },
248     { "HL++"  , 5 , True  },
249     { "(HL)++", 5 , False },
250     { NULL    , 0 , False },
251   };
252   Boolean WasIndirect = False;
253 
254   if (DecodeAdrMode(pArg->Str, AdrModes, Erg, &WasIndirect))
255   {
256     *Disp = 0;
257     return True;
258   }
259 
260   if (!Decode_rpa2(pArg, &WasIndirect, Erg, Disp))
261     return False;
262   return ((*Erg == 2) || (*Erg == 3) || (*Erg >= 8));
263 }
264 
Decode_f(char * Asc,ShortInt * Erg)265 static Boolean Decode_f(char *Asc, ShortInt *Erg)
266 {
267 #define FlagCnt 3
268   static const char Flags[FlagCnt][3] = {"CY", "HC", "Z"};
269 
270   for (*Erg = 0; *Erg < FlagCnt; (*Erg)++)
271    if (!as_strcasecmp(Flags[*Erg], Asc)) break;
272   *Erg += 2; return (*Erg <= 4);
273 }
274 
Decode_sr0(char * Asc,ShortInt * Erg)275 static Boolean Decode_sr0(char *Asc, ShortInt *Erg)
276 {
277   int z;
278 
279   for (z = 0; z < SRegCnt; z++)
280    if (!as_strcasecmp(Asc, SRegs[z].Name)) break;
281   if ((z == SRegCnt-1) && (MomCPU == CPU7810))
282   {
283     WrError(ErrNum_InvCtrlReg); return False;
284   }
285   if (z < SRegCnt)
286   {
287     *Erg = SRegs[z].Code; return True;
288   }
289   else return False;
290 }
291 
Decode_sr1(char * Asc,ShortInt * Erg)292 static Boolean Decode_sr1(char *Asc, ShortInt *Erg)
293 {
294   if (!Decode_sr0(Asc, Erg)) return False;
295   return (((*Erg >= 0) && (*Erg <= 9)) || (*Erg == 11) || (*Erg == 13) || (*Erg == 25) || ((*Erg >= 32) && (*Erg <= 35)));
296 }
297 
Decode_sr(char * Asc,ShortInt * Erg)298 static Boolean Decode_sr(char *Asc, ShortInt *Erg)
299 {
300   if (!Decode_sr0(Asc, Erg)) return False;
301   return (((*Erg >= 0) && (*Erg <= 24)) || (*Erg == 26) || (*Erg == 27) || (*Erg == 40));
302 }
303 
Decode_sr2(char * Asc,ShortInt * Erg)304 static Boolean Decode_sr2(char *Asc, ShortInt *Erg)
305 {
306   if (!Decode_sr0(Asc, Erg)) return False;
307   return (((*Erg >= 0) && (*Erg <= 9)) || (*Erg == 11) || (*Erg == 13));
308 }
309 
Decode_sr3(char * Asc,ShortInt * Erg)310 static Boolean Decode_sr3(char *Asc, ShortInt *Erg)
311 {
312   if (!as_strcasecmp(Asc, "ETM0")) *Erg = 0;
313   else if (!as_strcasecmp(Asc, "ETM1")) *Erg = 1;
314   else return False;
315   return True;
316 }
317 
Decode_sr4(char * Asc,ShortInt * Erg)318 static Boolean Decode_sr4(char *Asc, ShortInt *Erg)
319 {
320   if (!as_strcasecmp(Asc, "ECNT")) *Erg = 0;
321   else if (!as_strcasecmp(Asc, "ECPT")) *Erg = 1;
322   else return False;
323   return True;
324 }
325 
Decode_irf(char * Asc,ShortInt * Erg)326 static Boolean Decode_irf(char *Asc, ShortInt *Erg)
327 {
328 #undef FlagCnt
329 #define FlagCnt 18
330   static const char FlagNames[FlagCnt][5] =
331            { "NMI" , "FT0" , "FT1" , "F1"  , "F2"  , "FE0" ,
332              "FE1" , "FEIN", "FAD" , "FSR" , "FST" , "ER"  ,
333              "OV"  , "AN4" , "AN5" , "AN6" , "AN7" , "SB"   };
334   static const ShortInt FlagCodes[FlagCnt] =
335             { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16, 17, 18, 19, 20 };
336 
337   for (*Erg = 0; *Erg < FlagCnt; (*Erg)++)
338    if (!as_strcasecmp(FlagNames[*Erg], Asc)) break;
339   if (*Erg >= FlagCnt) return False;
340   *Erg = FlagCodes[*Erg];
341   return True;
342 }
343 
Decode_wa(const tStrComp * pArg,Byte * Erg)344 static Boolean Decode_wa(const tStrComp *pArg, Byte *Erg)
345 {
346   Word Adr;
347   Boolean OK;
348   tSymbolFlags Flags;
349 
350   Adr = EvalStrIntExpressionWithFlags(pArg, Int16, &OK, &Flags);
351   if (!OK) return False;
352   if (!mFirstPassUnknown(Flags) && (Hi(Adr) != WorkArea)) WrError(ErrNum_InAccPage);
353   *Erg = Lo(Adr);
354   return True;
355 }
356 
HasDisp(ShortInt Mode)357 static Boolean HasDisp(ShortInt Mode)
358 {
359   return ((Mode & 11) == 11);
360 }
361 
362 /*--------------------------------------------------------------------------------*/
363 
DecodeFixed(Word Code)364 static void DecodeFixed(Word Code)
365 {
366   if (ChkArgCnt(0, 0))
367   {
368     CodeLen = 0;
369     if (Hi(Code) != 0)
370       BAsmCode[CodeLen++] = Hi(Code);
371     BAsmCode[CodeLen++] = Lo(Code);
372   }
373 }
374 
DecodeMOV(Word Code)375 static void DecodeMOV(Word Code)
376 {
377   Boolean OK;
378   ShortInt HReg;
379   Integer AdrInt;
380 
381   UNUSED(Code);
382 
383   if (!ChkArgCnt(2, 2));
384   else if (!as_strcasecmp(ArgStr[1].Str, "A"))
385   {
386     if (Decode_sr1(ArgStr[2].Str, &HReg))
387     {
388       CodeLen = 2;
389       BAsmCode[0] = 0x4c;
390       BAsmCode[1] = 0xc0 + HReg;
391     }
392     else if (Decode_r1(ArgStr[2].Str, &HReg))
393     {
394       CodeLen = 1;
395       BAsmCode[0] = 0x08 + HReg;
396     }
397     else
398     {
399       AdrInt = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
400       if (OK)
401       {
402         CodeLen = 4;
403         BAsmCode[0] = 0x70;
404         BAsmCode[1] = 0x69;
405         BAsmCode[2] = Lo(AdrInt);
406         BAsmCode[3] = Hi(AdrInt);
407       }
408     }
409   }
410   else if (!as_strcasecmp(ArgStr[2].Str, "A"))
411   {
412     if (Decode_sr(ArgStr[1].Str, &HReg))
413     {
414       CodeLen = 2;
415       BAsmCode[0] = 0x4d;
416       BAsmCode[1] = 0xc0 + HReg;
417     }
418     else if (Decode_r1(ArgStr[1].Str, &HReg))
419     {
420       CodeLen = 1;
421       BAsmCode[0] = 0x18 + HReg;
422     }
423     else
424     {
425       AdrInt = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
426       if (OK)
427       {
428         CodeLen = 4;
429         BAsmCode[0] = 0x70;
430         BAsmCode[1] = 0x79;
431         BAsmCode[2] = Lo(AdrInt);
432         BAsmCode[3] = Hi(AdrInt);
433       }
434     }
435   }
436   else if (Decode_r(ArgStr[1].Str, &HReg))
437   {
438     AdrInt = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
439     if (OK)
440     {
441       CodeLen = 4;
442       BAsmCode[0] = 0x70;
443       BAsmCode[1] = 0x68 + HReg;
444       BAsmCode[2] = Lo(AdrInt);
445       BAsmCode[3] = Hi(AdrInt);
446     }
447   }
448   else if (Decode_r(ArgStr[2].Str, &HReg))
449   {
450     AdrInt = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
451     if (OK)
452     {
453       CodeLen = 4;
454       BAsmCode[0] = 0x70;
455       BAsmCode[1] = 0x78 + HReg;
456       BAsmCode[2] = Lo(AdrInt);
457       BAsmCode[3] = Hi(AdrInt);
458     }
459   }
460   else
461     WrError(ErrNum_InvAddrMode);
462 }
463 
DecodeMVI(Word Code)464 static void DecodeMVI(Word Code)
465 {
466   UNUSED(Code);
467 
468   if (ChkArgCnt(2, 2))
469   {
470     ShortInt HReg;
471     Boolean OK;
472 
473     BAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
474     if (OK)
475     {
476       if (Decode_r(ArgStr[1].Str, &HReg))
477       {
478         CodeLen = 2;
479         BAsmCode[0] = 0x68 + HReg;
480       }
481       else if (Decode_sr2(ArgStr[1].Str, &HReg))
482       {
483         CodeLen = 3;
484         BAsmCode[2] = BAsmCode[1];
485         BAsmCode[0] = 0x64;
486         BAsmCode[1] = (HReg & 7) + ((HReg & 8) << 4);
487       }
488       else WrError(ErrNum_InvAddrMode);
489     }
490   }
491 }
492 
DecodeMVIW(Word Code)493 static void DecodeMVIW(Word Code)
494 {
495   Boolean OK;
496 
497   UNUSED(Code);
498 
499   if (!ChkArgCnt(2, 2));
500   else if (Decode_wa(&ArgStr[1], BAsmCode + 1))
501   {
502     BAsmCode[2] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
503     if (OK)
504     {
505       CodeLen = 3;
506       BAsmCode[0] = 0x71;
507     }
508   }
509 }
510 
DecodeMVIX(Word Code)511 static void DecodeMVIX(Word Code)
512 {
513   Boolean OK;
514   ShortInt HReg;
515 
516   UNUSED(Code);
517 
518   if (!ChkArgCnt(2, 2));
519   else if (!Decode_rpa1(&ArgStr[1], &HReg)) WrError(ErrNum_InvAddrMode);
520   else
521   {
522     BAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
523     if (OK)
524     {
525       BAsmCode[0] = 0x48 + HReg;
526       CodeLen = 2;
527     }
528   }
529 }
530 
DecodeLDAX_STAX(Word Code)531 static void DecodeLDAX_STAX(Word Code)
532 {
533   ShortInt HReg;
534   Boolean WasIndirect = False;
535 
536   if (!ChkArgCnt(1, 1));
537   else if (!Decode_rpa2(&ArgStr[1], &WasIndirect, &HReg, (ShortInt *) BAsmCode + 1)) WrError(ErrNum_InvAddrMode);
538   else
539   {
540     CodeLen = 1 + Ord(HasDisp(HReg));
541     BAsmCode[0] = Code + ((HReg & 8) << 4) + (HReg & 7);
542   }
543 }
544 
DecodeLDEAX_STEAX(Word Code)545 static void DecodeLDEAX_STEAX(Word Code)
546 {
547   ShortInt HReg;
548 
549   if (!ChkArgCnt(1, 1));
550   else if (!Decode_rpa3(&ArgStr[1], &HReg, (ShortInt *) BAsmCode + 2)) WrError(ErrNum_InvAddrMode);
551   else
552   {
553     CodeLen = 2 + Ord(HasDisp(HReg));
554     BAsmCode[0] = 0x48;
555     BAsmCode[1] = Code + HReg;
556   }
557 }
558 
DecodeLXI(Word Code)559 static void DecodeLXI(Word Code)
560 {
561   ShortInt HReg;
562   Integer AdrInt;
563   Boolean OK;
564 
565   UNUSED(Code);
566 
567   if (!ChkArgCnt(2, 2));
568   else if (!Decode_rp2(ArgStr[1].Str, &HReg)) WrError(ErrNum_InvAddrMode);
569   else
570   {
571     AdrInt = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
572     if (OK)
573     {
574       CodeLen = 3;
575       BAsmCode[0] = 0x04 + (HReg << 4);
576       BAsmCode[1] = Lo(AdrInt);
577       BAsmCode[2] = Hi(AdrInt);
578     }
579   }
580 }
581 
DecodePUSH_POP(Word Code)582 static void DecodePUSH_POP(Word Code)
583 {
584   ShortInt HReg;
585 
586   if (!ChkArgCnt(1, 1));
587   else if (!Decode_rp1(ArgStr[1].Str, &HReg)) WrError(ErrNum_InvAddrMode);
588   else
589   {
590     CodeLen = 1;
591     BAsmCode[0] = Code + HReg;
592   }
593 }
594 
DecodeDMOV(Word Code)595 static void DecodeDMOV(Word Code)
596 {
597   ShortInt HReg;
598 
599   UNUSED(Code);
600 
601   if (ChkArgCnt(2, 2))
602   {
603     Boolean Swap = as_strcasecmp(ArgStr[1].Str, "EA") || False;
604     char *pArg1 = Swap ? ArgStr[2].Str : ArgStr[1].Str,
605          *pArg2 = Swap ? ArgStr[1].Str : ArgStr[2].Str;
606 
607     if (as_strcasecmp(pArg1, "EA")) WrError(ErrNum_InvAddrMode);
608     else if (Decode_rp3(pArg2, &HReg))
609     {
610       CodeLen = 1;
611       BAsmCode[0] = 0xa4 + HReg;
612       if (Swap)
613         BAsmCode[0] += 0x10;
614     }
615     else if (((Swap) && (Decode_sr3(pArg2, &HReg)))
616           || ((!Swap) && (Decode_sr4(pArg2, &HReg))))
617     {
618       CodeLen = 2;
619       BAsmCode[0] = 0x48;
620       BAsmCode[1] = 0xc0 + HReg;
621       if (Swap)
622         BAsmCode[1] += 0x12;
623     }
624     else
625       WrError(ErrNum_InvAddrMode);
626   }
627 }
628 
DecodeALUImm(Word Code)629 static void DecodeALUImm(Word Code)
630 {
631   ShortInt HVal8, HReg;
632   Boolean OK;
633 
634   if (ChkArgCnt(2, 2))
635   {
636     HVal8 = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
637     if (OK)
638     {
639       if (!as_strcasecmp(ArgStr[1].Str, "A"))
640       {
641         CodeLen = 2;
642         BAsmCode[0] = 0x06 + ((Code & 14) << 3) + (Code & 1);
643         BAsmCode[1] = HVal8;
644       }
645       else if (Decode_r(ArgStr[1].Str, &HReg))
646       {
647         CodeLen = 3;
648         BAsmCode[0] = 0x74;
649         BAsmCode[2] = HVal8;
650         BAsmCode[1] = HReg + (Code << 3);
651       }
652       else if (Decode_sr2(ArgStr[1].Str, &HReg))
653       {
654         CodeLen = 3;
655         BAsmCode[0] = 0x64;
656         BAsmCode[2] = HVal8;
657         BAsmCode[1] = (HReg & 7) + (Code << 3) + ((HReg & 8) << 4);
658       }
659       else WrError(ErrNum_InvAddrMode);
660     }
661   }
662 }
663 
DecodeALUReg(Word Code)664 static void DecodeALUReg(Word Code)
665 {
666   ShortInt HReg;
667 
668   if (ChkArgCnt(2, 2))
669   {
670     Boolean NoSwap = !as_strcasecmp(ArgStr[1].Str, "A");
671     char *pArg1 = NoSwap ? ArgStr[1].Str : ArgStr[2].Str,
672          *pArg2 = NoSwap ? ArgStr[2].Str : ArgStr[1].Str;
673 
674     if (as_strcasecmp(pArg1, "A")) WrError(ErrNum_InvAddrMode);
675     else if (!Decode_r(pArg2, &HReg)) WrError(ErrNum_InvAddrMode);
676     else
677     {
678       CodeLen = 2;
679       BAsmCode[0] = 0x60;
680       BAsmCode[1] = (Code << 3) + HReg;
681       if ((NoSwap) || (Memo("ONA")) || (Memo("OFFA")))
682         BAsmCode[1] += 0x80;
683     }
684   }
685 }
686 
DecodeALURegW(Word Code)687 static void DecodeALURegW(Word Code)
688 {
689   if (!ChkArgCnt(1, 1));
690   else if (Decode_wa(&ArgStr[1], BAsmCode + 2))
691   {
692     CodeLen = 3;
693     BAsmCode[0] = 0x74;
694     BAsmCode[1] = 0x80 + (Code << 3);
695   }
696 }
697 
DecodeALURegX(Word Code)698 static void DecodeALURegX(Word Code)
699 {
700   ShortInt HReg;
701 
702   if (!ChkArgCnt(1, 1));
703   else if (!Decode_rpa(&ArgStr[1], &HReg)) WrError(ErrNum_InvAddrMode);
704   else
705   {
706     CodeLen = 2;
707     BAsmCode[0] = 0x70;
708     BAsmCode[1] = 0x80 + (Code << 3) + HReg;
709   }
710 }
711 
DecodeALUEA(Word Code)712 static void DecodeALUEA(Word Code)
713 {
714   ShortInt HReg;
715 
716   if (!ChkArgCnt(2, 2));
717   else if (as_strcasecmp(ArgStr[1].Str, "EA")) WrError(ErrNum_InvAddrMode);
718   else if (!Decode_rp3(ArgStr[2].Str, &HReg)) WrError(ErrNum_InvAddrMode);
719   else
720   {
721     CodeLen = 2;
722     BAsmCode[0] = 0x74;
723     BAsmCode[1] = 0x84 + (Code << 3) + HReg;
724   }
725 }
726 
DecodeALUImmW(Word Code)727 static void DecodeALUImmW(Word Code)
728 {
729   Boolean OK;
730 
731   if (!ChkArgCnt(2, 2));
732   else if (Decode_wa(&ArgStr[1], BAsmCode + 1))
733   {
734     BAsmCode[2] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
735     if (OK)
736     {
737       CodeLen = 3;
738       BAsmCode[0] = 0x05 + ((Code >> 1) << 4);
739     }
740   }
741 }
742 
DecodeAbs(Word Code)743 static void DecodeAbs(Word Code)
744 {
745   if (!ChkArgCnt(1, 1));
746   else
747   {
748     Boolean OK;
749     Integer AdrInt;
750 
751     AdrInt = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
752     if (OK)
753     {
754       CodeLen = 0;
755       if (Hi(Code) != 0)
756         BAsmCode[CodeLen++] = Hi(Code);
757       BAsmCode[CodeLen++] = Lo(Code);
758       BAsmCode[CodeLen++] = Lo(AdrInt);
759       BAsmCode[CodeLen++] = Hi(AdrInt);
760     }
761   }
762 }
763 
DecodeReg2(Word Code)764 static void DecodeReg2(Word Code)
765 {
766   ShortInt HReg;
767 
768   if (!ChkArgCnt(1, 1));
769   else if (!Decode_r2(ArgStr[1].Str, &HReg)) WrError(ErrNum_InvAddrMode);
770   else
771   {
772     CodeLen = 0;
773     if (Hi(Code) != 0)
774       BAsmCode[CodeLen++] = Hi(Code);
775     BAsmCode[CodeLen++] = Lo(Code) + HReg;
776   }
777 }
778 
DecodeWork(Word Code)779 static void DecodeWork(Word Code)
780 {
781   if (ChkArgCnt(1, 1)
782    && Decode_wa(&ArgStr[1], BAsmCode + 1))
783   {
784     CodeLen = 2;
785     BAsmCode[0] = Code;
786   }
787 }
788 
DecodeEA(Word Code)789 static void DecodeEA(Word Code)
790 {
791   if (!ChkArgCnt(1, 1));
792   else if (as_strcasecmp(ArgStr[1].Str, "EA")) WrError(ErrNum_InvAddrMode);
793   else
794   {
795     CodeLen = 2;
796     BAsmCode[0] = Hi(Code);
797     BAsmCode[1] = Lo(Code);
798   }
799   return;
800 }
801 
DecodeDCX_INX(Word Code)802 static void DecodeDCX_INX(Word Code)
803 {
804   ShortInt HReg;
805 
806   if (!ChkArgCnt(1, 1));
807   else if (!as_strcasecmp(ArgStr[1].Str, "EA"))
808   {
809     CodeLen = 1;
810     BAsmCode[0] = 0xa8 + Code;
811   }
812   else if (Decode_rp(ArgStr[1].Str, &HReg))
813   {
814     CodeLen = 1;
815     BAsmCode[0] = 0x02 + Code + (HReg << 4);
816   }
817   else
818     WrError(ErrNum_InvAddrMode);
819 }
820 
DecodeEADD_ESUB(Word Code)821 static void DecodeEADD_ESUB(Word Code)
822 {
823   ShortInt HReg;
824 
825   if (!ChkArgCnt(2, 2));
826   else if (as_strcasecmp(ArgStr[1].Str, "EA")) WrError(ErrNum_InvAddrMode);
827   else if (!Decode_r2(ArgStr[2].Str, &HReg)) WrError(ErrNum_InvAddrMode);
828   else
829   {
830     CodeLen = 2;
831     BAsmCode[0] = 0x70;
832     BAsmCode[1] = Code + HReg;
833   }
834 }
835 
DecodeJ_JR_JRE(Word Type)836 static void DecodeJ_JR_JRE(Word Type)
837 {
838   Boolean OK;
839   Integer AdrInt;
840   tSymbolFlags Flags;
841 
842   if (!ChkArgCnt(1, 1))
843     return;
844 
845   AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags) - (EProgCounter() + 1);
846   if (!OK)
847     return;
848 
849   if (!Type) /* generic J */
850     Type = RangeCheck(AdrInt, SInt6) ? 1 : 2;
851 
852   switch (Type)
853   {
854     case 1: /* JR */
855       if (!mSymbolQuestionable(Flags) && !RangeCheck(AdrInt, SInt6)) WrError(ErrNum_JmpDistTooBig);
856       else
857       {
858         CodeLen = 1;
859         BAsmCode[0] = 0xc0 + (AdrInt & 0x3f);
860       }
861       break;
862     case 2:
863       AdrInt--; /* JRE is 2 bytes long */
864       if (!mSymbolQuestionable(Flags) && !RangeCheck(AdrInt, SInt9)) WrError(ErrNum_JmpDistTooBig);
865       else
866       {
867         CodeLen = 2;
868         BAsmCode[0] = 0x4e + (Hi(AdrInt) & 1);
869         BAsmCode[1] = Lo(AdrInt);
870       }
871       break;
872   }
873 }
874 
DecodeCALF(Word Code)875 static void DecodeCALF(Word Code)
876 {
877   UNUSED(Code);
878 
879   if (ChkArgCnt(1, 1))
880   {
881     Boolean OK;
882     Integer AdrInt;
883     tSymbolFlags Flags;
884 
885     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
886     if (OK)
887     {
888       if (!mFirstPassUnknown(Flags) && ((AdrInt >> 11) != 1)) WrError(ErrNum_NotFromThisAddress);
889       else
890       {
891         CodeLen = 2;
892         BAsmCode[0] = Hi(AdrInt) + 0x70;
893         BAsmCode[1] = Lo(AdrInt);
894       }
895     }
896   }
897 }
898 
DecodeCALT(Word Code)899 static void DecodeCALT(Word Code)
900 {
901   UNUSED(Code);
902 
903   if (ChkArgCnt(1, 1))
904   {
905     Boolean OK;
906     Integer AdrInt;
907     tSymbolFlags Flags;
908 
909     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
910     if (OK)
911     {
912       if (!mFirstPassUnknown(Flags) && ((AdrInt & 0xffc1) != 0x80)) WrError(ErrNum_NotFromThisAddress);
913       else
914       {
915         CodeLen = 1;
916         BAsmCode[0] = 0x80 + ((AdrInt & 0x3f) >> 1);
917       }
918     }
919   }
920 }
921 
DecodeBIT(Word Code)922 static void DecodeBIT(Word Code)
923 {
924   UNUSED(Code);
925 
926   if (ChkArgCnt(2, 2))
927   {
928     Boolean OK;
929     ShortInt HReg;
930 
931     HReg = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
932     if (OK)
933      if (Decode_wa(&ArgStr[2], BAsmCode + 1))
934      {
935        CodeLen = 2; BAsmCode[0] = 0x58 + HReg;
936      }
937   }
938 }
939 
DecodeSK_SKN(Word Code)940 static void DecodeSK_SKN(Word Code)
941 {
942   ShortInt HReg;
943 
944   if (!ChkArgCnt(1, 1));
945   else if (!Decode_f(ArgStr[1].Str, &HReg)) WrError(ErrNum_InvAddrMode);
946   else
947   {
948     CodeLen = 2;
949     BAsmCode[0] = 0x48;
950     BAsmCode[1] = Code + HReg;
951   }
952 }
953 
DecodeSKIT_SKNIT(Word Code)954 static void DecodeSKIT_SKNIT(Word Code)
955 {
956   ShortInt HReg;
957 
958   if (!ChkArgCnt(1, 1));
959   else if (!Decode_irf(ArgStr[1].Str, &HReg)) WrError(ErrNum_InvAddrMode);
960   else
961   {
962     CodeLen = 2;
963     BAsmCode[0] = 0x48;
964     BAsmCode[1] = Code + HReg;
965   }
966 }
967 
968 /*--------------------------------------------------------------------------------*/
969 
AddFixed(const char * NName,Word NCode)970 static void AddFixed(const char *NName, Word NCode)
971 {
972   if ((!strcmp(NName, "STOP")) && (MomCPU == CPU7810));
973   else
974     AddInstTable(InstTable, NName, NCode, DecodeFixed);
975 }
976 
AddSReg(const char * NName,Word NCode)977 static void AddSReg(const char *NName, Word NCode)
978 {
979   if (InstrZ >= SRegCnt) exit(255);
980   SRegs[InstrZ].Name = NName;
981   SRegs[InstrZ++].Code = NCode;
982 }
983 
AddALU(Byte NCode,const char * NNameI,const char * NNameReg,const char * NNameEA)984 static void AddALU(Byte NCode, const char *NNameI, const char *NNameReg, const char *NNameEA)
985 {
986   char Name[20];
987 
988   AddInstTable(InstTable, NNameI, NCode, DecodeALUImm);
989   AddInstTable(InstTable, NNameReg, NCode, DecodeALUReg);
990   AddInstTable(InstTable, NNameEA, NCode, DecodeALUEA);
991   as_snprintf(Name, sizeof(Name), "%sW", NNameReg);
992   AddInstTable(InstTable, Name, NCode, DecodeALURegW);
993   as_snprintf(Name, sizeof(Name), "%sX", NNameReg);
994   AddInstTable(InstTable, Name, NCode, DecodeALURegX);
995   as_snprintf(Name, sizeof(Name), "%sW", NNameI);
996   AddInstTable(InstTable, Name, NCode, DecodeALUImmW);
997 }
998 
AddAbs(const char * NName,Word NCode)999 static void AddAbs(const char *NName, Word NCode)
1000 {
1001   AddInstTable(InstTable, NName, NCode, DecodeAbs);
1002 }
1003 
AddReg2(const char * NName,Word NCode)1004 static void AddReg2(const char *NName, Word NCode)
1005 {
1006   AddInstTable(InstTable, NName, NCode, DecodeReg2);
1007 }
1008 
AddWork(const char * NName,Word NCode)1009 static void AddWork(const char *NName, Word NCode)
1010 {
1011   AddInstTable(InstTable, NName, NCode, DecodeWork);
1012 }
1013 
AddEA(const char * NName,Word NCode)1014 static void AddEA(const char *NName, Word NCode)
1015 {
1016   AddInstTable(InstTable, NName, NCode, DecodeEA);
1017 }
1018 
InitFields(void)1019 static void InitFields(void)
1020 {
1021   InstTable = CreateInstTable(301);
1022   SetDynamicInstTable(InstTable);
1023 
1024   AddInstTable(InstTable, "MOV", 0, DecodeMOV);
1025   AddInstTable(InstTable, "MVI", 0, DecodeMVI);
1026   AddInstTable(InstTable, "MVIW", 0, DecodeMVIW);
1027   AddInstTable(InstTable, "MVIX", 0, DecodeMVIX);
1028   AddInstTable(InstTable, "LDAX", 0x28, DecodeLDAX_STAX);
1029   AddInstTable(InstTable, "STAX", 0x38, DecodeLDAX_STAX);
1030   AddInstTable(InstTable, "LDEAX", 0x80, DecodeLDEAX_STEAX);
1031   AddInstTable(InstTable, "STEAX", 0x90, DecodeLDEAX_STEAX);
1032   AddInstTable(InstTable, "LXI", 0, DecodeLXI);
1033   AddInstTable(InstTable, "PUSH", 0xb0, DecodePUSH_POP);
1034   AddInstTable(InstTable, "POP", 0xa0, DecodePUSH_POP);
1035   AddInstTable(InstTable, "DMOV", 0, DecodeDMOV);
1036   AddInstTable(InstTable, "DCX", 1, DecodeDCX_INX);
1037   AddInstTable(InstTable, "INX", 0, DecodeDCX_INX);
1038   AddInstTable(InstTable, "EADD", 0x40, DecodeEADD_ESUB);
1039   AddInstTable(InstTable, "ESUB", 0x60, DecodeEADD_ESUB);
1040   AddInstTable(InstTable, "JR", 1, DecodeJ_JR_JRE);
1041   AddInstTable(InstTable, "JRE", 2, DecodeJ_JR_JRE);
1042   AddInstTable(InstTable, "J", 0, DecodeJ_JR_JRE);
1043   AddInstTable(InstTable, "CALF", 0, DecodeCALF);
1044   AddInstTable(InstTable, "CALT", 0, DecodeCALT);
1045   AddInstTable(InstTable, "BIT", 0, DecodeBIT);
1046   AddInstTable(InstTable, "SK", 0x08, DecodeSK_SKN);
1047   AddInstTable(InstTable, "SKN", 0x18, DecodeSK_SKN);
1048   AddInstTable(InstTable, "SKIT", 0x40, DecodeSKIT_SKNIT);
1049   AddInstTable(InstTable, "SKNIT", 0x60, DecodeSKIT_SKNIT);
1050 
1051   AddFixed("EXX"  , 0x0011); AddFixed("EXA"  , 0x0010);
1052   AddFixed("EXH"  , 0x0050); AddFixed("BLOCK", 0x0031);
1053   AddFixed("TABLE", 0x48a8); AddFixed("DAA"  , 0x0061);
1054   AddFixed("STC"  , 0x482b); AddFixed("CLC"  , 0x482a);
1055   AddFixed("NEGA" , 0x483a); AddFixed("RLD"  , 0x4838);
1056   AddFixed("RRD"  , 0x4839); AddFixed("JB"   , 0x0021);
1057   AddFixed("JEA"  , 0x4828); AddFixed("CALB" , 0x4829);
1058   AddFixed("SOFTI", 0x0072); AddFixed("RET"  , 0x00b8);
1059   AddFixed("RETS" , 0x00b9); AddFixed("RETI" , 0x0062);
1060   AddFixed("NOP"  , 0x0000); AddFixed("EI"   , 0x00aa);
1061   AddFixed("DI"   , 0x00ba); AddFixed("HLT"  , 0x483b);
1062   AddFixed("STOP" , 0x48bb);
1063 
1064   SRegs = (SReg *) malloc(sizeof(SReg)*SRegCnt); InstrZ = 0;
1065   AddSReg("PA"  , 0x00); AddSReg("PB"  , 0x01);
1066   AddSReg("PC"  , 0x02); AddSReg("PD"  , 0x03);
1067   AddSReg("PF"  , 0x05); AddSReg("MKH" , 0x06);
1068   AddSReg("MKL" , 0x07); AddSReg("ANM" , 0x08);
1069   AddSReg("SMH" , 0x09); AddSReg("SML" , 0x0a);
1070   AddSReg("EOM" , 0x0b); AddSReg("ETMM", 0x0c);
1071   AddSReg("TMM" , 0x0d); AddSReg("MM"  , 0x10);
1072   AddSReg("MCC" , 0x11); AddSReg("MA"  , 0x12);
1073   AddSReg("MB"  , 0x13); AddSReg("MC"  , 0x14);
1074   AddSReg("MF"  , 0x17); AddSReg("TXB" , 0x18);
1075   AddSReg("RXB" , 0x19); AddSReg("TM0" , 0x1a);
1076   AddSReg("TM1" , 0x1b); AddSReg("CR0" , 0x20);
1077   AddSReg("CR1" , 0x21); AddSReg("CR2" , 0x22);
1078   AddSReg("CR3" , 0x23); AddSReg("ZCM" , 0x28);
1079 
1080   AddALU(10, "ACI"  , "ADC"  , "DADC"  );
1081   AddALU( 4, "ADINC", "ADDNC", "DADDNC");
1082   AddALU( 8, "ADI"  , "ADD"  , "DADD"  );
1083   AddALU( 1, "ANI"  , "ANA"  , "DAN"   );
1084   AddALU(15, "EQI"  , "EQA"  , "DEQ"   );
1085   AddALU( 5, "GTI"  , "GTA"  , "DGT"   );
1086   AddALU( 7, "LTI"  , "LTA"  , "DLT"   );
1087   AddALU(13, "NEI"  , "NEA"  , "DNE"   );
1088   AddALU(11, "OFFI" , "OFFA" , "DOFF"  );
1089   AddALU( 9, "ONI"  , "ONA"  , "DON"   );
1090   AddALU( 3, "ORI"  , "ORA"  , "DOR"   );
1091   AddALU(14, "SBI"  , "SBB"  , "DSBB"  );
1092   AddALU( 6, "SUINB", "SUBNB", "DSUBNB");
1093   AddALU(12, "SUI"  , "SUB"  , "DSUB"  );
1094   AddALU( 2, "XRI"  , "XRA"  , "DXR"   );
1095 
1096   AddAbs("CALL", 0x0040); AddAbs("JMP" , 0x0054);
1097   AddAbs("LBCD", 0x701f); AddAbs("LDED", 0x702f);
1098   AddAbs("LHLD", 0x703f); AddAbs("LSPD", 0x700f);
1099   AddAbs("SBCD", 0x701e); AddAbs("SDED", 0x702e);
1100   AddAbs("SHLD", 0x703e); AddAbs("SSPD", 0x700e);
1101 
1102   AddReg2("DCR" , 0x0050); AddReg2("DIV" , 0x483c);
1103   AddReg2("INR" , 0x0040); AddReg2("MUL" , 0x482c);
1104   AddReg2("RLL" , 0x4834); AddReg2("RLR" , 0x4830);
1105   AddReg2("SLL" , 0x4824); AddReg2("SLR" , 0x4820);
1106   AddReg2("SLLC", 0x4804); AddReg2("SLRC", 0x4800);
1107 
1108   AddWork("DCRW", 0x30); AddWork("INRW", 0x20);
1109   AddWork("LDAW", 0x01); AddWork("STAW", 0x63);
1110 
1111   AddEA("DRLL", 0x48b4); AddEA("DRLR", 0x48b0);
1112   AddEA("DSLL", 0x48a4); AddEA("DSLR", 0x48a0);
1113 }
1114 
DeinitFields(void)1115 static void DeinitFields(void)
1116 {
1117   DestroyInstTable(InstTable);
1118   free(SRegs);
1119 }
1120 
1121 /*--------------------------------------------------------------------------*/
1122 
MakeCode_78C10(void)1123 static void MakeCode_78C10(void)
1124 {
1125   CodeLen = 0;
1126   DontPrint = False;
1127 
1128   /* zu ignorierendes */
1129 
1130   if (Memo("")) return;
1131 
1132   /* Pseudoanweisungen */
1133 
1134   if (DecodeIntelPseudo(False)) return;
1135 
1136   if (!LookupInstTable(InstTable, OpPart.Str))
1137     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
1138 }
1139 
InitCode_78C10(void)1140 static void InitCode_78C10(void)
1141 {
1142   WorkArea = 0x100;
1143 }
1144 
IsDef_78C10(void)1145 static Boolean IsDef_78C10(void)
1146 {
1147   return False;
1148 }
1149 
SwitchFrom_78C10(void)1150 static void SwitchFrom_78C10(void)
1151 {
1152   DeinitFields();
1153 }
1154 
SwitchTo_78C10(void)1155 static void SwitchTo_78C10(void)
1156 {
1157   TurnWords = False; ConstMode = ConstModeIntel;
1158 
1159   PCSymbol = "$"; HeaderID = 0x7a; NOPCode = 0x00;
1160   DivideChars = ","; HasAttrs = False;
1161 
1162   ValidSegs = 1 << SegCode;
1163   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
1164   SegLimits[SegCode] = 0xffff;
1165 
1166   pASSUMERecs = ASSUME78C10s;
1167   ASSUMERecCnt = sizeof(ASSUME78C10s) / sizeof(*ASSUME78C10s);
1168 
1169   MakeCode = MakeCode_78C10; IsDef = IsDef_78C10;
1170   SwitchFrom = SwitchFrom_78C10;
1171   InitFields();
1172 }
1173 
code78c10_init(void)1174 void code78c10_init(void)
1175 {
1176   CPU7810 = AddCPU("7810" , SwitchTo_78C10);
1177   CPU78C10 = AddCPU("78C10", SwitchTo_78C10);
1178 
1179   AddInitPassProc(InitCode_78C10);
1180 }
1181