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