1 /* code68.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* Codegenerator fuer 68xx Prozessoren */
8 /* */
9 /*****************************************************************************/
10
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14
15 #include "bpemu.h"
16 #include "strutil.h"
17 #include "asmdef.h"
18 #include "asmpars.h"
19 #include "asmallg.h"
20 #include "asmsub.h"
21 #include "errmsg.h"
22 #include "codepseudo.h"
23 #include "motpseudo.h"
24 #include "asmitree.h"
25 #include "codevars.h"
26 #include "nlmessages.h"
27 #include "as.rsc"
28
29 #include "code68.h"
30
31 /*---------------------------------------------------------------------------*/
32
33 typedef struct
34 {
35 CPUVar MinCPU, MaxCPU;
36 Word Code;
37 } FixedOrder;
38
39 typedef struct
40 {
41 CPUVar MinCPU;
42 Word Code;
43 } RelOrder;
44
45 typedef struct
46 {
47 Boolean MayImm;
48 CPUVar MinCPU; /* Shift andere ,Y */
49 Byte PageShift; /* 0 : nix Pg 2 */
50 Byte Code; /* 1 : Pg 3 Pg 4 */
51 } ALU16Order; /* 2 : nix Pg 4 */
52 /* 3 : Pg 2 Pg 3 */
53
54 enum
55 {
56 ModNone = -1,
57 ModAcc = 0,
58 ModDir = 1,
59 ModExt = 2,
60 ModInd = 3,
61 ModImm = 4
62 };
63
64 #define MModAcc (1 << ModAcc)
65 #define MModDir (1 << ModDir)
66 #define MModExt (1 << ModExt)
67 #define MModInd (1 << ModInd)
68 #define MModImm (1 << ModImm)
69
70 #define Page2Prefix 0x18
71 #define Page3Prefix 0x1a
72 #define Page4Prefix 0xcd
73
74 #define FixedOrderCnt 45
75 #define RelOrderCnt 19
76 #define ALU16OrderCnt 16
77
78
79 static tSymbolSize OpSize;
80 static Byte PrefCnt; /* Anzahl Befehlspraefixe */
81 static ShortInt AdrMode; /* Ergebnisadressmodus */
82 static Byte AdrPart; /* Adressierungsmodusbits im Opcode */
83 static Byte AdrVals[4]; /* Adressargument */
84
85 static FixedOrder *FixedOrders;
86 static RelOrder *RelOrders;
87 static ALU16Order *ALU16Orders;
88
89 static LongInt Reg_MMSIZ, Reg_MMWBR, Reg_MM1CR, Reg_MM2CR;
90 static LongWord Win1VStart, Win1VEnd, Win1PStart, Win1PEnd,
91 Win2VStart, Win2VEnd, Win2PStart, Win2PEnd;
92
93 static CPUVar CPU6800, CPU6801, CPU6301, CPU6811, CPU68HC11K4;
94
95 /*---------------------------------------------------------------------------*/
96
SetK4Ranges(void)97 static void SetK4Ranges(void)
98 {
99 Byte WSize;
100
101 /* window 1 first */
102
103 WSize = Reg_MMSIZ & 0x3;
104 if (WSize)
105 {
106 /* window size */
107
108 Win1VEnd = Win1PEnd = 0x1000 << WSize;
109
110 /* physical start: assume 8K window, systematically clip out bits for
111 larger windows */
112
113 Win1PStart = (Reg_MMWBR & 0x0e) << 12;
114 if (WSize > 1)
115 Win1PStart &= ~0x2000;
116 if (WSize > 2)
117 Win1PStart = (Win1PStart == 0xc000) ? 0x8000 : Win1PStart;
118
119 /* logical start: mask out lower bits according to window size */
120
121 Win1VStart = ((Reg_MM1CR & 0x7f & (~((1 << WSize) - 1))) << 12) + 0x10000;
122
123 /* set end addresses */
124
125 Win1VEnd += Win1VStart;
126 Win1PEnd += Win1PStart;
127 }
128 else
129 Win1VStart = Win1VEnd = Win1PStart = Win1PEnd = 0;
130
131 /* window 2 similarly */
132
133 WSize = Reg_MMSIZ & 0x30;
134 if (WSize)
135 {
136 /* window size */
137
138 WSize = WSize >> 4;
139 Win2VEnd = Win2PEnd = 0x1000 << WSize;
140
141 /* physical start: assume 8K window, systematically clip out bits for
142 larger windows */
143
144 Win2PStart = (Reg_MMWBR & 0x0e0) << 8;
145 if (WSize > 1)
146 Win2PStart &= ~0x2000;
147 if (WSize > 2)
148 Win2PStart = (Win2PStart == 0xc000) ? 0x8000 : Win2PStart;
149
150 /* logical start: mask out lower bits according to window size */
151
152 Win2VStart = ((Reg_MM2CR & 0x7f & (~((1 << WSize) - 1))) << 12) + 0x90000;
153
154 /* set end addresses */
155
156 Win2VEnd += Win2VStart;
157 Win2PEnd += Win2PStart;
158 }
159 else
160 Win2VStart = Win2VEnd = Win2PStart = Win2PEnd = 0;
161 }
162
TranslateAddress(LongWord * Address)163 static void TranslateAddress(LongWord *Address)
164 {
165 /* do not translate the first 64K */
166
167 if (*Address < 0x10000)
168 return;
169
170 /* in first window ? */
171
172 if ((*Address >= Win1VStart) && (*Address < Win1VEnd))
173 {
174 *Address = Win1PStart + (Win1VStart - *Address);
175 return;
176 }
177
178 /* in second window ? After calculation, check against overlap into first
179 window. */
180
181 if ((*Address >= Win2VStart) && (*Address < Win2VEnd))
182 {
183 *Address = Win2PStart + (Win2VStart - *Address);
184 if ((*Address >= Win1PStart) && (*Address < Win1PEnd))
185 WrError(ErrNum_InAccPage);
186 return;
187 }
188
189 /* print out warning if not mapped */
190
191 *Address &= 0xffff;
192 WrError(ErrNum_InAccPage);
193 }
194
195 /*---------------------------------------------------------------------------*/
196
DecodeAcc(const char * pArg,Byte * pReg)197 static Boolean DecodeAcc(const char *pArg, Byte *pReg)
198 {
199 static const char Regs[] = "AB";
200
201 if (strlen(pArg) == 1)
202 {
203 const char *pPos = strchr(Regs, as_toupper(*pArg));
204
205 if (pPos)
206 {
207 *pReg = pPos - Regs;
208 return True;
209 }
210 }
211 return False;
212 }
213
DecodeAdr(int StartInd,int StopInd,Byte Erl)214 static void DecodeAdr(int StartInd, int StopInd, Byte Erl)
215 {
216 tStrComp *pStartArg = &ArgStr[StartInd];
217 Boolean OK, ErrOcc;
218 tSymbolFlags Flags;
219 LongWord AdrWord;
220 Byte Bit8;
221
222 AdrMode = ModNone;
223 AdrPart = 0;
224 ErrOcc = False;
225
226 /* eine Komponente ? */
227
228 if (StartInd == StopInd)
229 {
230 /* Akkumulatoren ? */
231
232 if (DecodeAcc(pStartArg->Str, &AdrPart))
233 {
234 if (MModAcc & Erl)
235 AdrMode = ModAcc;
236 }
237
238 /* immediate ? */
239
240 else if ((strlen(pStartArg->Str) > 1) && (*pStartArg->Str == '#'))
241 {
242 if (MModImm & Erl)
243 {
244 if (OpSize == eSymbolSize16Bit)
245 {
246 AdrWord = EvalStrIntExpressionOffs(pStartArg, 1, Int16, &OK);
247 if (OK)
248 {
249 AdrMode = ModImm;
250 AdrVals[AdrCnt++] = Hi(AdrWord);
251 AdrVals[AdrCnt++] = Lo(AdrWord);
252 }
253 else
254 ErrOcc = True;
255 }
256 else
257 {
258 AdrVals[AdrCnt] = EvalStrIntExpressionOffs(pStartArg, 1, Int8, &OK);
259 if (OK)
260 {
261 AdrMode = ModImm;
262 AdrCnt++;
263 }
264 else
265 ErrOcc = True;
266 }
267 }
268 }
269
270 /* absolut ? */
271
272 else
273 {
274 unsigned Offset = 0;
275
276 Bit8 = 0;
277 if (pStartArg->Str[Offset] == '<')
278 {
279 Bit8 = 2;
280 Offset++;
281 }
282 else if (pStartArg->Str[Offset] == '>')
283 {
284 Bit8 = 1;
285 Offset++;
286 }
287 if (MomCPU == CPU68HC11K4)
288 {
289 AdrWord = EvalStrIntExpressionOffsWithFlags(pStartArg, Offset, UInt21, &OK, &Flags);
290 if (OK)
291 TranslateAddress(&AdrWord);
292 }
293 else
294 AdrWord = EvalStrIntExpressionOffsWithFlags(pStartArg, Offset, UInt16, &OK, &Flags);
295 if (OK)
296 {
297 if ((MModDir & Erl) && (Bit8 != 1) && ((Bit8 == 2) || (!(MModExt & Erl)) || (Hi(AdrWord) == 0)))
298 {
299 if ((Hi(AdrWord) != 0) && !mFirstPassUnknown(Flags))
300 {
301 WrError(ErrNum_NoShortAddr);
302 ErrOcc = True;
303 }
304 else
305 {
306 AdrMode = ModDir;
307 AdrPart = 1;
308 AdrVals[AdrCnt++] = Lo(AdrWord);
309 }
310 }
311 else if ((MModExt & Erl)!=0)
312 {
313 AdrMode = ModExt;
314 AdrPart = 3;
315 AdrVals[AdrCnt++] = Hi(AdrWord);
316 AdrVals[AdrCnt++] = Lo(AdrWord);
317 }
318 }
319 else
320 ErrOcc = True;
321 }
322 }
323
324 /* zwei Komponenten ? */
325
326 else if (StartInd + 1 == StopInd)
327 {
328 Boolean IsX = !as_strcasecmp(ArgStr[StopInd].Str, "X"),
329 IsY = !as_strcasecmp(ArgStr[StopInd].Str, "Y");
330
331 /* indiziert ? */
332
333 if (IsX || IsY)
334 {
335 if (MModInd & Erl)
336 {
337 AdrWord = EvalStrIntExpression(pStartArg, UInt8, &OK);
338 if (OK)
339 {
340 if (IsY && !ChkMinCPUExt(CPU6811, ErrNum_AddrModeNotSupported))
341 ErrOcc = True;
342 else
343 {
344 AdrVals[AdrCnt++] = Lo(AdrWord);
345 AdrMode = ModInd;
346 AdrPart = 2;
347 if (IsY)
348 {
349 BAsmCode[PrefCnt++] = 0x18;
350 }
351 }
352 }
353 else
354 ErrOcc = True;
355 }
356 }
357 else
358 {
359 WrStrErrorPos(ErrNum_InvReg, &ArgStr[StopInd]);
360 ErrOcc = True;
361 }
362 }
363
364 else
365 {
366 char Str[100];
367
368 as_snprintf(Str, sizeof(Str), getmessage(Num_ErrMsgAddrArgCnt), 1, 2, StopInd - StartInd + 1);
369 WrXError(ErrNum_WrongArgCnt, Str);
370 ErrOcc = True;
371 }
372
373 if ((!ErrOcc) && (AdrMode == ModNone))
374 WrError(ErrNum_InvAddrMode);
375 }
376
AddPrefix(Byte Prefix)377 static void AddPrefix(Byte Prefix)
378 {
379 BAsmCode[PrefCnt++] = Prefix;
380 }
381
Try2Split(int Src)382 static void Try2Split(int Src)
383 {
384 Integer z;
385 char *p;
386
387 KillPrefBlanksStrComp(&ArgStr[Src]);
388 KillPostBlanksStrComp(&ArgStr[Src]);
389 p = ArgStr[Src].Str + strlen(ArgStr[Src].Str) - 1;
390 while ((p > ArgStr[Src].Str) && !as_isspace(*p))
391 p--;
392 if (p > ArgStr[Src].Str)
393 {
394 IncArgCnt();
395 for (z = ArgCnt - 1; z >= Src + 1; z--)
396 StrCompCopy(&ArgStr[z + 1], &ArgStr[z]);
397 StrCompSplitRight(&ArgStr[Src], &ArgStr[Src + 1], p);
398 KillPostBlanksStrComp(&ArgStr[Src]);
399 KillPrefBlanksStrComp(&ArgStr[Src + 1]);
400 }
401 }
402
403 /*---------------------------------------------------------------------------*/
404
DecodeFixed(Word Index)405 static void DecodeFixed(Word Index)
406 {
407 const FixedOrder *forder = FixedOrders + Index;
408
409 if (!ChkArgCnt(0, 0));
410 else if (!ChkRangeCPU(forder->MinCPU, forder->MaxCPU));
411 else if (Hi(forder->Code) != 0)
412 {
413 CodeLen = 2;
414 BAsmCode[0] = Hi(forder->Code);
415 BAsmCode[1] = Lo(forder->Code);
416 }
417 else
418 {
419 CodeLen = 1;
420 BAsmCode[0] = Lo(forder->Code);
421 }
422 }
423
DecodeRel(Word Index)424 static void DecodeRel(Word Index)
425 {
426 const RelOrder *pOrder = &RelOrders[Index];
427 Integer AdrInt;
428 Boolean OK;
429 tSymbolFlags Flags;
430
431 if (ChkArgCnt(1, 1)
432 && ChkMinCPU(pOrder->MinCPU))
433 {
434 AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
435 if (OK)
436 {
437 AdrInt -= EProgCounter() + 2;
438 if (((AdrInt < -128) || (AdrInt > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
439 else
440 {
441 CodeLen = 2;
442 BAsmCode[0] = pOrder->Code;
443 BAsmCode[1] = Lo(AdrInt);
444 }
445 }
446 }
447 }
448
DecodeALU16(Word Index)449 static void DecodeALU16(Word Index)
450 {
451 const ALU16Order *forder = ALU16Orders + Index;
452
453 OpSize = eSymbolSize16Bit;
454 if (ChkArgCnt(1, 2)
455 && ChkMinCPU(forder->MinCPU))
456 {
457 DecodeAdr(1, ArgCnt, (forder->MayImm ? MModImm : 0) | MModInd | MModExt | MModDir);
458 if (AdrMode != ModNone)
459 {
460 switch (forder->PageShift)
461 {
462 case 1:
463 if (PrefCnt == 1)
464 BAsmCode[PrefCnt - 1] = Page4Prefix;
465 else
466 AddPrefix(Page3Prefix);
467 break;
468 case 2:
469 if (PrefCnt == 1)
470 BAsmCode[PrefCnt - 1] = Page4Prefix;
471 break;
472 case 3:
473 if (PrefCnt == 0)
474 AddPrefix((AdrMode == ModInd) ? Page3Prefix : Page2Prefix);
475 break;
476 }
477 BAsmCode[PrefCnt] = forder->Code + (AdrPart << 4);
478 CodeLen = PrefCnt + 1 + AdrCnt;
479 memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
480 }
481 }
482 }
483
DecodeBit63(Word Code)484 static void DecodeBit63(Word Code)
485 {
486 if (ChkArgCnt(2, 3)
487 && ChkExactCPU(CPU6301))
488 {
489 DecodeAdr(1, 1, MModImm);
490 if (AdrMode != ModNone)
491 {
492 DecodeAdr(2, ArgCnt, MModDir | MModInd);
493 if (AdrMode != ModNone)
494 {
495 BAsmCode[PrefCnt] = Code;
496 if (AdrMode == ModDir)
497 BAsmCode[PrefCnt] |= 0x10;
498 CodeLen = PrefCnt + 1 + AdrCnt;
499 memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
500 }
501 }
502 }
503 }
504
DecodeJMP(Word Index)505 static void DecodeJMP(Word Index)
506 {
507 UNUSED(Index);
508
509 if (ChkArgCnt(1, 2))
510 {
511 DecodeAdr(1, ArgCnt, MModExt | MModInd);
512 if (AdrMode != ModImm)
513 {
514 CodeLen = PrefCnt + 1 + AdrCnt;
515 BAsmCode[PrefCnt] = 0x4e + (AdrPart << 4);
516 memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
517 }
518 }
519 }
520
DecodeJSR(Word Index)521 static void DecodeJSR(Word Index)
522 {
523 UNUSED(Index);
524
525 if (ChkArgCnt(1, 2))
526 {
527 DecodeAdr(1, ArgCnt, MModExt | MModInd | ((MomCPU >= CPU6801) ? MModDir : 0));
528 if (AdrMode != ModImm)
529 {
530 CodeLen=PrefCnt + 1 + AdrCnt;
531 BAsmCode[PrefCnt] = 0x8d + (AdrPart << 4);
532 memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
533 }
534 }
535 }
536
DecodeBRxx(Word Index)537 static void DecodeBRxx(Word Index)
538 {
539 Boolean OK;
540 Byte Mask;
541 Integer AdrInt;
542
543 if (ArgCnt == 1)
544 {
545 Try2Split(1);
546 Try2Split(1);
547 }
548 else if (ArgCnt == 2)
549 {
550 Try2Split(ArgCnt);
551 Try2Split(2);
552 }
553 if (ChkArgCnt(3, 4)
554 && ChkMinCPU(CPU6811))
555 {
556 Mask = EvalStrIntExpressionOffs(&ArgStr[ArgCnt - 1], !!(*ArgStr[ArgCnt - 1].Str == '#'), Int8, &OK);
557 if (OK)
558 {
559 DecodeAdr(1, ArgCnt - 2, MModDir | MModInd);
560 if (AdrMode != ModNone)
561 {
562 AdrInt = EvalStrIntExpression(&ArgStr[ArgCnt], Int16, &OK);
563 if (OK)
564 {
565 AdrInt -= EProgCounter() + 3 + PrefCnt + AdrCnt;
566 if ((AdrInt < -128) || (AdrInt > 127)) WrError(ErrNum_JmpDistTooBig);
567 else
568 {
569 CodeLen = PrefCnt + 3 + AdrCnt;
570 BAsmCode[PrefCnt] = 0x12 + Index;
571 if (AdrMode == ModInd)
572 BAsmCode[PrefCnt] += 12;
573 memcpy(BAsmCode + PrefCnt + 1, AdrVals, AdrCnt);
574 BAsmCode[PrefCnt + 1 + AdrCnt] = Mask;
575 BAsmCode[PrefCnt + 2 + AdrCnt] = Lo(AdrInt);
576 }
577 }
578 }
579 }
580 }
581 }
582
DecodeBxx(Word Index)583 static void DecodeBxx(Word Index)
584 {
585 Byte Mask;
586 Boolean OK;
587 int AddrStart, AddrEnd;
588 tStrComp *pMaskArg;
589
590 if (MomCPU == CPU6301)
591 {
592 pMaskArg = &ArgStr[1];
593 AddrStart = 2;
594 AddrEnd = ArgCnt;
595 }
596 else
597 {
598 if ((ArgCnt >= 1) && (ArgCnt <= 2)) Try2Split(ArgCnt);
599 pMaskArg = &ArgStr[ArgCnt];
600 AddrStart = 1;
601 AddrEnd = ArgCnt - 1;
602 }
603 if (ChkArgCnt(2, 3)
604 && ChkMinCPU(CPU6301))
605 {
606 Mask = EvalStrIntExpressionOffs(pMaskArg, !!(*pMaskArg->Str == '#'),
607 (MomCPU == CPU6301) ? UInt3 : Int8, &OK);
608 if (OK && (MomCPU == CPU6301))
609 {
610 Mask = 1 << Mask;
611 if (Index == 1) Mask = 0xff - Mask;
612 }
613 if (OK)
614 {
615 DecodeAdr(AddrStart, AddrEnd, MModDir | MModInd);
616 if (AdrMode != ModNone)
617 {
618 CodeLen = PrefCnt + 2 + AdrCnt;
619 if (MomCPU == CPU6301)
620 {
621 BAsmCode[PrefCnt] = 0x62 - Index;
622 if (AdrMode == ModDir)
623 BAsmCode[PrefCnt] += 0x10;
624 BAsmCode[1 + PrefCnt] = Mask;
625 memcpy(BAsmCode + 2 + PrefCnt, AdrVals, AdrCnt);
626 }
627 else
628 {
629 BAsmCode[PrefCnt] = 0x14 + Index;
630 if (AdrMode == ModInd)
631 BAsmCode[PrefCnt] += 8;
632 memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
633 BAsmCode[1 + PrefCnt + AdrCnt] = Mask;
634 }
635 }
636 }
637 }
638 }
639
DecodeBTxx(Word Index)640 static void DecodeBTxx(Word Index)
641 {
642 Boolean OK;
643 Byte AdrByte;
644
645 if (ChkArgCnt(2, 3)
646 && ChkExactCPU(CPU6301))
647 {
648 AdrByte = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].Str == '#'), UInt3, &OK);
649 if (OK)
650 {
651 DecodeAdr(2, ArgCnt, MModDir | MModInd);
652 if (AdrMode != ModNone)
653 {
654 CodeLen = PrefCnt + 2 + AdrCnt;
655 BAsmCode[1 + PrefCnt] = 1 << AdrByte;
656 memcpy(BAsmCode + 2 + PrefCnt, AdrVals, AdrCnt);
657 BAsmCode[PrefCnt] = 0x65 + Index;
658 if (AdrMode == ModDir)
659 BAsmCode[PrefCnt] += 0x10;
660 }
661 }
662 }
663 }
664
DecodeALU8(Word Code)665 static void DecodeALU8(Word Code)
666 {
667 Byte Reg;
668 int MinArgCnt = Hi(Code) & 3;
669
670 /* dirty hack: LDA/STA/ORA, and first arg is not A or B, treat like LDAA/STAA/ORAA: */
671
672 if ((MinArgCnt == 2)
673 && (as_toupper(OpPart.Str[2]) == 'A')
674 && (ArgCnt >= 1)
675 && !DecodeAcc(ArgStr[1].Str, &Reg))
676 MinArgCnt = 1;
677
678 if (ChkArgCnt(MinArgCnt, MinArgCnt + 1))
679 {
680 DecodeAdr(MinArgCnt , ArgCnt, ((Code & 0x8000) ? MModImm : 0) | MModInd | MModExt | MModDir);
681 if (AdrMode != ModNone)
682 {
683 BAsmCode[PrefCnt] = Lo(Code) | (AdrPart << 4);
684 if (MinArgCnt == 1)
685 {
686 AdrMode = ModAcc;
687 AdrPart = (Code & 0x4000) >> 14;
688 }
689 else
690 DecodeAdr(1, 1, MModAcc);
691 if (AdrMode != ModNone)
692 {
693 BAsmCode[PrefCnt] |= AdrPart << 6;
694 CodeLen = PrefCnt + 1 + AdrCnt;
695 memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
696 }
697 }
698 }
699 }
700
DecodeSing8(Word Code)701 static void DecodeSing8(Word Code)
702 {
703 if (ChkArgCnt(1, 2))
704 {
705 DecodeAdr(1, ArgCnt, MModAcc | MModExt | MModInd);
706 if (AdrMode!=ModNone)
707 {
708 CodeLen = PrefCnt + 1 + AdrCnt;
709 BAsmCode[PrefCnt] = Code | (AdrPart << 4);
710 memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
711 }
712 }
713 }
714
DecodeSing8_Acc(Word Code)715 static void DecodeSing8_Acc(Word Code)
716 {
717 if (ChkArgCnt(0, 0))
718 {
719 BAsmCode[PrefCnt] = Code;
720 CodeLen = PrefCnt + 1;
721 }
722 }
723
DecodePSH_PUL(Word Code)724 static void DecodePSH_PUL(Word Code)
725 {
726 if (ChkArgCnt(1, 1))
727 {
728 DecodeAdr(1, 1, MModAcc);
729 if (AdrMode != ModNone)
730 {
731 CodeLen = 1;
732 BAsmCode[0]=Code | AdrPart;
733 }
734 }
735 }
736
DecodePRWINS(Word Code)737 static void DecodePRWINS(Word Code)
738 {
739 UNUSED(Code);
740
741 if (ChkExactCPU(CPU68HC11K4))
742 {
743 printf("\nMMSIZ %02x MMWBR %02x MM1CR %02x MM2CR %02x",
744 (unsigned)Reg_MMSIZ, (unsigned)Reg_MMWBR, (unsigned)Reg_MM1CR, (unsigned)Reg_MM2CR);
745 printf("\nWindow 1: %lx...%lx --> %lx...%lx",
746 (long)Win1VStart, (long)Win1VEnd, (long)Win1PStart, (long)Win1PEnd);
747 printf("\nWindow 2: %lx...%lx --> %lx...%lx\n",
748 (long)Win2VStart, (long)Win2VEnd, (long)Win2PStart, (long)Win2PEnd);
749 }
750 }
751
752 /*---------------------------------------------------------------------------*/
753
AddFixed(const char * NName,CPUVar NMin,CPUVar NMax,Word NCode)754 static void AddFixed(const char *NName, CPUVar NMin, CPUVar NMax, Word NCode)
755 {
756 if (InstrZ >= FixedOrderCnt) exit(255);
757
758 FixedOrders[InstrZ].MinCPU = NMin;
759 FixedOrders[InstrZ].MaxCPU = NMax;
760 FixedOrders[InstrZ].Code = NCode;
761 AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
762 }
763
AddRel(const char * NName,CPUVar NMin,Word NCode)764 static void AddRel(const char *NName, CPUVar NMin, Word NCode)
765 {
766 if (InstrZ >= RelOrderCnt) exit(255);
767
768 RelOrders[InstrZ].MinCPU = NMin;
769 RelOrders[InstrZ].Code = NCode;
770 AddInstTable(InstTable, NName, InstrZ++, DecodeRel);
771 }
772
AddALU8(const char * NamePlain,const char * NameA,const char * NameB,const char * NameB2,Boolean MayImm,Byte NCode)773 static void AddALU8(const char *NamePlain, const char *NameA, const char *NameB, const char *NameB2, Boolean MayImm, Byte NCode)
774 {
775 Word BaseCode = NCode | (MayImm ? 0x8000 : 0);
776
777 AddInstTable(InstTable, NamePlain, BaseCode | (2 << 8), DecodeALU8);
778 AddInstTable(InstTable, NameA, BaseCode | (1 << 8), DecodeALU8);
779 AddInstTable(InstTable, NameB, BaseCode | (1 << 8) | 0x4000, DecodeALU8);
780 if (NameB2)
781 AddInstTable(InstTable, NameB2, BaseCode | (1 << 8) | 0x4000, DecodeALU8);
782 }
783
AddALU16(const char * NName,Boolean NMay,CPUVar NMin,Byte NShift,Byte NCode)784 static void AddALU16(const char *NName, Boolean NMay, CPUVar NMin, Byte NShift, Byte NCode)
785 {
786 if (InstrZ >= ALU16OrderCnt) exit(255);
787
788 ALU16Orders[InstrZ].MayImm = NMay;
789 ALU16Orders[InstrZ].MinCPU = NMin;
790 ALU16Orders[InstrZ].PageShift = NShift;
791 ALU16Orders[InstrZ].Code = NCode;
792 AddInstTable(InstTable, NName, InstrZ++, DecodeALU16);
793 }
794
AddSing8(const char * NamePlain,const char * NameA,const char * NameB,Byte NCode)795 static void AddSing8(const char *NamePlain, const char *NameA, const char *NameB, Byte NCode)
796 {
797 AddInstTable(InstTable, NamePlain, NCode, DecodeSing8);
798 AddInstTable(InstTable, NameA, NCode | 0, DecodeSing8_Acc);
799 AddInstTable(InstTable, NameB, NCode | 0x10, DecodeSing8_Acc);
800 }
801
InitFields(void)802 static void InitFields(void)
803 {
804 InstTable = CreateInstTable(302);
805 AddInstTable(InstTable, "JMP" , 0, DecodeJMP);
806 AddInstTable(InstTable, "JSR" , 0, DecodeJSR);
807 AddInstTable(InstTable, "BRCLR", 1, DecodeBRxx);
808 AddInstTable(InstTable, "BRSET", 0, DecodeBRxx);
809 AddInstTable(InstTable, "BCLR" , 1, DecodeBxx);
810 AddInstTable(InstTable, "BSET" , 0, DecodeBxx);
811 AddInstTable(InstTable, "BTST" , 6, DecodeBTxx);
812 AddInstTable(InstTable, "BTGL" , 0, DecodeBTxx);
813
814 FixedOrders = (FixedOrder *) malloc(sizeof(FixedOrder) * FixedOrderCnt); InstrZ = 0;
815 AddFixed("ABA" ,CPU6800, CPU68HC11K4, 0x001b); AddFixed("ABX" ,CPU6801, CPU68HC11K4, 0x003a);
816 AddFixed("ABY" ,CPU6811, CPU68HC11K4, 0x183a); AddFixed("ASLD" ,CPU6801, CPU68HC11K4, 0x0005);
817 AddFixed("CBA" ,CPU6800, CPU68HC11K4, 0x0011); AddFixed("CLC" ,CPU6800, CPU68HC11K4, 0x000c);
818 AddFixed("CLI" ,CPU6800, CPU68HC11K4, 0x000e); AddFixed("CLV" ,CPU6800, CPU68HC11K4, 0x000a);
819 AddFixed("DAA" ,CPU6800, CPU68HC11K4, 0x0019); AddFixed("DES" ,CPU6800, CPU68HC11K4, 0x0034);
820 AddFixed("DEX" ,CPU6800, CPU68HC11K4, 0x0009); AddFixed("DEY" ,CPU6811, CPU68HC11K4, 0x1809);
821 AddFixed("FDIV" ,CPU6811, CPU68HC11K4, 0x0003); AddFixed("IDIV" ,CPU6811, CPU68HC11K4, 0x0002);
822 AddFixed("INS" ,CPU6800, CPU68HC11K4, 0x0031); AddFixed("INX" ,CPU6800, CPU68HC11K4, 0x0008);
823 AddFixed("INY" ,CPU6811, CPU68HC11K4, 0x1808); AddFixed("LSLD" ,CPU6801, CPU68HC11K4, 0x0005);
824 AddFixed("LSRD" ,CPU6801, CPU68HC11K4, 0x0004); AddFixed("MUL" ,CPU6801, CPU68HC11K4, 0x003d);
825 AddFixed("NOP" ,CPU6800, CPU68HC11K4, 0x0001); AddFixed("PSHX" ,CPU6801, CPU68HC11K4, 0x003c);
826 AddFixed("PSHY" ,CPU6811, CPU68HC11K4, 0x183c); AddFixed("PULX" ,CPU6801, CPU68HC11K4, 0x0038);
827 AddFixed("PULY" ,CPU6811, CPU68HC11K4, 0x1838); AddFixed("RTI" ,CPU6800, CPU68HC11K4, 0x003b);
828 AddFixed("RTS" ,CPU6800, CPU68HC11K4, 0x0039); AddFixed("SBA" ,CPU6800, CPU68HC11K4, 0x0010);
829 AddFixed("SEC" ,CPU6800, CPU68HC11K4, 0x000d); AddFixed("SEI" ,CPU6800, CPU68HC11K4, 0x000f);
830 AddFixed("SEV" ,CPU6800, CPU68HC11K4, 0x000b); AddFixed("SLP" ,CPU6301, CPU6301 , 0x001a);
831 AddFixed("STOP" ,CPU6811, CPU68HC11K4, 0x00cf); AddFixed("SWI" ,CPU6800, CPU68HC11K4, 0x003f);
832 AddFixed("TAB" ,CPU6800, CPU68HC11K4, 0x0016); AddFixed("TAP" ,CPU6800, CPU68HC11K4, 0x0006);
833 AddFixed("TBA" ,CPU6800, CPU68HC11K4, 0x0017); AddFixed("TPA" ,CPU6800, CPU68HC11K4, 0x0007);
834 AddFixed("TSX" ,CPU6800, CPU68HC11K4, 0x0030); AddFixed("TSY" ,CPU6811, CPU68HC11K4, 0x1830);
835 AddFixed("TXS" ,CPU6800, CPU68HC11K4, 0x0035); AddFixed("TYS" ,CPU6811, CPU68HC11K4, 0x1835);
836 AddFixed("WAI" ,CPU6800, CPU68HC11K4, 0x003e);
837 AddFixed("XGDX" ,CPU6301, CPU68HC11K4, (MomCPU == CPU6301) ? 0x0018 : 0x008f);
838 AddFixed("XGDY" ,CPU6811, CPU68HC11K4, 0x188f);
839
840 RelOrders = (RelOrder *) malloc(sizeof(*RelOrders) * RelOrderCnt); InstrZ = 0;
841 AddRel("BCC", CPU6800, 0x24);
842 AddRel("BCS", CPU6800, 0x25);
843 AddRel("BEQ", CPU6800, 0x27);
844 AddRel("BGE", CPU6800, 0x2c);
845 AddRel("BGT", CPU6800, 0x2e);
846 AddRel("BHI", CPU6800, 0x22);
847 AddRel("BHS", CPU6800, 0x24);
848 AddRel("BLE", CPU6800, 0x2f);
849 AddRel("BLO", CPU6800, 0x25);
850 AddRel("BLS", CPU6800, 0x23);
851 AddRel("BLT", CPU6800, 0x2d);
852 AddRel("BMI", CPU6800, 0x2b);
853 AddRel("BNE", CPU6800, 0x26);
854 AddRel("BPL", CPU6800, 0x2a);
855 AddRel("BRA", CPU6800, 0x20);
856 AddRel("BRN", CPU6801, 0x21);
857 AddRel("BSR", CPU6800, 0x8d);
858 AddRel("BVC", CPU6800, 0x28);
859 AddRel("BVS", CPU6800, 0x29);
860
861 AddALU8("ADC", "ADCA", "ADCB", NULL , True , 0x89);
862 AddALU8("ADD", "ADDA", "ADDB", NULL , True , 0x8b);
863 AddALU8("AND", "ANDA", "ANDB", NULL , True , 0x84);
864 AddALU8("BIT", "BITA", "BITB", NULL , True , 0x85);
865 AddALU8("CMP", "CMPA", "CMPB", NULL , True , 0x81);
866 AddALU8("EOR", "EORA", "EORB", NULL , True , 0x88);
867 AddALU8("LDA", "LDAA", "LDAB", "LDB", True , 0x86);
868 AddALU8("ORA", "ORAA", "ORAB", "ORB", True , 0x8a);
869 AddALU8("SBC", "SBCA", "SBCB", NULL , True , 0x82);
870 AddALU8("STA", "STAA", "STAB", "STB", False, 0x87);
871 AddALU8("SUB", "SUBA", "SUBB", NULL , True , 0x80);
872
873 ALU16Orders = (ALU16Order *) malloc(sizeof(ALU16Order) * ALU16OrderCnt); InstrZ = 0;
874 AddALU16("ADDD", True , CPU6801, 0, 0xc3);
875 AddALU16("CPD" , True , CPU6811, 1, 0x83);
876 AddALU16("CMPD", True , CPU6811, 1, 0x83);
877 AddALU16("CPX" , True , CPU6800, 2, 0x8c);
878 AddALU16("CMPX", True , CPU6800, 2, 0x8c);
879 AddALU16("CPY" , True , CPU6811, 3, 0x8c);
880 AddALU16("CMPY", True , CPU6811, 3, 0x8c);
881 AddALU16("LDD" , True , CPU6801, 0, 0xcc);
882 AddALU16("LDS" , True , CPU6800, 0, 0x8e);
883 AddALU16("LDX" , True , CPU6800, 2, 0xce);
884 AddALU16("LDY" , True , CPU6811, 3, 0xce);
885 AddALU16("STD" , False, CPU6801, 0, 0xcd);
886 AddALU16("STS" , False, CPU6800, 0, 0x8f);
887 AddALU16("STX" , False, CPU6800, 2, 0xcf);
888 AddALU16("STY" , False, CPU6811, 3, 0xcf);
889 AddALU16("SUBD", True , CPU6801, 0, 0x83);
890
891 AddSing8("ASL", "ASLA", "ASLB", 0x48);
892 AddSing8("ASR", "ASRA", "ASRB", 0x47);
893 AddSing8("CLR", "CLRA", "CLRB", 0x4f);
894 AddSing8("COM", "COMA", "COMB", 0x43);
895 AddSing8("DEC", "DECA", "DECB", 0x4a);
896 AddSing8("INC", "INCA", "INCB", 0x4c);
897 AddSing8("LSL", "LSLA", "LSLB", 0x48);
898 AddSing8("LSR", "LSRA", "LSRB", 0x44);
899 AddSing8("NEG", "NEGA", "NEGB", 0x40);
900 AddSing8("ROL", "ROLA", "ROLB", 0x49);
901 AddSing8("ROR", "RORA", "RORB", 0x46);
902 AddSing8("TST", "TSTA", "TSTB", 0x4d);
903
904 AddInstTable(InstTable, "PSH" , 0x36, DecodePSH_PUL);
905 AddInstTable(InstTable, "PSHA", 0x36, DecodeSing8_Acc);
906 AddInstTable(InstTable, "PSHB", 0x37, DecodeSing8_Acc);
907 AddInstTable(InstTable, "PUL" , 0x32, DecodePSH_PUL);
908 AddInstTable(InstTable, "PULA", 0x32, DecodeSing8_Acc);
909 AddInstTable(InstTable, "PULB", 0x33, DecodeSing8_Acc);
910
911
912 AddInstTable(InstTable, "AIM", 0x61, DecodeBit63);
913 AddInstTable(InstTable, "EIM", 0x65, DecodeBit63);
914 AddInstTable(InstTable, "OIM", 0x62, DecodeBit63);
915 AddInstTable(InstTable, "TIM", 0x6b, DecodeBit63);
916
917 AddInstTable(InstTable, "PRWINS", 0, DecodePRWINS);
918
919 AddInstTable(InstTable, "DB", 0, DecodeMotoBYT);
920 AddInstTable(InstTable, "DW", 0, DecodeMotoADR);
921 }
922
DeinitFields(void)923 static void DeinitFields(void)
924 {
925 DestroyInstTable(InstTable);
926 free(FixedOrders);
927 free(RelOrders);
928 free(ALU16Orders);
929 }
930
DecodeAttrPart_68(void)931 static Boolean DecodeAttrPart_68(void)
932 {
933 return DecodeMoto16AttrSize(*AttrPart.Str, &AttrPartOpSize, False);
934 }
935
MakeCode_68(void)936 static void MakeCode_68(void)
937 {
938 CodeLen = 0;
939 DontPrint = False;
940 PrefCnt = 0;
941 AdrCnt = 0;
942
943 /* Operandengroesse festlegen */
944
945 OpSize = (AttrPartOpSize != eSymbolSizeUnknown) ? AttrPartOpSize : eSymbolSize8Bit;
946
947 /* zu ignorierendes */
948
949 if (*OpPart.Str == '\0')
950 return;
951
952 /* Pseudoanweisungen */
953
954 if (DecodeMotoPseudo(True))
955 return;
956 if (DecodeMoto16Pseudo(OpSize, True))
957 return;
958
959 /* gehashtes */
960
961 if (!LookupInstTable(InstTable, OpPart.Str))
962 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
963 }
964
InitCode_68(void)965 static void InitCode_68(void)
966 {
967 Reg_MMSIZ = Reg_MMWBR = Reg_MM1CR = Reg_MM2CR = 0;
968 SetK4Ranges();
969 }
970
IsDef_68(void)971 static Boolean IsDef_68(void)
972 {
973 return False;
974 }
975
SwitchFrom_68(void)976 static void SwitchFrom_68(void)
977 {
978 DeinitFields();
979 ClearONOFF();
980 }
981
982
SwitchTo_68(void)983 static void SwitchTo_68(void)
984 {
985 #define ASSUMEHC11Count (sizeof(ASSUMEHC11s) / sizeof(*ASSUMEHC11s))
986 static const ASSUMERec ASSUMEHC11s[] =
987 {
988 {"MMSIZ", &Reg_MMSIZ, 0, 0xff, 0, SetK4Ranges},
989 {"MMWBR", &Reg_MMWBR, 0, 0xff, 0, SetK4Ranges},
990 {"MM1CR", &Reg_MM1CR, 0, 0xff, 0, SetK4Ranges},
991 {"MM2CR", &Reg_MM2CR, 0, 0xff, 0, SetK4Ranges}
992 };
993 TurnWords = False;
994 ConstMode = ConstModeMoto;
995
996 PCSymbol = "*";
997 HeaderID = 0x61;
998 NOPCode = 0x01;
999 DivideChars = ",";
1000 HasAttrs = True;
1001 AttrChars = ".";
1002
1003 ValidSegs = 1 << SegCode;
1004 Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
1005 SegLimits[SegCode] = (MomCPU == CPU68HC11K4) ? 0x10ffffl : 0xffff;
1006
1007 DecodeAttrPart = DecodeAttrPart_68;
1008 MakeCode = MakeCode_68;
1009 IsDef = IsDef_68;
1010 SwitchFrom = SwitchFrom_68;
1011 InitFields();
1012 AddMoto16PseudoONOFF();
1013
1014 if (MomCPU == CPU68HC11K4)
1015 {
1016 pASSUMERecs = ASSUMEHC11s;
1017 ASSUMERecCnt = ASSUMEHC11Count;
1018 }
1019
1020 SetFlag(&DoPadding, DoPaddingName, False);
1021 }
1022
code68_init(void)1023 void code68_init(void)
1024 {
1025 CPU6800 = AddCPU("6800", SwitchTo_68);
1026 CPU6801 = AddCPU("6801", SwitchTo_68);
1027 CPU6301 = AddCPU("6301", SwitchTo_68);
1028 CPU6811 = AddCPU("6811", SwitchTo_68);
1029 CPU68HC11K4 = AddCPU("68HC11K4", SwitchTo_68);
1030
1031 AddInitPassProc(InitCode_68);
1032 }
1033