Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1186 | savelij | 1 | /* code166.c */ |
2 | /*****************************************************************************/ |
||
3 | /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */ |
||
4 | /* */ |
||
5 | /* AS-Portierung */ |
||
6 | /* */ |
||
7 | /* AS-Codegenerator Siemens 80C16x */ |
||
8 | /* */ |
||
9 | /*****************************************************************************/ |
||
10 | |||
11 | #include "stdinc.h" |
||
12 | #include <string.h> |
||
13 | #include <ctype.h> |
||
14 | |||
15 | #include "nls.h" |
||
16 | #include "strutil.h" |
||
17 | #include "bpemu.h" |
||
18 | #include "asmdef.h" |
||
19 | #include "asmsub.h" |
||
20 | #include "asmpars.h" |
||
21 | #include "asmitree.h" |
||
22 | #include "asmcode.h" |
||
23 | #include "asmallg.h" |
||
24 | #include "codepseudo.h" |
||
25 | #include "intpseudo.h" |
||
26 | #include "codevars.h" |
||
27 | #include "errmsg.h" |
||
28 | |||
29 | #include "code166.h" |
||
30 | |||
31 | typedef struct |
||
32 | { |
||
33 | CPUVar MinCPU; |
||
34 | Word Code1, Code2; |
||
35 | } BaseOrder; |
||
36 | |||
37 | typedef struct |
||
38 | { |
||
39 | const char *Name; |
||
40 | Byte Code; |
||
41 | } Condition; |
||
42 | |||
43 | #define COND_CODE_TRUE 0x0 |
||
44 | |||
45 | #define DPPCount 4 |
||
46 | static const char RegNames[6][5] = { "DPP0", "DPP1", "DPP2", "DPP3", "CP", "SP" }; |
||
47 | |||
48 | static CPUVar CPU80C166, CPU80C167, CPU80C167CS; |
||
49 | |||
50 | static BaseOrder *FixedOrders; |
||
51 | static Condition *Conditions; |
||
52 | static int TrueCond; |
||
53 | |||
54 | static LongInt DPPAssumes[DPPCount]; |
||
55 | static IntType MemInt, MemInt2; |
||
56 | static tSymbolSize OpSize; |
||
57 | |||
58 | static Boolean DPPChanged[DPPCount], N_DPPChanged[DPPCount]; |
||
59 | static Boolean SPChanged, CPChanged, N_SPChanged, N_CPChanged; |
||
60 | |||
61 | static ShortInt ExtCounter; |
||
62 | static enum |
||
63 | { |
||
64 | MemModeStd, /* normal */ |
||
65 | MemModeNoCheck, /* EXTS Rn */ |
||
66 | MemModeZeroPage, /* EXTP Rn */ |
||
67 | MemModeFixedBank, /* EXTS nn */ |
||
68 | MemModeFixedPage /* EXTP nn */ |
||
69 | } MemMode; |
||
70 | static Word MemPage; |
||
71 | static Boolean ExtSFRs; |
||
72 | |||
73 | #define ASSUME166Count 4 |
||
74 | static ASSUMERec ASSUME166s[ASSUME166Count] = |
||
75 | { |
||
76 | { "DPP0", DPPAssumes + 0, 0, 15, -1, NULL }, |
||
77 | { "DPP1", DPPAssumes + 1, 0, 15, -1, NULL }, |
||
78 | { "DPP2", DPPAssumes + 2, 0, 15, -1, NULL }, |
||
79 | { "DPP3", DPPAssumes + 3, 0, 15, -1, NULL } |
||
80 | }; |
||
81 | |||
82 | /*-------------------------------------------------------------------------*/ |
||
83 | |||
84 | enum |
||
85 | { |
||
86 | ModNone = -1, |
||
87 | ModReg = 0, |
||
88 | ModImm = 1, |
||
89 | ModIReg = 2, |
||
90 | ModPreDec = 3, |
||
91 | ModPostInc = 4, |
||
92 | ModIndex = 5, |
||
93 | ModAbs = 6, |
||
94 | ModMReg = 7, |
||
95 | ModLAbs = 8 |
||
96 | }; |
||
97 | |||
98 | typedef enum |
||
99 | { |
||
100 | eForceNone = 0, |
||
101 | eForceShort = 1, |
||
102 | eForceLong = 2 |
||
103 | } tForceSize; |
||
104 | |||
105 | #define MModReg (1 << ModReg) |
||
106 | #define MModImm (1 << ModImm) |
||
107 | #define MModIReg (1 << ModIReg) |
||
108 | #define MModPreDec (1 << ModPreDec) |
||
109 | #define MModPostInc (1 << ModPostInc) |
||
110 | #define MModIndex (1 << ModIndex) |
||
111 | #define MModAbs (1 << ModAbs) |
||
112 | #define MModMReg (1 << ModMReg) |
||
113 | #define MModLAbs (1 << ModLAbs) |
||
114 | |||
115 | #define M_InCode (1 << 14) |
||
116 | #define M_Dest (1 << 13) |
||
117 | |||
118 | typedef struct |
||
119 | { |
||
120 | Byte Mode; |
||
121 | Byte Vals[2]; |
||
122 | ShortInt Type; |
||
123 | tSymbolFlags SymFlags; |
||
124 | tForceSize ForceSize; |
||
125 | int Cnt; |
||
126 | } tAdrResult; |
||
127 | |||
128 | /*!------------------------------------------------------------------------ |
||
129 | * \fn IsRegCore(const char *pArg, tRegInt *pValue, tSymbolSize *pSize) |
||
130 | * \brief check whether argument describes a CPU (general purpose) register |
||
131 | * \param pArg argument |
||
132 | * \param pValue resulting register # if yes |
||
133 | * \param pSize resulting register size if yes |
||
134 | * \return true if yes |
||
135 | * ------------------------------------------------------------------------ */ |
||
136 | |||
137 | static Boolean IsRegCore(const char *pArg, tRegInt *pValue, tSymbolSize *pSize) |
||
138 | { |
||
139 | int l = strlen(pArg); |
||
140 | Boolean OK; |
||
141 | |||
142 | if ((l < 2) || (as_toupper(*pArg) != 'R')) |
||
143 | return False; |
||
144 | else if ((l > 2) && (as_toupper(pArg[1]) == 'L')) |
||
145 | { |
||
146 | *pValue = ConstLongInt(pArg + 2, &OK, 10) << 1; |
||
147 | *pSize = eSymbolSize8Bit; |
||
148 | return (OK && (*pValue <= 15)); |
||
149 | } |
||
150 | else if ((l > 2) && (as_toupper(pArg[1]) == 'H')) |
||
151 | { |
||
152 | *pValue = (ConstLongInt(pArg + 2, &OK, 10) << 1) + 1; |
||
153 | *pSize = eSymbolSize8Bit; |
||
154 | return (OK && (*pValue <= 15)); |
||
155 | } |
||
156 | else |
||
157 | { |
||
158 | *pValue = ConstLongInt(pArg + 1, &OK, 10); |
||
159 | *pSize = eSymbolSize16Bit; |
||
160 | return (OK && (*pValue <= 15)); |
||
161 | } |
||
162 | } |
||
163 | |||
164 | /*!------------------------------------------------------------------------ |
||
165 | * \fn DissectReg_166(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize) |
||
166 | * \brief dissect register symbols - C16x variant |
||
167 | * \param pDest destination buffer |
||
168 | * \param DestSize destination buffer size |
||
169 | * \param Value numeric register value |
||
170 | * \param InpSize register size |
||
171 | * ------------------------------------------------------------------------ */ |
||
172 | |||
173 | static void DissectReg_166(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize) |
||
174 | { |
||
175 | switch (InpSize) |
||
176 | { |
||
177 | case eSymbolSize8Bit: |
||
178 | as_snprintf(pDest, DestSize, "R%c%u", Value & 1 ? 'H' : 'L', (unsigned)(Value >> 1)); |
||
179 | break; |
||
180 | case eSymbolSize16Bit: |
||
181 | as_snprintf(pDest, DestSize, "R%u", (unsigned)Value); |
||
182 | break; |
||
183 | default: |
||
184 | as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value); |
||
185 | } |
||
186 | } |
||
187 | |||
188 | /*!------------------------------------------------------------------------ |
||
189 | * \fn IsReg(const tStrComp *pArg, Byte *pValue, tSymbolSize *pSize, tSymbolSize ReqSize, Boolean MustBeReg) |
||
190 | * \brief check whether argument is a CPU register or user-defined register alias |
||
191 | * \param pArg argument |
||
192 | * \param pValue resulting register # if yes |
||
193 | * \param pSize resulting register size if yes |
||
194 | * \param ReqSize requested register size |
||
195 | * \param MustBeReg expecting register or maybe not? |
||
196 | * \return reg eval result |
||
197 | * ------------------------------------------------------------------------ */ |
||
198 | |||
199 | /* NOTE: If requester register size is 8 bits, R0..R15 is allowed as |
||
200 | alias for R0L,R0H,R1L,...,R7H: */ |
||
201 | |||
202 | static Boolean ChkRegSize(tSymbolSize ReqSize, tSymbolSize ActSize) |
||
203 | { |
||
204 | return (ReqSize == eSymbolSizeUnknown) |
||
205 | || (ReqSize == ActSize) |
||
206 | || ((ReqSize == eSymbolSize8Bit) && (ActSize == eSymbolSize16Bit)); |
||
207 | } |
||
208 | |||
209 | static tRegEvalResult IsReg(const tStrComp *pArg, Byte *pValue, tSymbolSize *pSize, tSymbolSize ReqSize, Boolean MustBeReg) |
||
210 | { |
||
211 | tRegDescr RegDescr; |
||
212 | tEvalResult EvalResult; |
||
213 | tRegEvalResult RegEvalResult; |
||
214 | |||
215 | if (IsRegCore(pArg->str.p_str, &RegDescr.Reg, &EvalResult.DataSize)) |
||
216 | RegEvalResult = eIsReg; |
||
217 | else |
||
218 | RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg); |
||
219 | |||
220 | if (RegEvalResult == eIsReg) |
||
221 | { |
||
222 | if (!ChkRegSize(ReqSize, EvalResult.DataSize)) |
||
223 | { |
||
224 | WrStrErrorPos(ErrNum_InvOpSize, pArg); |
||
225 | RegEvalResult = MustBeReg ? eIsNoReg : eRegAbort; |
||
226 | } |
||
227 | } |
||
228 | |||
229 | *pValue = RegDescr.Reg; |
||
230 | if (pSize) *pSize = EvalResult.DataSize; |
||
231 | return RegEvalResult; |
||
232 | } |
||
233 | |||
234 | static tRegEvalResult IsRegM1(const tStrComp *pArg, Byte *pValue, tSymbolSize ReqSize, Boolean MustBeReg) |
||
235 | { |
||
236 | if (*pArg->str.p_str) |
||
237 | { |
||
238 | int l; |
||
239 | char tmp = pArg->str.p_str[l = (strlen(pArg->str.p_str) - 1)]; |
||
240 | tRegEvalResult b; |
||
241 | |||
242 | pArg->str.p_str[l] = '\0'; |
||
243 | b = IsReg(pArg, pValue, NULL, ReqSize, MustBeReg); |
||
244 | pArg->str.p_str[l] = tmp; |
||
245 | return b; |
||
246 | } |
||
247 | else |
||
248 | return eIsNoReg; |
||
249 | } |
||
250 | |||
251 | static tRegEvalResult IsRegP1(const tStrComp *pArg, Byte *pValue, tSymbolSize ReqSize, Boolean MustBeReg) |
||
252 | { |
||
253 | tStrComp Arg; |
||
254 | |||
255 | StrCompRefRight(&Arg, pArg, 1); |
||
256 | return IsReg(&Arg, pValue, NULL, ReqSize, MustBeReg); |
||
257 | } |
||
258 | |||
259 | static LongInt SFRStart(void) |
||
260 | { |
||
261 | return (ExtSFRs) ? 0xf000 : 0xfe00; |
||
262 | } |
||
263 | |||
264 | static LongInt SFREnd(void) |
||
265 | { |
||
266 | return (ExtSFRs) ? 0xf1de : 0xffde; |
||
267 | } |
||
268 | |||
269 | static Boolean CalcPage(LongInt *Adr, Boolean DoAnyway) |
||
270 | { |
||
271 | int z; |
||
272 | Word Bank; |
||
273 | |||
274 | switch (MemMode) |
||
275 | { |
||
276 | case MemModeStd: |
||
277 | z = 0; |
||
278 | while ((z <= 3) && (((*Adr) >> 14) != DPPAssumes[z])) |
||
279 | z++; |
||
280 | if (z > 3) |
||
281 | { |
||
282 | WrError(ErrNum_InAccPage); |
||
283 | (*Adr) &= 0xffff; |
||
284 | return DoAnyway; |
||
285 | } |
||
286 | else |
||
287 | { |
||
288 | *Adr = ((*Adr) & 0x3fff) + (z << 14); |
||
289 | if (DPPChanged[z]) |
||
290 | WrXError(ErrNum_Pipeline, RegNames[z]); |
||
291 | return True; |
||
292 | } |
||
293 | case MemModeZeroPage: |
||
294 | (*Adr) &= 0x3fff; |
||
295 | return True; |
||
296 | case MemModeFixedPage: |
||
297 | Bank = (*Adr) >> 14; |
||
298 | (*Adr) &= 0x3fff; |
||
299 | if (Bank != MemPage) |
||
300 | { |
||
301 | WrError(ErrNum_InAccPage); |
||
302 | return (DoAnyway); |
||
303 | } |
||
304 | else |
||
305 | return True; |
||
306 | case MemModeNoCheck: |
||
307 | (*Adr) &= 0xffff; |
||
308 | return True; |
||
309 | case MemModeFixedBank: |
||
310 | Bank = (*Adr) >> 16; (*Adr) &= 0xffff; |
||
311 | if (Bank != MemPage) |
||
312 | { |
||
313 | WrError(ErrNum_InAccPage); |
||
314 | return (DoAnyway); |
||
315 | } |
||
316 | else |
||
317 | return True; |
||
318 | default: |
||
319 | return False; |
||
320 | } |
||
321 | } |
||
322 | |||
323 | static void DecideAbsolute(LongInt DispAcc, Word Mask, tAdrResult *pResult) |
||
324 | { |
||
325 | #define DPPAdr 0xfe00 |
||
326 | #define SPAdr 0xfe12 |
||
327 | #define CPAdr 0xfe10 |
||
328 | |||
329 | int z; |
||
330 | |||
331 | if (Mask & M_InCode) |
||
332 | { |
||
333 | if ((HiWord(EProgCounter()) == HiWord(DispAcc)) && (Mask & MModAbs)) |
||
334 | { |
||
335 | pResult->Type = ModAbs; |
||
336 | pResult->Cnt = 2; |
||
337 | pResult->Vals[0] = Lo(DispAcc); |
||
338 | pResult->Vals[1] = Hi(DispAcc); |
||
339 | } |
||
340 | else |
||
341 | { |
||
342 | pResult->Type = ModLAbs; |
||
343 | pResult->Cnt = 2; |
||
344 | pResult->Mode = DispAcc >> 16; |
||
345 | pResult->Vals[0] = Lo(DispAcc); |
||
346 | pResult->Vals[1] = Hi(DispAcc); |
||
347 | } |
||
348 | } |
||
349 | else if (((Mask & MModMReg) != 0) && (DispAcc >= SFRStart()) && (DispAcc <= SFREnd()) && (!(DispAcc & 1))) |
||
350 | { |
||
351 | pResult->Type = ModMReg; |
||
352 | pResult->Cnt = 1; |
||
353 | pResult->Vals[0] = (DispAcc - SFRStart()) >> 1; |
||
354 | } |
||
355 | else switch (MemMode) |
||
356 | { |
||
357 | case MemModeStd: |
||
358 | z = 0; |
||
359 | while ((z <= 3) && ((DispAcc >> 14) != DPPAssumes[z])) |
||
360 | z++; |
||
361 | if (z > 3) |
||
362 | { |
||
363 | WrError(ErrNum_InAccPage); |
||
364 | z = (DispAcc >> 14) & 3; |
||
365 | } |
||
366 | pResult->Type = ModAbs; |
||
367 | pResult->Cnt = 2; |
||
368 | pResult->Vals[0] = Lo(DispAcc); |
||
369 | pResult->Vals[1] = (Hi(DispAcc) & 0x3f) + (z << 6); |
||
370 | if (DPPChanged[z]) |
||
371 | WrXError(ErrNum_Pipeline, RegNames[z]); |
||
372 | break; |
||
373 | case MemModeZeroPage: |
||
374 | pResult->Type = ModAbs; |
||
375 | pResult->Cnt = 2; |
||
376 | pResult->Vals[0] = Lo(DispAcc); |
||
377 | pResult->Vals[1] = Hi(DispAcc) & 0x3f; |
||
378 | break; |
||
379 | case MemModeFixedPage: |
||
380 | if ((DispAcc >> 14) != MemPage) |
||
381 | WrError(ErrNum_InAccPage); |
||
382 | pResult->Type = ModAbs; |
||
383 | pResult->Cnt = 2; |
||
384 | pResult->Vals[0] = Lo(DispAcc); |
||
385 | pResult->Vals[1] = Hi(DispAcc) & 0x3f; |
||
386 | break; |
||
387 | case MemModeNoCheck: |
||
388 | pResult->Type = ModAbs; |
||
389 | pResult->Cnt = 2; |
||
390 | pResult->Vals[0] = Lo(DispAcc); |
||
391 | pResult->Vals[1] = Hi(DispAcc); |
||
392 | break; |
||
393 | case MemModeFixedBank: |
||
394 | if ((DispAcc >> 16) != MemPage) |
||
395 | WrError(ErrNum_InAccPage); |
||
396 | pResult->Type = ModAbs; |
||
397 | pResult->Cnt = 2; |
||
398 | pResult->Vals[0] = Lo(DispAcc); |
||
399 | pResult->Vals[1] = Hi(DispAcc); |
||
400 | break; |
||
401 | } |
||
402 | |||
403 | if ((pResult->Type != ModNone) && (Mask & M_Dest)) |
||
404 | { |
||
405 | switch ((Word)DispAcc) |
||
406 | { |
||
407 | case SPAdr : N_SPChanged = True; break; |
||
408 | case CPAdr : N_CPChanged = True; break; |
||
409 | case DPPAdr : |
||
410 | case DPPAdr + 1 : N_DPPChanged[0] = True; break; |
||
411 | case DPPAdr + 2 : |
||
412 | case DPPAdr + 3 : N_DPPChanged[1] = True; break; |
||
413 | case DPPAdr + 4 : |
||
414 | case DPPAdr + 5 : N_DPPChanged[2] = True; break; |
||
415 | case DPPAdr + 6 : |
||
416 | case DPPAdr + 7 : N_DPPChanged[3] = True; break; |
||
417 | } |
||
418 | } |
||
419 | } |
||
420 | |||
421 | static int SplitForceSize(const char *pArg, tForceSize *pForceSize) |
||
422 | { |
||
423 | switch (*pArg) |
||
424 | { |
||
425 | case '>': *pForceSize = eForceLong; return 1; |
||
426 | case '<': *pForceSize = eForceShort; return 1; |
||
427 | default: return 0; |
||
428 | } |
||
429 | } |
||
430 | |||
431 | typedef struct |
||
432 | { |
||
433 | as_eval_cb_data_t cb_data; |
||
434 | tAdrResult *p_result; |
||
435 | } s166_eval_cb_data_t; |
||
436 | |||
437 | DECLARE_AS_EVAL_CB(s166_eval_cb) |
||
438 | { |
||
439 | s166_eval_cb_data_t *p_s166_eval_cb_data = (s166_eval_cb_data_t*)p_data; |
||
440 | Byte reg; |
||
441 | |||
442 | switch (IsReg(p_arg, ®, NULL, eSymbolSize16Bit, False)) |
||
443 | { |
||
444 | case eIsNoReg: |
||
445 | return e_eval_none; |
||
446 | case eIsReg: |
||
447 | if ((p_s166_eval_cb_data->p_result->Mode != 0xff) |
||
448 | || !as_eval_cb_data_stack_plain_add(p_data->p_stack)) |
||
449 | { |
||
450 | WrStrErrorPos(ErrNum_InvAddrMode, p_arg); |
||
451 | return e_eval_fail; |
||
452 | } |
||
453 | p_s166_eval_cb_data->p_result->Mode = reg; |
||
454 | as_tempres_set_int(p_res, 0); |
||
455 | return e_eval_ok; |
||
456 | default: |
||
457 | return e_eval_fail; |
||
458 | } |
||
459 | } |
||
460 | |||
461 | static ShortInt DecodeAdr(const tStrComp *pArg, Word Mask, tAdrResult *pResult) |
||
462 | { |
||
463 | LongInt HDisp, DispAcc; |
||
464 | Boolean OK; |
||
465 | int Offs; |
||
466 | tRegEvalResult RegEvalResult; |
||
467 | |||
468 | pResult->Type = ModNone; |
||
469 | pResult->Cnt = 0; |
||
470 | pResult->ForceSize = eForceNone; |
||
471 | |||
472 | /* immediate ? */ |
||
473 | |||
474 | if (*pArg->str.p_str == '#') |
||
475 | { |
||
476 | Offs = SplitForceSize(pArg->str.p_str + 1, &pResult->ForceSize); |
||
477 | switch (OpSize) |
||
478 | { |
||
479 | case eSymbolSize8Bit: |
||
480 | pResult->Vals[0] = EvalStrIntExpressionOffsWithFlags(pArg, 1 + Offs, Int8, &OK, &pResult->SymFlags); |
||
481 | pResult->Vals[1] = 0; |
||
482 | break; |
||
483 | case eSymbolSize16Bit: |
||
484 | HDisp = EvalStrIntExpressionOffsWithFlags(pArg, 1 + Offs, Int16, &OK, &pResult->SymFlags); |
||
485 | pResult->Vals[0] = Lo(HDisp); |
||
486 | pResult->Vals[1] = Hi(HDisp); |
||
487 | break; |
||
488 | default: |
||
489 | OK = False; |
||
490 | break; |
||
491 | } |
||
492 | if (OK) |
||
493 | { |
||
494 | pResult->Type = ModImm; |
||
495 | AdrCnt = OpSize + 1; |
||
496 | } |
||
497 | } |
||
498 | |||
499 | /* Register ? */ |
||
500 | |||
501 | else if ((RegEvalResult = IsReg(pArg, &pResult->Mode, NULL, OpSize, False)) != eIsNoReg) |
||
502 | { |
||
503 | if (RegEvalResult == eRegAbort) |
||
504 | return pResult->Type; |
||
505 | if ((Mask & MModReg) != 0) |
||
506 | pResult->Type = ModReg; |
||
507 | else |
||
508 | { |
||
509 | pResult->Type = ModMReg; |
||
510 | pResult->Vals[0] = 0xf0 + pResult->Mode; |
||
511 | AdrCnt = 1; |
||
512 | } |
||
513 | if (CPChanged) |
||
514 | WrXError(ErrNum_Pipeline, RegNames[4]); |
||
515 | } |
||
516 | |||
517 | /* indirekt ? */ |
||
518 | |||
519 | else if ((*pArg->str.p_str == '[') && (pArg->str.p_str[strlen(pArg->str.p_str) - 1] == ']')) |
||
520 | { |
||
521 | tStrComp Arg; |
||
522 | int ArgLen; |
||
523 | |||
524 | StrCompRefRight(&Arg, pArg, 1); |
||
525 | StrCompShorten(&Arg, 1); |
||
526 | KillPrefBlanksStrCompRef(&Arg); |
||
527 | KillPostBlanksStrComp(&Arg); |
||
528 | ArgLen = strlen(Arg.str.p_str); |
||
529 | |||
530 | /* Predekrement ? */ |
||
531 | |||
532 | if ((ArgLen > 2) && (*Arg.str.p_str == '-') && ((RegEvalResult = IsRegP1(&Arg, &pResult->Mode, eSymbolSize16Bit, False)) != eIsNoReg)) |
||
533 | { |
||
534 | if (eRegAbort == RegEvalResult) |
||
535 | return pResult->Type; |
||
536 | pResult->Type = ModPreDec; |
||
537 | } |
||
538 | |||
539 | /* Postinkrement ? */ |
||
540 | |||
541 | else if ((ArgLen > 2) && (Arg.str.p_str[ArgLen - 1] == '+') && ((RegEvalResult = IsRegM1(&Arg, &pResult->Mode, eSymbolSize16Bit, False)) != eIsNoReg)) |
||
542 | { |
||
543 | if (eRegAbort == RegEvalResult) |
||
544 | return pResult->Type; |
||
545 | pResult->Type = ModPostInc; |
||
546 | } |
||
547 | |||
548 | /* indiziert ? */ |
||
549 | |||
550 | else |
||
551 | { |
||
552 | s166_eval_cb_data_t s166_eval_cb_data; |
||
553 | tEvalResult eval_result; |
||
554 | |||
555 | as_eval_cb_data_ini(&s166_eval_cb_data.cb_data, s166_eval_cb); |
||
556 | pResult->Mode = 0xff; |
||
557 | s166_eval_cb_data.p_result = pResult; |
||
558 | DispAcc = EvalStrIntExprWithResultAndCallback(&Arg, Int16, &eval_result, &s166_eval_cb_data.cb_data); |
||
559 | if (!eval_result.OK) |
||
560 | return pResult->Type; |
||
561 | |||
562 | if (pResult->Mode == 0xff) |
||
563 | DecideAbsolute(DispAcc, Mask, pResult); |
||
564 | else if (DispAcc == 0) |
||
565 | pResult->Type = ModIReg; |
||
566 | else if (DispAcc > 0xffff) |
||
567 | WrError(ErrNum_OverRange); |
||
568 | else if (DispAcc < -0x8000l) |
||
569 | WrError(ErrNum_UnderRange); |
||
570 | else |
||
571 | { |
||
572 | pResult->Vals[0] = Lo(DispAcc); |
||
573 | pResult->Vals[1] = Hi(DispAcc); |
||
574 | pResult->Type = ModIndex; |
||
575 | pResult->Cnt = 2; |
||
576 | } |
||
577 | } |
||
578 | } |
||
579 | else |
||
580 | { |
||
581 | int Offset = SplitForceSize(pArg->str.p_str, &pResult->ForceSize); |
||
582 | |||
583 | DispAcc = EvalStrIntExpressionOffsWithFlags(pArg, Offset, MemInt, &OK, &pResult->SymFlags); |
||
584 | if (OK) |
||
585 | DecideAbsolute(DispAcc, Mask, pResult); |
||
586 | } |
||
587 | |||
588 | if ((pResult->Type != ModNone) && (!((1 << pResult->Type) & Mask))) |
||
589 | { |
||
590 | WrError(ErrNum_InvAddrMode); |
||
591 | pResult->Type = ModNone; |
||
592 | pResult->Cnt = 0; |
||
593 | } |
||
594 | return pResult->Type; |
||
595 | } |
||
596 | |||
597 | static Boolean DecodeCondition(const char *Name, Byte *p_cond_code) |
||
598 | { |
||
599 | int z; |
||
600 | |||
601 | for (z = 0; Conditions[z].Name; z++) |
||
602 | if (!as_strcasecmp(Conditions[z].Name, Name)) |
||
603 | { |
||
604 | *p_cond_code = Conditions[z].Code; |
||
605 | return True; |
||
606 | } |
||
607 | return False; |
||
608 | } |
||
609 | |||
610 | static Boolean DecodeBitAddr(const tStrComp *pArg, Word *Adr, Byte *Bit, Boolean MayBeOut) |
||
611 | { |
||
612 | char *p; |
||
613 | Word LAdr; |
||
614 | Byte Reg; |
||
615 | Boolean OK; |
||
616 | |||
617 | p = QuotPos(pArg->str.p_str, '.'); |
||
618 | if (!p) |
||
619 | { |
||
620 | LAdr = EvalStrIntExpression(pArg, UInt16, &OK) & 0x1fff; |
||
621 | if (OK) |
||
622 | { |
||
623 | if ((!MayBeOut) && ((LAdr >> 12) != Ord(ExtSFRs))) |
||
624 | { |
||
625 | WrError(ErrNum_InAccReg); |
||
626 | return False; |
||
627 | } |
||
628 | *Adr = LAdr >> 4; |
||
629 | *Bit = LAdr & 15; |
||
630 | if (!MayBeOut) |
||
631 | *Adr = Lo(*Adr); |
||
632 | return True; |
||
633 | } |
||
634 | else return False; |
||
635 | } |
||
636 | else if (p == pArg->str.p_str) |
||
637 | { |
||
638 | WrError(ErrNum_InvAddrMode); |
||
639 | return False; |
||
640 | } |
||
641 | else |
||
642 | { |
||
643 | tStrComp AddrComp, BitComp; |
||
644 | |||
645 | StrCompSplitRef(&AddrComp, &BitComp, pArg, p); |
||
646 | |||
647 | switch (IsReg(&AddrComp, &Reg, NULL, eSymbolSize16Bit, False)) |
||
648 | { |
||
649 | case eIsReg: |
||
650 | *Adr = 0xf0 + Reg; |
||
651 | break; |
||
652 | case eRegAbort: |
||
653 | return False; |
||
654 | case eIsNoReg: |
||
655 | { |
||
656 | tSymbolFlags Flags; |
||
657 | |||
658 | LAdr = EvalStrIntExpressionWithFlags(&AddrComp, UInt16, &OK, &Flags); |
||
659 | if (!OK) |
||
660 | return False; |
||
661 | if (mFirstPassUnknown(Flags)) |
||
662 | LAdr = 0xfd00; |
||
663 | |||
664 | /* full addresses must be even, since bitfields in memory are 16 bit: */ |
||
665 | |||
666 | if ((LAdr > 0xff) && (LAdr & 1)) |
||
667 | { |
||
668 | WrStrErrorPos(ErrNum_NotAligned, &AddrComp); |
||
669 | return False; |
||
670 | } |
||
671 | |||
672 | /* coded bit address: */ |
||
673 | |||
674 | if (LAdr <= 0xff) |
||
675 | *Adr = LAdr; |
||
676 | |||
677 | /* 1st RAM bank: */ |
||
678 | |||
679 | else if ((LAdr >= 0xfd00) && (LAdr <= 0xfdfe)) |
||
680 | *Adr = (LAdr - 0xfd00)/2; |
||
681 | |||
682 | /* SFR space: */ |
||
683 | |||
684 | else if ((LAdr >= 0xff00) && (LAdr <= 0xffde)) |
||
685 | { |
||
686 | if ((ExtSFRs) && (!MayBeOut)) |
||
687 | { |
||
688 | WrStrErrorPos(ErrNum_InAccReg, &AddrComp); |
||
689 | return False; |
||
690 | } |
||
691 | *Adr = 0x80 + ((LAdr - 0xff00) / 2); |
||
692 | } |
||
693 | |||
694 | /* extended SFR space: */ |
||
695 | |||
696 | else if ((LAdr >= 0xf100) && (LAdr <= 0xf1de)) |
||
697 | { |
||
698 | if ((!ExtSFRs) && (!MayBeOut)) |
||
699 | { |
||
700 | WrStrErrorPos(ErrNum_InAccReg, &AddrComp); |
||
701 | return False; |
||
702 | } |
||
703 | *Adr = 0x80 + ((LAdr - 0xf100) / 2); |
||
704 | if (MayBeOut) |
||
705 | (*Adr) += 0x100; |
||
706 | } |
||
707 | else |
||
708 | { |
||
709 | WrStrErrorPos(ErrNum_OverRange, &AddrComp); |
||
710 | return False; |
||
711 | } |
||
712 | } |
||
713 | } |
||
714 | |||
715 | *Bit = EvalStrIntExpression(&BitComp, UInt4, &OK); |
||
716 | return OK; |
||
717 | } |
||
718 | } |
||
719 | |||
720 | static Word WordVal(const tAdrResult *pResult) |
||
721 | { |
||
722 | return pResult->Vals[0] + (((Word)pResult->Vals[1]) << 8); |
||
723 | } |
||
724 | |||
725 | static Boolean DecodePref(const tStrComp *pArg, Byte *Erg) |
||
726 | { |
||
727 | Boolean OK; |
||
728 | tSymbolFlags Flags; |
||
729 | |||
730 | if (*pArg->str.p_str != '#') |
||
731 | { |
||
732 | WrError(ErrNum_InvAddrMode); |
||
733 | return False; |
||
734 | } |
||
735 | *Erg = EvalStrIntExpressionOffsWithFlags(pArg, 1, UInt3, &OK, &Flags); |
||
736 | if (mFirstPassUnknown(Flags)) |
||
737 | *Erg = 1; |
||
738 | if (!OK) |
||
739 | return False; |
||
740 | if (*Erg < 1) |
||
741 | WrError(ErrNum_UnderRange); |
||
742 | else if (*Erg > 4) |
||
743 | WrError(ErrNum_OverRange); |
||
744 | else |
||
745 | { |
||
746 | (*Erg)--; |
||
747 | return True; |
||
748 | } |
||
749 | return False; |
||
750 | } |
||
751 | |||
752 | /*-------------------------------------------------------------------------*/ |
||
753 | |||
754 | static void DecodeFixed(Word Index) |
||
755 | { |
||
756 | const BaseOrder *pOrder = FixedOrders + Index; |
||
757 | |||
758 | if (ChkArgCnt(0, 0)) |
||
759 | { |
||
760 | CodeLen = 2; |
||
761 | BAsmCode[0] = Lo(pOrder->Code1); |
||
762 | BAsmCode[1] = Hi(pOrder->Code1); |
||
763 | if (pOrder->Code2 != 0) |
||
764 | { |
||
765 | CodeLen = 4; |
||
766 | BAsmCode[2] = Lo(pOrder->Code2); |
||
767 | BAsmCode[3] = Hi(pOrder->Code2); |
||
768 | if ((!strncmp(OpPart.str.p_str, "RET", 3)) && (SPChanged)) |
||
769 | WrXError(ErrNum_Pipeline, RegNames[5]); |
||
770 | } |
||
771 | } |
||
772 | } |
||
773 | |||
774 | static void DecodeMOV(Word Code) |
||
775 | { |
||
776 | LongInt AdrLong; |
||
777 | |||
778 | OpSize = (tSymbolSize)Hi(Code); |
||
779 | Code = 1 - OpSize; |
||
780 | |||
781 | if (ChkArgCnt(2, 2)) |
||
782 | { |
||
783 | tAdrResult DestResult; |
||
784 | |||
785 | switch (DecodeAdr(&ArgStr[1], MModReg | MModMReg | MModIReg | MModPreDec | MModPostInc | MModIndex | MModAbs | M_Dest, &DestResult)) |
||
786 | { |
||
787 | case ModReg: |
||
788 | { |
||
789 | tAdrResult SrcResult; |
||
790 | |||
791 | switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | MModIReg | MModPostInc | MModIndex | MModAbs, &SrcResult)) |
||
792 | { |
||
793 | case ModReg: |
||
794 | CodeLen = 2; |
||
795 | BAsmCode[0] = 0xf0 + Code; |
||
796 | BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode; |
||
797 | break; |
||
798 | case ModImm: |
||
799 | { |
||
800 | Boolean IsShort = WordVal(&SrcResult) <= 15; |
||
801 | |||
802 | if (!SrcResult.ForceSize) |
||
803 | SrcResult.ForceSize = IsShort ? eForceShort : eForceLong; |
||
804 | if (SrcResult.ForceSize == eForceShort) |
||
805 | { |
||
806 | if (!IsShort && !mSymbolQuestionable(SrcResult.SymFlags)) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]); |
||
807 | else |
||
808 | { |
||
809 | CodeLen = 2; |
||
810 | BAsmCode[0] = 0xe0 + Code; |
||
811 | BAsmCode[1] = (WordVal(&SrcResult) << 4) + DestResult.Mode; |
||
812 | } |
||
813 | } |
||
814 | else |
||
815 | { |
||
816 | CodeLen = 4; |
||
817 | BAsmCode[0] = 0xe6 + Code; |
||
818 | BAsmCode[1] = DestResult.Mode + 0xf0; |
||
819 | memcpy(BAsmCode + 2, SrcResult.Vals, 2); |
||
820 | } |
||
821 | break; |
||
822 | } |
||
823 | case ModIReg: |
||
824 | CodeLen = 2; |
||
825 | BAsmCode[0] = 0xa8 + Code; |
||
826 | BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode; |
||
827 | break; |
||
828 | case ModPostInc: |
||
829 | CodeLen = 2; |
||
830 | BAsmCode[0] = 0x98 + Code; |
||
831 | BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode; |
||
832 | break; |
||
833 | case ModIndex: |
||
834 | CodeLen = 2 + SrcResult.Cnt; |
||
835 | BAsmCode[0] = 0xd4 + (Code << 5); |
||
836 | BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode; |
||
837 | memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt); |
||
838 | break; |
||
839 | case ModAbs: |
||
840 | CodeLen = 2 + SrcResult.Cnt; |
||
841 | BAsmCode[0] = 0xf2 + Code; |
||
842 | BAsmCode[1] = 0xf0 + DestResult.Mode; |
||
843 | memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt); |
||
844 | break; |
||
845 | } |
||
846 | break; |
||
847 | } |
||
848 | case ModMReg: |
||
849 | { |
||
850 | tAdrResult SrcResult; |
||
851 | |||
852 | BAsmCode[1] = DestResult.Vals[0]; |
||
853 | switch (DecodeAdr(&ArgStr[2], MModImm | MModMReg | ((DPPAssumes[3] == 3) ? MModIReg : 0) | MModAbs, &SrcResult)) |
||
854 | { |
||
855 | case ModImm: |
||
856 | CodeLen = 4; |
||
857 | BAsmCode[0] = 0xe6 + Code; |
||
858 | memcpy(BAsmCode + 2, SrcResult.Vals, 2); |
||
859 | break; |
||
860 | case ModMReg: /* BAsmCode[1] sicher absolut darstellbar, da Rn vorher */ |
||
861 | /* abgefangen wird! */ |
||
862 | BAsmCode[0] = 0xf6 + Code; |
||
863 | AdrLong = SFRStart() + (((Word)BAsmCode[1]) << 1); |
||
864 | CalcPage(&AdrLong, True); |
||
865 | BAsmCode[2] = Lo(AdrLong); |
||
866 | BAsmCode[3] = Hi(AdrLong); |
||
867 | BAsmCode[1] = SrcResult.Vals[0]; |
||
868 | CodeLen = 4; |
||
869 | break; |
||
870 | case ModIReg: |
||
871 | CodeLen = 4; BAsmCode[0] = 0x94 + (Code << 5); |
||
872 | BAsmCode[2] = BAsmCode[1] << 1; |
||
873 | BAsmCode[3] = 0xfe + (BAsmCode[1] >> 7); /* ANSI :-0 */ |
||
874 | BAsmCode[1] = SrcResult.Mode; |
||
875 | break; |
||
876 | case ModAbs: |
||
877 | CodeLen = 2 + SrcResult.Cnt; |
||
878 | BAsmCode[0] = 0xf2 + Code; |
||
879 | memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt); |
||
880 | break; |
||
881 | } |
||
882 | break; |
||
883 | } |
||
884 | case ModIReg: |
||
885 | { |
||
886 | tAdrResult SrcResult; |
||
887 | |||
888 | switch (DecodeAdr(&ArgStr[2], MModReg | MModIReg | MModPostInc | MModAbs, &SrcResult)) |
||
889 | { |
||
890 | case ModReg: |
||
891 | CodeLen = 2; |
||
892 | BAsmCode[0] = 0xb8 + Code; |
||
893 | BAsmCode[1] = DestResult.Mode + (SrcResult.Mode << 4); |
||
894 | break; |
||
895 | case ModIReg: |
||
896 | CodeLen = 2; |
||
897 | BAsmCode[0] = 0xc8 + Code; |
||
898 | BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode; |
||
899 | break; |
||
900 | case ModPostInc: |
||
901 | CodeLen = 2; |
||
902 | BAsmCode[0] = 0xe8 + Code; |
||
903 | BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode; |
||
904 | break; |
||
905 | case ModAbs: |
||
906 | CodeLen = 2 + SrcResult.Cnt; |
||
907 | BAsmCode[0] = 0x84 + (Code << 5); |
||
908 | BAsmCode[1] = DestResult.Mode; |
||
909 | memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt); |
||
910 | break; |
||
911 | } |
||
912 | break; |
||
913 | } |
||
914 | case ModPreDec: |
||
915 | { |
||
916 | tAdrResult SrcResult; |
||
917 | |||
918 | switch (DecodeAdr(&ArgStr[2], MModReg, &SrcResult)) |
||
919 | { |
||
920 | case ModReg: |
||
921 | CodeLen = 2; |
||
922 | BAsmCode[0] = 0x88 + Code; |
||
923 | BAsmCode[1] = DestResult.Mode + (SrcResult.Mode << 4); |
||
924 | break; |
||
925 | } |
||
926 | break; |
||
927 | } |
||
928 | case ModPostInc: |
||
929 | { |
||
930 | tAdrResult SrcResult; |
||
931 | |||
932 | switch (DecodeAdr(&ArgStr[2], MModIReg, &SrcResult)) |
||
933 | { |
||
934 | case ModIReg: |
||
935 | CodeLen = 2; |
||
936 | BAsmCode[0] = 0xd8 + Code; |
||
937 | BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode; |
||
938 | break; |
||
939 | } |
||
940 | break; |
||
941 | } |
||
942 | case ModIndex: |
||
943 | { |
||
944 | tAdrResult SrcResult; |
||
945 | |||
946 | BAsmCode[1] = DestResult.Mode; |
||
947 | memcpy(BAsmCode + 2, DestResult.Vals, DestResult.Cnt); |
||
948 | switch (DecodeAdr(&ArgStr[2], MModReg, &SrcResult)) |
||
949 | { |
||
950 | case ModReg: |
||
951 | BAsmCode[0] = 0xc4 + (Code << 5); |
||
952 | CodeLen = 4; |
||
953 | BAsmCode[1] += SrcResult.Mode << 4; |
||
954 | break; |
||
955 | } |
||
956 | break; |
||
957 | } |
||
958 | case ModAbs: |
||
959 | { |
||
960 | tAdrResult SrcResult; |
||
961 | |||
962 | memcpy(BAsmCode + 2, DestResult.Vals, DestResult.Cnt); |
||
963 | switch (DecodeAdr(&ArgStr[2], MModIReg | MModMReg, &SrcResult)) |
||
964 | { |
||
965 | case ModIReg: |
||
966 | CodeLen = 4; |
||
967 | BAsmCode[0] = 0x94 + (Code << 5); |
||
968 | BAsmCode[1] = SrcResult.Mode; |
||
969 | break; |
||
970 | case ModMReg: |
||
971 | CodeLen = 4; |
||
972 | BAsmCode[0] = 0xf6 + Code; |
||
973 | BAsmCode[1] = SrcResult.Vals[0]; |
||
974 | break; |
||
975 | } |
||
976 | break; |
||
977 | } |
||
978 | } |
||
979 | } |
||
980 | } |
||
981 | |||
982 | static void DecodeMOVBS_MOVBZ(Word Code) |
||
983 | { |
||
984 | LongInt AdrLong; |
||
985 | |||
986 | if (ChkArgCnt(2, 2)) |
||
987 | { |
||
988 | tAdrResult DestResult; |
||
989 | |||
990 | OpSize = eSymbolSize16Bit; |
||
991 | switch (DecodeAdr(&ArgStr[1], MModReg | MModMReg | MModAbs | M_Dest, &DestResult)) |
||
992 | { |
||
993 | case ModReg: |
||
994 | { |
||
995 | tAdrResult SrcResult; |
||
996 | |||
997 | OpSize = eSymbolSize8Bit; |
||
998 | switch (DecodeAdr(&ArgStr[2], MModReg | MModAbs, &SrcResult)) |
||
999 | { |
||
1000 | case ModReg: |
||
1001 | CodeLen = 2; |
||
1002 | BAsmCode[0] = 0xc0 + Code; |
||
1003 | BAsmCode[1] = DestResult.Mode + (SrcResult.Mode << 4); |
||
1004 | break; |
||
1005 | case ModAbs: |
||
1006 | CodeLen = 4; |
||
1007 | BAsmCode[0] = 0xc2 + Code; |
||
1008 | BAsmCode[1] = 0xf0 + DestResult.Mode; |
||
1009 | memcpy(BAsmCode + 2, SrcResult.Vals, 2); |
||
1010 | break; |
||
1011 | } |
||
1012 | break; |
||
1013 | } |
||
1014 | case ModMReg: |
||
1015 | { |
||
1016 | tAdrResult SrcResult; |
||
1017 | |||
1018 | BAsmCode[1] = DestResult.Vals[0]; |
||
1019 | OpSize = eSymbolSize8Bit; |
||
1020 | switch (DecodeAdr(&ArgStr[2], MModAbs | MModMReg, &SrcResult)) |
||
1021 | { |
||
1022 | case ModMReg: /* BAsmCode[1] sicher absolut darstellbar, da Rn vorher */ |
||
1023 | /* abgefangen wird! */ |
||
1024 | BAsmCode[0] = 0xc5 + Code; |
||
1025 | AdrLong = SFRStart() + (((Word)BAsmCode[1]) << 1); |
||
1026 | CalcPage(&AdrLong, True); |
||
1027 | BAsmCode[2] = Lo(AdrLong); |
||
1028 | BAsmCode[3] = Hi(AdrLong); |
||
1029 | BAsmCode[1] = SrcResult.Vals[0]; |
||
1030 | CodeLen = 4; |
||
1031 | break; |
||
1032 | case ModAbs: |
||
1033 | CodeLen = 2 + SrcResult.Cnt; |
||
1034 | BAsmCode[0] = 0xc2 + Code; |
||
1035 | memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt); |
||
1036 | break; |
||
1037 | } |
||
1038 | break; |
||
1039 | } |
||
1040 | case ModAbs: |
||
1041 | { |
||
1042 | tAdrResult SrcResult; |
||
1043 | |||
1044 | OpSize = eSymbolSize8Bit; |
||
1045 | memcpy(BAsmCode + 2, DestResult.Vals, DestResult.Cnt); |
||
1046 | switch (DecodeAdr(&ArgStr[2], MModMReg, &SrcResult)) |
||
1047 | { |
||
1048 | case ModMReg: |
||
1049 | CodeLen = 4; |
||
1050 | BAsmCode[0] = 0xc5 + Code; |
||
1051 | BAsmCode[1] = SrcResult.Vals[0]; |
||
1052 | break; |
||
1053 | } |
||
1054 | break; |
||
1055 | } |
||
1056 | } |
||
1057 | } |
||
1058 | } |
||
1059 | |||
1060 | static void DecodePUSH_POP(Word Code) |
||
1061 | { |
||
1062 | if (ChkArgCnt(1, 1)) |
||
1063 | { |
||
1064 | tAdrResult Result; |
||
1065 | |||
1066 | switch (DecodeAdr(&ArgStr[1], MModMReg | ((Code & 0x10) ? M_Dest : 0), &Result)) |
||
1067 | { |
||
1068 | case ModMReg: |
||
1069 | CodeLen = 2; |
||
1070 | BAsmCode[0] = Code; |
||
1071 | BAsmCode[1] = Result.Vals[0]; |
||
1072 | if (SPChanged) WrXError(ErrNum_Pipeline, RegNames[5]); |
||
1073 | break; |
||
1074 | } |
||
1075 | } |
||
1076 | } |
||
1077 | |||
1078 | static void DecodeSCXT(Word Code) |
||
1079 | { |
||
1080 | UNUSED(Code); |
||
1081 | |||
1082 | if (ChkArgCnt(2, 2)) |
||
1083 | { |
||
1084 | tAdrResult Result; |
||
1085 | |||
1086 | switch (DecodeAdr(&ArgStr[1], MModMReg | M_Dest, &Result)) |
||
1087 | { |
||
1088 | case ModMReg: |
||
1089 | BAsmCode[1] = Result.Vals[0]; |
||
1090 | if (DecodeAdr(&ArgStr[2], MModAbs | MModImm, &Result) != ModNone) |
||
1091 | { |
||
1092 | CodeLen = 4; BAsmCode[0] = 0xc6 + (Ord(Result.Type == ModAbs) << 4); |
||
1093 | memcpy(BAsmCode + 2, Result.Vals, 2); |
||
1094 | } |
||
1095 | break; |
||
1096 | } |
||
1097 | } |
||
1098 | } |
||
1099 | |||
1100 | static void DecodeALU2(Word Code) |
||
1101 | { |
||
1102 | LongInt AdrLong; |
||
1103 | |||
1104 | OpSize = (tSymbolSize)Hi(Code); |
||
1105 | Code = (1 - OpSize) + (Lo(Code) << 4); |
||
1106 | |||
1107 | if (ChkArgCnt(2, 2)) |
||
1108 | { |
||
1109 | tAdrResult DestResult; |
||
1110 | |||
1111 | switch (DecodeAdr(&ArgStr[1], MModReg | MModMReg | MModAbs | M_Dest, &DestResult)) |
||
1112 | { |
||
1113 | case ModReg: |
||
1114 | { |
||
1115 | tAdrResult SrcResult; |
||
1116 | |||
1117 | switch (DecodeAdr(&ArgStr[2], MModReg | MModIReg | MModPostInc | MModAbs | MModImm, &SrcResult)) |
||
1118 | { |
||
1119 | case ModReg: |
||
1120 | CodeLen = 2; |
||
1121 | BAsmCode[0] = Code; |
||
1122 | BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode; |
||
1123 | break; |
||
1124 | case ModIReg: |
||
1125 | if (SrcResult.Mode > 3) WrError(ErrNum_InvAddrMode); |
||
1126 | else |
||
1127 | { |
||
1128 | CodeLen = 2; |
||
1129 | BAsmCode[0] = 0x08 + Code; |
||
1130 | BAsmCode[1] = (DestResult.Mode << 4) + 8 + SrcResult.Mode; |
||
1131 | } |
||
1132 | break; |
||
1133 | case ModPostInc: |
||
1134 | if (SrcResult.Mode > 3) WrError(ErrNum_InvAddrMode); |
||
1135 | else |
||
1136 | { |
||
1137 | CodeLen = 2; |
||
1138 | BAsmCode[0] = 0x08 + Code; |
||
1139 | BAsmCode[1] = (DestResult.Mode << 4) + 12 + SrcResult.Mode; |
||
1140 | } |
||
1141 | break; |
||
1142 | case ModAbs: |
||
1143 | CodeLen = 4; |
||
1144 | BAsmCode[0] = 0x02 + Code; |
||
1145 | BAsmCode[1] = 0xf0 + DestResult.Mode; |
||
1146 | memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt); |
||
1147 | break; |
||
1148 | case ModImm: |
||
1149 | { |
||
1150 | Boolean IsShort = WordVal(&SrcResult) <= 7; |
||
1151 | |||
1152 | if (!SrcResult.ForceSize) |
||
1153 | SrcResult.ForceSize = IsShort ? eForceShort : eForceLong; |
||
1154 | if (SrcResult.ForceSize == eForceShort) |
||
1155 | { |
||
1156 | if (!IsShort && !mSymbolQuestionable(SrcResult.SymFlags)) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]); |
||
1157 | else |
||
1158 | { |
||
1159 | CodeLen = 2; |
||
1160 | BAsmCode[0] = 0x08 + Code; |
||
1161 | BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Vals[0]; |
||
1162 | } |
||
1163 | } |
||
1164 | else |
||
1165 | { |
||
1166 | CodeLen = 4; |
||
1167 | BAsmCode[0] = 0x06 + Code; |
||
1168 | BAsmCode[1] = 0xf0 + DestResult.Mode; |
||
1169 | memcpy(BAsmCode + 2, SrcResult.Vals, 2); |
||
1170 | } |
||
1171 | break; |
||
1172 | } |
||
1173 | } |
||
1174 | break; |
||
1175 | } |
||
1176 | case ModMReg: |
||
1177 | { |
||
1178 | tAdrResult SrcResult; |
||
1179 | |||
1180 | BAsmCode[1] = DestResult.Vals[0]; |
||
1181 | switch (DecodeAdr(&ArgStr[2], MModAbs | MModMReg | MModImm, &SrcResult)) |
||
1182 | { |
||
1183 | case ModAbs: |
||
1184 | CodeLen = 4; |
||
1185 | BAsmCode[0] = 0x02 + Code; |
||
1186 | memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt); |
||
1187 | break; |
||
1188 | case ModMReg: /* BAsmCode[1] sicher absolut darstellbar, da Rn vorher */ |
||
1189 | /* abgefangen wird! */ |
||
1190 | BAsmCode[0] = 0x04 + Code; |
||
1191 | AdrLong = SFRStart() + (((Word)BAsmCode[1]) << 1); |
||
1192 | CalcPage(&AdrLong, True); |
||
1193 | BAsmCode[2] = Lo(AdrLong); |
||
1194 | BAsmCode[3] = Hi(AdrLong); |
||
1195 | BAsmCode[1] = SrcResult.Vals[0]; |
||
1196 | CodeLen = 4; |
||
1197 | break; |
||
1198 | case ModImm: |
||
1199 | CodeLen = 4; |
||
1200 | BAsmCode[0] = 0x06 + Code; |
||
1201 | memcpy(BAsmCode + 2, SrcResult.Vals, 2); |
||
1202 | break; |
||
1203 | } |
||
1204 | break; |
||
1205 | } |
||
1206 | case ModAbs: |
||
1207 | { |
||
1208 | tAdrResult SrcResult; |
||
1209 | |||
1210 | memcpy(BAsmCode + 2, DestResult.Vals, DestResult.Cnt); |
||
1211 | switch (DecodeAdr(&ArgStr[2], MModMReg, &SrcResult)) |
||
1212 | { |
||
1213 | case ModMReg: |
||
1214 | CodeLen = 4; |
||
1215 | BAsmCode[0] = 0x04 + Code; |
||
1216 | BAsmCode[1] = SrcResult.Vals[0]; |
||
1217 | break; |
||
1218 | } |
||
1219 | break; |
||
1220 | } |
||
1221 | } |
||
1222 | } |
||
1223 | } |
||
1224 | |||
1225 | static void DecodeCPL_NEG(Word Code) |
||
1226 | { |
||
1227 | OpSize = (tSymbolSize)Hi(Code); |
||
1228 | |||
1229 | Code = Lo(Code) + ((1 - OpSize) << 5); |
||
1230 | if (ChkArgCnt(1, 1)) |
||
1231 | { |
||
1232 | tAdrResult Result; |
||
1233 | |||
1234 | if (DecodeAdr(&ArgStr[1], MModReg | M_Dest, &Result) == ModReg) |
||
1235 | { |
||
1236 | CodeLen = 2; |
||
1237 | BAsmCode[0] = Code; |
||
1238 | BAsmCode[1] = Result.Mode << 4; |
||
1239 | } |
||
1240 | } |
||
1241 | } |
||
1242 | |||
1243 | static void DecodeDiv(Word Code) |
||
1244 | { |
||
1245 | if (ChkArgCnt(1, 1)) |
||
1246 | { |
||
1247 | tAdrResult Result; |
||
1248 | |||
1249 | if (DecodeAdr(&ArgStr[1], MModReg, &Result) == ModReg) |
||
1250 | { |
||
1251 | CodeLen = 2; |
||
1252 | BAsmCode[0] = 0x4b + (Code << 4); |
||
1253 | BAsmCode[1] = Result.Mode * 0x11; |
||
1254 | } |
||
1255 | } |
||
1256 | } |
||
1257 | |||
1258 | static void DecodeLoop(Word Code) |
||
1259 | { |
||
1260 | if (ChkArgCnt(2, 2)) |
||
1261 | { |
||
1262 | tAdrResult Result; |
||
1263 | |||
1264 | if (DecodeAdr(&ArgStr[1], MModReg | M_Dest, &Result) == ModReg) |
||
1265 | { |
||
1266 | BAsmCode[1] = Result.Mode; |
||
1267 | switch (DecodeAdr(&ArgStr[2], MModAbs | MModImm, &Result)) |
||
1268 | { |
||
1269 | case ModAbs: |
||
1270 | CodeLen = 4; |
||
1271 | BAsmCode[0] = Code + 2; |
||
1272 | BAsmCode[1] += 0xf0; |
||
1273 | memcpy(BAsmCode + 2, Result.Vals, 2); |
||
1274 | break; |
||
1275 | case ModImm: |
||
1276 | { |
||
1277 | Boolean IsShort = WordVal(&Result) < 16; |
||
1278 | |||
1279 | if (!Result.ForceSize) |
||
1280 | Result.ForceSize = IsShort ? eForceShort : eForceLong; |
||
1281 | if (Result.ForceSize == eForceShort) |
||
1282 | { |
||
1283 | if (!IsShort && !mSymbolQuestionable(Result.SymFlags)) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]); |
||
1284 | else |
||
1285 | { |
||
1286 | CodeLen = 2; |
||
1287 | BAsmCode[0] = Code; |
||
1288 | BAsmCode[1] += (WordVal(&Result) << 4); |
||
1289 | } |
||
1290 | } |
||
1291 | else |
||
1292 | { |
||
1293 | CodeLen = 4; |
||
1294 | BAsmCode[0] = Code + 6; |
||
1295 | BAsmCode[1] += 0xf0; |
||
1296 | memcpy(BAsmCode + 2, Result.Vals, 2); |
||
1297 | } |
||
1298 | break; |
||
1299 | } |
||
1300 | } |
||
1301 | } |
||
1302 | } |
||
1303 | } |
||
1304 | |||
1305 | static void DecodeMul(Word Code) |
||
1306 | { |
||
1307 | if (ChkArgCnt(2, 2)) |
||
1308 | { |
||
1309 | tAdrResult DestResult; |
||
1310 | |||
1311 | switch (DecodeAdr(&ArgStr[1], MModReg, &DestResult)) |
||
1312 | { |
||
1313 | case ModReg: |
||
1314 | { |
||
1315 | tAdrResult SrcResult; |
||
1316 | |||
1317 | switch (DecodeAdr(&ArgStr[2], MModReg, &SrcResult)) |
||
1318 | { |
||
1319 | case ModReg: |
||
1320 | CodeLen = 2; |
||
1321 | BAsmCode[0] = 0x0b + (Code << 4); |
||
1322 | BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode; |
||
1323 | break; |
||
1324 | } |
||
1325 | break; |
||
1326 | } |
||
1327 | } |
||
1328 | } |
||
1329 | } |
||
1330 | |||
1331 | static void DecodeShift(Word Code) |
||
1332 | { |
||
1333 | if (ChkArgCnt(2, 2)) |
||
1334 | { |
||
1335 | tAdrResult DestResult; |
||
1336 | |||
1337 | OpSize = eSymbolSize16Bit; |
||
1338 | switch (DecodeAdr(&ArgStr[1], MModReg | M_Dest, &DestResult)) |
||
1339 | { |
||
1340 | case ModReg: |
||
1341 | { |
||
1342 | tAdrResult SrcResult; |
||
1343 | |||
1344 | switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | M_Dest, &SrcResult)) |
||
1345 | { |
||
1346 | case ModReg: |
||
1347 | BAsmCode[0] = Code; |
||
1348 | BAsmCode[1] = SrcResult.Mode + (DestResult.Mode << 4); |
||
1349 | CodeLen = 2; |
||
1350 | break; |
||
1351 | case ModImm: |
||
1352 | if ((WordVal(&SrcResult) > 15) && !mSymbolQuestionable(SrcResult.SymFlags)) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]); |
||
1353 | else |
||
1354 | { |
||
1355 | BAsmCode[0] = Code + 0x10; |
||
1356 | BAsmCode[1] = (WordVal(&SrcResult) << 4) + DestResult.Mode; |
||
1357 | CodeLen = 2; |
||
1358 | } |
||
1359 | break; |
||
1360 | } |
||
1361 | break; |
||
1362 | } |
||
1363 | } |
||
1364 | } |
||
1365 | } |
||
1366 | |||
1367 | static void DecodeBit2(Word Code) |
||
1368 | { |
||
1369 | Byte BOfs1, BOfs2; |
||
1370 | Word BAdr1, BAdr2; |
||
1371 | |||
1372 | if (ChkArgCnt(2, 2) |
||
1373 | && DecodeBitAddr(&ArgStr[1], &BAdr1, &BOfs1, False) |
||
1374 | && DecodeBitAddr(&ArgStr[2], &BAdr2, &BOfs2, False)) |
||
1375 | { |
||
1376 | CodeLen = 4; |
||
1377 | BAsmCode[0] = Code; |
||
1378 | BAsmCode[1] = BAdr2; |
||
1379 | BAsmCode[2] = BAdr1; |
||
1380 | BAsmCode[3] = (BOfs2 << 4) + BOfs1; |
||
1381 | } |
||
1382 | } |
||
1383 | |||
1384 | static void DecodeBCLR_BSET(Word Code) |
||
1385 | { |
||
1386 | Byte BOfs; |
||
1387 | Word BAdr; |
||
1388 | |||
1389 | if (ChkArgCnt(1, 1) |
||
1390 | && DecodeBitAddr(&ArgStr[1], &BAdr, &BOfs, False)) |
||
1391 | { |
||
1392 | CodeLen = 2; |
||
1393 | BAsmCode[0] = (BOfs << 4) + Code; |
||
1394 | BAsmCode[1] = BAdr; |
||
1395 | } |
||
1396 | } |
||
1397 | |||
1398 | static void DecodeBFLDH_BFLDL(Word Code) |
||
1399 | { |
||
1400 | Byte BOfs; |
||
1401 | Word BAdr; |
||
1402 | |||
1403 | if (ChkArgCnt(3, 3)) |
||
1404 | { |
||
1405 | strmaxcat(ArgStr[1].str.p_str, ".0", STRINGSIZE); |
||
1406 | if (DecodeBitAddr(&ArgStr[1], &BAdr, &BOfs, False)) |
||
1407 | { |
||
1408 | tAdrResult Result; |
||
1409 | |||
1410 | OpSize = eSymbolSize8Bit; |
||
1411 | BAsmCode[1] = BAdr; |
||
1412 | if (DecodeAdr(&ArgStr[2], MModImm, &Result) == ModImm) |
||
1413 | { |
||
1414 | BAsmCode[2] = Result.Vals[0]; |
||
1415 | if (DecodeAdr(&ArgStr[3], MModImm, &Result) == ModImm) |
||
1416 | { |
||
1417 | BAsmCode[3] = Result.Vals[0]; |
||
1418 | CodeLen = 4; |
||
1419 | BAsmCode[0] = Code; |
||
1420 | if (Code & 0x10) |
||
1421 | { |
||
1422 | BAdr = BAsmCode[2]; |
||
1423 | BAsmCode[2] = BAsmCode[3]; |
||
1424 | BAsmCode[3] = BAdr; |
||
1425 | } |
||
1426 | } |
||
1427 | } |
||
1428 | } |
||
1429 | } |
||
1430 | } |
||
1431 | |||
1432 | static void DecodeJMP(Word Code) |
||
1433 | { |
||
1434 | UNUSED(Code); |
||
1435 | |||
1436 | if (ChkArgCnt(1, 2)) |
||
1437 | { |
||
1438 | Byte cond_code; |
||
1439 | tAdrResult Result; |
||
1440 | |||
1441 | if (ArgCnt == 1) |
||
1442 | cond_code = TrueCond; |
||
1443 | else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code)) |
||
1444 | { |
||
1445 | WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]); |
||
1446 | return; |
||
1447 | } |
||
1448 | |||
1449 | switch (DecodeAdr(&ArgStr[ArgCnt], MModAbs | MModLAbs | MModIReg | M_InCode, &Result)) |
||
1450 | { |
||
1451 | case ModLAbs: |
||
1452 | if (cond_code != COND_CODE_TRUE) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]); |
||
1453 | else |
||
1454 | { |
||
1455 | CodeLen = 2 + Result.Cnt; |
||
1456 | BAsmCode[0] = 0xfa; |
||
1457 | BAsmCode[1] = Result.Mode; |
||
1458 | memcpy(BAsmCode + 2, Result.Vals, Result.Cnt); |
||
1459 | } |
||
1460 | break; |
||
1461 | case ModAbs: |
||
1462 | { |
||
1463 | LongInt AdrDist = WordVal(&Result) - (EProgCounter() + 2); |
||
1464 | Boolean IsShort = (AdrDist <= 254) && (AdrDist >= -256) && ((AdrDist & 1) == 0); |
||
1465 | |||
1466 | if (!Result.ForceSize) |
||
1467 | Result.ForceSize = IsShort ? eForceShort : eForceLong; |
||
1468 | if (Result.ForceSize == eForceShort) |
||
1469 | { |
||
1470 | if (!IsShort && !mSymbolQuestionable(Result.SymFlags)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[ArgCnt]); |
||
1471 | else |
||
1472 | { |
||
1473 | CodeLen = 2; |
||
1474 | BAsmCode[0] = 0x0d + (cond_code << 4); |
||
1475 | BAsmCode[1] = (AdrDist / 2) & 0xff; |
||
1476 | } |
||
1477 | } |
||
1478 | else |
||
1479 | { |
||
1480 | CodeLen = 2 + Result.Cnt; |
||
1481 | BAsmCode[0] = 0xea; |
||
1482 | BAsmCode[1] = cond_code << 4; |
||
1483 | memcpy(BAsmCode + 2, Result.Vals, Result.Cnt); |
||
1484 | } |
||
1485 | break; |
||
1486 | } |
||
1487 | case ModIReg: |
||
1488 | CodeLen = 2; BAsmCode[0] = 0x9c; |
||
1489 | BAsmCode[1] = (cond_code << 4) + Result.Mode; |
||
1490 | break; |
||
1491 | } |
||
1492 | } |
||
1493 | } |
||
1494 | |||
1495 | static void DecodeCALL(Word Code) |
||
1496 | { |
||
1497 | UNUSED(Code); |
||
1498 | |||
1499 | if (ChkArgCnt(1, 2)) |
||
1500 | { |
||
1501 | Byte cond_code; |
||
1502 | tAdrResult Result; |
||
1503 | |||
1504 | if (ArgCnt == 1) |
||
1505 | cond_code = COND_CODE_TRUE; |
||
1506 | else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code)) |
||
1507 | { |
||
1508 | WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]); |
||
1509 | return; |
||
1510 | } |
||
1511 | |||
1512 | switch (DecodeAdr(&ArgStr[ArgCnt], MModAbs | MModLAbs | MModIReg | M_InCode, &Result)) |
||
1513 | { |
||
1514 | case ModLAbs: |
||
1515 | if (cond_code != COND_CODE_TRUE) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]); |
||
1516 | else |
||
1517 | { |
||
1518 | CodeLen = 2 + Result.Cnt; |
||
1519 | BAsmCode[0] = 0xda; |
||
1520 | BAsmCode[1] = Result.Mode; |
||
1521 | memcpy(BAsmCode + 2, Result.Vals, Result.Cnt); |
||
1522 | } |
||
1523 | break; |
||
1524 | case ModAbs: |
||
1525 | { |
||
1526 | LongInt AdrLong = WordVal(&Result) - (EProgCounter() + 2); |
||
1527 | Boolean IsShort = (AdrLong <= 254) && (AdrLong >= -256) && ((AdrLong & 1) == 0); |
||
1528 | |||
1529 | if (!Result.ForceSize && (cond_code == COND_CODE_TRUE)) |
||
1530 | Result.ForceSize = IsShort ? eForceShort : eForceLong; |
||
1531 | if (Result.ForceSize == eForceShort) |
||
1532 | { |
||
1533 | if (!IsShort && !mSymbolQuestionable(Result.SymFlags)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[ArgCnt]); |
||
1534 | else |
||
1535 | { |
||
1536 | CodeLen = 2; |
||
1537 | BAsmCode[0] = 0xbb; |
||
1538 | BAsmCode[1] = (AdrLong / 2) & 0xff; |
||
1539 | } |
||
1540 | } |
||
1541 | else |
||
1542 | { |
||
1543 | CodeLen = 2 + Result.Cnt; |
||
1544 | BAsmCode[0] = 0xca; |
||
1545 | BAsmCode[1] = 0x00 + (cond_code << 4); |
||
1546 | memcpy(BAsmCode + 2, Result.Vals, Result.Cnt); |
||
1547 | } |
||
1548 | break; |
||
1549 | } |
||
1550 | case ModIReg: |
||
1551 | CodeLen = 2; |
||
1552 | BAsmCode[0] = 0xab; |
||
1553 | BAsmCode[1] = (cond_code << 4) + Result.Mode; |
||
1554 | break; |
||
1555 | } |
||
1556 | } |
||
1557 | } |
||
1558 | |||
1559 | static void DecodeJMPR(Word Code) |
||
1560 | { |
||
1561 | UNUSED(Code); |
||
1562 | |||
1563 | if (ChkArgCnt(1, 2)) |
||
1564 | { |
||
1565 | Byte cond_code; |
||
1566 | Boolean OK; |
||
1567 | tSymbolFlags Flags; |
||
1568 | LongInt AdrLong; |
||
1569 | |||
1570 | if (ArgCnt == 1) |
||
1571 | cond_code = COND_CODE_TRUE; |
||
1572 | else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code)) |
||
1573 | { |
||
1574 | WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]); |
||
1575 | return; |
||
1576 | } |
||
1577 | |||
1578 | AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], MemInt, &OK, &Flags) - (EProgCounter() + 2); |
||
1579 | if (OK) |
||
1580 | { |
||
1581 | if (AdrLong & 1) WrError(ErrNum_DistIsOdd); |
||
1582 | else if (!mSymbolQuestionable(Flags) && ((AdrLong > 254) || (AdrLong < -256))) WrError(ErrNum_JmpDistTooBig); |
||
1583 | else |
||
1584 | { |
||
1585 | CodeLen = 2; |
||
1586 | BAsmCode[0] = 0x0d + (cond_code << 4); |
||
1587 | BAsmCode[1] = (AdrLong / 2) & 0xff; |
||
1588 | } |
||
1589 | } |
||
1590 | } |
||
1591 | } |
||
1592 | |||
1593 | static void DecodeCALLR(Word Code) |
||
1594 | { |
||
1595 | UNUSED(Code); |
||
1596 | |||
1597 | if (ChkArgCnt(1, 1)) |
||
1598 | { |
||
1599 | Boolean OK; |
||
1600 | tSymbolFlags Flags; |
||
1601 | LongInt AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], MemInt, &OK, &Flags) - (EProgCounter() + 2); |
||
1602 | if (OK) |
||
1603 | { |
||
1604 | if (AdrLong & 1) WrError(ErrNum_DistIsOdd); |
||
1605 | else if (!mSymbolQuestionable(Flags) && ((AdrLong > 254) || (AdrLong < -256))) WrError(ErrNum_JmpDistTooBig); |
||
1606 | else |
||
1607 | { |
||
1608 | CodeLen = 2; |
||
1609 | BAsmCode[0] = 0xbb; |
||
1610 | BAsmCode[1] = (AdrLong / 2) & 0xff; |
||
1611 | } |
||
1612 | } |
||
1613 | } |
||
1614 | } |
||
1615 | |||
1616 | static void DecodeJMPA_CALLA(Word Code) |
||
1617 | { |
||
1618 | if (ChkArgCnt(1, 2)) |
||
1619 | { |
||
1620 | Byte cond_code; |
||
1621 | Boolean OK; |
||
1622 | LongInt AdrLong; |
||
1623 | tSymbolFlags Flags; |
||
1624 | |||
1625 | if (ArgCnt == 1) |
||
1626 | cond_code = COND_CODE_TRUE; |
||
1627 | else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code)) |
||
1628 | { |
||
1629 | WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]); |
||
1630 | return; |
||
1631 | } |
||
1632 | |||
1633 | AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], MemInt, &OK, &Flags); |
||
1634 | if (OK && ChkSamePage(AdrLong, EProgCounter(), 16, Flags)) |
||
1635 | { |
||
1636 | CodeLen = 4; |
||
1637 | BAsmCode[0] = Code; |
||
1638 | BAsmCode[1] = 0x00 + (cond_code << 4); |
||
1639 | BAsmCode[2] = Lo(AdrLong); |
||
1640 | BAsmCode[3] = Hi(AdrLong); |
||
1641 | } |
||
1642 | } |
||
1643 | } |
||
1644 | |||
1645 | static void DecodeJMPS_CALLS(Word Code) |
||
1646 | { |
||
1647 | if (ChkArgCnt(1, 2)) |
||
1648 | { |
||
1649 | Boolean OK; |
||
1650 | Word AdrWord; |
||
1651 | Byte AdrBank; |
||
1652 | LongInt AdrLong; |
||
1653 | |||
1654 | if (ArgCnt == 1) |
||
1655 | { |
||
1656 | AdrLong = EvalStrIntExpression(&ArgStr[1], MemInt, &OK); |
||
1657 | AdrWord = AdrLong & 0xffff; |
||
1658 | AdrBank = AdrLong >> 16; |
||
1659 | } |
||
1660 | else |
||
1661 | { |
||
1662 | AdrWord = EvalStrIntExpression(&ArgStr[2], UInt16, &OK); |
||
1663 | AdrBank = OK ? EvalStrIntExpression(&ArgStr[1], MemInt2, &OK) : 0; |
||
1664 | } |
||
1665 | if (OK) |
||
1666 | { |
||
1667 | CodeLen = 4; |
||
1668 | BAsmCode[0] = Code; |
||
1669 | BAsmCode[1] = AdrBank; |
||
1670 | BAsmCode[2] = Lo(AdrWord); |
||
1671 | BAsmCode[3] = Hi(AdrWord); |
||
1672 | } |
||
1673 | } |
||
1674 | } |
||
1675 | |||
1676 | static void DecodeJMPI_CALLI(Word Code) |
||
1677 | { |
||
1678 | if (ChkArgCnt(1, 2)) |
||
1679 | { |
||
1680 | Byte cond_code; |
||
1681 | tAdrResult Result; |
||
1682 | |||
1683 | if (ArgCnt == 1) |
||
1684 | cond_code = COND_CODE_TRUE; |
||
1685 | else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code)) |
||
1686 | { |
||
1687 | WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]); |
||
1688 | return; |
||
1689 | } |
||
1690 | |||
1691 | switch (DecodeAdr(&ArgStr[ArgCnt], MModIReg | M_InCode, &Result)) |
||
1692 | { |
||
1693 | case ModIReg: |
||
1694 | CodeLen = 2; |
||
1695 | BAsmCode[0] = Code; |
||
1696 | BAsmCode[1] = Result.Mode + (cond_code << 4); |
||
1697 | break; |
||
1698 | } |
||
1699 | } |
||
1700 | } |
||
1701 | |||
1702 | static void DecodeBJmp(Word Code) |
||
1703 | { |
||
1704 | Byte BOfs; |
||
1705 | Word BAdr; |
||
1706 | |||
1707 | if (ChkArgCnt(2, 2) |
||
1708 | && DecodeBitAddr(&ArgStr[1], &BAdr, &BOfs, False)) |
||
1709 | { |
||
1710 | Boolean OK; |
||
1711 | tSymbolFlags Flags; |
||
1712 | LongInt AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[2], MemInt, &OK, &Flags) - (EProgCounter() + 4); |
||
1713 | if (OK) |
||
1714 | { |
||
1715 | if (AdrLong & 1) WrError(ErrNum_DistIsOdd); |
||
1716 | else if (!mSymbolQuestionable(Flags) && ((AdrLong < -256) || (AdrLong > 254))) WrError(ErrNum_JmpDistTooBig); |
||
1717 | else |
||
1718 | { |
||
1719 | CodeLen = 4; BAsmCode[0] = 0x8a + (Code << 4); |
||
1720 | BAsmCode[1] = BAdr; |
||
1721 | BAsmCode[2] = (AdrLong / 2) & 0xff; |
||
1722 | BAsmCode[3] = BOfs << 4; |
||
1723 | } |
||
1724 | } |
||
1725 | } |
||
1726 | } |
||
1727 | |||
1728 | static void DecodePCALL(Word Code) |
||
1729 | { |
||
1730 | UNUSED(Code); |
||
1731 | |||
1732 | if (ChkArgCnt(2, 2)) |
||
1733 | { |
||
1734 | tAdrResult Result; |
||
1735 | |||
1736 | switch (DecodeAdr(&ArgStr[1], MModMReg, &Result)) |
||
1737 | { |
||
1738 | case ModMReg: |
||
1739 | BAsmCode[1] = Result.Vals[0]; |
||
1740 | switch (DecodeAdr(&ArgStr[2], MModAbs | M_InCode, &Result)) |
||
1741 | { |
||
1742 | case ModAbs: |
||
1743 | CodeLen = 4; |
||
1744 | BAsmCode[0] = 0xe2; |
||
1745 | memcpy(BAsmCode + 2, Result.Vals, 2); |
||
1746 | break; |
||
1747 | } |
||
1748 | break; |
||
1749 | } |
||
1750 | } |
||
1751 | } |
||
1752 | |||
1753 | static void DecodeRETP(Word Code) |
||
1754 | { |
||
1755 | UNUSED(Code); |
||
1756 | |||
1757 | if (ChkArgCnt(1, 1)) |
||
1758 | { |
||
1759 | tAdrResult Result; |
||
1760 | |||
1761 | switch (DecodeAdr(&ArgStr[1], MModMReg, &Result)) |
||
1762 | { |
||
1763 | case ModMReg: |
||
1764 | BAsmCode[1] = Result.Vals[0]; |
||
1765 | BAsmCode[0] = 0xeb; |
||
1766 | CodeLen = 2; |
||
1767 | if (SPChanged) |
||
1768 | WrXError(ErrNum_Pipeline, RegNames[5]); |
||
1769 | break; |
||
1770 | } |
||
1771 | } |
||
1772 | } |
||
1773 | |||
1774 | static void DecodeTRAP(Word Code) |
||
1775 | { |
||
1776 | UNUSED(Code); |
||
1777 | |||
1778 | if (!ChkArgCnt(1, 1)); |
||
1779 | else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode); |
||
1780 | else |
||
1781 | { |
||
1782 | Boolean OK; |
||
1783 | |||
1784 | BAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt7, &OK) << 1; |
||
1785 | if (OK) |
||
1786 | { |
||
1787 | BAsmCode[0] = 0x9b; |
||
1788 | CodeLen = 2; |
||
1789 | } |
||
1790 | } |
||
1791 | } |
||
1792 | |||
1793 | static void DecodeATOMIC(Word Code) |
||
1794 | { |
||
1795 | Byte HReg; |
||
1796 | |||
1797 | UNUSED(Code); |
||
1798 | |||
1799 | if (ChkArgCnt(1, 1) |
||
1800 | && ChkMinCPU(CPU80C167) |
||
1801 | && DecodePref(&ArgStr[1], &HReg)) |
||
1802 | { |
||
1803 | CodeLen = 2; |
||
1804 | BAsmCode[0] = 0xd1; |
||
1805 | BAsmCode[1] = HReg << 4; |
||
1806 | } |
||
1807 | } |
||
1808 | |||
1809 | static void DecodeEXTR(Word Code) |
||
1810 | { |
||
1811 | Byte HReg; |
||
1812 | |||
1813 | UNUSED(Code); |
||
1814 | |||
1815 | if (ChkArgCnt(1, 1) |
||
1816 | && ChkMinCPU(CPU80C167) |
||
1817 | && DecodePref(&ArgStr[1], &HReg)) |
||
1818 | { |
||
1819 | CodeLen = 2; |
||
1820 | BAsmCode[0] = 0xd1; |
||
1821 | BAsmCode[1] = 0x80 + (HReg << 4); |
||
1822 | ExtCounter = HReg + 1; |
||
1823 | ExtSFRs = True; |
||
1824 | } |
||
1825 | } |
||
1826 | |||
1827 | static void DecodeEXTP_EXTPR(Word Code) |
||
1828 | { |
||
1829 | Byte HReg; |
||
1830 | |||
1831 | if (ChkArgCnt(2, 2) |
||
1832 | && ChkMinCPU(CPU80C167) |
||
1833 | && DecodePref(&ArgStr[2], &HReg)) |
||
1834 | { |
||
1835 | tAdrResult Result; |
||
1836 | |||
1837 | switch (DecodeAdr(&ArgStr[1], MModReg | MModImm, &Result)) |
||
1838 | { |
||
1839 | case ModReg: |
||
1840 | CodeLen = 2; |
||
1841 | BAsmCode[0] = 0xdc; |
||
1842 | BAsmCode[1] = Code + 0x40 + (HReg << 4) + Result.Mode; |
||
1843 | ExtCounter = HReg + 1; |
||
1844 | MemMode = MemModeZeroPage; |
||
1845 | break; |
||
1846 | case ModImm: |
||
1847 | CodeLen = 4; |
||
1848 | BAsmCode[0] = 0xd7; |
||
1849 | BAsmCode[1] = Code + 0x40 + (HReg << 4); |
||
1850 | BAsmCode[2] = WordVal(&Result) & 0xff; |
||
1851 | BAsmCode[3] = (WordVal(&Result) >> 8) & 3; |
||
1852 | ExtCounter = HReg + 1; |
||
1853 | MemMode = MemModeFixedPage; |
||
1854 | MemPage = WordVal(&Result) & 0x3ff; |
||
1855 | break; |
||
1856 | } |
||
1857 | } |
||
1858 | } |
||
1859 | |||
1860 | static void DecodeEXTS_EXTSR(Word Code) |
||
1861 | { |
||
1862 | Byte HReg; |
||
1863 | |||
1864 | OpSize = eSymbolSize8Bit; |
||
1865 | if (ChkArgCnt(2, 2) |
||
1866 | && ChkMinCPU(CPU80C167) |
||
1867 | && DecodePref(&ArgStr[2], &HReg)) |
||
1868 | { |
||
1869 | tAdrResult Result; |
||
1870 | |||
1871 | switch (DecodeAdr(&ArgStr[1], MModReg | MModImm, &Result)) |
||
1872 | { |
||
1873 | case ModReg: |
||
1874 | CodeLen = 2; |
||
1875 | BAsmCode[0] = 0xdc; |
||
1876 | BAsmCode[1] = Code + 0x00 + (HReg << 4) + Result.Mode; |
||
1877 | ExtCounter = HReg + 1; |
||
1878 | MemMode = MemModeNoCheck; |
||
1879 | break; |
||
1880 | case ModImm: |
||
1881 | CodeLen = 4; |
||
1882 | BAsmCode[0] = 0xd7; |
||
1883 | BAsmCode[1] = Code + 0x00 + (HReg << 4); |
||
1884 | BAsmCode[2] = Result.Vals[0]; |
||
1885 | BAsmCode[3] = 0; |
||
1886 | ExtCounter = HReg + 1; |
||
1887 | MemMode = MemModeFixedBank; |
||
1888 | MemPage = Result.Vals[0]; |
||
1889 | break; |
||
1890 | } |
||
1891 | } |
||
1892 | } |
||
1893 | |||
1894 | static void DecodeBIT(Word Code) |
||
1895 | { |
||
1896 | Word Adr; |
||
1897 | Byte Bit; |
||
1898 | |||
1899 | UNUSED(Code); |
||
1900 | |||
1901 | if (ChkArgCnt(1, 1) |
||
1902 | && DecodeBitAddr(&ArgStr[1], &Adr, &Bit, True)) |
||
1903 | { |
||
1904 | PushLocHandle(-1); |
||
1905 | EnterIntSymbol(&LabPart, (Adr << 4) + Bit, SegNone, False); |
||
1906 | PopLocHandle(); |
||
1907 | as_snprintf(ListLine, STRINGSIZE, "=%02xH.%1x", (unsigned)Adr, (unsigned)Bit); |
||
1908 | } |
||
1909 | } |
||
1910 | |||
1911 | /*!------------------------------------------------------------------------ |
||
1912 | * \fn update_prefixes(Word index) |
||
1913 | * \brief necessary operations prior to assembling machine instructions |
||
1914 | * ------------------------------------------------------------------------ */ |
||
1915 | |||
1916 | static void update_prefixes(Word index) |
||
1917 | { |
||
1918 | int z; |
||
1919 | |||
1920 | UNUSED(index); |
||
1921 | |||
1922 | /* Pipeline-Flags weiterschalten */ |
||
1923 | |||
1924 | SPChanged = N_SPChanged; N_SPChanged = False; |
||
1925 | CPChanged = N_CPChanged; N_CPChanged = False; |
||
1926 | for (z = 0; z < DPPCount; z++) |
||
1927 | { |
||
1928 | DPPChanged[z] = N_DPPChanged[z]; |
||
1929 | N_DPPChanged[z] = False; |
||
1930 | } |
||
1931 | |||
1932 | /* Praefixe herunterzaehlen */ |
||
1933 | |||
1934 | if (ExtCounter >= 0) |
||
1935 | if (--ExtCounter < 0) |
||
1936 | { |
||
1937 | MemMode = MemModeStd; |
||
1938 | ExtSFRs = False; |
||
1939 | } |
||
1940 | } |
||
1941 | |||
1942 | /*-------------------------------------------------------------------------*/ |
||
1943 | |||
1944 | static void AddBInstTable(const char *NName, Word NCode, InstProc Proc) |
||
1945 | { |
||
1946 | char BName[30]; |
||
1947 | |||
1948 | AddInstTable(InstTable, NName, NCode | (eSymbolSize16Bit << 8), Proc); |
||
1949 | as_snprintf(BName, sizeof(BName), "%sB", NName); |
||
1950 | AddInstTable(InstTable, BName, NCode | (eSymbolSize8Bit << 8), Proc); |
||
1951 | } |
||
1952 | |||
1953 | static void AddFixed(const char *NName, CPUVar NMin, Word NCode1, Word NCode2) |
||
1954 | { |
||
1955 | order_array_rsv_end(FixedOrders, BaseOrder); |
||
1956 | FixedOrders[InstrZ].MinCPU = NMin; |
||
1957 | FixedOrders[InstrZ].Code1 = NCode1; |
||
1958 | FixedOrders[InstrZ].Code2 = NCode2; |
||
1959 | AddInstTable(InstTable, NName, InstrZ++, DecodeFixed); |
||
1960 | } |
||
1961 | |||
1962 | static void AddShift(const char *NName, Byte NCode) |
||
1963 | { |
||
1964 | AddInstTable(InstTable, NName, NCode, DecodeShift); |
||
1965 | } |
||
1966 | |||
1967 | static void AddBit2(const char *NName, Byte NCode) |
||
1968 | { |
||
1969 | AddInstTable(InstTable, NName, NCode, DecodeBit2); |
||
1970 | } |
||
1971 | |||
1972 | static void AddLoop(const char *NName, Byte NCode) |
||
1973 | { |
||
1974 | AddInstTable(InstTable, NName, NCode, DecodeLoop); |
||
1975 | } |
||
1976 | |||
1977 | static void AddCondition(const char *NName, Byte NCode) |
||
1978 | { |
||
1979 | order_array_rsv_end(Conditions, Condition); |
||
1980 | Conditions[InstrZ].Name = NName; |
||
1981 | Conditions[InstrZ++].Code = NCode; |
||
1982 | } |
||
1983 | |||
1984 | static void InitFields(void) |
||
1985 | { |
||
1986 | InstTable = CreateInstTable(201); |
||
1987 | SetDynamicInstTable(InstTable); |
||
1988 | |||
1989 | add_null_pseudo(InstTable); |
||
1990 | |||
1991 | inst_table_set_prefix_proc(InstTable, update_prefixes, 0); |
||
1992 | |||
1993 | AddBInstTable("MOV", 0, DecodeMOV); |
||
1994 | AddInstTable(InstTable, "MOVBS", 0x10, DecodeMOVBS_MOVBZ); |
||
1995 | AddInstTable(InstTable, "MOVBZ", 0x00, DecodeMOVBS_MOVBZ); |
||
1996 | AddInstTable(InstTable, "PUSH", 0xec, DecodePUSH_POP); |
||
1997 | AddInstTable(InstTable, "POP", 0xfc, DecodePUSH_POP); |
||
1998 | AddInstTable(InstTable, "SCXT", 0, DecodeSCXT); |
||
1999 | AddBInstTable("CPL", 0x91, DecodeCPL_NEG); |
||
2000 | AddBInstTable("NEG", 0x81, DecodeCPL_NEG); |
||
2001 | AddInstTable(InstTable, "BCLR", 0x0e, DecodeBCLR_BSET); |
||
2002 | AddInstTable(InstTable, "BSET", 0x0f, DecodeBCLR_BSET); |
||
2003 | AddInstTable(InstTable, "BFLDL", 0x0a, DecodeBFLDH_BFLDL); |
||
2004 | AddInstTable(InstTable, "BFLDH", 0x1a, DecodeBFLDH_BFLDL); |
||
2005 | AddInstTable(InstTable, "JMP", 0, DecodeJMP); |
||
2006 | AddInstTable(InstTable, "CALL", 0, DecodeCALL); |
||
2007 | AddInstTable(InstTable, "JMPR", 0, DecodeJMPR); |
||
2008 | AddInstTable(InstTable, "CALLR", 0, DecodeCALLR); |
||
2009 | AddInstTable(InstTable, "JMPA", 0xea, DecodeJMPA_CALLA); |
||
2010 | AddInstTable(InstTable, "CALLA", 0xca, DecodeJMPA_CALLA); |
||
2011 | AddInstTable(InstTable, "JMPS", 0xfa, DecodeJMPS_CALLS); |
||
2012 | AddInstTable(InstTable, "CALLS", 0xda, DecodeJMPS_CALLS); |
||
2013 | AddInstTable(InstTable, "JMPI", 0x9c, DecodeJMPI_CALLI); |
||
2014 | AddInstTable(InstTable, "CALLI", 0xab, DecodeJMPI_CALLI); |
||
2015 | AddInstTable(InstTable, "PCALL", 0, DecodePCALL); |
||
2016 | AddInstTable(InstTable, "RETP", 0, DecodeRETP); |
||
2017 | AddInstTable(InstTable, "TRAP", 0, DecodeTRAP); |
||
2018 | AddInstTable(InstTable, "ATOMIC", 0, DecodeATOMIC); |
||
2019 | AddInstTable(InstTable, "EXTR", 0, DecodeEXTR); |
||
2020 | AddInstTable(InstTable, "EXTP", 0x00, DecodeEXTP_EXTPR); |
||
2021 | AddInstTable(InstTable, "EXTPR", 0x80, DecodeEXTP_EXTPR); |
||
2022 | AddInstTable(InstTable, "EXTS", 0x00, DecodeEXTS_EXTSR); |
||
2023 | AddInstTable(InstTable, "EXTSR", 0x80, DecodeEXTS_EXTSR); |
||
2024 | |||
2025 | InstrZ = 0; |
||
2026 | AddFixed("DISWDT", CPU80C166, 0x5aa5, 0xa5a5); |
||
2027 | AddFixed("EINIT" , CPU80C166, 0x4ab5, 0xb5b5); |
||
2028 | AddFixed("IDLE" , CPU80C166, 0x7887, 0x8787); |
||
2029 | AddFixed("NOP" , CPU80C166, 0x00cc, 0x0000); |
||
2030 | AddFixed("PWRDN" , CPU80C166, 0x6897, 0x9797); |
||
2031 | AddFixed("RET" , CPU80C166, 0x00cb, 0x0000); |
||
2032 | AddFixed("RETI" , CPU80C166, 0x88fb, 0x0000); |
||
2033 | AddFixed("RETS" , CPU80C166, 0x00db, 0x0000); |
||
2034 | AddFixed("SRST" , CPU80C166, 0x48b7, 0xb7b7); |
||
2035 | AddFixed("SRVWDT", CPU80C166, 0x58a7, 0xa7a7); |
||
2036 | |||
2037 | InstrZ = 0; |
||
2038 | AddCondition("UC" , COND_CODE_TRUE); AddCondition("Z" , 0x2); |
||
2039 | AddCondition("NZ" , 0x3); AddCondition("V" , 0x4); |
||
2040 | AddCondition("NV" , 0x5); AddCondition("N" , 0x6); |
||
2041 | AddCondition("NN" , 0x7); AddCondition("C" , 0x8); |
||
2042 | AddCondition("NC" , 0x9); AddCondition("EQ" , 0x2); |
||
2043 | AddCondition("NE" , 0x3); AddCondition("ULT", 0x8); |
||
2044 | AddCondition("ULE", 0xf); AddCondition("UGE", 0x9); |
||
2045 | AddCondition("UGT", 0xe); AddCondition("SLT", 0xc); |
||
2046 | AddCondition("SLE", 0xb); AddCondition("SGE", 0xd); |
||
2047 | AddCondition("SGT", 0xa); AddCondition("NET", 0x1); |
||
2048 | AddCondition(NULL, 0); |
||
2049 | |||
2050 | InstrZ = 0; |
||
2051 | AddBInstTable("ADD" , InstrZ++, DecodeALU2); |
||
2052 | AddBInstTable("ADDC", InstrZ++, DecodeALU2); |
||
2053 | AddBInstTable("SUB" , InstrZ++, DecodeALU2); |
||
2054 | AddBInstTable("SUBC", InstrZ++, DecodeALU2); |
||
2055 | AddBInstTable("CMP" , InstrZ++, DecodeALU2); |
||
2056 | AddBInstTable("XOR" , InstrZ++, DecodeALU2); |
||
2057 | AddBInstTable("AND" , InstrZ++, DecodeALU2); |
||
2058 | AddBInstTable("OR" , InstrZ++, DecodeALU2); |
||
2059 | |||
2060 | AddShift("ASHR", 0xac); AddShift("ROL" , 0x0c); |
||
2061 | AddShift("ROR" , 0x2c); AddShift("SHL" , 0x4c); |
||
2062 | AddShift("SHR" , 0x6c); |
||
2063 | |||
2064 | AddBit2("BAND", 0x6a); AddBit2("BCMP" , 0x2a); |
||
2065 | AddBit2("BMOV", 0x4a); AddBit2("BMOVN", 0x3a); |
||
2066 | AddBit2("BOR" , 0x5a); AddBit2("BXOR" , 0x7a); |
||
2067 | |||
2068 | AddLoop("CMPD1", 0xa0); AddLoop("CMPD2", 0xb0); |
||
2069 | AddLoop("CMPI1", 0x80); AddLoop("CMPI2", 0x90); |
||
2070 | |||
2071 | InstrZ = 0; |
||
2072 | AddInstTable(InstTable, "DIV" , InstrZ++, DecodeDiv); |
||
2073 | AddInstTable(InstTable, "DIVU" , InstrZ++, DecodeDiv); |
||
2074 | AddInstTable(InstTable, "DIVL" , InstrZ++, DecodeDiv); |
||
2075 | AddInstTable(InstTable, "DIVLU", InstrZ++, DecodeDiv); |
||
2076 | |||
2077 | InstrZ = 0; |
||
2078 | AddInstTable(InstTable, "JB" , InstrZ++, DecodeBJmp); |
||
2079 | AddInstTable(InstTable, "JNB" , InstrZ++, DecodeBJmp); |
||
2080 | AddInstTable(InstTable, "JBC" , InstrZ++, DecodeBJmp); |
||
2081 | AddInstTable(InstTable, "JNBS" , InstrZ++, DecodeBJmp); |
||
2082 | |||
2083 | InstrZ = 0; |
||
2084 | AddInstTable(InstTable, "MUL" , InstrZ++, DecodeMul); |
||
2085 | AddInstTable(InstTable, "MULU" , InstrZ++, DecodeMul); |
||
2086 | AddInstTable(InstTable, "PRIOR", InstrZ++, DecodeMul); |
||
2087 | |||
2088 | inst_table_set_prefix_proc(InstTable, NULL, 0); |
||
2089 | |||
2090 | AddInstTable(InstTable, "BIT" , 0, DecodeBIT); |
||
2091 | AddInstTable(InstTable, "REG" , 0, CodeREG); |
||
2092 | AddIntelPseudo(InstTable, eIntPseudoFlag_LittleEndian); |
||
2093 | } |
||
2094 | |||
2095 | static void DeinitFields(void) |
||
2096 | { |
||
2097 | DestroyInstTable(InstTable); |
||
2098 | order_array_free(FixedOrders); |
||
2099 | order_array_free(Conditions); |
||
2100 | } |
||
2101 | |||
2102 | static void MakeCode_166(void) |
||
2103 | { |
||
2104 | OpSize = eSymbolSize16Bit; |
||
2105 | |||
2106 | if (!LookupInstTable(InstTable, OpPart.str.p_str)) |
||
2107 | WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart); |
||
2108 | } |
||
2109 | |||
2110 | /*!------------------------------------------------------------------------ |
||
2111 | * \fn InternSymbol_166(char *pArg, TempResult *pResult) |
||
2112 | * \brief handle built-in symbols on C16x |
||
2113 | * \param pArg source argument |
||
2114 | * \param pResult result buffer |
||
2115 | * ------------------------------------------------------------------------ */ |
||
2116 | |||
2117 | static void InternSymbol_166(char *pArg, TempResult *pResult) |
||
2118 | { |
||
2119 | tRegInt Erg; |
||
2120 | tSymbolSize Size; |
||
2121 | |||
2122 | if (IsRegCore(pArg, &Erg, &Size)) |
||
2123 | { |
||
2124 | pResult->Typ = TempReg; |
||
2125 | pResult->DataSize = Size; |
||
2126 | pResult->Contents.RegDescr.Reg = Erg; |
||
2127 | pResult->Contents.RegDescr.Dissect = DissectReg_166; |
||
2128 | pResult->Contents.RegDescr.compare = NULL; |
||
2129 | } |
||
2130 | } |
||
2131 | |||
2132 | static void InitCode_166(void) |
||
2133 | { |
||
2134 | int z; |
||
2135 | |||
2136 | for (z = 0; z < DPPCount; z++) |
||
2137 | { |
||
2138 | DPPAssumes[z] = z; |
||
2139 | N_DPPChanged[z] = False; |
||
2140 | } |
||
2141 | N_CPChanged = False; |
||
2142 | N_SPChanged = False; |
||
2143 | |||
2144 | MemMode = MemModeStd; |
||
2145 | ExtSFRs = False; |
||
2146 | ExtCounter = (-1); |
||
2147 | } |
||
2148 | |||
2149 | static Boolean IsDef_166(void) |
||
2150 | { |
||
2151 | return (Memo("BIT")) || (Memo("REG")); |
||
2152 | } |
||
2153 | |||
2154 | static void SwitchFrom_166(void) |
||
2155 | { |
||
2156 | DeinitFields(); |
||
2157 | } |
||
2158 | |||
2159 | static void SwitchTo_166(void) |
||
2160 | { |
||
2161 | Byte z; |
||
2162 | |||
2163 | TurnWords = False; |
||
2164 | SetIntConstMode(eIntConstModeIntel); |
||
2165 | OpSize = eSymbolSize16Bit; |
||
2166 | |||
2167 | PCSymbol = "$"; |
||
2168 | HeaderID = 0x4c; |
||
2169 | NOPCode = 0xcc00; |
||
2170 | DivideChars = ","; |
||
2171 | HasAttrs = False; |
||
2172 | |||
2173 | ValidSegs = (1 << SegCode); |
||
2174 | Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0; |
||
2175 | |||
2176 | MakeCode = MakeCode_166; |
||
2177 | IsDef = IsDef_166; |
||
2178 | InternSymbol = InternSymbol_166; |
||
2179 | DissectReg = DissectReg_166; |
||
2180 | SwitchFrom = SwitchFrom_166; |
||
2181 | |||
2182 | if (MomCPU == CPU80C166) |
||
2183 | { |
||
2184 | MemInt = UInt18; |
||
2185 | MemInt2 = UInt2; |
||
2186 | ASSUME166s[0].Max = 15; |
||
2187 | SegLimits[SegCode] = 0x3ffffl; |
||
2188 | } |
||
2189 | else |
||
2190 | { |
||
2191 | MemInt = UInt24; |
||
2192 | MemInt2 = UInt8; |
||
2193 | ASSUME166s[0].Max = 1023; |
||
2194 | SegLimits[SegCode] = 0xffffffl; |
||
2195 | } |
||
2196 | for (z = 1; z < 4; z++) |
||
2197 | ASSUME166s[z].Max = ASSUME166s[0].Max; |
||
2198 | |||
2199 | pASSUMERecs = ASSUME166s; |
||
2200 | ASSUMERecCnt = ASSUME166Count; |
||
2201 | |||
2202 | InitFields(); |
||
2203 | } |
||
2204 | |||
2205 | void code166_init(void) |
||
2206 | { |
||
2207 | CPU80C166 = AddCPU("80C166", SwitchTo_166); |
||
2208 | CPU80C167 = AddCPU("80C167", SwitchTo_166); |
||
2209 | CPU80C167CS = AddCPU("80C167CS", SwitchTo_166); |
||
2210 | |||
2211 | AddInitPassProc(InitCode_166); |
||
2212 | } |