1 /* code53c8xx.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* Makroassembler AS */
6 /* */
7 /* Codegenerator SYM53C8xx */
8 /* */
9 /*****************************************************************************/
10
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14
15 #include "asmdef.h"
16 #include "asmsub.h"
17 #include "asmpars.h"
18 #include "asmitree.h"
19 #include "headids.h"
20 #include "strutil.h"
21 #include "codevars.h"
22 #include "intpseudo.h"
23 #include "errmsg.h"
24
25 #include "code53c8xx.h"
26
27 /*---------------------------------------------------------------------------*/
28
29 #define RegCnt 69
30
31 typedef struct
32 {
33 const char *Name;
34 LongWord Code;
35 Word Mask;
36 } TReg, *PReg;
37
38 static CPUVar CPU53C810, CPU53C860, CPU53C815, CPU53C825, CPU53C875,
39 CPU53C895;
40
41 #define M_53C810 0x0001
42 #define M_53C860 0x0002
43 #define M_53C815 0x0004
44 #define M_53C825 0x0008
45 #define M_53C875 0x0010
46 #define M_53C895 0x0020
47
48 static PReg Regs;
49
50 /*---------------------------------------------------------------------------*/
51
IsInToken(char Inp)52 static Boolean IsInToken(char Inp)
53 {
54 return ((Inp == '_') || (isalnum(((usint) Inp) & 0xff)));
55 }
56
GetToken(tStrComp * pSrc,tStrComp * pDest)57 static void GetToken(tStrComp *pSrc, tStrComp *pDest)
58 {
59 char *p;
60
61 /* search token start, by skipping spaces */
62
63 for (p = pSrc->Str; as_isspace(*p); p++)
64 if (*p == '\0') break;
65 StrCompCutLeft(pSrc, p - pSrc->Str);
66 if (*p == '\0')
67 {
68 StrCompReset(pDest);
69 return;
70 }
71 pDest->Pos.StartCol = pSrc->Pos.StartCol;
72
73 /* geklammerter Ausdruck ? */
74
75 if (*pSrc->Str == '(')
76 {
77 p = QuotPos(pSrc->Str, ')');
78
79 /* no closing ) -> copy all up to end */
80
81 if (!p)
82 {
83 StrCompCopy(pDest, pSrc);
84 StrCompCutLeft(pSrc, strlen(pSrc->Str));
85 }
86
87 /* otherwise, copy (...) */
88
89 else
90 {
91 pDest->Pos.Len = strmemcpy(pDest->Str, STRINGSIZE, pSrc->Str, p + 1 - pSrc->Str);
92 StrCompCutLeft(pSrc, p + 1 - pSrc->Str);
93 }
94 }
95
96 /* Spezialtoken ? */
97
98 else if (!IsInToken(*pSrc->Str))
99 {
100 pDest->Str[0] = *pSrc->Str;
101 pDest->Str[1] = '\0';
102 pDest->Pos.Len = 1;
103 StrCompCutLeft(pSrc, 1);
104 }
105
106 /* Wort ? */
107
108 else
109 {
110 for (; IsInToken(*p); p++)
111 if (*p == '\0')
112 break;
113 pDest->Pos.Len = strmemcpy(pDest->Str, STRINGSIZE, pSrc->Str, p - pSrc->Str);
114 StrCompCutLeft(pSrc, p - pSrc->Str);
115 }
116 }
117
118
DecodePhase(char * Name,LongWord * Result)119 static Boolean DecodePhase(char *Name, LongWord *Result)
120 {
121 *Result = 8;
122 if (!as_strcasecmp(Name, "DATA_OUT")) *Result = 0;
123 else if (!as_strcasecmp(Name, "DATA_IN")) *Result = 1;
124 else if (!as_strcasecmp(Name, "CMD")) *Result = 2;
125 else if (!as_strcasecmp(Name, "COMMAND")) *Result = 2;
126 else if (!as_strcasecmp(Name, "STATUS")) *Result = 3;
127 else if (!as_strcasecmp(Name, "RES4")) *Result = 4;
128 else if (!as_strcasecmp(Name, "RES5")) *Result = 5;
129 else if (!as_strcasecmp(Name, "MSG_OUT")) *Result = 6;
130 else if (!as_strcasecmp(Name, "MSG_IN")) *Result = 7;
131 else if (!as_strcasecmp(Name, "MESSAGE_OUT")) *Result = 6;
132 else if (!as_strcasecmp(Name, "MESSAGE_IN")) *Result = 7;
133 return (*Result < 8);
134 }
135
DecodeReg(char * Name,LongWord * Result)136 static Boolean DecodeReg(char *Name, LongWord *Result)
137 {
138 int z;
139 Integer Mask = 1 << (MomCPU - CPU53C810);
140 PReg Reg;
141
142 for (z = 0, Reg = Regs; z < RegCnt; z++, Reg++)
143 if (!(as_strcasecmp(Reg->Name, Name)) && (Mask & Reg->Mask))
144 {
145 *Result = Reg->Code;
146 return True;
147 }
148
149 return False;
150 }
151
Err(tErrorNum Num,const char * Msg)152 static Boolean Err(tErrorNum Num, const char *Msg)
153 {
154 WrXError(Num, Msg);
155 return False;
156 }
157
DecodeCond(tStrComp * pSrc,LongWord * Dest)158 static Boolean DecodeCond(tStrComp *pSrc, LongWord *Dest)
159 {
160 String TokStr;
161 tStrComp Tok;
162 Boolean PhaseATNUsed, DataUsed, CarryUsed, MaskUsed;
163 LongWord Tmp;
164 Boolean OK;
165
166 /* IF/WHEN/Nix-Unterscheidung - TRUE fuer Nix setzen */
167
168 StrCompMkTemp(&Tok, TokStr);
169 GetToken(pSrc, &Tok);
170 if (*Tok.Str == '\0')
171 {
172 *Dest |= 0x00080000;
173 return True;
174 }
175
176 if (as_strcasecmp(Tok.Str, "WHEN") == 0)
177 *Dest |= 0x00010000;
178 else if (as_strcasecmp(Tok.Str, "IF") != 0)
179 return Err(ErrNum_OpTypeMismatch, Tok.Str);
180
181 /* Negierung? */
182
183 GetToken(pSrc, &Tok);
184 if (as_strcasecmp(Tok.Str, "NOT") == 0)
185 GetToken(pSrc, &Tok);
186 else
187 *Dest |= 0x00080000;
188
189 /* Bedingungen durchgehen */
190
191 PhaseATNUsed = DataUsed = MaskUsed = CarryUsed = False;
192 do
193 {
194 if (!as_strcasecmp(Tok.Str, "ATN"))
195 {
196 if (PhaseATNUsed)
197 return Err(ErrNum_InvAddrMode, "2 x ATN/Phase");
198 if (CarryUsed)
199 return Err(ErrNum_InvAddrMode, "Carry + ATN/Phase");
200 if ((*Dest & 0x00010000) != 0)
201 return Err(ErrNum_InvAddrMode, "WHEN + ATN");
202 PhaseATNUsed = True;
203 *Dest |= 0x00020000;
204 }
205 else if (DecodePhase(Tok.Str, &Tmp))
206 {
207 if (PhaseATNUsed)
208 return Err(ErrNum_InvAddrMode, "2 x ATN/Phase");
209 if (CarryUsed)
210 return Err(ErrNum_InvAddrMode, "Carry + ATN/Phase");
211 PhaseATNUsed = True;
212 *Dest |= 0x00020000 + (Tmp << 24);
213 }
214 else if (!as_strcasecmp(Tok.Str, "CARRY"))
215 {
216 if (CarryUsed)
217 return Err(ErrNum_InvAddrMode, "2 x Carry");
218 if ((PhaseATNUsed) || (DataUsed))
219 return Err(ErrNum_InvAddrMode, "Carry + ...");
220 CarryUsed = True;
221 *Dest |= 0x00200000;
222 }
223 else if (!as_strcasecmp(Tok.Str, "MASK"))
224 {
225 if (CarryUsed)
226 return Err(ErrNum_InvAddrMode, "Carry + Data");
227 if (MaskUsed)
228 return Err(ErrNum_InvAddrMode, "2 x Mask");
229 if (!DataUsed)
230 return Err(ErrNum_InvAddrMode, "Mask + !Data");
231 GetToken(pSrc, &Tok);
232 Tmp = EvalStrIntExpression(&Tok, UInt8, &OK);
233 if (!OK)
234 return False;
235 MaskUsed = True;
236 *Dest |= (Tmp << 8);
237 }
238 else
239 {
240 if (CarryUsed)
241 return Err(ErrNum_InvAddrMode, "Carry + Data");
242 if (DataUsed)
243 return Err(ErrNum_InvAddrMode, "2 x Data");
244 Tmp = EvalStrIntExpression(&Tok, UInt8, &OK);
245 if (!OK)
246 return False;
247 DataUsed = True;
248 *Dest |= 0x00040000 + Tmp;
249 }
250 GetToken(pSrc, &Tok);
251 if (*Tok.Str != '\0')
252 {
253 if (as_strcasecmp(Tok.Str, "AND"))
254 return Err(ErrNum_InvAddrMode, Tok.Str);
255 GetToken(pSrc, &Tok);
256 }
257 }
258 while (*Tok.Str != '\0');
259
260 return True;
261 }
262
263 typedef enum
264 {
265 NONE, SFBR, REGISTER, IMM8
266 } CompType;
267
DecodeComp(const tStrComp * pInp,LongWord * Outp)268 static CompType DecodeComp(const tStrComp *pInp, LongWord *Outp)
269 {
270 Boolean OK;
271
272 if (!as_strcasecmp(pInp->Str, "SFBR"))
273 return SFBR;
274 else if (DecodeReg(pInp->Str, Outp))
275 return REGISTER;
276 else
277 {
278 *Outp = EvalStrIntExpression(pInp, Int8, &OK) & 0xff;
279 return (OK) ? IMM8 : NONE;
280 }
281 }
282
283 /*---------------------------------------------------------------------------*/
284
DecodeFixed(Word Index)285 static void DecodeFixed(Word Index)
286 {
287 if (ChkArgCnt(0, 0))
288 {
289 DAsmCode[0] = ((LongWord) Index) << 24;
290 DAsmCode[1] = 0x00000000;
291 CodeLen = 8;
292 }
293 }
294
DecodeJmps(Word Index)295 static void DecodeJmps(Word Index)
296 {
297 LongWord Buf;
298 LongInt Adr;
299 int l;
300 Boolean OK;
301 tSymbolFlags Flags;
302
303 if (ArgCnt == 0)
304 {
305 if (Memo("INTFLY"))
306 {
307 ArgCnt = 1;
308 strcpy(ArgStr[1].Str, "0");
309 }
310 else if (Memo("RETURN"))
311 {
312 ArgCnt = 1;
313 *ArgStr[1].Str = '\0';
314 }
315 }
316 if (ChkArgCnt(1, 2))
317 {
318 if (ArgCnt == 1)
319 {
320 if (Memo("RETURN"))
321 StrCompCopy(&ArgStr[2], &ArgStr[1]);
322 else
323 StrCompReset(&ArgStr[2]);
324 }
325 Buf = 0;
326 if (Memo("RETURN"))
327 {
328 Adr = 0;
329 OK = True;
330 }
331 else
332 {
333 l = strlen(ArgStr[1].Str);
334 if ((!as_strncasecmp(ArgStr[1].Str, "REL(", 4)) && (ArgStr[1].Str[l - 1] == ')'))
335 {
336 if (*OpPart.Str == 'I')
337 {
338 WrError(ErrNum_InvAddrMode);
339 OK = False;
340 }
341 Buf |= 0x00800000;
342 strmov(ArgStr[1].Str, ArgStr[1].Str + 4);
343 ArgStr[1].Str[l - 5] = '\0';
344 }
345 Adr = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt32, &OK, &Flags);
346 if ((OK) && (Buf != 0))
347 {
348 Adr -= EProgCounter() + 8;
349 if (!mSymbolQuestionable(Flags) && ((Adr > 0x7fffff) || (Adr < -0x800000)))
350 {
351 WrError(ErrNum_JmpDistTooBig);
352 OK = False;
353 }
354 }
355 }
356 if ((OK) && (DecodeCond(&ArgStr[2], &Buf)))
357 {
358 DAsmCode[0] = 0x80000000 + (((LongWord) Index) << 27) + Buf;
359 if (Memo("INTFLY")) DAsmCode[0] |= 0x00100000;
360 DAsmCode[1] = Adr;
361 CodeLen = 8;
362 }
363 }
364 }
365
DecodeCHMOV(Word Index)366 static void DecodeCHMOV(Word Index)
367 {
368 String TokenStr;
369 tStrComp Token, *pAdrArg = NULL;
370 LongWord Phase;
371 Boolean OK;
372
373 UNUSED(Index);
374 StrCompMkTemp(&Token, TokenStr);
375
376 if ((ChkExactCPUList(ErrNum_InstructionNotSupported, CPU53C825, CPU53C875, CPU53C895, CPUNone) >= 0)
377 && ChkArgCnt(2, 3))
378 {
379 GetToken(&ArgStr[ArgCnt], &Token);
380 if (!as_strcasecmp(Token.Str, "WITH"))
381 DAsmCode[0] = 0x08000000;
382 else if (!as_strcasecmp(Token.Str, "WHEN"))
383 DAsmCode[0] = 0x00000000;
384 else
385 {
386 WrStrErrorPos(ErrNum_InvAddrMode, &Token);
387 return;
388 }
389 KillPrefBlanksStrComp(&ArgStr[ArgCnt]);
390 KillPostBlanksStrComp(&ArgStr[ArgCnt]);
391 if (!DecodePhase(ArgStr[ArgCnt].Str, &Phase)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[ArgCnt]);
392 else
393 {
394 DAsmCode[0] |= Phase << 24;
395 OK = False;
396 if (ArgCnt == 2)
397 {
398 GetToken(&ArgStr[1], &Token);
399 if (as_strcasecmp(Token.Str, "FROM")) WrError(ErrNum_InvAddrMode);
400 else
401 {
402 pAdrArg = &ArgStr[1];
403 DAsmCode[0] |= 0x10000000;
404 OK = True;
405 }
406 }
407 else
408 {
409 Phase = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
410 if (OK)
411 {
412 DAsmCode[0] |= Phase;
413 if (!as_strncasecmp(ArgStr[2].Str,"PTR", 3))
414 {
415 StrCompCutLeft(&ArgStr[2], 4);
416 DAsmCode[0] |= 0x20000000;
417 }
418 pAdrArg = &ArgStr[2];
419 }
420 }
421 if (OK)
422 {
423 KillPrefBlanksStrComp(pAdrArg);
424 DAsmCode[1] = EvalStrIntExpression(pAdrArg, UInt32, &OK);
425 if (OK)
426 CodeLen = 8;
427 }
428 }
429 }
430 }
431
TrueFnc(void)432 static Boolean TrueFnc(void)
433 {
434 return True;
435 }
436
DecodeFlags(Word Index)437 static void DecodeFlags(Word Index)
438 {
439 Boolean OK;
440 String TokenStr;
441 tStrComp Token;
442
443 StrCompMkTemp(&Token, TokenStr);
444 if (ChkArgCnt(1, 1))
445 {
446 OK = True;
447 DAsmCode[0] = ((LongWord) Index) << 24;
448 DAsmCode[1] = 0;
449 while ((OK) && (*ArgStr[1].Str != '\0'))
450 {
451 GetToken(&ArgStr[1], &Token);
452 if (!as_strcasecmp(Token.Str, "ACK"))
453 DAsmCode[0] |= 0x00000040;
454 else if (!as_strcasecmp(Token.Str, "ATN"))
455 DAsmCode[0] |= 0x00000008;
456 else if (!as_strcasecmp(Token.Str, "TARGET"))
457 DAsmCode[0] |= 0x00000200;
458 else if (!as_strcasecmp(Token.Str, "CARRY"))
459 DAsmCode[0] |= 0x00000400;
460 else
461 {
462 OK = False;
463 WrStrErrorPos(ErrNum_InvAddrMode, &Token);
464 }
465 if (OK && (*ArgStr[1].Str != '\0'))
466 {
467 GetToken(&ArgStr[1], &Token);
468 if (as_strcasecmp(Token.Str, "AND"))
469 {
470 OK = False;
471 WrStrErrorPos(ErrNum_InvAddrMode, &Token);
472 }
473 }
474 }
475 if (OK)
476 CodeLen = 8;
477 }
478 }
479
DecodeRegTrans(Word Index)480 static void DecodeRegTrans(Word Index)
481 {
482 LongWord Reg, Cnt;
483 Boolean OK;
484
485 if (!ChkArgCnt(3, 3));
486 else if (!ChkExcludeCPU(CPU53C815));
487 else if (!DecodeReg(ArgStr[1].Str, &Reg)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
488 else
489 {
490 tSymbolFlags Flags;
491
492 Cnt = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt3, &OK, &Flags);
493 if (mFirstPassUnknown(Flags))
494 Cnt = 1;
495 if ((OK) && (ChkRange(Cnt, 1, 4)))
496 {
497 int l = strlen(ArgStr[3].Str);
498 DAsmCode[0] = 0xe0000000 + (((LongInt) Index) << 24) + (Reg << 16) + Cnt;
499 if ((!as_strncasecmp(ArgStr[3].Str, "DSAREL(", 7))
500 && (ArgStr[3].Str[l - 1] == ')'))
501 {
502 ArgStr[3].Str[--l] = '\0';
503 DAsmCode[0] |= 0x10000000;
504 DAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[3], 6, SInt24, &OK) & 0xffffff;
505 }
506 else
507 DAsmCode[1] = EvalStrIntExpression(&ArgStr[3], UInt32, &OK);
508 if (OK)
509 CodeLen = 8;
510 }
511 }
512 }
513
DecodeMOVE(Word Index)514 static void DecodeMOVE(Word Index)
515 {
516 #define MAXPARTS 8
517 Boolean WithCarry;
518 String TokenStr;
519 tStrComp Token;
520 LongWord Tmp, DReg , AriOp = 0xff, ImmVal = 0x100;
521 Boolean OK;
522 int z;
523 Word BigCPUMask = (1 << (CPU53C825 - CPU53C810))
524 | (1 << (CPU53C875 - CPU53C810))
525 | (1 << (CPU53C895 - CPU53C810));
526
527 UNUSED(Index);
528 StrCompMkTemp(&Token, TokenStr);
529
530 if (!ChkArgCnt(1, 3));
531 else if (ArgCnt == 1) /* MOVE Register */
532 {
533 String PartStr[MAXPARTS];
534 tStrComp Parts[MAXPARTS];
535 int PartCnt = 0;
536
537 for (z = 0; z < MAXPARTS; z++)
538 StrCompMkTemp(&Parts[z], PartStr[z]);
539 do
540 {
541 GetToken(&ArgStr[1], &Parts[PartCnt++]);
542 }
543 while ((*ArgStr[1].Str != '\0') && (PartCnt < MAXPARTS));
544 if ((PartCnt > 1) && (!as_strcasecmp(Parts[PartCnt - 1].Str, "CARRY")) && (!as_strcasecmp(Parts[PartCnt - 1].Str, "TO")))
545 {
546 WithCarry = True;
547 PartCnt -= 2;
548 }
549 else
550 WithCarry = False;
551 DAsmCode[0] = 0x40000000;
552 DAsmCode[1] = 0;
553 if (PartCnt == 3)
554 {
555 if (WithCarry) WrError(ErrNum_InvAddrMode);
556 else if (!as_strcasecmp(Parts[1].Str, "TO")) /* MOVE */
557 {
558 switch (DecodeComp(&Parts[0], &ImmVal))
559 {
560 case SFBR:
561 switch (DecodeComp(&Parts[2], &ImmVal))
562 {
563 case SFBR:
564 ImmVal = 8;
565 /* fall-through */
566 case REGISTER: /* --> 0x00 OR SFBR to reg */
567 DAsmCode[0] += 0x2a000000 + (ImmVal << 16);
568 CodeLen = 8;
569 break;
570 default:
571 WrError(ErrNum_InvAddrMode);
572 }
573 break;
574 case REGISTER:
575 DReg = ImmVal;
576 switch (DecodeComp(&Parts[2], &ImmVal))
577 {
578 case SFBR: /* --> 0x00 OR reg to SFBR */
579 DAsmCode[0] += 0x32000000 + (DReg << 16);
580 CodeLen = 8;
581 break;
582 case REGISTER:
583 if (ImmVal != DReg) WrError(ErrNum_InvAddrMode);
584 else
585 {
586 DAsmCode[0] += 0x3a000000 + (DReg << 16);
587 CodeLen = 8;
588 }
589 break;
590 default:
591 WrError(ErrNum_InvAddrMode);
592 }
593 break;
594 case IMM8:
595 switch (DecodeComp(&Parts[2], &DReg))
596 {
597 case SFBR:
598 DReg = 8;
599 /* fall-through */
600 case REGISTER: /* --> imm to reg */
601 DAsmCode[0] += 0x38000000 + (DReg << 16) + (ImmVal << 8);
602 CodeLen = 8;
603 break;
604 default:
605 WrError(ErrNum_InvAddrMode);
606 }
607 break;
608 default:
609 WrError(ErrNum_InvAddrMode);
610 break;
611 }
612 } /* ... TO ... */
613 else if ((!as_strcasecmp(Parts[1].Str, "SHL")) || (!as_strcasecmp(Parts[1].Str, "SHR")))
614 {
615 AriOp = 1 + (Ord(as_toupper(Parts[1].Str[2]) == 'R') << 2);
616 switch (DecodeComp(&Parts[0], &DReg))
617 {
618 case SFBR:
619 switch (DecodeComp(&Parts[2], &DReg))
620 {
621 case SFBR:
622 DReg = 8;
623 /* fall-through */
624 case REGISTER:
625 DAsmCode[0] += 0x28000000 + (AriOp << 24) + (DReg << 16);
626 CodeLen = 8;
627 break;
628 default:
629 WrError(ErrNum_InvAddrMode);
630 }
631 break;
632 case REGISTER:
633 ImmVal = DReg;
634 switch (DecodeComp(&Parts[2], &DReg))
635 {
636 case SFBR:
637 DAsmCode[0] += 0x30000000 + (AriOp << 24) + (ImmVal << 16);
638 CodeLen = 8;
639 break;
640 case REGISTER:
641 if (DReg != ImmVal) WrError(ErrNum_InvAddrMode);
642 else
643 {
644 DAsmCode[0] += 0x38000000 + (AriOp << 24) + (ImmVal << 16);
645 CodeLen = 8;
646 }
647 break;
648 default:
649 WrError(ErrNum_InvAddrMode);
650 }
651 break;
652 default:
653 WrError(ErrNum_InvAddrMode);
654 }
655 } /* ... SHx ... */
656 } /* PartCnt == 3 */
657 else if (PartCnt == 5)
658 {
659 if (as_strcasecmp(Parts[3].Str, "TO")) WrError(ErrNum_InvAddrMode);
660 else
661 {
662 if ((!as_strcasecmp(Parts[1].Str, "XOR"))
663 || (!as_strcasecmp(Parts[1].Str, "^")))
664 AriOp = 3;
665 else if ((!as_strcasecmp(Parts[1].Str, "OR"))
666 || (!as_strcasecmp(Parts[1].Str, "|")))
667 AriOp = 2;
668 else if ((!as_strcasecmp(Parts[1].Str, "AND"))
669 || (!as_strcasecmp(Parts[1].Str, "&")))
670 AriOp = 4;
671 else if (!strcmp(Parts[1].Str, "+"))
672 AriOp = 6;
673 if (WithCarry)
674 AriOp = (AriOp == 6) ? 7 : 0xff;
675 if (AriOp == 0xff) WrError(ErrNum_InvAddrMode);
676 else
677 {
678 DAsmCode[0] |= (AriOp << 24);
679 switch (DecodeComp(&Parts[0], &ImmVal))
680 {
681 case SFBR:
682 switch (DecodeComp(&Parts[2], &ImmVal))
683 {
684 case SFBR:
685 switch (DecodeComp(&Parts[4], &ImmVal))
686 {
687 case SFBR:
688 ImmVal = 8;
689 /* fall-through */
690 case REGISTER:
691 if (ChkExactCPUMask(BigCPUMask, CPU53C810) >= 0)
692 {
693 DAsmCode[0] |= 0x28800000 + (ImmVal << 16);
694 CodeLen = 8;
695 }
696 break;
697 default:
698 WrError(ErrNum_InvAddrMode);
699 }
700 break;
701 case IMM8:
702 switch (DecodeComp(&Parts[4], &DReg))
703 {
704 case SFBR:
705 DReg = 8;
706 /* fall-through */
707 case REGISTER:
708 DAsmCode[0] |= 0x28000000 + (DReg << 16) + (ImmVal << 8);
709 CodeLen = 8;
710 break;
711 default:
712 WrError(ErrNum_InvAddrMode);
713 }
714 break;
715 default:
716 WrError(ErrNum_InvAddrMode);
717 }
718 break;
719 case REGISTER:
720 DAsmCode[0] |= ImmVal << 16;
721 DReg = ImmVal;
722 switch (DecodeComp(&Parts[2], &ImmVal))
723 {
724 case SFBR:
725 switch (DecodeComp(&Parts[4], &ImmVal))
726 {
727 case SFBR:
728 if (ChkExactCPUMask(BigCPUMask, CPU53C810) >= 0)
729 {
730 DAsmCode[0] |= 0x30800000;
731 CodeLen = 8;
732 }
733 break;
734 case REGISTER:
735 if (DReg != ImmVal) WrError(ErrNum_InvAddrMode);
736 else if (ChkExactCPUMask(BigCPUMask, CPU53C810) >= 0)
737 {
738 DAsmCode[0] |= 0x38800000;
739 CodeLen = 8;
740 }
741 break;
742 default:
743 WrError(ErrNum_InvAddrMode);
744 }
745 break;
746 case IMM8:
747 DAsmCode[0] |= (ImmVal << 8);
748 switch (DecodeComp(&Parts[4], &Tmp))
749 {
750 case SFBR:
751 DAsmCode[0] |= 0x30000000;
752 CodeLen = 8;
753 break;
754 case REGISTER:
755 if (DReg != Tmp) WrError(ErrNum_InvAddrMode);
756 else
757 {
758 DAsmCode[0] |= 0x38000000;
759 CodeLen = 8;
760 }
761 break;
762 default:
763 WrError(ErrNum_InvAddrMode);
764 }
765 break;
766 default:
767 WrError(ErrNum_InvAddrMode);
768 }
769 break;
770 default:
771 WrError(ErrNum_InvAddrMode);
772 }
773 }
774 }
775 } /* PartCnt == 5 */
776 else
777 WrError(ErrNum_InvAddrMode);
778 }
779 else if (ArgCnt == 2)
780 {
781 GetToken(&ArgStr[1], &Token);
782 if (as_strcasecmp(Token.Str, "FROM")) WrError(ErrNum_InvAddrMode);
783 else
784 {
785 DAsmCode[0] = 0x00000000;
786 DAsmCode[1] = EvalStrIntExpression(&ArgStr[1], Int32, &OK);
787 if (OK)
788 {
789 GetToken(&ArgStr[2], &Token);
790 OK = True;
791 if (!as_strcasecmp(Token.Str, "WHEN"))
792 DAsmCode[0] |= 0x08000000;
793 else if (as_strcasecmp(Token.Str, "WITH"))
794 OK = False;
795 if (!OK) WrError(ErrNum_InvAddrMode);
796 else
797 {
798 KillPrefBlanksStrComp(&ArgStr[2]);
799 KillPostBlanksStrComp(&ArgStr[2]);
800 if (!DecodePhase(ArgStr[2].Str, &ImmVal)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
801 else
802 {
803 DAsmCode[0] |= ImmVal << 24;
804 CodeLen = 8;
805 }
806 }
807 }
808 }
809 }
810 else if (ArgCnt == 3)
811 {
812 if (!as_strncasecmp(ArgStr[1].Str, "MEMORY", 6))
813 {
814 StrCompCutLeft(&ArgStr[1], 7);
815 if (!as_strncasecmp(ArgStr[1].Str, "NO FLUSH", 8))
816 {
817 DAsmCode[0] = 0xc1000000;
818 StrCompCutLeft(&ArgStr[1], 9);
819 }
820 else DAsmCode[0] = 0xc0000000;
821 DAsmCode[0] |= EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
822 if (OK)
823 {
824 DAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int32, &OK);
825 if (OK)
826 {
827 DAsmCode[2] = EvalStrIntExpression(&ArgStr[3], Int32, &OK);
828 if (OK) CodeLen = 12;
829 }
830 }
831 }
832 else
833 {
834 DAsmCode[0] = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
835 if (OK)
836 {
837 GetToken(&ArgStr[3], &Token);
838 OK = True;
839 if (!as_strcasecmp(Token.Str, "WHEN")) DAsmCode[0] |= 0x08000000;
840 else if (as_strcasecmp(Token.Str, "WITH")) OK = False;
841 if (!OK) WrError(ErrNum_InvAddrMode);
842 else
843 {
844 KillPrefBlanksStrComp(&ArgStr[3]);
845 KillPostBlanksStrComp(&ArgStr[3]);
846 if (!DecodePhase(ArgStr[3].Str, &ImmVal)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[3]);
847 else
848 {
849 DAsmCode[0] |= ImmVal << 24;
850 if (!as_strncasecmp(ArgStr[2].Str, "PTR", 3))
851 {
852 StrCompCutLeft(&ArgStr[2], 4);
853 DAsmCode[0] |= 0x20000000;
854 }
855 DAsmCode[1] = EvalStrIntExpression(&ArgStr[2], UInt32, &OK);
856 if (OK) CodeLen = 8;
857 }
858 }
859 }
860 }
861 }
862 }
863
DecodeSELECT(Word MayATN)864 static void DecodeSELECT(Word MayATN)
865 {
866 Boolean OK;
867 LongInt Dist;
868 tSymbolFlags Flags;
869 int l;
870
871 if (ChkArgCnt(2, 2))
872 {
873 DAsmCode[0] = 0x40000000;
874 OK = True;
875 if (!as_strncasecmp(ArgStr[1].Str, "ATN ", 4))
876 {
877 strmov(ArgStr[1].Str, ArgStr[1].Str + 4);
878 ArgStr[1].Pos.StartCol += 4;
879 ArgStr[1].Pos.Len -= 4;
880 KillPrefBlanksStrComp(&ArgStr[1]);
881 if (!MayATN)
882 OK = False;
883 else
884 DAsmCode[0] |= 0x01000000;
885 }
886 if (!OK) WrError(ErrNum_InvAddrMode);
887 else
888 {
889 if (!as_strncasecmp(ArgStr[1].Str, "FROM ", 5))
890 {
891 strmov(ArgStr[1].Str, ArgStr[1].Str + 5);
892 ArgStr[1].Pos.StartCol += 5;
893 ArgStr[1].Pos.Len -= 5;
894 KillPrefBlanksStrComp(&ArgStr[1]);
895 DAsmCode[0] |= 0x02000000 + EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
896 }
897 else
898 DAsmCode[0] |= EvalStrIntExpression(&ArgStr[1], UInt4, &OK) << 16;
899 if (OK)
900 {
901 l = strlen(ArgStr[2].Str);
902 if ((!as_strncasecmp(ArgStr[2].Str, "REL(", 4)) && (ArgStr[2].Str[l - 1] == ')'))
903 {
904 DAsmCode[0] |= 0x04000000;
905 ArgStr[2].Str[l - 1] = '\0';
906 Dist = EvalStrIntExpressionOffsWithFlags(&ArgStr[2], 4, UInt32, &OK, &Flags) - (EProgCounter() + 8);
907 if (OK)
908 {
909 if (!mSymbolQuestionable(Flags) && ((Dist > 0x7fffff) || (Dist < -0x800000))) WrError(ErrNum_JmpDistTooBig);
910 else DAsmCode[1] = Dist & 0xffffff;
911 }
912 }
913 else DAsmCode[1] = EvalStrIntExpression(&ArgStr[2], UInt32, &OK);
914 if (OK) CodeLen = 8;
915 }
916 }
917 }
918 }
919
DecodeWAIT(Word Index)920 static void DecodeWAIT(Word Index)
921 {
922 String TokenStr;
923 tStrComp Token;
924 Boolean OK;
925 LongInt Dist;
926 tSymbolFlags Flags;
927
928 UNUSED(Index);
929 StrCompMkTemp(&Token, TokenStr);
930
931 if (ChkArgCnt(1, 1))
932 {
933 GetToken(&ArgStr[1], &Token);
934 KillPrefBlanksStrComp(&ArgStr[1]);
935 if (!as_strcasecmp(Token.Str, "DISCONNECT"))
936 {
937 if (*ArgStr[1].Str != '\0') WrError(ErrNum_InvAddrMode);
938 else
939 {
940 DAsmCode[0] = 0x48000000;
941 DAsmCode[1] = 0;
942 CodeLen = 8;
943 }
944 }
945 else if ((!as_strcasecmp(Token.Str, "RESELECT")) || (!as_strcasecmp(Token.Str, "SELECT")))
946 {
947 if ((!as_strncasecmp(ArgStr[1].Str, "REL(", 4)) && (ArgStr[1].Str[strlen(ArgStr[1].Str) - 1] == ')'))
948 {
949 StrCompShorten(&ArgStr[1], 1);
950 DAsmCode[0] = 0x54000000;
951 Dist = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], 4, UInt32, &OK, &Flags) - (EProgCounter() + 8);
952 if (OK)
953 {
954 if (mSymbolQuestionable(Flags) && ((Dist > 0x7fffff) || (Dist < -0x800000))) WrError(ErrNum_JmpDistTooBig);
955 else
956 DAsmCode[1] = Dist & 0xffffff;
957 }
958 }
959 else
960 {
961 DAsmCode[0] = 0x50000000;
962 DAsmCode[1] = EvalStrIntExpression(&ArgStr[1], UInt32, &OK);
963 }
964 if (OK)
965 {
966 if (as_toupper(*Token.Str) == 'S')
967 DAsmCode[0] |= 0x00000200;
968 CodeLen = 8;
969 }
970 }
971 }
972 }
973
974 /*---------------------------------------------------------------------------*/
975
AddReg(const char * NName,LargeWord Adr,Word Mask)976 static void AddReg(const char *NName, LargeWord Adr, Word Mask)
977 {
978 if (InstrZ >= RegCnt) exit(255);
979 Regs[InstrZ].Name = NName;
980 Regs[InstrZ].Code = Adr;
981 Regs[InstrZ++].Mask = Mask;
982 }
983
InitFields(void)984 static void InitFields(void)
985 {
986 InstTable = CreateInstTable(51);
987 AddInstTable(InstTable, "NOP" , 0x80, DecodeFixed);
988 AddInstTable(InstTable, "DISCONNECT" , 0x48, DecodeFixed);
989 AddInstTable(InstTable, "JUMP" , 0, DecodeJmps);
990 AddInstTable(InstTable, "CALL" , 1, DecodeJmps);
991 AddInstTable(InstTable, "RETURN" , 2, DecodeJmps);
992 AddInstTable(InstTable, "INT" , 3, DecodeJmps);
993 AddInstTable(InstTable, "INTFLY" , 3, DecodeJmps);
994 AddInstTable(InstTable, "CHMOV" , 0, DecodeCHMOV);
995 AddInstTable(InstTable, "CLEAR" , 0x60, DecodeFlags);
996 AddInstTable(InstTable, "SET" , 0x58, DecodeFlags);
997 AddInstTable(InstTable, "LOAD" , 1, DecodeRegTrans);
998 AddInstTable(InstTable, "STORE" , 0, DecodeRegTrans);
999 AddInstTable(InstTable, "MOVE" , 0, DecodeMOVE);
1000 AddInstTable(InstTable, "RESELECT", 0, DecodeSELECT);
1001 AddInstTable(InstTable, "SELECT" , 1, DecodeSELECT);
1002 AddInstTable(InstTable, "WAIT" , 0, DecodeWAIT);
1003
1004 Regs = (PReg) malloc(sizeof(TReg) * RegCnt); InstrZ = 0;
1005 AddReg("SCNTL0" , 0x00, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1006 AddReg("SCNTL1" , 0x01, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1007 AddReg("SCNTL2" , 0x02, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1008 AddReg("SCNTL3" , 0x03, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1009 AddReg("SCID" , 0x04, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1010 AddReg("SXFER" , 0x05, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1011 AddReg("SDID" , 0x06, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1012 AddReg("GPREG" , 0x07, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1013 AddReg("SFBR" , 0x08, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1014 AddReg("SOCL" , 0x09, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1015 AddReg("SSID" , 0x0a, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1016 AddReg("SBCL" , 0x0b, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1017 AddReg("DSTAT" , 0x0c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1018 AddReg("SSTAT0" , 0x0d, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1019 AddReg("SSTAT1" , 0x0e, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1020 AddReg("SSTAT2" , 0x0f, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1021 AddReg("DSA" , 0x10, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1022 AddReg("ISTAT" , 0x14, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1023 AddReg("CTEST0" , 0x18, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1024 AddReg("CTEST1" , 0x19, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1025 AddReg("CTEST2" , 0x1a, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1026 AddReg("CTEST3" , 0x1b, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1027 AddReg("TEMP" , 0x1c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1028 AddReg("DFIFO" , 0x20, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1029 AddReg("CTEST4" , 0x21, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1030 AddReg("CTEST5" , 0x22, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1031 AddReg("CTEST6" , 0x23, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1032 AddReg("DBC" , 0x24, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1033 AddReg("DCMD" , 0x27, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1034 AddReg("DNAD" , 0x28, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1035 AddReg("DSP" , 0x2c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1036 AddReg("DSPS" , 0x30, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1037 AddReg("SCRATCHA" , 0x34, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1038 AddReg("DMODE" , 0x38, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1039 AddReg("DIEN" , 0x39, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1040 AddReg("SBR" , 0x3a, M_53C810 + M_53C860 + M_53C875 + M_53C895);
1041 AddReg("DWT" , 0x3a, M_53C815 );
1042 AddReg("DCNTL" , 0x3b, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1043 AddReg("ADDER" , 0x3c, M_53C810 + M_53C825 + M_53C860 + M_53C895);
1044 AddReg("SIEN0" , 0x40, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1045 AddReg("SIEN1" , 0x41, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1046 AddReg("SIST0" , 0x42, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1047 AddReg("SIST1" , 0x43, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1048 AddReg("SLPAR" , 0x44, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1049 AddReg("SWIDE" , 0x45, M_53C825 + M_53C875 + M_53C895);
1050 AddReg("MACNTL" , 0x46, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1051 AddReg("GPCNTL" , 0x47, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1052 AddReg("STIME0" , 0x48, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1053 AddReg("STIME1" , 0x49, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1054 AddReg("RESPID" , 0x4a, M_53C810 + M_53C815 + M_53C825 + M_53C860 );
1055 AddReg("RESPID0" , 0x4a, M_53C875 + M_53C895);
1056 AddReg("RESPID1" , 0x4b, M_53C875 + M_53C895);
1057 AddReg("STEST0" , 0x4c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1058 AddReg("STEST1" , 0x4d, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1059 AddReg("STEST2" , 0x4e, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1060 AddReg("STEST3" , 0x4f, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1061 AddReg("SIDL" , 0x50, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1062 AddReg("STEST4" , 0x52, + M_53C895);
1063 AddReg("SODL" , 0x54, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1064 AddReg("SBDL" , 0x58, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1065 AddReg("SCRATCHB" , 0x5c, M_53C810 + M_53C815 + M_53C825 + M_53C860 + M_53C875 + M_53C895);
1066 AddReg("SCRATCHC" , 0x60, M_53C875 + M_53C895);
1067 AddReg("SCRATCHD" , 0x64, M_53C875 + M_53C895);
1068 AddReg("SCRATCHE" , 0x68, M_53C875 + M_53C895);
1069 AddReg("SCRATCHF" , 0x6c, M_53C875 + M_53C895);
1070 AddReg("SCRATCHG" , 0x70, M_53C875 + M_53C895);
1071 AddReg("SCRATCHH" , 0x74, M_53C875 + M_53C895);
1072 AddReg("SCRATCHI" , 0x78, M_53C875 + M_53C895);
1073 AddReg("SCRATCHJ" , 0x7c, M_53C875 + M_53C895);
1074 }
1075
DeinitFields(void)1076 static void DeinitFields(void)
1077 {
1078 DestroyInstTable(InstTable);
1079 free(Regs);
1080 }
1081
1082 /*---------------------------------------------------------------------------*/
1083
MakeCode_53c8xx(void)1084 static void MakeCode_53c8xx(void)
1085 {
1086 CodeLen = 0;
1087 DontPrint = False;
1088
1089 /* zu ignorierendes */
1090
1091 if (Memo(""))
1092 return;
1093
1094 if (DecodeIntelPseudo(False))
1095 return;
1096
1097 if (!LookupInstTable(InstTable, OpPart.Str))
1098 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
1099 }
1100
IsDef_53c8xx(void)1101 static Boolean IsDef_53c8xx(void)
1102 {
1103 return False;
1104 }
1105
SwitchFrom_53c8xx(void)1106 static void SwitchFrom_53c8xx(void)
1107 {
1108 DeinitFields();
1109 }
1110
SwitchTo_53c8xx(void)1111 static void SwitchTo_53c8xx(void)
1112 {
1113 PFamilyDescr FoundDescr;
1114
1115 FoundDescr = FindFamilyByName("SYM53C8xx");
1116
1117 TurnWords = False;
1118 ConstMode = ConstModeC;
1119 SetIsOccupiedFnc = TrueFnc;
1120 PCSymbol="$";
1121 HeaderID = FoundDescr->Id;
1122 NOPCode = 0;
1123 DivideChars = ",";
1124 HasAttrs = False;
1125
1126 ValidSegs = (1 << SegCode);
1127 Grans[SegCode ] = 1; ListGrans[SegCode ] = 4; SegInits[SegCode ] = 0;
1128 SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
1129
1130 MakeCode = MakeCode_53c8xx;
1131 IsDef = IsDef_53c8xx;
1132 SwitchFrom = SwitchFrom_53c8xx;
1133
1134 InitFields();
1135 }
1136
1137 /*---------------------------------------------------------------------------*/
1138
code53c8xx_init(void)1139 void code53c8xx_init(void)
1140 {
1141 CPU53C810 = AddCPU("SYM53C810", SwitchTo_53c8xx);
1142 CPU53C860 = AddCPU("SYM53C860", SwitchTo_53c8xx);
1143 CPU53C815 = AddCPU("SYM53C815", SwitchTo_53c8xx);
1144 CPU53C825 = AddCPU("SYM53C825", SwitchTo_53c8xx);
1145 CPU53C875 = AddCPU("SYM53C875", SwitchTo_53c8xx);
1146 CPU53C895 = AddCPU("SYM53C895", SwitchTo_53c8xx);
1147 }
1148