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