1 /* code77230.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* Makroassembler AS                                                         */
6 /*                                                                           */
7 /* Codegenerator NEC uPD77230                                                */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 /*---------------------------------------------------------------------------*/
12 /* Includes */
13 
14 #include "stdinc.h"
15 #include <string.h>
16 #include <ctype.h>
17 
18 #include "strutil.h"
19 #include "nls.h"
20 #include "endian.h"
21 #include "ieeefloat.h"
22 #include "bpemu.h"
23 
24 #include "asmdef.h"
25 #include "asmsub.h"
26 #include "asmpars.h"
27 #include "asmitree.h"
28 #include "headids.h"
29 #include "codevars.h"
30 #include "errmsg.h"
31 
32 #include "code77230.h"
33 
34 /*---------------------------------------------------------------------------*/
35 /* Definitionen */
36 
37 #define SrcRegCnt 32
38 #define DestRegCnt 32
39 #define ALUSrcRegCnt 4
40 
41 #define JmpOrderCnt 32
42 #define ALU1OrderCnt 15
43 #define ALU2OrderCnt 10
44 
45 #define CaseCnt 17
46 
47 typedef struct
48 {
49   LongWord Code;
50 } FixedOrder;
51 
52 typedef struct
53 {
54   const char *Name;
55   LongWord Code;
56 } Register;
57 
58 enum
59 {
60   InstrLDI, InstrBranch,
61   InstrALU, InstrMove,
62   InstrM0, InstrM1, InstrDP0, InstrDP1,
63   InstrEA, InstrRP, InstrFC, InstrLC,
64   InstrBASE0, InstrBASE1, InstrRPC,
65   InstrP2, InstrP3, InstrEM, InstrBM,
66   InstrL, InstrRW, InstrWT, InstrNF, InstrWI,
67   InstrFIS, InstrFD, InstrSHV, InstrRPS, InstrNAL, InstrCnt
68 };
69 
70 static LongWord CaseMasks[CaseCnt] =
71 {
72   (1l << InstrLDI),
73   (1l << InstrBranch) | (1l << InstrMove),
74   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrM0) | (1l << InstrM1) | (1l << InstrDP0) | (1l << InstrDP1),
75   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrEA) | (1l << InstrDP0) | (1l << InstrDP1),
76   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrRP) | (1l << InstrM0) | (1l << InstrDP0) | (1l << InstrFC),
77   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrRP) | (1l << InstrM1) | (1l << InstrDP1) | (1l << InstrFC),
78   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrRP) | (1l << InstrM0) | (1l << InstrM1) | (1l << InstrL) | (1l << InstrFC),
79   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrBASE0) | (1l << InstrBASE1) | (1l << InstrFC),
80   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrRPC) | (1l << InstrL) | (1l << InstrFC),
81   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrP3) | (1l << InstrP2) | (1l << InstrEM) | (1l << InstrBM) | (1l << InstrL) | (1l << InstrFC),
82   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrRW) | (1l << InstrL) | (1l << InstrFC),
83   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrWT) | (1l << InstrL) | (1l << InstrFC),
84   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrNF) | (1l << InstrWI) | (1l << InstrL) | (1l << InstrFC),
85   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrFIS) | (1l << InstrFD) | (1l << InstrL),
86   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrSHV),
87   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrRPS),
88   (1l << InstrALU) | (1l << InstrMove) | (1l << InstrNAL)
89 };
90 
91 static CPUVar CPU77230;
92 static LongWord InstrMask;
93 static Boolean Error;
94 static LongWord *InstrComps, *InstrDefs;
95 
96 static Register *SrcRegs, *ALUSrcRegs, *DestRegs;
97 static FixedOrder *JmpOrders, *ALU1Orders, *ALU2Orders;
98 
99 /*---------------------------------------------------------------------------*/
100 /* Hilfsroutinen */
101 
102 static int DiscCnt, SplittedArg;
103 static char *DiscPtr;
104 
SplitArgs(int Count)105 static Boolean SplitArgs(int Count)
106 {
107   char *p, *p1, *p2;
108 
109   SplittedArg = DiscCnt = Count;
110 
111   if (Count == 0)
112   {
113     if (ArgCnt > 0)
114     {
115       DiscPtr = ArgStr[1].Str - 1;
116       SplittedArg = 1;
117     }
118     else
119       DiscPtr = NULL;
120     return True;
121   }
122 
123   if (!ChkArgCnt(Count, ArgCntMax))
124   {
125     Error = True;
126     return False;
127   }
128 
129   for (p = ArgStr[SplittedArg].Str; isspace(((usint)*p) & 0xff); p++);
130   p1 = QuotPos(p, ' ');
131   p2 = QuotPos(p, '\t');
132   DiscPtr = ((!p1) || ((p2) && (p2 < p1))) ? p2 : p1;
133   if (DiscPtr)
134     *(DiscPtr) = '\0';
135 
136   return True;
137 }
138 
DiscardArgs(void)139 static void DiscardArgs(void)
140 {
141   char *p, *p2;
142   int z;
143   Boolean Eaten;
144 
145   if (DiscPtr)
146   {
147     for (p = DiscPtr + 1; as_isspace(*p); p++)
148       if (*p == '\0') break;
149     for (p2 = p; !as_isspace(*p2); p2++)
150       if (*p2 == '\0') break;
151     Eaten = (*p2 == '\0');
152     *p2 = '\0';
153     strmov(OpPart.Str, p);
154     NLS_UpString(OpPart.Str);
155     if (Eaten)
156     {
157       for (z = 1; z < ArgCnt; z++)
158         strmov(ArgStr[z].Str, ArgStr[z + 1].Str);
159       ArgCnt--;
160     }
161     else
162     {
163       if (p2)
164         for (p2++; as_isspace(*p2); p2++);
165       strmov(ArgStr[SplittedArg].Str, p2);
166     }
167   }
168   else
169     *OpPart.Str = '\0';
170   if (DiscCnt > 0)
171   {
172     for (z = 0; z <= ArgCnt - DiscCnt; z++)
173       strmov(ArgStr[z + 1].Str, ArgStr[z + DiscCnt].Str);
174     ArgCnt -= DiscCnt - 1;
175   }
176 }
177 
AddComp(int Index,LongWord Value)178 static void AddComp(int Index, LongWord Value)
179 {
180   if ((InstrMask & (1l << Index)) != 0)
181   {
182     WrError(ErrNum_InvParAddrMode);
183     Error = True;
184   }
185   else
186   {
187     InstrMask |= (1l << Index);
188     InstrComps[Index] = Value;
189   }
190 }
191 
DecodeReg(char * Asc,LongWord * Erg,Register * Regs,int Cnt)192 static Boolean DecodeReg(char *Asc, LongWord *Erg, Register *Regs, int Cnt)
193 {
194   int z;
195 
196   for (z = 0; z < Cnt; z++)
197     if (!as_strcasecmp(Asc, Regs[z].Name))
198     {
199       *Erg = Regs[z].Code;
200       return True;
201     }
202   *Erg = 0;
203   return False;
204 }
205 
206 /*---------------------------------------------------------------------------*/
207 /* Dekoder fuer Routinen */
208 
DecodeJmp(Word Index)209 static void DecodeJmp(Word Index)
210 {
211   FixedOrder *Op = JmpOrders + Index;
212   int acnt = Hi(Op->Code);
213   LongWord Adr;
214 
215   if (!SplitArgs(acnt))
216     return;
217   if (acnt == 0)
218   {
219     Adr = 0;
220     Error = True;
221   }
222   else
223     Adr = EvalStrIntExpression(&ArgStr[1], UInt13, &Error);
224   Error = !Error;
225   if (!Error)
226     AddComp(InstrBranch, Lo(Op->Code) + (Adr << 5));
227   DiscardArgs();
228 }
229 
DecodeMOV(Word Index)230 static void DecodeMOV(Word Index)
231 {
232   LongWord DReg, SReg;
233   UNUSED(Index);
234 
235   if (!SplitArgs(2))
236     return;
237   if (!DecodeReg(ArgStr[1].Str, &DReg, DestRegs, DestRegCnt))
238   {
239     WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
240     Error = True;
241   }
242   else if (!DecodeReg(ArgStr[2].Str, &SReg, SrcRegs, SrcRegCnt))
243   {
244     WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
245     Error = True;
246   }
247   else
248     AddComp(InstrMove, (SReg << 5) + DReg);
249   DiscardArgs();
250 }
251 
DecodeLDI(Word Index)252 static void DecodeLDI(Word Index)
253 {
254   LongWord DReg, Src = 0;
255   UNUSED(Index);
256 
257   if (!SplitArgs(2))
258     return;
259   if (!DecodeReg(ArgStr[1].Str, &DReg, DestRegs, DestRegCnt))
260   {
261     WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
262     Error = True;
263   }
264   else
265     Src = EvalStrIntExpression(&ArgStr[2], Int24, &Error);
266   Error = !Error;
267   if (!Error)
268     AddComp(InstrLDI, (Src << 5) + DReg);
269   DiscardArgs();
270 }
271 
DecodeNOP(Word Index)272 static void DecodeNOP(Word Index)
273 {
274   UNUSED(Index);
275 
276   if (!SplitArgs(0))
277     return;
278   AddComp(InstrALU, 0);
279   DiscardArgs();
280 }
281 
DecodeALU1(Word Index)282 static void DecodeALU1(Word Index)
283 {
284   FixedOrder *Op = ALU1Orders + Index;
285   LongWord DReg;
286 
287   if (!SplitArgs(1))
288     return;
289   if ((!DecodeReg(ArgStr[1].Str, &DReg, DestRegs, DestRegCnt))
290    || (DReg < 16) || (DReg > 23))
291   {
292     WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
293     Error = True;
294   }
295   else
296     AddComp(InstrALU, (Op->Code << 17) + (DReg & 7));
297   DiscardArgs();
298 }
299 
DecodeALU2(Word Index)300 static void DecodeALU2(Word Index)
301 {
302   FixedOrder *Op = ALU2Orders + Index;
303   LongWord DReg, SReg;
304 
305   if (!SplitArgs(2)) return;
306   if ((!DecodeReg(ArgStr[1].Str, &DReg, DestRegs, DestRegCnt))
307    || (DReg < 16) || (DReg > 23))
308   {
309     WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
310     Error = True;
311   }
312   else if (!DecodeReg(ArgStr[2].Str, &SReg, ALUSrcRegs, ALUSrcRegCnt))
313   {
314     WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
315     Error = True;
316   }
317   else
318     AddComp(InstrALU, (Op->Code << 17) + (SReg << 3) + (DReg & 7));
319   DiscardArgs();
320 }
321 
DecodeM0(Word Index)322 static void DecodeM0(Word Index)
323 {
324   if (!SplitArgs(0))
325     return;
326 
327   AddComp(InstrM0, Index);
328   DiscardArgs();
329 }
330 
DecodeM1(Word Index)331 static void DecodeM1(Word Index)
332 {
333   if (!SplitArgs(0))
334     return;
335 
336   AddComp(InstrM1, Index);
337   DiscardArgs();
338 }
339 
DecodeDP0(Word Index)340 static void DecodeDP0(Word Index)
341 {
342   if (!SplitArgs(0))
343     return;
344 
345   AddComp(InstrDP0, Index);
346   DiscardArgs();
347 }
348 
DecodeDP1(Word Index)349 static void DecodeDP1(Word Index)
350 {
351   if (!SplitArgs(0))
352     return;
353 
354   AddComp(InstrDP1, Index);
355   DiscardArgs();
356 }
357 
DecodeEA(Word Index)358 static void DecodeEA(Word Index)
359 {
360   if (!SplitArgs(0))
361     return;
362 
363   AddComp(InstrEA, Index);
364   DiscardArgs();
365 }
366 
DecodeFC(Word Index)367 static void DecodeFC(Word Index)
368 {
369   if (!SplitArgs(0))
370     return;
371 
372   AddComp(InstrFC, Index);
373   DiscardArgs();
374 }
375 
DecodeRP(Word Index)376 static void DecodeRP(Word Index)
377 {
378   if (!SplitArgs(0))
379     return;
380 
381   AddComp(InstrRP, Index);
382   DiscardArgs();
383 }
384 
DecodeL(Word Index)385 static void DecodeL(Word Index)
386 {
387   if (!SplitArgs(0))
388     return;
389 
390   AddComp(InstrL, Index);
391   DiscardArgs();
392 }
393 
DecodeBASE(Word Index)394 static void DecodeBASE(Word Index)
395 {
396   LongWord Value;
397 
398   if (!SplitArgs(1))
399     return;
400   Value = EvalStrIntExpression(&ArgStr[1], UInt3, &Error);
401   Error = !Error;
402   if (!Error)
403     AddComp(Index, Value);
404   DiscardArgs();
405 }
406 
DecodeRPC(Word Index)407 static void DecodeRPC(Word Index)
408 {
409   LongWord Value;
410   tSymbolFlags Flags;
411 
412   UNUSED(Index);
413 
414   if (!SplitArgs(1))
415     return;
416 
417   Value = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt4, &Error, &Flags);
418   if (mFirstPassUnknown(Flags))
419     Value &= 7;
420   Error = (Value > 9) ? True : !Error;
421   if (!Error)
422     AddComp(InstrRPC, Value);
423   DiscardArgs();
424 }
425 
DecodeP2(Word Index)426 static void DecodeP2(Word Index)
427 {
428   if (!SplitArgs(0))
429     return;
430 
431   AddComp(InstrP2, Index);
432   DiscardArgs();
433 }
434 
DecodeP3(Word Index)435 static void DecodeP3(Word Index)
436 {
437   if (!SplitArgs(0))
438     return;
439 
440   AddComp(InstrP3, Index);
441   DiscardArgs();
442 }
443 
DecodeBM(Word Index)444 static void DecodeBM(Word Index)
445 {
446   /* Wenn EM-Feld schon da war, muss es EI gewesen sein */
447 
448   if (!SplitArgs(0))
449     return;
450 
451   if ((InstrMask & (1 << InstrEM)) != 0)
452   {
453     Error = (InstrComps[InstrEM] == 0);
454     if (Error) WrError(ErrNum_InvParAddrMode);
455     else
456       AddComp(InstrBM, Index);
457   }
458   else
459     AddComp(InstrBM, Index);
460   DiscardArgs();
461 }
462 
DecodeEM(Word Index)463 static void DecodeEM(Word Index)
464 {
465   /* Wenn BM-Feld schon da war, muss es EI sein */
466 
467   if (!SplitArgs(0))
468     return;
469 
470   if ((InstrMask & (1 << InstrBM)) != 0)
471   {
472     Error = (Index == 0);
473     if (Error)
474       WrError(ErrNum_InvParAddrMode);
475     else
476       AddComp(InstrEM, Index);
477   }
478   else
479   {
480     AddComp(InstrEM, Index);
481     if (Index == 0)
482       InstrComps[InstrBM] = 3;
483   }
484   DiscardArgs();
485 }
486 
DecodeRW(Word Index)487 static void DecodeRW(Word Index)
488 {
489   if (!SplitArgs(0))
490     return;
491 
492   AddComp(InstrRW, Index);
493   DiscardArgs();
494 }
495 
DecodeWT(Word Index)496 static void DecodeWT(Word Index)
497 {
498   if (!SplitArgs(0))
499     return;
500 
501   AddComp(InstrWT, Index);
502   DiscardArgs();
503 }
504 
DecodeNF(Word Index)505 static void DecodeNF(Word Index)
506 {
507   if (!SplitArgs(0))
508     return;
509 
510   AddComp(InstrNF, Index);
511   DiscardArgs();
512 }
513 
DecodeWI(Word Index)514 static void DecodeWI(Word Index)
515 {
516   if (!SplitArgs(0))
517     return;
518 
519   AddComp(InstrWI, Index);
520   DiscardArgs();
521 }
522 
DecodeFIS(Word Index)523 static void DecodeFIS(Word Index)
524 {
525   if (!SplitArgs(0))
526     return;
527 
528   AddComp(InstrFIS, Index);
529   DiscardArgs();
530 }
531 
DecodeFD(Word Index)532 static void DecodeFD(Word Index)
533 {
534   if (!SplitArgs(0))
535     return;
536 
537   AddComp(InstrFD, Index);
538   DiscardArgs();
539 }
540 
DecodeSHV(Word Index)541 static void DecodeSHV(Word Index)
542 {
543   LongWord Value;
544   tSymbolFlags Flags;
545 
546   if (!SplitArgs(1))
547     return;
548 
549   Value = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt6, &Error, &Flags);
550   if (mFirstPassUnknown(Flags))
551     Value &= 31;
552   Error = (Value > 46) ? True : !Error;
553   if (!Error)
554     AddComp(InstrSHV, (Index << 6) + Value);
555   DiscardArgs();
556 }
557 
DecodeRPS(Word Index)558 static void DecodeRPS(Word Index)
559 {
560   LongWord Value;
561   UNUSED(Index);
562 
563   if (!SplitArgs(1))
564     return;
565   Value = EvalStrIntExpression(&ArgStr[1], UInt9, &Error);
566   Error = !Error;
567   if (!Error)
568     AddComp(InstrRPS, Value);
569   DiscardArgs();
570 }
571 
DecodeNAL(Word Index)572 static void DecodeNAL(Word Index)
573 {
574   LongWord Value;
575   tSymbolFlags Flags;
576 
577   UNUSED(Index);
578 
579   if (!SplitArgs(1))
580     return;
581 
582   Value = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt13, &Error, &Flags);
583   Error = !Error;
584   if (!Error)
585   {
586     if (ChkSamePage(Value, EProgCounter(), 9, Flags))
587       AddComp(InstrNAL, Value & 0x1ff);
588   }
589   DiscardArgs();
590 }
591 
DecodePseudo(void)592 static Boolean DecodePseudo(void)
593 {
594   int z;
595   Boolean OK;
596   TempResult t;
597   LongWord temp;
598   LongInt sign, mant, expo, Size;
599   char *cp, *cend;
600 
601   if (Memo("DW"))
602   {
603     if (ChkArgCnt(1, ArgCntMax))
604     {
605       z = 1; OK = True;
606       while ((OK) && (z <= ArgCnt))
607       {
608         EvalStrExpression(&ArgStr[z], &t);
609         switch(t.Typ)
610         {
611           case TempString:
612             if (MultiCharToInt(&t, 4))
613               goto ToInt;
614 
615             for (z = 0, cp = t.Contents.Ascii.Contents, cend = cp + t.Contents.Ascii.Length; cp < cend; cp++, z++)
616             {
617               DAsmCode[CodeLen] = (DAsmCode[CodeLen] << 8) + CharTransTable[((usint)*cp) & 0xff];
618               if ((z & 3) == 3)
619                 CodeLen++;
620             }
621             if ((z & 3) != 0)
622             {
623               DAsmCode[CodeLen] = (DAsmCode[CodeLen]) << ((4 - (z & 3)) << 3);
624               CodeLen++;
625             }
626             break;
627           case TempInt:
628           ToInt:
629             if (!RangeCheck(t.Contents.Int, Int32))
630             {
631               WrError(ErrNum_OverRange);
632               OK = False;
633               break;
634             }
635             DAsmCode[CodeLen++] = t.Contents.Int;
636             break;
637           case TempFloat:
638             if (!FloatRangeCheck(t.Contents.Float, Float32))
639             {
640               WrError(ErrNum_OverRange);
641               OK = False;
642               break;
643             }
644             Double_2_ieee4(t.Contents.Float, (Byte*) &temp, BigEndian);
645             sign = (temp >> 31) & 1;
646             expo = (temp >> 23) & 255;
647             mant = temp & 0x7fffff;
648             if ((mant == 0) && (expo == 0))
649               DAsmCode[CodeLen++] = 0x80000000;
650             else
651             {
652               if (expo > 0)
653               {
654                 mant |= 0x800000;
655                 expo -= 127;
656               }
657               else
658                 expo -= 126;
659               if (mant >= 0x800000)
660               {
661                 mant = mant >> 1;
662                 expo += 1;
663               }
664               if (sign == 1)
665                 mant = ((mant ^ 0xffffff) + 1);
666               DAsmCode[CodeLen++] = ((expo & 0xff) << 24) | (mant & 0xffffff);
667             }
668             break;
669           default:
670             OK = False;
671         }
672         z++;
673       }
674       if (!OK)
675         CodeLen = 0;
676     }
677     return True;
678   }
679 
680   if (Memo("DS"))
681   {
682     if (ChkArgCnt(1, 1))
683     {
684       tSymbolFlags Flags;
685 
686       Size = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
687       if (mFirstPassUnknown(Flags))
688       {
689         WrError(ErrNum_FirstPassCalc);
690         OK = False;
691       }
692       if (OK)
693       {
694         DontPrint = True;
695         if (!Size)
696           WrError(ErrNum_NullResMem);
697         CodeLen = Size;
698         BookKeeping();
699       }
700     }
701     return True;
702   }
703 
704   return FALSE;
705 }
706 
707 /*---------------------------------------------------------------------------*/
708 /* Codetabellenverwaltung */
709 
AddJmp(const char * NName,LongWord NCode)710 static void AddJmp(const char *NName, LongWord NCode)
711 {
712   if (InstrZ >= JmpOrderCnt) exit(255);
713   JmpOrders[InstrZ].Code = NCode;
714   AddInstTable(InstTable, NName, InstrZ++, DecodeJmp);
715 }
716 
AddALU1(const char * NName,LongWord NCode)717 static void AddALU1(const char *NName, LongWord NCode)
718 {
719   if (InstrZ >= ALU1OrderCnt) exit(255);
720   ALU1Orders[InstrZ].Code = NCode;
721   AddInstTable(InstTable, NName, InstrZ++, DecodeALU1);
722 }
723 
AddALU2(const char * NName,LongWord NCode)724 static void AddALU2(const char *NName, LongWord NCode)
725 {
726   if (InstrZ >= ALU2OrderCnt) exit(255);
727   ALU2Orders[InstrZ].Code = NCode;
728   AddInstTable(InstTable, NName, InstrZ++, DecodeALU2);
729 }
730 
AddSrcReg(const char * NName,LongWord NCode)731 static void AddSrcReg(const char *NName, LongWord NCode)
732 {
733   if (InstrZ >= SrcRegCnt) exit(255);
734   SrcRegs[InstrZ].Name = NName;
735   SrcRegs[InstrZ++].Code = NCode;
736 }
737 
AddALUSrcReg(const char * NName,LongWord NCode)738 static void AddALUSrcReg(const char *NName, LongWord NCode)
739 {
740   if (InstrZ >= ALUSrcRegCnt) exit(255);
741   ALUSrcRegs[InstrZ].Name = NName;
742   ALUSrcRegs[InstrZ++].Code = NCode;
743 }
744 
AddDestReg(const char * NName,LongWord NCode)745 static void AddDestReg(const char *NName, LongWord NCode)
746 {
747   if (InstrZ >= DestRegCnt) exit(255);
748   DestRegs[InstrZ].Name = NName;
749   DestRegs[InstrZ++].Code = NCode;
750 }
751 
InitFields(void)752 static void InitFields(void)
753 {
754   InstTable = CreateInstTable(201);
755 
756   AddInstTable(InstTable, "MOV", 0, DecodeMOV);
757   AddInstTable(InstTable, "LDI", 0, DecodeLDI);
758   AddInstTable(InstTable, "NOP", 0, DecodeNOP);
759 
760   AddInstTable(InstTable, "SPCBP0", 1, DecodeM0);
761   AddInstTable(InstTable, "SPCIX0", 2, DecodeM0);
762   AddInstTable(InstTable, "SPCBI0", 3, DecodeM0);
763 
764   AddInstTable(InstTable, "SPCBP1", 1, DecodeM1);
765   AddInstTable(InstTable, "SPCIX1", 2, DecodeM1);
766   AddInstTable(InstTable, "SPCBI1", 3, DecodeM1);
767 
768   AddInstTable(InstTable, "INCBP0", 1, DecodeDP0);
769   AddInstTable(InstTable, "DECBP0", 2, DecodeDP0);
770   AddInstTable(InstTable, "CLRBP0", 3, DecodeDP0);
771   AddInstTable(InstTable, "STIX0" , 4, DecodeDP0);
772   AddInstTable(InstTable, "INCIX0", 5, DecodeDP0);
773   AddInstTable(InstTable, "DECIX0", 6, DecodeDP0);
774   AddInstTable(InstTable, "CLRIX0", 7, DecodeDP0);
775 
776   AddInstTable(InstTable, "INCBP1", 1, DecodeDP1);
777   AddInstTable(InstTable, "DECBP1", 2, DecodeDP1);
778   AddInstTable(InstTable, "CLRBP1", 3, DecodeDP1);
779   AddInstTable(InstTable, "STIX1" , 4, DecodeDP1);
780   AddInstTable(InstTable, "INCIX1", 5, DecodeDP1);
781   AddInstTable(InstTable, "DECIX1", 6, DecodeDP1);
782   AddInstTable(InstTable, "CLRIX1", 7, DecodeDP1);
783 
784   AddInstTable(InstTable, "INCAR" , 1, DecodeEA);
785   AddInstTable(InstTable, "DECAR" , 2, DecodeEA);
786 
787   AddInstTable(InstTable, "XCHPSW", 1, DecodeFC);
788 
789   AddInstTable(InstTable, "INCRP" , 1, DecodeRP);
790   AddInstTable(InstTable, "DECRP" , 2, DecodeRP);
791   AddInstTable(InstTable, "INCBRP", 3, DecodeRP);
792 
793   AddInstTable(InstTable, "DECLC" , 1, DecodeL);
794 
795   AddInstTable(InstTable, "MCNBP0", InstrBASE0, DecodeBASE);
796   AddInstTable(InstTable, "MCNBP1", InstrBASE1, DecodeBASE);
797 
798   AddInstTable(InstTable, "BITRP" , 0, DecodeRPC);
799 
800   AddInstTable(InstTable, "CLRP2" , 0, DecodeP2);
801   AddInstTable(InstTable, "SETP2" , 1, DecodeP2);
802 
803   AddInstTable(InstTable, "CLRP3" , 0, DecodeP3);
804   AddInstTable(InstTable, "SETP3" , 1, DecodeP3);
805 
806   AddInstTable(InstTable, "DI"    , 0, DecodeEM);
807   AddInstTable(InstTable, "EI"    , 1, DecodeEM);
808   AddInstTable(InstTable, "CLRBM" , 1, DecodeBM);
809   AddInstTable(InstTable, "SETBM" , 2, DecodeBM);
810 
811   AddInstTable(InstTable, "RD"    , 1, DecodeRW);
812   AddInstTable(InstTable, "WR"    , 2, DecodeRW);
813 
814   AddInstTable(InstTable, "WRBORD", 1, DecodeWT);
815   AddInstTable(InstTable, "WRBL24", 2, DecodeWT);
816   AddInstTable(InstTable, "WRBL23", 3, DecodeWT);
817   AddInstTable(InstTable, "WRBEL8", 4, DecodeWT);
818   AddInstTable(InstTable, "WRBL8E", 5, DecodeWT);
819   AddInstTable(InstTable, "WRBXCH", 6, DecodeWT);
820   AddInstTable(InstTable, "WRBBRV", 7, DecodeWT);
821 
822   AddInstTable(InstTable, "TRNORM", 2, DecodeNF);
823   AddInstTable(InstTable, "RDNORM", 4, DecodeNF);
824   AddInstTable(InstTable, "FLTFIX", 6, DecodeNF);
825   AddInstTable(InstTable, "FIXMA" , 7, DecodeNF);
826 
827   AddInstTable(InstTable, "BWRL24", 1, DecodeWI);
828   AddInstTable(InstTable, "BWRORD", 2, DecodeWI);
829 
830   AddInstTable(InstTable, "SPCPSW0", 1, DecodeFIS);
831   AddInstTable(InstTable, "SPCPSW1", 2, DecodeFIS);
832   AddInstTable(InstTable, "CLRPSW0", 4, DecodeFIS);
833   AddInstTable(InstTable, "CLRPSW1", 5, DecodeFIS);
834   AddInstTable(InstTable, "CLRPSW" , 6, DecodeFIS);
835 
836   AddInstTable(InstTable, "SPIE", 1, DecodeFD);
837   AddInstTable(InstTable, "IESP", 2, DecodeFD);
838 
839   AddInstTable(InstTable, "SETSVL", 0, DecodeSHV);
840   AddInstTable(InstTable, "SETSVR", 1, DecodeSHV);
841 
842   AddInstTable(InstTable, "SPCRA", 0, DecodeRPS);
843   AddInstTable(InstTable, "JBLK" , 0, DecodeNAL);
844 
845   JmpOrders = (FixedOrder*) malloc(sizeof(FixedOrder)*JmpOrderCnt); InstrZ = 0;
846   AddJmp("JMP"   , 0x0100); AddJmp("CALL"  , 0x0101); AddJmp("RET"   , 0x0002);
847   AddJmp("JNZRP" , 0x0103); AddJmp("JZ0"   , 0x0104); AddJmp("JNZ0"  , 0x0105);
848   AddJmp("JZ1"   , 0x0106); AddJmp("JNZ1"  , 0x0107); AddJmp("JC0"   , 0x0108);
849   AddJmp("JNC0"  , 0x0109); AddJmp("JC1"   , 0x010a); AddJmp("JNC1"  , 0x010b);
850   AddJmp("JS0"   , 0x010c); AddJmp("JNS0"  , 0x010d); AddJmp("JS1"   , 0x010e);
851   AddJmp("JNS1"  , 0x010f); AddJmp("JV0"   , 0x0110); AddJmp("JNV0"  , 0x0111);
852   AddJmp("JV1"   , 0x0112); AddJmp("JNV1"  , 0x0113); AddJmp("JEV0"  , 0x0114);
853   AddJmp("JEV1"  , 0x0115); AddJmp("JNFSI" , 0x0116); AddJmp("JNESO" , 0x0117);
854   AddJmp("JIP0"  , 0x0118); AddJmp("JIP1"  , 0x0119); AddJmp("JNZIX0", 0x011a);
855   AddJmp("JNZIX1", 0x011b); AddJmp("JNZBP0", 0x011c); AddJmp("JNZBP1", 0x011d);
856   AddJmp("JRDY"  , 0x011e); AddJmp("JRQM"  , 0x011f);
857 
858   ALU1Orders = (FixedOrder*) malloc(sizeof(FixedOrder)*ALU1OrderCnt); InstrZ = 0;
859   AddALU1("INC"  , 0x01); AddALU1("DEC"  , 0x02); AddALU1("ABS"  , 0x03);
860   AddALU1("NOT"  , 0x04); AddALU1("NEG"  , 0x05); AddALU1("SHLC" , 0x06);
861   AddALU1("SHRC" , 0x07); AddALU1("ROL"  , 0x08); AddALU1("ROR"  , 0x09);
862   AddALU1("SHLM" , 0x0a); AddALU1("SHRM" , 0x0b); AddALU1("SHRAM", 0x0c);
863   AddALU1("CLR"  , 0x0d); AddALU1("NORM" , 0x0e); AddALU1("CVT"  , 0x0f);
864 
865   ALU2Orders = (FixedOrder*) malloc(sizeof(FixedOrder)*ALU2OrderCnt); InstrZ = 0;
866   AddALU2("ADD"  , 0x10); AddALU2("SUB"  , 0x11); AddALU2("ADDC" , 0x12);
867   AddALU2("SUBC" , 0x13); AddALU2("CMP"  , 0x14); AddALU2("AND"  , 0x15);
868   AddALU2("OR"   , 0x16); AddALU2("XOR"  , 0x17); AddALU2("ADDF" , 0x18);
869   AddALU2("SUBF" , 0x19);
870 
871   SrcRegs = (Register*) malloc(sizeof(Register)*SrcRegCnt); InstrZ = 0;
872   AddSrcReg("NON" , 0x00); AddSrcReg("RP"  , 0x01); AddSrcReg("PSW0" , 0x02);
873   AddSrcReg("PSW1", 0x03); AddSrcReg("SVR" , 0x04); AddSrcReg("SR"   , 0x05);
874   AddSrcReg("LC"  , 0x06); AddSrcReg("STX" , 0x07); AddSrcReg("M"    , 0x08);
875   AddSrcReg("ML"  , 0x09); AddSrcReg("ROM" , 0x0a); AddSrcReg("TR"   , 0x0b);
876   AddSrcReg("AR"  , 0x0c); AddSrcReg("SI"  , 0x0d); AddSrcReg("DR"   , 0x0e);
877   AddSrcReg("DRS" , 0x0f); AddSrcReg("WR0" , 0x10); AddSrcReg("WR1"  , 0x11);
878   AddSrcReg("WR2" , 0x12); AddSrcReg("WR3" , 0x13); AddSrcReg("WR4"  , 0x14);
879   AddSrcReg("WR5" , 0x15); AddSrcReg("WR6" , 0x16); AddSrcReg("WR7"  , 0x17);
880   AddSrcReg("RAM0", 0x18); AddSrcReg("RAM1", 0x19); AddSrcReg("BP0"  , 0x1a);
881   AddSrcReg("BP1" , 0x1b); AddSrcReg("IX0" , 0x1c); AddSrcReg("IX1"  , 0x1d);
882   AddSrcReg("K"   , 0x1e); AddSrcReg("L"   , 0x1f);
883 
884   ALUSrcRegs = (Register*) malloc(sizeof(Register)*ALUSrcRegCnt); InstrZ = 0;
885   AddALUSrcReg("IB"  , 0x00); AddALUSrcReg("M"   , 0x01);
886   AddALUSrcReg("RAM0", 0x02); AddALUSrcReg("RAM1", 0x03);
887 
888   DestRegs = (Register*) malloc(sizeof(Register)*DestRegCnt); InstrZ = 0;
889   AddDestReg("NON" , 0x00); AddDestReg("RP"  , 0x01); AddDestReg("PSW0" , 0x02);
890   AddDestReg("PSW1", 0x03); AddDestReg("SVR" , 0x04); AddDestReg("SR"   , 0x05);
891   AddDestReg("LC"  , 0x06); AddDestReg("STK" , 0x07); AddDestReg("LKR0" , 0x08);
892   AddDestReg("KLR1", 0x09); AddDestReg("TRE" , 0x0a); AddDestReg("TR"   , 0x0b);
893   AddDestReg("AR"  , 0x0c); AddDestReg("SO"  , 0x0d); AddDestReg("DR"   , 0x0e);
894   AddDestReg("DRS" , 0x0f); AddDestReg("WR0" , 0x10); AddDestReg("WR1"  , 0x11);
895   AddDestReg("WR2" , 0x12); AddDestReg("WR3" , 0x13); AddDestReg("WR4"  , 0x14);
896   AddDestReg("WR5" , 0x15); AddDestReg("WR6" , 0x16); AddDestReg("WR7"  , 0x17);
897   AddDestReg("RAM0", 0x18); AddDestReg("RAM1", 0x19); AddDestReg("BP0"  , 0x1a);
898   AddDestReg("BP1" , 0x1b); AddDestReg("IX0" , 0x1c); AddDestReg("IX1"  , 0x1d);
899   AddDestReg("K"   , 0x1e); AddDestReg("L"   , 0x1f);
900 
901   InstrComps = (LongWord*) malloc(sizeof(LongWord)*InstrCnt);
902   InstrDefs = (LongWord*) malloc(sizeof(LongWord)*InstrCnt);
903   for (InstrZ = 0; InstrZ < InstrCnt; InstrDefs[InstrZ++] = 0xffffffff);
904   InstrDefs[InstrALU] = 0;
905   InstrDefs[InstrMove] = 0;
906   InstrDefs[InstrBM] = 0;
907   InstrDefs[InstrEM] = 0;
908   InstrDefs[InstrDP0] = 0;
909   InstrDefs[InstrDP1] = 0;
910   InstrDefs[InstrEA] = 0;
911   InstrDefs[InstrFC] = 0;
912   InstrDefs[InstrFD] = 0;
913   InstrDefs[InstrFIS] = 0;
914   InstrDefs[InstrL] = 0;
915   InstrDefs[InstrM0] = 0;
916   InstrDefs[InstrM1] = 0;
917   InstrDefs[InstrNF] = 0;
918   InstrDefs[InstrRP] = 0;
919   InstrDefs[InstrRW] = 0;
920   InstrDefs[InstrWI] = 0;
921   InstrDefs[InstrWT] = 0;
922 }
923 
DeinitFields(void)924 static void DeinitFields(void)
925 {
926   DestroyInstTable(InstTable);
927 
928   free(SrcRegs);
929   free(ALUSrcRegs);
930   free(DestRegs);
931 
932   free(JmpOrders);
933   free(ALU1Orders);
934   free(ALU2Orders);
935 
936   free(InstrComps);
937   free(InstrDefs);
938 }
939 
940 /*---------------------------------------------------------------------------*/
941 /* Callbacks */
942 
MakeCode_77230(void)943 static void MakeCode_77230(void)
944 {
945   int z, z2;
946   LongWord Diff;
947 
948   /* Nullanweisung */
949 
950   if (Memo("") && !*AttrPart.Str && (ArgCnt == 0))
951     return;
952 
953   /* Pseudoanweisungen */
954 
955   if (DecodePseudo())
956     return;
957 
958   /* solange dekodieren, bis keine Operanden mehr da oder Fehler */
959 
960   Error = False;
961   InstrMask = 0;
962   memset(InstrComps, 0, sizeof(LongWord) * InstrCnt);
963   do
964   {
965     if (!LookupInstTable(InstTable, OpPart.Str))
966     {
967       WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
968       Error = True;
969     }
970   }
971   while ((!Error) && (*OpPart.Str != '\0'));
972 
973   /* passende Verknuepfung suchen */
974 
975   if (!Error)
976   {
977     for (z = 0; z < CaseCnt; z++)
978     {
979       /* Bits ermitteln, die nur in einer Maske vorhanden sind */
980 
981       Diff = InstrMask^CaseMasks[z];
982 
983       /* Fall nur moeglich, wenn Bits im aktuellen Fall gesetzt sind, die
984          der Fall nicht hat */
985 
986       if ((Diff & InstrMask) == 0)
987       {
988         /* ist irgendein Feld unbenutzt, fuer das wir keinen Default haben? */
989 
990         for (z2 = 0; z2 < InstrCnt; z2++)
991           if (((Diff & (1l << z2)) != 0) && (InstrDefs[z2] == 0xffffffff))
992             break;
993         if (z2 == InstrCnt)
994           break;
995       }
996     }
997 
998     switch (z)
999     {
1000       case 0: /* nur LDI */
1001         DAsmCode[0] = 0xe0000000 + InstrComps[InstrLDI];
1002         CodeLen = 1;
1003         break;
1004       case 1: /* JMP + MOV */
1005         DAsmCode[0] = 0xd0000000 + (InstrComps[InstrBranch] << 10)
1006                                  + InstrComps[InstrMove];
1007         CodeLen = 1;
1008         break;
1009       case 2: /* ALU + MOV + M0 + M1 + DP0 + DP1 */
1010         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1011                     + (InstrComps[InstrDP1] << 15) + (InstrComps[InstrDP0] << 18)
1012                     + (InstrComps[InstrM1] << 21) + (InstrComps[InstrM0] << 23);
1013         CodeLen = 1;
1014         break;
1015       case 3: /* ALU + MOV + EA + DP0 + DP1 */
1016         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1017                     + (InstrComps[InstrDP1] << 15) + (InstrComps[InstrDP0] << 18)
1018                     + (InstrComps[InstrEA] << 21) + 0x02000000;
1019         CodeLen = 1;
1020         break;
1021       case 4: /* ALU + MOV + RP + M0 + DP0 + FC */
1022         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1023                     + (InstrComps[InstrRP] << 21) + (InstrComps[InstrFC] << 15)
1024                     + (InstrComps[InstrM0] << 19) + (InstrComps[InstrDP0] << 16)
1025                     + 0x02800000;
1026         CodeLen = 1;
1027         break;
1028       case 5: /* ALU + MOV + RP + M1 + DP1 + FC */
1029         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1030                     + (InstrComps[InstrRP] << 21) + (InstrComps[InstrFC] << 15)
1031                     + (InstrComps[InstrM1] << 19) + (InstrComps[InstrDP1] << 16)
1032                     + 0x03000000;
1033         CodeLen = 1;
1034         break;
1035       case 6: /* ALU + MOV + RP + M0 + M1 + L + FC */
1036         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1037                     + (InstrComps[InstrRP] << 21) + (InstrComps[InstrL] << 16)
1038                     + (InstrComps[InstrM0] << 19) + (InstrComps[InstrM1] << 17)
1039                     + (InstrComps[InstrFC] << 15) + 0x03800000;
1040         CodeLen = 1;
1041         break;
1042       case 7: /* ALU + MOV + BASE0 + BASE1 + FC */
1043         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1044                     + (InstrComps[InstrBASE0] << 19) + (InstrComps[InstrBASE1] << 16)
1045                     + (InstrComps[InstrFC] << 15) + 0x04000000;
1046         CodeLen = 1;
1047         break;
1048       case 8: /* ALU + MOV + RPC + L+ FC */
1049         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1050                     + (InstrComps[InstrRPC] << 18) + (InstrComps[InstrL] << 16)
1051                     + (InstrComps[InstrFC] << 15) + 0x04400000;
1052         CodeLen = 1;
1053         break;
1054       case 9: /* ALU + MOV + P2 + P3 + EM + BM + L + FC */
1055         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1056                     + (InstrComps[InstrP2] << 20) + (InstrComps[InstrP3] << 21)
1057                     + (InstrComps[InstrEM] << 19) + (InstrComps[InstrBM] << 17)
1058                     + (InstrComps[InstrL] << 16) + (InstrComps[InstrFC] << 15)
1059                     + 0x04800000;
1060         CodeLen = 1;
1061         break;
1062       case 10: /* ALU + MOV + RW + L + FC */
1063         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1064                     + (InstrComps[InstrRW] << 20) + (InstrComps[InstrL] << 16)
1065                     + (InstrComps[InstrFC] << 15) + 0x04c00000;
1066         CodeLen = 1;
1067         break;
1068       case 11: /* ALU + MOV + WT + L + FC */
1069         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1070                     + (InstrComps[InstrWT] << 19) + (InstrComps[InstrL] << 16)
1071                     + (InstrComps[InstrFC] << 15) + 0x05000000;
1072         CodeLen = 1;
1073         break;
1074       case 12: /* ALU + MOV + NF + WI + L + FC */
1075         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1076                     + (InstrComps[InstrNF] << 19) + (InstrComps[InstrWI] << 17)
1077                     + (InstrComps[InstrL] << 16) + (InstrComps[InstrFC] << 15)
1078                     + 0x05400000;
1079         CodeLen = 1;
1080         break;
1081       case 13: /* ALU + MOV + FIS + FD + L */
1082         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1083                     + (InstrComps[InstrFIS] << 19) + (InstrComps[InstrFD] << 17)
1084                     + (InstrComps[InstrL] << 16) + 0x05800000;
1085         CodeLen = 1;
1086         break;
1087       case 14: /* ALU + MOV + SHV */
1088         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1089                     + (InstrComps[InstrSHV] << 15) + 0x05c00000;
1090         CodeLen = 1;
1091         break;
1092       case 15: /* ALU + MOV + RPS */
1093         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1094                     + (InstrComps[InstrRPS] << 15) + 0x06000000;
1095         CodeLen = 1;
1096         break;
1097       case 16: /* ALU + MOV + NAL */
1098         DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1099                     + (InstrComps[InstrNAL] << 15) + 0x07000000;
1100         CodeLen = 1;
1101         break;
1102       default:
1103         WrError(ErrNum_InvParAddrMode);
1104     }
1105   }
1106 }
1107 
IsDef_77230(void)1108 static Boolean IsDef_77230(void)
1109 {
1110   return False;
1111 }
1112 
SwitchFrom_77230(void)1113 static void SwitchFrom_77230(void)
1114 {
1115   DeinitFields();
1116 }
1117 
SwitchTo_77230(void)1118 static void SwitchTo_77230(void)
1119 {
1120   PFamilyDescr FoundDescr;
1121 
1122   FoundDescr = FindFamilyByName("77230");
1123 
1124   TurnWords = False;
1125   ConstMode = ConstModeIntel;
1126   PCSymbol = "$";
1127   HeaderID = FoundDescr->Id;
1128   NOPCode = 0x00000000;
1129   DivideChars = ",";
1130   HasAttrs = False;
1131 
1132   ValidSegs = (1 << SegCode) | (1 << SegXData) | (1 << SegYData) | (1 << SegRData);
1133   Grans[SegCode ] = 4; ListGrans[SegCode ] = 4; SegInits[SegCode ] = 0;
1134   SegLimits[SegCode ] = 0x1fff;
1135   Grans[SegXData] = 4; ListGrans[SegXData] = 4; SegInits[SegXData] = 0;
1136   SegLimits[SegXData] = 0x1ff;
1137   Grans[SegYData] = 4; ListGrans[SegYData] = 4; SegInits[SegYData] = 0;
1138   SegLimits[SegYData] = 0x1ff;
1139   Grans[SegRData] = 4; ListGrans[SegRData] = 4; SegInits[SegRData] = 0;
1140   SegLimits[SegRData] = 0x3ff;
1141 
1142   MakeCode = MakeCode_77230;
1143   IsDef = IsDef_77230;
1144   SwitchFrom = SwitchFrom_77230;
1145 
1146   InitFields();
1147 }
1148 
1149 /*---------------------------------------------------------------------------*/
1150 /* Initialisierung */
1151 
code77230_init(void)1152 void code77230_init(void)
1153 {
1154   CPU77230 = AddCPU("77230", SwitchTo_77230);
1155 }
1156