Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1186 | savelij | 1 | /* codexgate.c */ |
2 | /*****************************************************************************/ |
||
3 | /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */ |
||
4 | /* */ |
||
5 | /* AS-Portierung */ |
||
6 | /* */ |
||
7 | /* Codegenerator XGATE-Kern */ |
||
8 | /* */ |
||
9 | /*****************************************************************************/ |
||
10 | |||
11 | #include "stdinc.h" |
||
12 | #include <ctype.h> |
||
13 | #include <string.h> |
||
14 | |||
15 | #include "nls.h" |
||
16 | #include "be_le.h" |
||
17 | #include "strutil.h" |
||
18 | #include "bpemu.h" |
||
19 | #include "asmdef.h" |
||
20 | #include "asmsub.h" |
||
21 | #include "asmpars.h" |
||
22 | #include "asmallg.h" |
||
23 | #include "headids.h" |
||
24 | #include "codepseudo.h" |
||
25 | #include "motpseudo.h" |
||
26 | #include "asmitree.h" |
||
27 | #include "codevars.h" |
||
28 | #include "errmsg.h" |
||
29 | |||
30 | #include "codexgate.h" |
||
31 | |||
32 | /*--------------------------------------------------------------------------*/ |
||
33 | /* Variables */ |
||
34 | |||
35 | #define FixedOrderCnt 2 |
||
36 | |||
37 | static CPUVar CPUXGate; |
||
38 | |||
39 | /*--------------------------------------------------------------------------*/ |
||
40 | /* Address Decoders */ |
||
41 | |||
42 | /*!------------------------------------------------------------------------ |
||
43 | * \fn DecodeRegCore(const char *pArg, Word *pResult) |
||
44 | * \brief check whether argument is a CPU register |
||
45 | * \param pArg argument |
||
46 | * \param pResult register # if yes |
||
47 | * \return True if yes |
||
48 | * ------------------------------------------------------------------------ */ |
||
49 | |||
50 | static Boolean DecodeRegCore(const char *pArg, Word *pResult) |
||
51 | { |
||
52 | if ((strlen(pArg) != 2) || (as_toupper(*pArg) != 'R') || (!as_isdigit(pArg[1]))) |
||
53 | { |
||
54 | *pResult = 0; |
||
55 | return False; |
||
56 | } |
||
57 | else |
||
58 | { |
||
59 | *pResult = pArg[1] - '0'; |
||
60 | return *pResult <= 7; |
||
61 | } |
||
62 | } |
||
63 | |||
64 | /*!------------------------------------------------------------------------ |
||
65 | * \fn DissectReg_XGATE(char *pDest, size_t DestSize, tRegInt Reg, tSymbolSize Size) |
||
66 | * \brief dissect register symbol - XGATE version |
||
67 | * \param pDest destination buffer |
||
68 | * \param DestSize size of destination buffer |
||
69 | * \param Reg register number |
||
70 | * \param Size register size |
||
71 | * ------------------------------------------------------------------------ */ |
||
72 | |||
73 | static void DissectReg_XGATE(char *pDest, size_t DestSize, tRegInt Reg, tSymbolSize Size) |
||
74 | { |
||
75 | switch (Size) |
||
76 | { |
||
77 | case eSymbolSize16Bit: |
||
78 | as_snprintf(pDest, DestSize, "R%u", (unsigned)Reg); |
||
79 | break; |
||
80 | default: |
||
81 | as_snprintf(pDest, DestSize, "%d-%u", Size, (unsigned)Reg); |
||
82 | } |
||
83 | } |
||
84 | |||
85 | /*!------------------------------------------------------------------------ |
||
86 | * \fn DecodeReg(const tStrComp *pArg, Word *pReg, Boolean MustBeReg) |
||
87 | * \brief check whether argument is CPU register or register alias |
||
88 | * \param pArg argument |
||
89 | * \param pReg register number if yes |
||
90 | * \param MustBeReg True if register is expected |
||
91 | * \return Reg eval result |
||
92 | * ------------------------------------------------------------------------ */ |
||
93 | |||
94 | static tRegEvalResult DecodeReg(const tStrComp *pArg, Word *pReg, Boolean MustBeReg) |
||
95 | { |
||
96 | tRegDescr RegDescr; |
||
97 | tEvalResult EvalResult; |
||
98 | tRegEvalResult RegEvalResult; |
||
99 | |||
100 | if (DecodeRegCore(pArg->str.p_str, pReg)) |
||
101 | return eIsReg; |
||
102 | |||
103 | RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize16Bit, MustBeReg); |
||
104 | *pReg = RegDescr.Reg; |
||
105 | return RegEvalResult; |
||
106 | } |
||
107 | |||
108 | /*!------------------------------------------------------------------------ |
||
109 | * \fn DecodeArgReg(int Index, Word *pReg) |
||
110 | * \brief check whether argument #n is CPU register or register alias |
||
111 | * \param Index argument index |
||
112 | * \param pReg register number if yes |
||
113 | * \return True if yes |
||
114 | * ------------------------------------------------------------------------ */ |
||
115 | |||
116 | static Boolean DecodeArgReg(int Index, Word *pReg) |
||
117 | { |
||
118 | return DecodeReg(&ArgStr[Index], pReg, True); |
||
119 | } |
||
120 | |||
121 | /*--------------------------------------------------------------------------*/ |
||
122 | /* Instruction Decoders */ |
||
123 | |||
124 | static void DecodeFixed(Word Index) |
||
125 | { |
||
126 | if (ChkArgCnt(0, 0)) |
||
127 | { |
||
128 | WAsmCode[0] = Index; |
||
129 | CodeLen = 2; |
||
130 | } |
||
131 | } |
||
132 | |||
133 | static void DecodeBranch(Word Index) |
||
134 | { |
||
135 | LongInt Dist; |
||
136 | Boolean OK; |
||
137 | tSymbolFlags Flags; |
||
138 | |||
139 | if (ChkArgCnt(1, 1)) |
||
140 | { |
||
141 | Dist = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &OK, &Flags) - (EProgCounter() + 2); |
||
142 | if (OK) |
||
143 | { |
||
144 | if (!mSymbolQuestionable(Flags) && (Dist & 1)) WrError(ErrNum_NotAligned); |
||
145 | else if (!mSymbolQuestionable(Flags) && ((Dist < -512) || (Dist > 510))) WrError(ErrNum_NotAligned); |
||
146 | else |
||
147 | { |
||
148 | WAsmCode[0] = Index | ((Dist >> 1) & 0x01ff); |
||
149 | CodeLen = 2; |
||
150 | } |
||
151 | } |
||
152 | } |
||
153 | } |
||
154 | |||
155 | static void DecodeBRA(Word Index) |
||
156 | { |
||
157 | LongInt Dist; |
||
158 | Boolean OK; |
||
159 | tSymbolFlags Flags; |
||
160 | |||
161 | UNUSED(Index); |
||
162 | |||
163 | if (ChkArgCnt(1, 1)) |
||
164 | { |
||
165 | Dist = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &OK, &Flags) - (EProgCounter() + 2); |
||
166 | if (OK) |
||
167 | { |
||
168 | if (!mSymbolQuestionable(Flags) && (Dist & 1)) WrError(ErrNum_NotAligned); |
||
169 | else if (!mSymbolQuestionable(Flags) && ((Dist < -1024) || (Dist > 1022))) WrError(ErrNum_NotAligned); |
||
170 | else |
||
171 | { |
||
172 | WAsmCode[0] = 0x3c00 | ((Dist >> 1) & 0x03ff); |
||
173 | CodeLen = 2; |
||
174 | } |
||
175 | } |
||
176 | } |
||
177 | } |
||
178 | |||
179 | static void DecodeShift(Word Index) |
||
180 | { |
||
181 | Word DReg, SReg; |
||
182 | Boolean OK; |
||
183 | |||
184 | if (!ChkArgCnt(2, 2)); |
||
185 | else if (!DecodeArgReg(1, &DReg)); |
||
186 | else if (*ArgStr[2].str.p_str == '#') |
||
187 | { |
||
188 | SReg = EvalStrIntExpressionOffs(&ArgStr[2], 1, UInt4, &OK); |
||
189 | if (OK) |
||
190 | { |
||
191 | WAsmCode[0] = 0x0808 | Index | (DReg << 8) | (SReg << 4); |
||
192 | CodeLen = 2; |
||
193 | } |
||
194 | } |
||
195 | else if (DecodeArgReg(2, &SReg)) |
||
196 | { |
||
197 | WAsmCode[0] = 0x0810 | Index | (DReg << 8) | (SReg << 5); |
||
198 | CodeLen = 2; |
||
199 | } |
||
200 | } |
||
201 | |||
202 | static void DecodeAriImm(Word Index) |
||
203 | { |
||
204 | Word DReg, SReg1, SReg2; |
||
205 | Boolean OK; |
||
206 | |||
207 | if (!ChkArgCnt(2, 3)); |
||
208 | else if (!DecodeArgReg(1, &DReg)); |
||
209 | else if (ArgCnt == 2) |
||
210 | { |
||
211 | if (*ArgStr[2].str.p_str == '#') |
||
212 | { |
||
213 | SReg1 = EvalStrIntExpressionOffs(&ArgStr[2], 1, Int16, &OK); |
||
214 | if (OK) |
||
215 | { |
||
216 | WAsmCode[0] = 0x8000 | (Index << 12) | (DReg << 8) | Lo(SReg1); |
||
217 | WAsmCode[1] = 0x8800 | (Index << 12) | (DReg << 8) | Hi(SReg1); |
||
218 | CodeLen = 4; |
||
219 | } |
||
220 | } |
||
221 | else if (DecodeArgReg(2, &SReg1)) |
||
222 | { |
||
223 | WAsmCode[0] = 0x1000 | ((Index & 4) << 9) | (Index & 3) | (DReg << 8) | (DReg << 5) | (SReg1 << 2); |
||
224 | CodeLen = 2; |
||
225 | } |
||
226 | } |
||
227 | else if (DecodeArgReg(2, &SReg1) && DecodeArgReg(3, &SReg2)) |
||
228 | { |
||
229 | WAsmCode[0] = 0x1000 | ((Index & 4) << 9) | (Index & 3) | (DReg << 8) | (SReg1 << 5) | (SReg2 << 2); |
||
230 | CodeLen = 2; |
||
231 | } |
||
232 | } |
||
233 | |||
234 | static void DecodeImm8(Word Index) |
||
235 | { |
||
236 | Word DReg, Src; |
||
237 | Boolean OK; |
||
238 | |||
239 | if (!ChkArgCnt(2, 2)); |
||
240 | else if (!DecodeArgReg(1, &DReg)); |
||
241 | else if (*ArgStr[2].str.p_str != '#') WrError(ErrNum_OnlyImmAddr); |
||
242 | else |
||
243 | { |
||
244 | Src = EvalStrIntExpressionOffs(&ArgStr[2], 1, Int8, &OK); |
||
245 | if (OK) |
||
246 | { |
||
247 | WAsmCode[0] = Index | (DReg << 8) | (Src & 0xff); |
||
248 | CodeLen = 2; |
||
249 | } |
||
250 | } |
||
251 | } |
||
252 | |||
253 | static void DecodeReg3(Word Index) |
||
254 | { |
||
255 | Word DReg, SReg1, SReg2; |
||
256 | |||
257 | if (ChkArgCnt(3, 3) |
||
258 | && DecodeArgReg(1, &DReg) |
||
259 | && DecodeArgReg(2, &SReg1) |
||
260 | && DecodeArgReg(3, &SReg2)) |
||
261 | { |
||
262 | WAsmCode[0] = Index | (DReg << 8) | (SReg1 << 5) | (SReg2 << 2); |
||
263 | CodeLen = 2; |
||
264 | } |
||
265 | } |
||
266 | |||
267 | static void DecodeReg23(Word Index) |
||
268 | { |
||
269 | Word DReg, SReg1, SReg2; |
||
270 | |||
271 | if (!ChkArgCnt(2, 3)); |
||
272 | else if (!DecodeArgReg(1, &DReg)); |
||
273 | else if (!DecodeArgReg(2, &SReg1)); |
||
274 | else if (ArgCnt == 2) |
||
275 | { |
||
276 | WAsmCode[0] = Index | (DReg << 8) | (DReg << 5) | (SReg1 << 2); |
||
277 | CodeLen = 2; |
||
278 | } |
||
279 | else if (DecodeArgReg(3, &SReg2)) |
||
280 | { |
||
281 | WAsmCode[0] = Index | (DReg << 8) | (SReg1 << 5) | (SReg2 << 2); |
||
282 | CodeLen = 2; |
||
283 | } |
||
284 | } |
||
285 | |||
286 | static void DecodeCPC(Word Index) |
||
287 | { |
||
288 | Word DReg, SReg; |
||
289 | |||
290 | if (ChkArgCnt(2, 3) |
||
291 | && DecodeArgReg(1, &DReg) |
||
292 | && DecodeArgReg(2, &SReg)) |
||
293 | { |
||
294 | WAsmCode[0] = Index | (DReg << 5) | (SReg << 2); |
||
295 | CodeLen = 2; |
||
296 | } |
||
297 | } |
||
298 | |||
299 | static void DecodeMOV(Word Index) |
||
300 | { |
||
301 | Word DReg, SReg; |
||
302 | |||
303 | if (ChkArgCnt(2, 3) |
||
304 | && DecodeArgReg(1, &DReg) |
||
305 | && DecodeArgReg(2, &SReg)) |
||
306 | { |
||
307 | WAsmCode[0] = Index | (DReg << 8) | (SReg << 2); |
||
308 | CodeLen = 2; |
||
309 | } |
||
310 | } |
||
311 | |||
312 | static void DecodeBFFFO(Word Index) |
||
313 | { |
||
314 | Word DReg, SReg; |
||
315 | |||
316 | if (ChkArgCnt(2, 3) |
||
317 | && DecodeArgReg(1, &DReg) |
||
318 | && DecodeArgReg(2, &SReg)) |
||
319 | { |
||
320 | WAsmCode[0] = Index | (DReg << 8) | (SReg << 5); |
||
321 | CodeLen = 2; |
||
322 | } |
||
323 | } |
||
324 | |||
325 | static void DecodeReg12(Word Index) |
||
326 | { |
||
327 | Word DReg, SReg; |
||
328 | |||
329 | if (!ChkArgCnt(1, 2)); |
||
330 | else if (!DecodeArgReg(1, &DReg)); |
||
331 | else if (ArgCnt == 1) |
||
332 | { |
||
333 | WAsmCode[0] = Index | (DReg << 8) | (DReg << 2); |
||
334 | CodeLen = 2; |
||
335 | } |
||
336 | else if (DecodeArgReg(2, &SReg)) |
||
337 | { |
||
338 | WAsmCode[0] = Index | (DReg << 8) | (SReg << 2); |
||
339 | CodeLen = 2; |
||
340 | } |
||
341 | } |
||
342 | |||
343 | static void DecodeReg1(Word Index) |
||
344 | { |
||
345 | Word Reg; |
||
346 | |||
347 | if (ChkArgCnt(1, 1) && DecodeArgReg(1, &Reg)) |
||
348 | { |
||
349 | WAsmCode[0] = Index | (Reg << 8); |
||
350 | CodeLen = 2; |
||
351 | } |
||
352 | } |
||
353 | |||
354 | static void DecodeTST(Word Index) |
||
355 | { |
||
356 | Word Reg; |
||
357 | |||
358 | if (ChkArgCnt(1, 1) && DecodeArgReg(1, &Reg)) |
||
359 | { |
||
360 | WAsmCode[0] = Index | (Reg << 5); |
||
361 | CodeLen = 2; |
||
362 | } |
||
363 | } |
||
364 | |||
365 | static void DecodeSem(Word Index) |
||
366 | { |
||
367 | Word Reg; |
||
368 | Boolean OK; |
||
369 | |||
370 | if (!ChkArgCnt(1, 1)); |
||
371 | else if (*ArgStr[1].str.p_str == '#') |
||
372 | { |
||
373 | Reg = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt3, &OK); |
||
374 | if (OK) |
||
375 | { |
||
376 | WAsmCode[0] = Index | (Reg << 8); |
||
377 | CodeLen = 2; |
||
378 | } |
||
379 | } |
||
380 | else if (DecodeArgReg(1, &Reg)) |
||
381 | { |
||
382 | WAsmCode[0] = Index | (Reg << 8) | 1; |
||
383 | CodeLen = 2; |
||
384 | } |
||
385 | } |
||
386 | |||
387 | static void DecodeSIF(Word Index) |
||
388 | { |
||
389 | Word Reg; |
||
390 | |||
391 | UNUSED(Index); |
||
392 | |||
393 | if (ArgCnt == 0) |
||
394 | { |
||
395 | WAsmCode[0] = 0x0300; |
||
396 | CodeLen = 2; |
||
397 | } |
||
398 | else if (ChkArgCnt(0, 1) && DecodeArgReg(1, &Reg)) |
||
399 | { |
||
400 | WAsmCode[0] = 0x00f7 | (Reg << 8); |
||
401 | CodeLen = 2; |
||
402 | } |
||
403 | } |
||
404 | |||
405 | static void DecodeTFR(Word Index) |
||
406 | { |
||
407 | Word Reg; |
||
408 | int RegIdx = 0; |
||
409 | |||
410 | UNUSED(Index); |
||
411 | |||
412 | if (ChkArgCnt(2, 2)) |
||
413 | { |
||
414 | Boolean OK = True; |
||
415 | |||
416 | if (!as_strcasecmp(ArgStr[2].str.p_str, "CCR")) |
||
417 | { |
||
418 | WAsmCode[0] = 0x00f8; |
||
419 | RegIdx = 1; |
||
420 | } |
||
421 | else if (!as_strcasecmp(ArgStr[1].str.p_str, "CCR")) |
||
422 | { |
||
423 | WAsmCode[0] = 0x00f9; |
||
424 | RegIdx = 2; |
||
425 | } |
||
426 | else if (!as_strcasecmp(ArgStr[2].str.p_str, "PC")) |
||
427 | { |
||
428 | WAsmCode[0] = 0x00fa; |
||
429 | RegIdx = 1; |
||
430 | } |
||
431 | else |
||
432 | OK = False; |
||
433 | |||
434 | if (!OK) WrError(ErrNum_OverRange); |
||
435 | else if (DecodeArgReg(RegIdx, &Reg)) |
||
436 | { |
||
437 | WAsmCode[0] |= (Reg << 8); |
||
438 | CodeLen = 2; |
||
439 | } |
||
440 | } |
||
441 | } |
||
442 | |||
443 | static void DecodeCmp(Word Index) |
||
444 | { |
||
445 | Word DReg, Src; |
||
446 | Boolean OK; |
||
447 | |||
448 | UNUSED(Index); |
||
449 | |||
450 | if (ChkArgCnt(2, 2) && DecodeArgReg(1, &DReg)) |
||
451 | { |
||
452 | if (*ArgStr[2].str.p_str == '#') |
||
453 | { |
||
454 | Src = EvalStrIntExpressionOffs(&ArgStr[2], 1, Int16, &OK); |
||
455 | if (OK) |
||
456 | { |
||
457 | WAsmCode[0] = 0xd000 | (DReg << 8) | Lo(Src); |
||
458 | WAsmCode[1] = 0xd800 | (DReg << 8) | Hi(Src); |
||
459 | CodeLen = 4; |
||
460 | } |
||
461 | } |
||
462 | else if (DecodeArgReg(2, &Src)) |
||
463 | { |
||
464 | WAsmCode[0] = 0x1800 | (DReg << 5) | (Src << 2); |
||
465 | CodeLen = 2; |
||
466 | } |
||
467 | } |
||
468 | } |
||
469 | |||
470 | static void DecodeMem(Word Code) |
||
471 | { |
||
472 | Word DReg; |
||
473 | |||
474 | if (!ChkArgCnt(2, 2)); |
||
475 | else if (!DecodeArgReg(1, &DReg)); |
||
476 | else if (*ArgStr[2].str.p_str == '#') |
||
477 | { |
||
478 | /* Only allowed for LDW */ |
||
479 | if (Code != 0x4800) WrError(ErrNum_InvAddrMode); |
||
480 | else |
||
481 | { |
||
482 | Word Val; |
||
483 | Boolean OK; |
||
484 | |||
485 | Val = EvalStrIntExpressionOffs(&ArgStr[2], 1, Int16, &OK); |
||
486 | if (OK) |
||
487 | { |
||
488 | WAsmCode[0] = 0xf000 | (DReg << 8) | Lo(Val); |
||
489 | WAsmCode[1] = 0xf800 | (DReg << 8) | Hi(Val); |
||
490 | CodeLen = 4; |
||
491 | } |
||
492 | } |
||
493 | } |
||
494 | else if (!IsIndirect(ArgStr[2].str.p_str)) WrError(ErrNum_InvAddrMode); |
||
495 | else |
||
496 | { |
||
497 | int l = strlen(ArgStr[2].str.p_str) - 2; |
||
498 | char *pPos; |
||
499 | Word Base, Index; |
||
500 | Boolean OK; |
||
501 | tStrComp IndexComp, *pIndexComp; |
||
502 | |||
503 | /* remove parentheses */ |
||
504 | |||
505 | StrCompCutLeft(&ArgStr[2], 1); |
||
506 | StrCompShorten(&ArgStr[2], 1); |
||
507 | |||
508 | /* base present? */ |
||
509 | |||
510 | pPos = strchr(ArgStr[2].str.p_str, ','); |
||
511 | if (pPos) |
||
512 | { |
||
513 | tStrComp RegComp; |
||
514 | |||
515 | StrCompSplitRef(&RegComp, &IndexComp, &ArgStr[2], pPos); |
||
516 | KillPostBlanksStrComp(&RegComp); |
||
517 | KillPrefBlanksStrCompRef(&RegComp); |
||
518 | OK = DecodeReg(&RegComp, &Base, True); |
||
519 | pIndexComp = &IndexComp; |
||
520 | } |
||
521 | else |
||
522 | { |
||
523 | Base = 0; |
||
524 | OK = True; |
||
525 | pIndexComp = &ArgStr[2]; |
||
526 | } |
||
527 | |||
528 | /* go on with index? */ |
||
529 | |||
530 | if (OK) |
||
531 | { |
||
532 | KillPrefBlanksStrComp(pIndexComp); |
||
533 | KillPostBlanksStrComp(pIndexComp); |
||
534 | |||
535 | if (*pIndexComp->str.p_str == '#') |
||
536 | Index = EvalStrIntExpressionOffs(pIndexComp, 1, UInt5, &OK); |
||
537 | else if (*pIndexComp->str.p_str == '-') |
||
538 | { |
||
539 | tStrComp RegArg; |
||
540 | |||
541 | Code |= 0x2000; |
||
542 | StrCompRefRight(&RegArg, pIndexComp, 1); |
||
543 | OK = DecodeReg(&RegArg, &Index, True); |
||
544 | if (OK) |
||
545 | Index = (Index << 2) | 2; |
||
546 | } |
||
547 | else if (((l = strlen(pIndexComp->str.p_str)) > 1) && (pIndexComp->str.p_str[l - 1] == '+')) |
||
548 | { |
||
549 | Code |= 0x2000; |
||
550 | StrCompShorten(pIndexComp, 1); |
||
551 | OK = DecodeReg(pIndexComp, &Index, True); |
||
552 | if (OK) |
||
553 | Index = (Index << 2) | 1; |
||
554 | } |
||
555 | else |
||
556 | { |
||
557 | Code |= 0x2000; |
||
558 | OK = DecodeReg(pIndexComp, &Index, True); |
||
559 | if (OK) |
||
560 | Index = (Index << 2); |
||
561 | } |
||
562 | |||
563 | if (OK) |
||
564 | { |
||
565 | WAsmCode[0] = Code | (DReg << 8) | (Base << 5) | Index; |
||
566 | CodeLen = 2; |
||
567 | } |
||
568 | } |
||
569 | } |
||
570 | } |
||
571 | |||
572 | /*!------------------------------------------------------------------------ |
||
573 | * \fn check_pc_even(Word index) |
||
574 | * \brief check that machine instruction ends up on even address |
||
575 | * ------------------------------------------------------------------------ */ |
||
576 | |||
577 | static void check_pc_even(Word index) |
||
578 | { |
||
579 | UNUSED(index); |
||
580 | if (Odd(EProgCounter())) WrError(ErrNum_AddrNotAligned); |
||
581 | } |
||
582 | |||
583 | /*--------------------------------------------------------------------------*/ |
||
584 | /* Dynamic Code Table Handling */ |
||
585 | |||
586 | static void InitFields(void) |
||
587 | { |
||
588 | InstTable = CreateInstTable(103); |
||
589 | |||
590 | inst_table_set_prefix_proc(InstTable, check_pc_even, 0); |
||
591 | |||
592 | AddInstTable(InstTable, "NOP", NOPCode, DecodeFixed); |
||
593 | AddInstTable(InstTable, "BRK", 0x0000 , DecodeFixed); |
||
594 | AddInstTable(InstTable, "RTS", 0x0200 , DecodeFixed); |
||
595 | |||
596 | AddInstTable(InstTable, "BCC", 0x2000 , DecodeBranch); |
||
597 | AddInstTable(InstTable, "BCS", 0x2200 , DecodeBranch); |
||
598 | AddInstTable(InstTable, "BEQ", 0x2600 , DecodeBranch); |
||
599 | AddInstTable(InstTable, "BGE", 0x3400 , DecodeBranch); |
||
600 | AddInstTable(InstTable, "BGT", 0x3800 , DecodeBranch); |
||
601 | AddInstTable(InstTable, "BHI", 0x3000 , DecodeBranch); |
||
602 | AddInstTable(InstTable, "BHS", 0x2000 , DecodeBranch); |
||
603 | AddInstTable(InstTable, "BLE", 0x3a00 , DecodeBranch); |
||
604 | AddInstTable(InstTable, "BLO", 0x2200 , DecodeBranch); |
||
605 | AddInstTable(InstTable, "BLS", 0x3200 , DecodeBranch); |
||
606 | AddInstTable(InstTable, "BLT", 0x3600 , DecodeBranch); |
||
607 | AddInstTable(InstTable, "BMI", 0x2a00 , DecodeBranch); |
||
608 | AddInstTable(InstTable, "BNE", 0x2400 , DecodeBranch); |
||
609 | AddInstTable(InstTable, "BPL", 0x2800 , DecodeBranch); |
||
610 | AddInstTable(InstTable, "BVC", 0x2c00 , DecodeBranch); |
||
611 | AddInstTable(InstTable, "BVS", 0x2e00 , DecodeBranch); |
||
612 | |||
613 | AddInstTable(InstTable, "BRA", 0 , DecodeBRA ); |
||
614 | |||
615 | AddInstTable(InstTable, "ASR", 0x0001 , DecodeShift); |
||
616 | AddInstTable(InstTable, "CSL", 0x0002 , DecodeShift); |
||
617 | AddInstTable(InstTable, "CSR", 0x0003 , DecodeShift); |
||
618 | AddInstTable(InstTable, "LSL", 0x0004 , DecodeShift); |
||
619 | AddInstTable(InstTable, "LSR", 0x0005 , DecodeShift); |
||
620 | AddInstTable(InstTable, "ROL", 0x0006 , DecodeShift); |
||
621 | AddInstTable(InstTable, "ROR", 0x0007 , DecodeShift); |
||
622 | |||
623 | AddInstTable(InstTable, "ADD" , 6, DecodeAriImm); |
||
624 | AddInstTable(InstTable, "AND" , 0, DecodeAriImm); |
||
625 | AddInstTable(InstTable, "OR" , 2, DecodeAriImm); |
||
626 | AddInstTable(InstTable, "SUB" , 4, DecodeAriImm); |
||
627 | AddInstTable(InstTable, "XNOR", 3, DecodeAriImm); |
||
628 | |||
629 | AddInstTable(InstTable, "ADDH" , 0xe800, DecodeImm8); |
||
630 | AddInstTable(InstTable, "ADDL" , 0xe000, DecodeImm8); |
||
631 | AddInstTable(InstTable, "ANDH" , 0x8800, DecodeImm8); |
||
632 | AddInstTable(InstTable, "ANDL" , 0x8000, DecodeImm8); |
||
633 | AddInstTable(InstTable, "BITH" , 0x9800, DecodeImm8); |
||
634 | AddInstTable(InstTable, "BITL" , 0x9000, DecodeImm8); |
||
635 | AddInstTable(InstTable, "CMPL" , 0xd000, DecodeImm8); |
||
636 | AddInstTable(InstTable, "CPCH" , 0xd800, DecodeImm8); |
||
637 | AddInstTable(InstTable, "ORH" , 0xa800, DecodeImm8); |
||
638 | AddInstTable(InstTable, "ORL" , 0xa000, DecodeImm8); |
||
639 | AddInstTable(InstTable, "SUBH" , 0xc800, DecodeImm8); |
||
640 | AddInstTable(InstTable, "SUBL" , 0xc000, DecodeImm8); |
||
641 | AddInstTable(InstTable, "XNORH", 0xb800, DecodeImm8); |
||
642 | AddInstTable(InstTable, "XNORL", 0xb000, DecodeImm8); |
||
643 | AddInstTable(InstTable, "LDH" , 0xf800, DecodeImm8); |
||
644 | AddInstTable(InstTable, "LDL" , 0xf000, DecodeImm8); |
||
645 | |||
646 | AddInstTable(InstTable, "BFEXT" , 0x6003, DecodeReg3); |
||
647 | AddInstTable(InstTable, "BFINS" , 0x6803, DecodeReg3); |
||
648 | AddInstTable(InstTable, "BFINSI", 0x7003, DecodeReg3); |
||
649 | AddInstTable(InstTable, "BFINSX", 0x7803, DecodeReg3); |
||
650 | |||
651 | AddInstTable(InstTable, "ADC" , 0x1803, DecodeReg23); |
||
652 | AddInstTable(InstTable, "SBC" , 0x1801, DecodeReg23); |
||
653 | |||
654 | AddInstTable(InstTable, "CPC" , 0x1801, DecodeCPC); |
||
655 | AddInstTable(InstTable, "MOV" , 0x1002, DecodeMOV); |
||
656 | AddInstTable(InstTable, "BFFFO", 0x0810, DecodeBFFFO); |
||
657 | |||
658 | AddInstTable(InstTable, "COM" , 0x1003, DecodeReg12); |
||
659 | AddInstTable(InstTable, "NEG" , 0x1800, DecodeReg12); |
||
660 | |||
661 | AddInstTable(InstTable, "JAL" , 0x00f6, DecodeReg1); |
||
662 | AddInstTable(InstTable, "PAR" , 0x00f5, DecodeReg1); |
||
663 | AddInstTable(InstTable, "SEX" , 0x00f4, DecodeReg1); |
||
664 | |||
665 | AddInstTable(InstTable, "TST" , 0x1800, DecodeTST); |
||
666 | |||
667 | AddInstTable(InstTable, "CSEM" , 0x00f0, DecodeSem); |
||
668 | AddInstTable(InstTable, "SSEM" , 0x00f2, DecodeSem); |
||
669 | |||
670 | AddInstTable(InstTable, "SIF" , 0 , DecodeSIF); |
||
671 | |||
672 | AddInstTable(InstTable, "TFR" , 0 , DecodeTFR); |
||
673 | |||
674 | AddInstTable(InstTable, "CMP" , 0 , DecodeCmp); |
||
675 | |||
676 | AddInstTable(InstTable, "LDB" , 0x4000, DecodeMem); |
||
677 | AddInstTable(InstTable, "LDW" , 0x4800, DecodeMem); |
||
678 | AddInstTable(InstTable, "STB" , 0x5000, DecodeMem); |
||
679 | AddInstTable(InstTable, "STW" , 0x5800, DecodeMem); |
||
680 | |||
681 | inst_table_set_prefix_proc(InstTable, NULL, 0); |
||
682 | AddInstTable(InstTable, "REG", 0, CodeREG); |
||
683 | add_moto8_pseudo(InstTable, e_moto_pseudo_flags_be); |
||
684 | } |
||
685 | |||
686 | static void DeinitFields(void) |
||
687 | { |
||
688 | DestroyInstTable(InstTable); |
||
689 | } |
||
690 | |||
691 | /*--------------------------------------------------------------------------*/ |
||
692 | /* Callbacks */ |
||
693 | |||
694 | /*!------------------------------------------------------------------------ |
||
695 | * \fn InternSymbol_XGATE(char *pArg, TempResult *pResult) |
||
696 | * \brief handle built-in symbols on XGATE |
||
697 | * \param pArg source argument |
||
698 | * \param pResult result buffer |
||
699 | * ------------------------------------------------------------------------ */ |
||
700 | |||
701 | static void InternSymbol_XGATE(char *pArg, TempResult *pResult) |
||
702 | { |
||
703 | Word Reg; |
||
704 | |||
705 | if (DecodeRegCore(pArg, &Reg)) |
||
706 | { |
||
707 | pResult->Typ = TempReg; |
||
708 | pResult->DataSize = eSymbolSize16Bit; |
||
709 | pResult->Contents.RegDescr.Reg = Reg; |
||
710 | pResult->Contents.RegDescr.Dissect = DissectReg_XGATE; |
||
711 | pResult->Contents.RegDescr.compare = NULL; |
||
712 | } |
||
713 | } |
||
714 | |||
715 | static void MakeCode_XGATE(void) |
||
716 | { |
||
717 | /* Nullanweisung */ |
||
718 | |||
719 | if ((*OpPart.str.p_str == '\0') && (ArgCnt == 0)) |
||
720 | return; |
||
721 | |||
722 | if (!LookupInstTable(InstTable, OpPart.str.p_str)) |
||
723 | WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart); |
||
724 | } |
||
725 | |||
726 | static Boolean IsDef_XGATE(void) |
||
727 | { |
||
728 | return Memo("REG"); |
||
729 | } |
||
730 | |||
731 | static void SwitchFrom_XGATE(void) |
||
732 | { |
||
733 | DeinitFields(); |
||
734 | } |
||
735 | |||
736 | static void SwitchTo_XGATE(void) |
||
737 | { |
||
738 | const TFamilyDescr *pDescr; |
||
739 | |||
740 | TurnWords = True; |
||
741 | SetIntConstMode(eIntConstModeMoto); |
||
742 | |||
743 | pDescr = FindFamilyByName("XGATE"); |
||
744 | PCSymbol = "*"; HeaderID = pDescr->Id; NOPCode = 0x0100; |
||
745 | DivideChars = ","; HasAttrs = False; |
||
746 | |||
747 | ValidSegs = (1 << SegCode); |
||
748 | Grans[SegCode] = 1; ListGrans[SegCode] = 2; SegInits[SegCode] = 0; |
||
749 | SegLimits[SegCode] = 0xffffl; |
||
750 | |||
751 | MakeCode = MakeCode_XGATE; |
||
752 | IsDef = IsDef_XGATE; |
||
753 | InternSymbol = InternSymbol_XGATE; |
||
754 | DissectReg = DissectReg_XGATE; |
||
755 | |||
756 | SwitchFrom = SwitchFrom_XGATE; InitFields(); |
||
757 | } |
||
758 | |||
759 | /*--------------------------------------------------------------------------*/ |
||
760 | /* Initialisierung */ |
||
761 | |||
762 | void codexgate_init(void) |
||
763 | { |
||
764 | CPUXGate = AddCPU("XGATE", SwitchTo_XGATE); |
||
765 | } |