1 /* code17c4x.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS-Portierung                                                             */
6 /*                                                                           */
7 /* Codegenerator PIC17C4x                                                    */
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 "chunks.h"
18 #include "asmdef.h"
19 #include "asmsub.h"
20 #include "asmitree.h"
21 #include "asmpars.h"
22 #include "codepseudo.h"
23 #include "fourpseudo.h"
24 #include "codevars.h"
25 #include "errmsg.h"
26 
27 #include "code17c4x.h"
28 
29 /*---------------------------------------------------------------------------*/
30 
31 static CPUVar CPU17C42;
32 
33 /*---------------------------------------------------------------------------*/
34 
DecodeFixed(Word Code)35 static void DecodeFixed(Word Code)
36 {
37   if (ChkArgCnt(0, 0))
38   {
39     CodeLen = 1;
40     WAsmCode[0] = Code;
41   }
42 }
43 
DecodeLitt(Word Code)44 static void DecodeLitt(Word Code)
45 {
46   if (ChkArgCnt(1, 1))
47   {
48     Boolean OK;
49     Word AdrWord = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
50     if (OK)
51     {
52       WAsmCode[0] = Code + (AdrWord & 0xff);
53       CodeLen = 1;
54     }
55   }
56 }
57 
DecodeAri(Word Code)58 static void DecodeAri(Word Code)
59 {
60   Word DefaultDir = (Code >> 7) & 0x100;
61 
62   Code &= 0x7fff;
63   if (ChkArgCnt(1, 2))
64   {
65     tEvalResult EvalResult;
66     Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], Int8, &EvalResult);
67 
68     if (EvalResult.OK)
69     {
70       ChkSpace(SegData, EvalResult.AddrSpaceMask);
71       WAsmCode[0] = Code + (AdrWord & 0xff);
72       if (ArgCnt == 1)
73       {
74         CodeLen = 1;
75         WAsmCode[0] += DefaultDir;
76       }
77       else if (as_strcasecmp(ArgStr[2].Str, "W") == 0)
78         CodeLen = 1;
79       else if (as_strcasecmp(ArgStr[2].Str, "F") == 0)
80       {
81         CodeLen = 1;
82         WAsmCode[0] += 0x100;
83       }
84       else
85       {
86         AdrWord = EvalStrIntExpressionWithResult(&ArgStr[2], UInt1, &EvalResult);
87         if (EvalResult.OK)
88         {
89           CodeLen = 1;
90           WAsmCode[0] += (AdrWord << 8);
91         }
92       }
93     }
94   }
95 }
96 
DecodeBit(Word Code)97 static void DecodeBit(Word Code)
98 {
99   if (ChkArgCnt(2, 2))
100   {
101     tEvalResult EvalResult;
102     Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[2], UInt3, &EvalResult);
103     if (EvalResult.OK)
104     {
105       WAsmCode[0] = EvalStrIntExpressionWithResult(&ArgStr[1], Int8, &EvalResult);
106        if (EvalResult.OK)
107        {
108          CodeLen = 1;
109          WAsmCode[0] += Code + (AdrWord << 8);
110          ChkSpace(SegData, EvalResult.AddrSpaceMask);
111        }
112     }
113   }
114 }
115 
DecodeF(Word Code)116 static void DecodeF(Word Code)
117 {
118   if (ChkArgCnt(1, 1))
119   {
120     tEvalResult EvalResult;
121     Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], Int8, &EvalResult);
122     if (EvalResult.OK)
123     {
124       CodeLen = 1;
125       WAsmCode[0] = Code + AdrWord;
126       ChkSpace(SegData, EvalResult.AddrSpaceMask);
127     }
128   }
129 }
130 
DecodeMOVFP_MOVPF(Word Code)131 static void DecodeMOVFP_MOVPF(Word Code)
132 {
133   if (ChkArgCnt(2, 2))
134   {
135     tStrComp *pArg1 = (Code & 0x2000) ? &ArgStr[2] : &ArgStr[1],
136              *pArg2 = (Code & 0x2000) ? &ArgStr[1] : &ArgStr[2];
137     Boolean OK;
138     Word AdrWord;
139 
140     AdrWord = EvalStrIntExpression(pArg1, UInt5, &OK);
141     if (OK)
142     {
143       WAsmCode[0] = EvalStrIntExpression(pArg2, Int8, &OK);
144       if (OK)
145       {
146         WAsmCode[0] = Code + Lo(WAsmCode[0]) + (AdrWord << 8);
147         CodeLen = 1;
148       }
149     }
150   }
151 }
152 
DecodeTABLRD_TABLWT(Word Code)153 static void DecodeTABLRD_TABLWT(Word Code)
154 {
155   if (ChkArgCnt(3, 3))
156   {
157     Boolean OK;
158 
159     WAsmCode[0] = Lo(EvalStrIntExpression(&ArgStr[3], Int8, &OK));
160     if (OK)
161     {
162       Word AdrWord = EvalStrIntExpression(&ArgStr[2], UInt1, &OK);
163       if (OK)
164       {
165         WAsmCode[0] += AdrWord << 8;
166         AdrWord = EvalStrIntExpression(&ArgStr[1], UInt1, &OK);
167         if (OK)
168         {
169           WAsmCode[0] += Code + (AdrWord << 9);
170           CodeLen = 1;
171         }
172       }
173     }
174   }
175 }
176 
DecodeTLRD_TLWT(Word Code)177 static void DecodeTLRD_TLWT(Word Code)
178 {
179   if (ChkArgCnt(2, 2))
180   {
181     Boolean OK;
182 
183     WAsmCode[0] = Lo(EvalStrIntExpression(&ArgStr[2], Int8, &OK));
184     if (OK)
185     {
186       Word AdrWord = EvalStrIntExpression(&ArgStr[1], UInt1, &OK);
187       if (OK)
188       {
189         WAsmCode[0] += (AdrWord << 9) + Code;
190         CodeLen = 1;
191       }
192     }
193   }
194   return;
195 }
196 
DecodeCALL_GOTO(Word Code)197 static void DecodeCALL_GOTO(Word Code)
198 {
199   if (ChkArgCnt(1, 1))
200   {
201     Boolean OK;
202     Word AdrWord;
203     tSymbolFlags Flags;
204 
205     AdrWord = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &OK, &Flags);
206     if (OK && ChkSamePage(ProgCounter(), AdrWord, 13, Flags))
207     {
208       WAsmCode[0] = Code + (AdrWord & 0x1fff);
209       CodeLen = 1;
210     }
211   }
212 }
213 
DecodeLCALL(Word Code)214 static void DecodeLCALL(Word Code)
215 {
216   UNUSED(Code);
217 
218   if (ChkArgCnt(1, 1))
219   {
220     Boolean OK;
221 
222     Word AdrWord = EvalStrIntExpression(&ArgStr[1], UInt16, &OK);
223     if (OK)
224     {
225       CodeLen = 3;
226       WAsmCode[0] = 0xb000 + Hi(AdrWord);
227       WAsmCode[1] = 0x0103;
228       WAsmCode[2] = 0xb700 + Lo(AdrWord);
229     }
230   }
231 }
232 
DecodeSFR(Word Code)233 static void DecodeSFR(Word Code)
234 {
235   UNUSED(Code);
236 
237   CodeEquate(SegData, 0, 0xff);
238 }
239 
DecodeDATA_17C4x(Word Code)240 static void DecodeDATA_17C4x(Word Code)
241 {
242   UNUSED(Code);
243 
244   DecodeDATA(Int16, Int8);
245 }
246 
DecodeZERO(Word Code)247 static void DecodeZERO(Word Code)
248 {
249   Word Size;
250   Boolean ValOK;
251   tSymbolFlags Flags;
252 
253   UNUSED(Code);
254 
255   if (ChkArgCnt(1, 1))
256   {
257     Size = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &ValOK, &Flags);
258     if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
259     if (ValOK && !mFirstPassUnknown(Flags))
260     {
261       if (SetMaxCodeLen(Size << 1)) WrError(ErrNum_CodeOverflow);
262       else
263       {
264         CodeLen = Size;
265         memset(WAsmCode, 0, 2 * Size);
266       }
267     }
268   }
269 }
270 
271 /*---------------------------------------------------------------------------*/
272 
AddFixed(const char * NName,Word NCode)273 static void AddFixed(const char *NName, Word NCode)
274 {
275   AddInstTable(InstTable, NName, NCode, DecodeFixed);
276 }
277 
AddLitt(const char * NName,Word NCode)278 static void AddLitt(const char *NName, Word NCode)
279 {
280   AddInstTable(InstTable, NName, NCode, DecodeLitt);
281 }
282 
AddAri(const char * NName,Word NDef,Word NCode)283 static void AddAri(const char *NName, Word NDef, Word NCode)
284 {
285   AddInstTable(InstTable, NName, NCode | (NDef << 15), DecodeAri);
286 }
287 
AddBit(const char * NName,Word NCode)288 static void AddBit(const char *NName, Word NCode)
289 {
290   AddInstTable(InstTable, NName, NCode, DecodeBit);
291 }
292 
AddF(const char * NName,Word NCode)293 static void AddF(const char *NName, Word NCode)
294 {
295   AddInstTable(InstTable, NName, NCode, DecodeF);
296 }
297 
InitFields(void)298 static void InitFields(void)
299 {
300   InstTable = CreateInstTable(203);
301   AddInstTable(InstTable, "MOVFP", 0x6000, DecodeMOVFP_MOVPF);
302   AddInstTable(InstTable, "MOVPF", 0x4000, DecodeMOVFP_MOVPF);
303   AddInstTable(InstTable, "TABLRD", 0xa800, DecodeTABLRD_TABLWT);
304   AddInstTable(InstTable, "TABLWT", 0xac00, DecodeTABLRD_TABLWT);
305   AddInstTable(InstTable, "TLRD", 0xa000, DecodeTLRD_TLWT);
306   AddInstTable(InstTable, "TLWT", 0xa400, DecodeTLRD_TLWT);
307   AddInstTable(InstTable, "CALL", 0xe000, DecodeCALL_GOTO);
308   AddInstTable(InstTable, "GOTO", 0xc000, DecodeCALL_GOTO);
309   AddInstTable(InstTable, "LCALL", 0, DecodeLCALL);
310   AddInstTable(InstTable, "SFR", 0, DecodeSFR);
311   AddInstTable(InstTable, "RES", 0, DecodeRES);
312   AddInstTable(InstTable, "DATA", 0, DecodeDATA_17C4x);
313   AddInstTable(InstTable, "ZERO", 0, DecodeZERO);
314 
315   AddFixed("RETFIE", 0x0005);
316   AddFixed("RETURN", 0x0002);
317   AddFixed("CLRWDT", 0x0004);
318   AddFixed("NOP"   , 0x0000);
319   AddFixed("SLEEP" , 0x0003);
320 
321   AddLitt("MOVLB", 0xb800);
322   AddLitt("ADDLW", 0xb100);
323   AddLitt("ANDLW", 0xb500);
324   AddLitt("IORLW", 0xb300);
325   AddLitt("MOVLW", 0xb000);
326   AddLitt("SUBLW", 0xb200);
327   AddLitt("XORLW", 0xb400);
328   AddLitt("RETLW", 0xb600);
329 
330   AddAri("ADDWF" , 0, 0x0e00);
331   AddAri("ADDWFC", 0, 0x1000);
332   AddAri("ANDWF" , 0, 0x0a00);
333   AddAri("CLRF"  , 1, 0x2800);
334   AddAri("COMF"  , 1, 0x1200);
335   AddAri("DAW"   , 1, 0x2e00);
336   AddAri("DECF"  , 1, 0x0600);
337   AddAri("INCF"  , 1, 0x1400);
338   AddAri("IORWF" , 0, 0x0800);
339   AddAri("NEGW"  , 1, 0x2c00);
340   AddAri("RLCF"  , 1, 0x1a00);
341   AddAri("RLNCF" , 1, 0x2200);
342   AddAri("RRCF"  , 1, 0x1800);
343   AddAri("RRNCF" , 1, 0x2000);
344   AddAri("SETF"  , 1, 0x2a00);
345   AddAri("SUBWF" , 0, 0x0400);
346   AddAri("SUBWFB", 0, 0x0200);
347   AddAri("SWAPF" , 1, 0x1c00);
348   AddAri("XORWF" , 0, 0x0c00);
349   AddAri("DECFSZ", 1, 0x1600);
350   AddAri("DCFSNZ", 1, 0x2600);
351   AddAri("INCFSZ", 1, 0x1e00);
352   AddAri("INFSNZ", 1, 0x2400);
353 
354   AddBit("BCF"  , 0x8800);
355   AddBit("BSF"  , 0x8000);
356   AddBit("BTFSC", 0x9800);
357   AddBit("BTFSS", 0x9000);
358   AddBit("BTG"  , 0x3800);
359 
360   AddF("MOVWF" , 0x0100);
361   AddF("CPFSEQ", 0x3100);
362   AddF("CPFSGT", 0x3200);
363   AddF("CPFSLT", 0x3000);
364   AddF("TSTFSZ", 0x3300);
365 }
366 
DeinitFields(void)367 static void DeinitFields(void)
368 {
369   DestroyInstTable(InstTable);
370 }
371 
372 /*---------------------------------------------------------------------------*/
373 
MakeCode_17c4x(void)374 static void MakeCode_17c4x(void)
375 {
376   CodeLen = 0;
377   DontPrint = False;
378 
379   /* zu ignorierendes */
380 
381   if (Memo(""))
382     return;
383 
384   if (!LookupInstTable(InstTable, OpPart.Str))
385     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
386 }
387 
IsDef_17c4x(void)388 static Boolean IsDef_17c4x(void)
389 {
390   return Memo("SFR");
391 }
392 
SwitchFrom_17c4x(void)393 static void SwitchFrom_17c4x(void)
394 {
395   DeinitFields();
396 }
397 
SwitchTo_17c4x(void)398 static void SwitchTo_17c4x(void)
399 {
400   TurnWords = False;
401   ConstMode = ConstModeMoto;
402 
403   PCSymbol = "*";
404   HeaderID = 0x72;
405   NOPCode = 0x0000;
406   DivideChars = ",";
407   HasAttrs = False;
408 
409   ValidSegs = (1 << SegCode) + (1 << SegData);
410   Grans[SegCode] = 2; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
411   SegLimits[SegCode] = 0xffff;
412   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 0;
413   SegLimits[SegData] = 0xff;
414 
415   MakeCode = MakeCode_17c4x;
416   IsDef = IsDef_17c4x;
417   SwitchFrom = SwitchFrom_17c4x;
418   InitFields();
419 }
420 
code17c4x_init(void)421 void code17c4x_init(void)
422 {
423   CPU17C42 = AddCPU("17C42", SwitchTo_17c4x);
424 }
425