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