Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1186 | savelij | 1 | /* code370.c */ |
2 | /*****************************************************************************/ |
||
3 | /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */ |
||
4 | /* */ |
||
5 | /* AS-Portierung */ |
||
6 | /* */ |
||
7 | /* Codegenerator 370-Familie */ |
||
8 | /* */ |
||
9 | /*****************************************************************************/ |
||
10 | |||
11 | #include "stdinc.h" |
||
12 | |||
13 | #include <ctype.h> |
||
14 | #include <string.h> |
||
15 | |||
16 | #include "bpemu.h" |
||
17 | #include "strutil.h" |
||
18 | #include "asmdef.h" |
||
19 | #include "asmsub.h" |
||
20 | #include "asmpars.h" |
||
21 | #include "asmitree.h" |
||
22 | #include "intformat.h" |
||
23 | #include "codepseudo.h" |
||
24 | #include "intpseudo.h" |
||
25 | #include "codevars.h" |
||
26 | #include "errmsg.h" |
||
27 | |||
28 | #include "code370.h" |
||
29 | |||
30 | typedef struct |
||
31 | { |
||
32 | char *Name; |
||
33 | Word Code; |
||
34 | } FixedOrder; |
||
35 | |||
36 | enum |
||
37 | { |
||
38 | ModNone = -1, |
||
39 | ModAccA = 0, /* A */ |
||
40 | ModAccB = 1, /* B */ |
||
41 | ModReg = 2, /* Rn */ |
||
42 | ModPort = 3, /* Pn */ |
||
43 | ModAbs = 4, /* nnnn */ |
||
44 | ModBRel = 5, /* nnnn(B) */ |
||
45 | ModSPRel = 6, /* nn(SP) */ |
||
46 | ModIReg = 7, /* @Rn */ |
||
47 | ModRegRel = 8, /* nn(Rn) */ |
||
48 | ModImm = 9, /* #nn */ |
||
49 | ModImmBRel = 10, /* #nnnn(B) */ |
||
50 | ModImmRegRel = 11 /* #nn(Rm) */ |
||
51 | }; |
||
52 | |||
53 | #define MModAccA (1 << ModAccA) |
||
54 | #define MModAccB (1 << ModAccB) |
||
55 | #define MModReg (1 << ModReg) |
||
56 | #define MModPort (1 << ModPort) |
||
57 | #define MModAbs (1 << ModAbs) |
||
58 | #define MModBRel (1 << ModBRel) |
||
59 | #define MModSPRel (1 << ModSPRel) |
||
60 | #define MModIReg (1 << ModIReg) |
||
61 | #define MModRegRel (1 << ModRegRel) |
||
62 | #define MModImm (1 << ModImm) |
||
63 | #define MModImmBRel (1 << ModImmBRel) |
||
64 | #define MModImmRegRel (1 << ModImmRegRel) |
||
65 | |||
66 | static CPUVar CPU37010, CPU37020, CPU37030, CPU37040, CPU37050; |
||
67 | |||
68 | static Byte OpSize; |
||
69 | static ShortInt AdrType; |
||
70 | static Byte AdrVals[2]; |
||
71 | |||
72 | /****************************************************************************/ |
||
73 | |||
74 | static char *HasDisp(char *Asc) |
||
75 | { |
||
76 | char *p; |
||
77 | int Lev; |
||
78 | |||
79 | if ((*Asc) && (Asc[strlen(Asc) - 1] == ')')) |
||
80 | { |
||
81 | p = Asc + strlen(Asc) - 2; |
||
82 | Lev = 0; |
||
83 | while ((p >= Asc) && (Lev != -1)) |
||
84 | { |
||
85 | switch (*p) |
||
86 | { |
||
87 | case '(': Lev--; break; |
||
88 | case ')': Lev++; break; |
||
89 | } |
||
90 | if (Lev != -1) |
||
91 | p--; |
||
92 | } |
||
93 | if (p < Asc) |
||
94 | { |
||
95 | WrXError(ErrNum_BrackErr, Asc); |
||
96 | return NULL; |
||
97 | } |
||
98 | } |
||
99 | else |
||
100 | p = NULL; |
||
101 | |||
102 | return p; |
||
103 | } |
||
104 | |||
105 | static void DecodeAdrRel(const tStrComp *pArg, Word Mask, Boolean AddrRel) |
||
106 | { |
||
107 | Integer HVal; |
||
108 | char *p; |
||
109 | Boolean OK; |
||
110 | |||
111 | AdrType = ModNone; |
||
112 | AdrCnt = 0; |
||
113 | |||
114 | if (!as_strcasecmp(pArg->str.p_str, "A")) |
||
115 | { |
||
116 | if (Mask & MModAccA) |
||
117 | AdrType = ModAccA; |
||
118 | else if (Mask & MModReg) |
||
119 | { |
||
120 | AdrCnt = 1; |
||
121 | AdrVals[0] = 0; |
||
122 | AdrType = ModReg; |
||
123 | } |
||
124 | else |
||
125 | { |
||
126 | AdrCnt = 2; |
||
127 | AdrVals[0] = 0; |
||
128 | AdrVals[1] = 0; |
||
129 | AdrType = ModAbs; |
||
130 | } |
||
131 | goto chk; |
||
132 | } |
||
133 | |||
134 | if (!as_strcasecmp(pArg->str.p_str, "B")) |
||
135 | { |
||
136 | if (Mask & MModAccB) |
||
137 | AdrType = ModAccB; |
||
138 | else if (Mask & MModReg) |
||
139 | { |
||
140 | AdrCnt = 1; |
||
141 | AdrVals[0] = 1; |
||
142 | AdrType = ModReg; |
||
143 | } |
||
144 | else |
||
145 | { |
||
146 | AdrCnt = 2; |
||
147 | AdrVals[0] = 0; |
||
148 | AdrVals[1] = 1; |
||
149 | AdrType = ModAbs; |
||
150 | } |
||
151 | goto chk; |
||
152 | } |
||
153 | |||
154 | if (*pArg->str.p_str == '#') |
||
155 | { |
||
156 | tStrComp Arg; |
||
157 | |||
158 | StrCompRefRight(&Arg, pArg, 1); |
||
159 | p = HasDisp(Arg.str.p_str); |
||
160 | if (!p) |
||
161 | { |
||
162 | switch (OpSize) |
||
163 | { |
||
164 | case 0: |
||
165 | AdrVals[0] = EvalStrIntExpression(&Arg, Int8, &OK); |
||
166 | break; |
||
167 | case 1: |
||
168 | HVal = EvalStrIntExpression(&Arg, Int16, &OK); |
||
169 | AdrVals[0] = Hi(HVal); AdrVals[1] = Lo(HVal); |
||
170 | break; |
||
171 | } |
||
172 | if (OK) |
||
173 | { |
||
174 | AdrCnt = 1 + OpSize; |
||
175 | AdrType = ModImm; |
||
176 | } |
||
177 | } |
||
178 | else |
||
179 | { |
||
180 | tStrComp Left, Right; |
||
181 | tSymbolFlags Flags; |
||
182 | |||
183 | StrCompSplitRef(&Left, &Right, &Arg, p); |
||
184 | if (Left.str.p_str[0]) |
||
185 | HVal = EvalStrIntExpressionWithFlags(&Left, Int16, &OK, &Flags); |
||
186 | else |
||
187 | { |
||
188 | HVal = 0; |
||
189 | OK = True; |
||
190 | Flags = eSymbolFlag_None; |
||
191 | } |
||
192 | if (OK) |
||
193 | { |
||
194 | *p = '('; |
||
195 | if (!as_strcasecmp(p, "(B)")) |
||
196 | { |
||
197 | AdrVals[0] = Hi(HVal); |
||
198 | AdrVals[1] = Lo(HVal); |
||
199 | AdrCnt = 2; |
||
200 | AdrType = ModImmBRel; |
||
201 | } |
||
202 | else |
||
203 | { |
||
204 | if (mFirstPassUnknown(Flags)) |
||
205 | HVal &= 127; |
||
206 | if (ChkRange(HVal, -128, 127)) |
||
207 | { |
||
208 | AdrVals[0] = HVal & 0xff; |
||
209 | AdrCnt = 1; |
||
210 | AdrVals[1] = EvalStrIntExpression(&Arg, UInt8, &OK); |
||
211 | if (OK) |
||
212 | { |
||
213 | AdrCnt = 2; |
||
214 | AdrType = ModImmRegRel; |
||
215 | } |
||
216 | } |
||
217 | } |
||
218 | } |
||
219 | } |
||
220 | goto chk; |
||
221 | } |
||
222 | |||
223 | if (*pArg->str.p_str == '@') |
||
224 | { |
||
225 | AdrVals[0] = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK); |
||
226 | if (OK) |
||
227 | { |
||
228 | AdrCnt = 1; |
||
229 | AdrType = ModIReg; |
||
230 | } |
||
231 | goto chk; |
||
232 | } |
||
233 | |||
234 | p = HasDisp(pArg->str.p_str); |
||
235 | |||
236 | if (!p) |
||
237 | { |
||
238 | HVal = EvalStrIntExpression(pArg, Int16, &OK); |
||
239 | if (OK) |
||
240 | { |
||
241 | if (((Mask & MModReg) != 0) && (Hi(HVal) == 0)) |
||
242 | { |
||
243 | AdrVals[0] = Lo(HVal); |
||
244 | AdrCnt = 1; |
||
245 | AdrType = ModReg; |
||
246 | } |
||
247 | else if (((Mask & MModPort) != 0) && (Hi(HVal) == 0x10)) |
||
248 | { |
||
249 | AdrVals[0] = Lo(HVal); |
||
250 | AdrCnt = 1; |
||
251 | AdrType = ModPort; |
||
252 | } |
||
253 | else |
||
254 | { |
||
255 | if (AddrRel) |
||
256 | HVal -= EProgCounter() + 3; |
||
257 | AdrVals[0] = Hi(HVal); |
||
258 | AdrVals[1] = Lo(HVal); |
||
259 | AdrCnt = 2; |
||
260 | AdrType = ModAbs; |
||
261 | } |
||
262 | } |
||
263 | goto chk; |
||
264 | } |
||
265 | else |
||
266 | { |
||
267 | tStrComp Left, Right; |
||
268 | tSymbolFlags Flags; |
||
269 | |||
270 | StrCompSplitRef(&Left, &Right, pArg, p); |
||
271 | HVal = EvalStrIntExpressionWithFlags(&Left, Int16, &OK, &Flags); |
||
272 | if (mFirstPassUnknown(Flags)) |
||
273 | HVal &= 0x7f; |
||
274 | if (OK) |
||
275 | { |
||
276 | StrCompShorten (&Right, 1); |
||
277 | if (!as_strcasecmp(Right.str.p_str, "B")) |
||
278 | { |
||
279 | if (AddrRel) |
||
280 | HVal -= EProgCounter() + 3; |
||
281 | AdrVals[0] = Hi(HVal); |
||
282 | AdrVals[1] = Lo(HVal); |
||
283 | AdrCnt = 2; |
||
284 | AdrType = ModBRel; |
||
285 | } |
||
286 | else if (!as_strcasecmp(Right.str.p_str, "SP")) |
||
287 | { |
||
288 | if (AddrRel) |
||
289 | HVal -= EProgCounter() + 3; |
||
290 | if (HVal > 127) WrError(ErrNum_OverRange); |
||
291 | else if (HVal < -128) WrError(ErrNum_UnderRange); |
||
292 | else |
||
293 | { |
||
294 | AdrVals[0] = HVal & 0xff; |
||
295 | AdrCnt = 1; |
||
296 | AdrType = ModSPRel; |
||
297 | } |
||
298 | } |
||
299 | else |
||
300 | { |
||
301 | if (HVal > 127) WrError(ErrNum_OverRange); |
||
302 | else if (HVal < -128) WrError(ErrNum_UnderRange); |
||
303 | else |
||
304 | { |
||
305 | AdrVals[0] = HVal & 0xff; |
||
306 | AdrVals[1] = EvalStrIntExpression(&Right, Int8, &OK); |
||
307 | if (OK) |
||
308 | { |
||
309 | AdrCnt = 2; |
||
310 | AdrType = ModRegRel; |
||
311 | } |
||
312 | } |
||
313 | } |
||
314 | } |
||
315 | goto chk; |
||
316 | } |
||
317 | |||
318 | chk: |
||
319 | if ((AdrType != ModNone) && (!(Mask & (1 << AdrType)))) |
||
320 | { |
||
321 | WrError(ErrNum_InvAddrMode); |
||
322 | AdrType = ModNone; |
||
323 | AdrCnt = 0; |
||
324 | } |
||
325 | } |
||
326 | |||
327 | static void DecodeAdr(const tStrComp *pArg, Word Mask) |
||
328 | { |
||
329 | DecodeAdrRel(pArg, Mask, FALSE); |
||
330 | } |
||
331 | |||
332 | static void PutCode(Word Code) |
||
333 | { |
||
334 | if (Hi(Code) == 0) |
||
335 | { |
||
336 | CodeLen = 1; |
||
337 | BAsmCode[0] = Code; |
||
338 | } |
||
339 | else |
||
340 | { |
||
341 | CodeLen = 2; |
||
342 | BAsmCode[0] = Hi(Code); |
||
343 | BAsmCode[1] = Lo(Code); |
||
344 | } |
||
345 | } |
||
346 | |||
347 | static void DissectBitValue(LargeWord Symbol, Word *pAddr, Byte *pBit) |
||
348 | { |
||
349 | *pAddr = Symbol & 0xffff; |
||
350 | *pBit = (Symbol >> 16) & 7; |
||
351 | } |
||
352 | |||
353 | static void DissectBit_370(char *pDest, size_t DestSize, LargeWord Symbol) |
||
354 | { |
||
355 | Word Addr; |
||
356 | Byte Bit; |
||
357 | |||
358 | DissectBitValue(Symbol, &Addr, &Bit); |
||
359 | |||
360 | if (Addr < 2) |
||
361 | as_snprintf(pDest, DestSize, "%c", HexStartCharacter + Addr); |
||
362 | else |
||
363 | as_snprintf(pDest, DestSize, "%~0.*u%s", |
||
364 | ListRadixBase, (unsigned)Addr, GetIntConstIntelSuffix(ListRadixBase)); |
||
365 | as_snprcatf(pDest, DestSize, ".%c", Bit + '0'); |
||
366 | } |
||
367 | |||
368 | static Boolean DecodeBitExpr(int Start, int Stop, LongWord *pResult) |
||
369 | { |
||
370 | Boolean OK; |
||
371 | |||
372 | if (Start == Stop) |
||
373 | { |
||
374 | *pResult = EvalStrIntExpression(&ArgStr[Start], UInt19, &OK); |
||
375 | return OK; |
||
376 | } |
||
377 | else |
||
378 | { |
||
379 | Byte Bit; |
||
380 | Word Addr; |
||
381 | |||
382 | Bit = EvalStrIntExpression(&ArgStr[Start], UInt3, &OK); |
||
383 | if (!OK) |
||
384 | return OK; |
||
385 | |||
386 | if ((!as_strcasecmp(ArgStr[Stop].str.p_str, "A")) || (!as_strcasecmp(ArgStr[Stop].str.p_str, "B"))) |
||
387 | { |
||
388 | Addr = toupper(*ArgStr[Stop].str.p_str) - 'A'; |
||
389 | OK = True; |
||
390 | } |
||
391 | else |
||
392 | { |
||
393 | tSymbolFlags Flags; |
||
394 | |||
395 | Addr = EvalStrIntExpressionWithFlags(&ArgStr[Stop], UInt16, &OK, &Flags); |
||
396 | if (!OK) |
||
397 | return OK; |
||
398 | if (mFirstPassUnknown(Flags)) |
||
399 | Addr &= 0xff; |
||
400 | if (Addr & 0xef00) /* 00h...0ffh, 1000h...10ffh allowed */ |
||
401 | { |
||
402 | WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[Stop]); |
||
403 | return False; |
||
404 | } |
||
405 | } |
||
406 | |||
407 | *pResult = (((LongWord)Bit) << 16) + Addr; |
||
408 | return True; |
||
409 | } |
||
410 | } |
||
411 | |||
412 | /****************************************************************************/ |
||
413 | |||
414 | static void DecodeFixed(Word Code) |
||
415 | { |
||
416 | if (ChkArgCnt(0, 0)) |
||
417 | PutCode(Code); |
||
418 | } |
||
419 | |||
420 | static void DecodeDBIT(Word Code) |
||
421 | { |
||
422 | LongWord Value; |
||
423 | |||
424 | UNUSED(Code); |
||
425 | |||
426 | if (ChkArgCnt(1, 2) && DecodeBitExpr(1, ArgCnt, &Value)) |
||
427 | { |
||
428 | PushLocHandle(-1); |
||
429 | EnterIntSymbol(&LabPart, Value, SegBData, False); |
||
430 | *ListLine = '='; |
||
431 | DissectBit_370(ListLine + 1, STRINGSIZE - 1, Value); |
||
432 | PopLocHandle(); |
||
433 | } |
||
434 | } |
||
435 | |||
436 | static void DecodeMOV(Word Code) |
||
437 | { |
||
438 | UNUSED(Code); |
||
439 | |||
440 | if (ChkArgCnt(2, 2)) |
||
441 | { |
||
442 | DecodeAdr(&ArgStr[2], MModAccB + MModReg + MModPort + MModAbs + MModIReg + MModBRel |
||
443 | + MModSPRel + MModRegRel + MModAccA); |
||
444 | switch (AdrType) |
||
445 | { |
||
446 | case ModAccA: |
||
447 | DecodeAdr(&ArgStr[1], MModReg + MModAbs + MModIReg + MModBRel + MModRegRel |
||
448 | + MModSPRel + MModAccB + MModPort + MModImm); |
||
449 | switch (AdrType) |
||
450 | { |
||
451 | case ModReg: |
||
452 | BAsmCode[0] = 0x12; |
||
453 | BAsmCode[1] = AdrVals[0]; |
||
454 | CodeLen = 2; |
||
455 | break; |
||
456 | case ModAbs: |
||
457 | BAsmCode[0] = 0x8a; |
||
458 | memcpy(BAsmCode + 1, AdrVals, 2); |
||
459 | CodeLen = 3; |
||
460 | break; |
||
461 | case ModIReg: |
||
462 | BAsmCode[0] = 0x9a; |
||
463 | BAsmCode[1] = AdrVals[0]; |
||
464 | CodeLen = 2; |
||
465 | break; |
||
466 | case ModBRel: |
||
467 | BAsmCode[0] = 0xaa; |
||
468 | memcpy(BAsmCode + 1, AdrVals, 2); |
||
469 | CodeLen = 3; |
||
470 | break; |
||
471 | case ModRegRel: |
||
472 | BAsmCode[0] = 0xf4; |
||
473 | BAsmCode[1] = 0xea; |
||
474 | memcpy(BAsmCode + 2, AdrVals, 2); |
||
475 | CodeLen = 4; |
||
476 | break; |
||
477 | case ModSPRel: |
||
478 | BAsmCode[0] = 0xf1; |
||
479 | BAsmCode[1] = AdrVals[0]; |
||
480 | CodeLen = 2; |
||
481 | break; |
||
482 | case ModAccB: |
||
483 | BAsmCode[0] = 0x62; |
||
484 | CodeLen = 1; |
||
485 | break; |
||
486 | case ModPort: |
||
487 | BAsmCode[0] = 0x80; |
||
488 | BAsmCode[1] = AdrVals[0]; |
||
489 | CodeLen = 2; |
||
490 | break; |
||
491 | case ModImm: |
||
492 | BAsmCode[0] = 0x22; |
||
493 | BAsmCode[1] = AdrVals[0]; |
||
494 | CodeLen = 2; |
||
495 | break; |
||
496 | } |
||
497 | break; |
||
498 | case ModAccB: |
||
499 | DecodeAdr(&ArgStr[1], MModAccA + MModReg + MModPort + MModImm); |
||
500 | switch (AdrType) |
||
501 | { |
||
502 | case ModAccA: |
||
503 | BAsmCode[0] = 0xc0; |
||
504 | CodeLen = 1; |
||
505 | break; |
||
506 | case ModReg: |
||
507 | BAsmCode[0] = 0x32; |
||
508 | BAsmCode[1] = AdrVals[0]; |
||
509 | CodeLen = 2; |
||
510 | break; |
||
511 | case ModPort: |
||
512 | BAsmCode[0] = 0x91; |
||
513 | BAsmCode[1] = AdrVals[0]; |
||
514 | CodeLen = 2; |
||
515 | break; |
||
516 | case ModImm: |
||
517 | BAsmCode[0] = 0x52; |
||
518 | BAsmCode[1] = AdrVals[0]; |
||
519 | CodeLen = 2; |
||
520 | break; |
||
521 | } |
||
522 | break; |
||
523 | case ModReg: |
||
524 | BAsmCode[1] = BAsmCode[2] = AdrVals[0]; |
||
525 | DecodeAdr(&ArgStr[1], MModAccA + MModAccB + MModReg + MModPort + MModImm); |
||
526 | switch (AdrType) |
||
527 | { |
||
528 | case ModAccA: |
||
529 | BAsmCode[0] = 0xd0; |
||
530 | CodeLen = 2; |
||
531 | break; |
||
532 | case ModAccB: |
||
533 | BAsmCode[0] = 0xd1; |
||
534 | CodeLen = 2; |
||
535 | break; |
||
536 | case ModReg: |
||
537 | BAsmCode[0] = 0x42; |
||
538 | BAsmCode[1] = AdrVals[0]; |
||
539 | CodeLen = 3; |
||
540 | break; |
||
541 | case ModPort: |
||
542 | BAsmCode[0] = 0xa2; |
||
543 | BAsmCode[1] = AdrVals[0]; |
||
544 | CodeLen = 3; |
||
545 | break; |
||
546 | case ModImm: |
||
547 | BAsmCode[0] = 0x72; |
||
548 | BAsmCode[1] = AdrVals[0]; |
||
549 | CodeLen = 3; |
||
550 | break; |
||
551 | } |
||
552 | break; |
||
553 | case ModPort: |
||
554 | BAsmCode[1] = BAsmCode[2] = AdrVals[0]; |
||
555 | DecodeAdr(&ArgStr[1], MModAccA + MModAccB + MModReg + MModImm); |
||
556 | switch (AdrType) |
||
557 | { |
||
558 | case ModAccA: |
||
559 | BAsmCode[0] = 0x21; |
||
560 | CodeLen = 2; |
||
561 | break; |
||
562 | case ModAccB: |
||
563 | BAsmCode[0] = 0x51; |
||
564 | CodeLen = 2; |
||
565 | break; |
||
566 | case ModReg: |
||
567 | BAsmCode[0] = 0x71; |
||
568 | BAsmCode[1] = AdrVals[0]; |
||
569 | CodeLen = 3; |
||
570 | break; |
||
571 | case ModImm: |
||
572 | BAsmCode[0] = 0xf7; |
||
573 | BAsmCode[1] = AdrVals[0]; |
||
574 | CodeLen = 3; |
||
575 | break; |
||
576 | } |
||
577 | break; |
||
578 | case ModAbs: |
||
579 | memcpy(BAsmCode + 1, AdrVals, AdrCnt); |
||
580 | DecodeAdr(&ArgStr[1], MModAccA); |
||
581 | if (AdrType != ModNone) |
||
582 | { |
||
583 | BAsmCode[0] = 0x8b; |
||
584 | CodeLen = 3; |
||
585 | } |
||
586 | break; |
||
587 | case ModIReg: |
||
588 | BAsmCode[1] = AdrVals[0]; |
||
589 | DecodeAdr(&ArgStr[1], MModAccA); |
||
590 | if (AdrType != ModNone) |
||
591 | { |
||
592 | BAsmCode[0] = 0x9b; |
||
593 | CodeLen = 2; |
||
594 | } |
||
595 | break; |
||
596 | case ModBRel: |
||
597 | memcpy(BAsmCode + 1, AdrVals, AdrCnt); |
||
598 | DecodeAdr(&ArgStr[1], MModAccA); |
||
599 | if (AdrType != ModNone) |
||
600 | { |
||
601 | BAsmCode[0] = 0xab; |
||
602 | CodeLen = 3; |
||
603 | } |
||
604 | break; |
||
605 | case ModSPRel: |
||
606 | BAsmCode[1] = AdrVals[0]; |
||
607 | DecodeAdr(&ArgStr[1], MModAccA); |
||
608 | if (AdrType != ModNone) |
||
609 | { |
||
610 | BAsmCode[0] = 0xf2; |
||
611 | CodeLen = 2; |
||
612 | } |
||
613 | break; |
||
614 | case ModRegRel: |
||
615 | memcpy(BAsmCode + 2, AdrVals, AdrCnt); |
||
616 | DecodeAdr(&ArgStr[1], MModAccA); |
||
617 | if (AdrType != ModNone) |
||
618 | { |
||
619 | BAsmCode[0] = 0xf4; |
||
620 | BAsmCode[1] = 0xeb; |
||
621 | CodeLen = 4; |
||
622 | } |
||
623 | break; |
||
624 | } |
||
625 | } |
||
626 | } |
||
627 | |||
628 | static void DecodeMOVW(Word Code) |
||
629 | { |
||
630 | UNUSED(Code); |
||
631 | |||
632 | OpSize = 1; |
||
633 | if (ChkArgCnt(2, 2)) |
||
634 | { |
||
635 | DecodeAdr(&ArgStr[2], MModReg); |
||
636 | if (AdrType != ModNone) |
||
637 | { |
||
638 | Byte AdrVal = AdrVals[0]; |
||
639 | |||
640 | DecodeAdr(&ArgStr[1], MModReg + MModImm + MModImmBRel + MModImmRegRel); |
||
641 | switch (AdrType) |
||
642 | { |
||
643 | case ModReg: |
||
644 | BAsmCode[0] = 0x98; |
||
645 | BAsmCode[1] = AdrVals[0]; |
||
646 | BAsmCode[2] = AdrVal; |
||
647 | CodeLen = 3; |
||
648 | break; |
||
649 | case ModImm: |
||
650 | BAsmCode[0] = 0x88; |
||
651 | memcpy(BAsmCode + 1, AdrVals, 2); |
||
652 | BAsmCode[3] = AdrVal; |
||
653 | CodeLen = 4; |
||
654 | break; |
||
655 | case ModImmBRel: |
||
656 | BAsmCode[0] = 0xa8; |
||
657 | memcpy(BAsmCode + 1, AdrVals, 2); |
||
658 | BAsmCode[3] = AdrVal; |
||
659 | CodeLen = 4; |
||
660 | break; |
||
661 | case ModImmRegRel: |
||
662 | BAsmCode[0] = 0xf4; |
||
663 | BAsmCode[1] = 0xe8; |
||
664 | memcpy(BAsmCode + 2, AdrVals, 2); |
||
665 | BAsmCode[4] = AdrVal; |
||
666 | CodeLen = 5; |
||
667 | break; |
||
668 | } |
||
669 | } |
||
670 | } |
||
671 | } |
||
672 | |||
673 | static void DecodeRel8(Word Code) |
||
674 | { |
||
675 | if (ChkArgCnt(1, 1)) |
||
676 | { |
||
677 | Boolean OK; |
||
678 | tSymbolFlags Flags; |
||
679 | Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags) - (EProgCounter() + 2); |
||
680 | |||
681 | if (OK) |
||
682 | { |
||
683 | if (!mSymbolQuestionable(Flags) && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig); |
||
684 | else |
||
685 | { |
||
686 | CodeLen = 2; |
||
687 | BAsmCode[0] = Code; |
||
688 | BAsmCode[1] = AdrInt & 0xff; |
||
689 | } |
||
690 | } |
||
691 | } |
||
692 | } |
||
693 | |||
694 | static void DecodeCMP(Word Code) |
||
695 | { |
||
696 | UNUSED(Code); |
||
697 | |||
698 | if (ChkArgCnt(2, 2)) |
||
699 | { |
||
700 | DecodeAdr(&ArgStr[2], MModAccA + MModAccB + MModReg); |
||
701 | switch (AdrType) |
||
702 | { |
||
703 | case ModAccA: |
||
704 | DecodeAdr(&ArgStr[1], MModAbs + MModIReg + MModBRel + MModRegRel + MModSPRel + MModAccB + MModReg + MModImm); |
||
705 | switch (AdrType) |
||
706 | { |
||
707 | case ModAbs: |
||
708 | BAsmCode[0] = 0x8d; |
||
709 | memcpy(BAsmCode + 1, AdrVals, 2); |
||
710 | CodeLen = 3; |
||
711 | break; |
||
712 | case ModIReg: |
||
713 | BAsmCode[0] = 0x9d; |
||
714 | BAsmCode[1] = AdrVals[0]; |
||
715 | CodeLen = 2; |
||
716 | break; |
||
717 | case ModBRel: |
||
718 | BAsmCode[0] = 0xad; |
||
719 | memcpy(BAsmCode + 1, AdrVals, 2); |
||
720 | CodeLen = 3; |
||
721 | break; |
||
722 | case ModRegRel: |
||
723 | BAsmCode[0] = 0xf4; |
||
724 | BAsmCode[1] = 0xed; |
||
725 | memcpy(BAsmCode + 2, AdrVals, 2); |
||
726 | CodeLen = 4; |
||
727 | break; |
||
728 | case ModSPRel: |
||
729 | BAsmCode[0] = 0xf3; |
||
730 | BAsmCode[1] = AdrVals[0]; |
||
731 | CodeLen = 2; |
||
732 | break; |
||
733 | case ModAccB: |
||
734 | BAsmCode[0] = 0x6d; |
||
735 | CodeLen = 1; |
||
736 | break; |
||
737 | case ModReg: |
||
738 | BAsmCode[0] = 0x1d; |
||
739 | BAsmCode[1] = AdrVals[0]; |
||
740 | CodeLen = 2; |
||
741 | break; |
||
742 | case ModImm: |
||
743 | BAsmCode[0] = 0x2d; |
||
744 | BAsmCode[1] = AdrVals[0]; |
||
745 | CodeLen = 2; |
||
746 | break; |
||
747 | } |
||
748 | break; |
||
749 | case ModAccB: |
||
750 | DecodeAdr(&ArgStr[1], MModReg + MModImm); |
||
751 | switch (AdrType) |
||
752 | { |
||
753 | case ModReg: |
||
754 | BAsmCode[0] = 0x3d; |
||
755 | BAsmCode[1] = AdrVals[0]; |
||
756 | CodeLen = 2; |
||
757 | break; |
||
758 | case ModImm: |
||
759 | BAsmCode[0] = 0x5d; |
||
760 | BAsmCode[1] = AdrVals[0]; |
||
761 | CodeLen = 2; |
||
762 | break; |
||
763 | } |
||
764 | break; |
||
765 | case ModReg: |
||
766 | BAsmCode[2] = AdrVals[0]; |
||
767 | DecodeAdr(&ArgStr[1], MModReg + MModImm); |
||
768 | switch (AdrType) |
||
769 | { |
||
770 | case ModReg: |
||
771 | BAsmCode[0] = 0x4d; |
||
772 | BAsmCode[1] = AdrVals[0]; |
||
773 | CodeLen = 3; |
||
774 | break; |
||
775 | case ModImm: |
||
776 | BAsmCode[0] = 0x7d; |
||
777 | BAsmCode[1] = AdrVals[0]; |
||
778 | CodeLen = 3; |
||
779 | break; |
||
780 | } |
||
781 | break; |
||
782 | } |
||
783 | } |
||
784 | } |
||
785 | |||
786 | static void DecodeALU1(Word Code) |
||
787 | { |
||
788 | if (ChkArgCnt(2, 2)) |
||
789 | { |
||
790 | DecodeAdr(&ArgStr[2], MModAccA + MModAccB + MModReg); |
||
791 | switch (AdrType) |
||
792 | { |
||
793 | case ModAccA: |
||
794 | DecodeAdr(&ArgStr[1], MModAccB + MModReg + MModImm); |
||
795 | switch (AdrType) |
||
796 | { |
||
797 | case ModAccB: |
||
798 | CodeLen = 1; |
||
799 | BAsmCode[0] = 0x60 + Code; |
||
800 | break; |
||
801 | case ModReg: |
||
802 | CodeLen = 2; |
||
803 | BAsmCode[0] = 0x10 + Code; |
||
804 | BAsmCode[1] = AdrVals[0]; |
||
805 | break; |
||
806 | case ModImm: |
||
807 | CodeLen = 2; |
||
808 | BAsmCode[0] = 0x20 + Code; |
||
809 | BAsmCode[1] = AdrVals[0]; |
||
810 | break; |
||
811 | } |
||
812 | break; |
||
813 | case ModAccB: |
||
814 | DecodeAdr(&ArgStr[1], MModReg + MModImm); |
||
815 | switch (AdrType) |
||
816 | { |
||
817 | case ModReg: |
||
818 | CodeLen = 2; |
||
819 | BAsmCode[0] = 0x30 + Code; |
||
820 | BAsmCode[1] = AdrVals[0]; |
||
821 | break; |
||
822 | case ModImm: |
||
823 | CodeLen = 2; |
||
824 | BAsmCode[0] = 0x50 + Code; |
||
825 | BAsmCode[1] = AdrVals[0]; |
||
826 | break; |
||
827 | } |
||
828 | break; |
||
829 | case ModReg: |
||
830 | BAsmCode[2] = AdrVals[0]; |
||
831 | DecodeAdr(&ArgStr[1], MModReg + MModImm); |
||
832 | switch (AdrType) |
||
833 | { |
||
834 | case ModReg: |
||
835 | CodeLen = 3; |
||
836 | BAsmCode[0] = 0x40 + Code; |
||
837 | BAsmCode[1] = AdrVals[0]; |
||
838 | break; |
||
839 | case ModImm: |
||
840 | CodeLen = 3; |
||
841 | BAsmCode[0] = 0x70 + Code; |
||
842 | BAsmCode[1] = AdrVals[0]; |
||
843 | break; |
||
844 | } |
||
845 | break; |
||
846 | } |
||
847 | } |
||
848 | } |
||
849 | |||
850 | static void DecodeALU2(Word Code) |
||
851 | { |
||
852 | Boolean Rela = Hi(Code) != 0; |
||
853 | Code &= 0xff; |
||
854 | |||
855 | if (ChkArgCnt(Rela ? 3 : 2, Rela ? 3 : 2)) |
||
856 | { |
||
857 | DecodeAdr(&ArgStr[2], MModAccA + MModAccB + MModReg + MModPort); |
||
858 | switch (AdrType) |
||
859 | { |
||
860 | case ModAccA: |
||
861 | DecodeAdr(&ArgStr[1], MModAccB + MModReg + MModImm); |
||
862 | switch (AdrType) |
||
863 | { |
||
864 | case ModAccB: |
||
865 | BAsmCode[0] = 0x60 + Code; |
||
866 | CodeLen = 1; |
||
867 | break; |
||
868 | case ModReg: |
||
869 | BAsmCode[0] = 0x10 + Code; |
||
870 | BAsmCode[1] = AdrVals[0]; |
||
871 | CodeLen = 2; |
||
872 | break; |
||
873 | case ModImm: |
||
874 | BAsmCode[0] = 0x20 + Code; |
||
875 | BAsmCode[1] = AdrVals[0]; |
||
876 | CodeLen = 2; |
||
877 | break; |
||
878 | } |
||
879 | break; |
||
880 | case ModAccB: |
||
881 | DecodeAdr(&ArgStr[1], MModReg + MModImm); |
||
882 | switch (AdrType) |
||
883 | { |
||
884 | case ModReg: |
||
885 | BAsmCode[0] = 0x30 + Code; |
||
886 | BAsmCode[1] = AdrVals[0]; |
||
887 | CodeLen = 2; |
||
888 | break; |
||
889 | case ModImm: |
||
890 | BAsmCode[0] = 0x50 + Code; |
||
891 | BAsmCode[1] = AdrVals[0]; |
||
892 | CodeLen = 2; |
||
893 | break; |
||
894 | } |
||
895 | break; |
||
896 | case ModReg: |
||
897 | BAsmCode[2] = AdrVals[0]; |
||
898 | DecodeAdr(&ArgStr[1], MModReg + MModImm); |
||
899 | switch (AdrType) |
||
900 | { |
||
901 | case ModReg: |
||
902 | BAsmCode[0] = 0x40 + Code; |
||
903 | BAsmCode[1] = AdrVals[0]; |
||
904 | CodeLen = 3; |
||
905 | break; |
||
906 | case ModImm: |
||
907 | BAsmCode[0] = 0x70 + Code; |
||
908 | BAsmCode[1] = AdrVals[0]; |
||
909 | CodeLen = 3; |
||
910 | break; |
||
911 | } |
||
912 | break; |
||
913 | case ModPort: |
||
914 | BAsmCode[1] = AdrVals[0]; |
||
915 | DecodeAdr(&ArgStr[1], MModAccA + MModAccB + MModImm); |
||
916 | switch (AdrType) |
||
917 | { |
||
918 | case ModAccA: |
||
919 | BAsmCode[0] = 0x80 + Code; |
||
920 | CodeLen = 2; |
||
921 | break; |
||
922 | case ModAccB: |
||
923 | BAsmCode[0] = 0x90 + Code; |
||
924 | CodeLen = 2; |
||
925 | break; |
||
926 | case ModImm: |
||
927 | BAsmCode[0] = 0xa0 + Code; |
||
928 | BAsmCode[2] = BAsmCode[1]; |
||
929 | BAsmCode[1] = AdrVals[0]; |
||
930 | CodeLen = 3; |
||
931 | break; |
||
932 | } |
||
933 | break; |
||
934 | } |
||
935 | if ((CodeLen != 0) && (Rela)) |
||
936 | { |
||
937 | Boolean OK; |
||
938 | tSymbolFlags Flags; |
||
939 | Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[3], UInt16, &OK, &Flags) - (EProgCounter() + CodeLen + 1); |
||
940 | |||
941 | if (!OK) |
||
942 | CodeLen = 0; |
||
943 | else if (!mSymbolQuestionable(Flags) && ((AdrInt > 127) || (AdrInt < -128))) |
||
944 | { |
||
945 | WrError(ErrNum_JmpDistTooBig); |
||
946 | CodeLen = 0; |
||
947 | } |
||
948 | else |
||
949 | BAsmCode[CodeLen++] = AdrInt & 0xff; |
||
950 | } |
||
951 | } |
||
952 | } |
||
953 | |||
954 | static void DecodeJmp(Word Code) |
||
955 | { |
||
956 | Boolean AddrRel = Hi(Code) != 0; |
||
957 | Code &= 0xff; |
||
958 | |||
959 | if (ChkArgCnt(1, 1)) |
||
960 | { |
||
961 | DecodeAdrRel(&ArgStr[1], MModAbs + MModIReg + MModBRel + MModRegRel, AddrRel); |
||
962 | switch (AdrType) |
||
963 | { |
||
964 | case ModAbs: |
||
965 | CodeLen = 3; |
||
966 | BAsmCode[0] = 0x80 + Code; |
||
967 | memcpy(BAsmCode + 1, AdrVals, 2); |
||
968 | break; |
||
969 | case ModIReg: |
||
970 | CodeLen = 2; |
||
971 | BAsmCode[0] = 0x90 + Code; |
||
972 | BAsmCode[1] = AdrVals[0]; |
||
973 | break; |
||
974 | case ModBRel: |
||
975 | CodeLen = 3; |
||
976 | BAsmCode[0] = 0xa0 + Code; |
||
977 | memcpy(BAsmCode + 1, AdrVals, 2); |
||
978 | break; |
||
979 | case ModRegRel: |
||
980 | CodeLen = 4; |
||
981 | BAsmCode[0] = 0xf4; |
||
982 | BAsmCode[1] = 0xe0 + Code; |
||
983 | memcpy(BAsmCode + 2, AdrVals, 2); |
||
984 | break; |
||
985 | } |
||
986 | } |
||
987 | } |
||
988 | |||
989 | static void DecodeABReg(Word Code) |
||
990 | { |
||
991 | int IsDJNZ = Hi(Code) & 1; |
||
992 | Boolean IsStack = (Code & 0x200) || False; |
||
993 | |||
994 | Code &= 0xff; |
||
995 | |||
996 | if (!ChkArgCnt(1 + IsDJNZ, 1 + IsDJNZ)); |
||
997 | else if (!as_strcasecmp(ArgStr[1].str.p_str, "ST")) |
||
998 | { |
||
999 | if (IsStack) |
||
1000 | { |
||
1001 | BAsmCode[0] = 0xf3 + Code; |
||
1002 | CodeLen = 1; |
||
1003 | } |
||
1004 | else |
||
1005 | WrError(ErrNum_InvAddrMode); |
||
1006 | } |
||
1007 | else |
||
1008 | { |
||
1009 | DecodeAdr(&ArgStr[1], MModAccA + MModAccB + MModReg); |
||
1010 | switch (AdrType) |
||
1011 | { |
||
1012 | case ModAccA: |
||
1013 | BAsmCode[0] = 0xb0 + Code; |
||
1014 | CodeLen = 1; |
||
1015 | break; |
||
1016 | case ModAccB: |
||
1017 | BAsmCode[0] = 0xc0 + Code; |
||
1018 | CodeLen = 1; |
||
1019 | break; |
||
1020 | case ModReg: |
||
1021 | BAsmCode[0] = 0xd0 + Code; |
||
1022 | BAsmCode[CodeLen + 1] = AdrVals[0]; |
||
1023 | CodeLen = 2; |
||
1024 | break; |
||
1025 | } |
||
1026 | if ((IsDJNZ) && (CodeLen != 0)) |
||
1027 | { |
||
1028 | Boolean OK; |
||
1029 | tSymbolFlags Flags; |
||
1030 | Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[2], Int16, &OK, &Flags) - (EProgCounter() + CodeLen + 1); |
||
1031 | |||
1032 | if (!OK) |
||
1033 | CodeLen = 0; |
||
1034 | else if (!mSymbolQuestionable(Flags) && ((AdrInt > 127) || (AdrInt < -128))) |
||
1035 | { |
||
1036 | WrError(ErrNum_JmpDistTooBig); |
||
1037 | CodeLen = 0; |
||
1038 | } |
||
1039 | else |
||
1040 | BAsmCode[CodeLen++] = AdrInt & 0xff; |
||
1041 | } |
||
1042 | } |
||
1043 | } |
||
1044 | |||
1045 | static void DecodeBit(Word Code) |
||
1046 | { |
||
1047 | int Rela = Hi(Code); |
||
1048 | LongWord BitExpr; |
||
1049 | |||
1050 | Code &= 0xff; |
||
1051 | |||
1052 | if (ChkArgCnt(1 + Rela, 2 + Rela) |
||
1053 | && DecodeBitExpr(1, ArgCnt - Rela, &BitExpr)) |
||
1054 | { |
||
1055 | Boolean OK; |
||
1056 | Word Addr; |
||
1057 | Byte Bit; |
||
1058 | |||
1059 | DissectBitValue(BitExpr, &Addr, &Bit); |
||
1060 | |||
1061 | BAsmCode[1] = 1 << Bit; |
||
1062 | BAsmCode[2] = Lo(Addr); |
||
1063 | switch (Hi(Addr)) |
||
1064 | { |
||
1065 | case 0x00: |
||
1066 | BAsmCode[0] = 0x70 + Code; |
||
1067 | CodeLen = 3; |
||
1068 | break; |
||
1069 | case 0x10: |
||
1070 | BAsmCode[0] = 0xa0 + Code; |
||
1071 | CodeLen = 3; |
||
1072 | break; |
||
1073 | default: |
||
1074 | WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[ArgCnt - 1]); |
||
1075 | } |
||
1076 | if ((CodeLen != 0) && Rela) |
||
1077 | { |
||
1078 | tSymbolFlags Flags; |
||
1079 | Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int16, &OK, &Flags) - (EProgCounter() + CodeLen + 1); |
||
1080 | |||
1081 | if (!OK) |
||
1082 | CodeLen = 0; |
||
1083 | else if (!mSymbolQuestionable(Flags) && ((AdrInt > 127) || (AdrInt < -128))) |
||
1084 | { |
||
1085 | WrError(ErrNum_JmpDistTooBig); |
||
1086 | CodeLen = 0; |
||
1087 | } |
||
1088 | else |
||
1089 | BAsmCode[CodeLen++] = AdrInt & 0xff; |
||
1090 | } |
||
1091 | } |
||
1092 | } |
||
1093 | |||
1094 | static void DecodeDIV(Word Code) |
||
1095 | { |
||
1096 | UNUSED(Code); |
||
1097 | |||
1098 | if (ChkArgCnt(2, 2)) |
||
1099 | { |
||
1100 | DecodeAdr(&ArgStr[2], MModAccA); |
||
1101 | if (AdrType != ModNone) |
||
1102 | { |
||
1103 | DecodeAdr(&ArgStr[1], MModReg); |
||
1104 | if (AdrType != ModNone) |
||
1105 | { |
||
1106 | BAsmCode[0] = 0xf4; |
||
1107 | BAsmCode[1] = 0xf8; |
||
1108 | BAsmCode[2] = AdrVals[0]; |
||
1109 | CodeLen = 3; |
||
1110 | } |
||
1111 | } |
||
1112 | } |
||
1113 | } |
||
1114 | |||
1115 | static void DecodeINCW(Word Code) |
||
1116 | { |
||
1117 | UNUSED(Code); |
||
1118 | |||
1119 | if (ChkArgCnt(2, 2)) |
||
1120 | { |
||
1121 | DecodeAdr(&ArgStr[2], MModReg); |
||
1122 | if (AdrType != ModNone) |
||
1123 | { |
||
1124 | BAsmCode[2] = AdrVals[0]; |
||
1125 | DecodeAdr(&ArgStr[1], MModImm); |
||
1126 | if (AdrType != ModNone) |
||
1127 | { |
||
1128 | BAsmCode[0] = 0x70; |
||
1129 | BAsmCode[1] = AdrVals[0]; |
||
1130 | CodeLen = 3; |
||
1131 | } |
||
1132 | } |
||
1133 | } |
||
1134 | } |
||
1135 | |||
1136 | static void DecodeLDST(Word Code) |
||
1137 | { |
||
1138 | UNUSED(Code); |
||
1139 | |||
1140 | if (ChkArgCnt(1, 1)) |
||
1141 | { |
||
1142 | DecodeAdr(&ArgStr[1], MModImm); |
||
1143 | if (AdrType != ModNone) |
||
1144 | { |
||
1145 | BAsmCode[0] = 0xf0; |
||
1146 | BAsmCode[1] = AdrVals[0]; |
||
1147 | CodeLen = 2; |
||
1148 | } |
||
1149 | } |
||
1150 | } |
||
1151 | |||
1152 | static void DecodeTRAP(Word Code) |
||
1153 | { |
||
1154 | UNUSED(Code); |
||
1155 | |||
1156 | if (ChkArgCnt(1, 1)) |
||
1157 | { |
||
1158 | Boolean OK; |
||
1159 | |||
1160 | BAsmCode[0] = EvalStrIntExpression(&ArgStr[1], Int4, &OK); |
||
1161 | if (OK) |
||
1162 | { |
||
1163 | BAsmCode[0] = 0xef - BAsmCode[0]; |
||
1164 | CodeLen = 1; |
||
1165 | } |
||
1166 | } |
||
1167 | } |
||
1168 | |||
1169 | static void DecodeTST(Word Code) |
||
1170 | { |
||
1171 | UNUSED(Code); |
||
1172 | |||
1173 | if (ChkArgCnt(1, 1)) |
||
1174 | { |
||
1175 | DecodeAdr(&ArgStr[1], MModAccA + MModAccB); |
||
1176 | switch (AdrType) |
||
1177 | { |
||
1178 | case ModAccA: |
||
1179 | BAsmCode[0] = 0xb0; |
||
1180 | CodeLen = 1; |
||
1181 | break; |
||
1182 | case ModAccB: |
||
1183 | BAsmCode[0] = 0xc6; |
||
1184 | CodeLen = 1; |
||
1185 | break; |
||
1186 | } |
||
1187 | } |
||
1188 | } |
||
1189 | |||
1190 | /****************************************************************************/ |
||
1191 | |||
1192 | static void InitFixed(const char *NName, Word NCode) |
||
1193 | { |
||
1194 | AddInstTable(InstTable, NName, NCode, DecodeFixed); |
||
1195 | } |
||
1196 | |||
1197 | static void InitRel8(const char *NName, Word NCode) |
||
1198 | { |
||
1199 | AddInstTable(InstTable, NName, NCode, DecodeRel8); |
||
1200 | } |
||
1201 | |||
1202 | static void InitALU1(const char *NName, Word NCode) |
||
1203 | { |
||
1204 | AddInstTable(InstTable, NName, NCode, DecodeALU1); |
||
1205 | } |
||
1206 | |||
1207 | static void InitALU2(const char *NName, Word NCode) |
||
1208 | { |
||
1209 | AddInstTable(InstTable, NName, NCode, DecodeALU2); |
||
1210 | } |
||
1211 | |||
1212 | static void InitJmp(const char *NName, Word NCode) |
||
1213 | { |
||
1214 | AddInstTable(InstTable, NName, NCode, DecodeJmp); |
||
1215 | } |
||
1216 | |||
1217 | static void InitABReg(const char *NName, Word NCode) |
||
1218 | { |
||
1219 | AddInstTable(InstTable, NName, NCode, DecodeABReg); |
||
1220 | } |
||
1221 | |||
1222 | static void InitBit(const char *NName, Word NCode) |
||
1223 | { |
||
1224 | AddInstTable(InstTable, NName, NCode, DecodeBit); |
||
1225 | } |
||
1226 | |||
1227 | static void InitFields(void) |
||
1228 | { |
||
1229 | InstTable = CreateInstTable(203); |
||
1230 | |||
1231 | add_null_pseudo(InstTable); |
||
1232 | |||
1233 | AddInstTable(InstTable, "MOV", 0, DecodeMOV); |
||
1234 | AddInstTable(InstTable, "MOVW", 0, DecodeMOVW); |
||
1235 | AddInstTable(InstTable, "CMP", 0, DecodeCMP); |
||
1236 | AddInstTable(InstTable, "DIV", 0, DecodeDIV); |
||
1237 | AddInstTable(InstTable, "INCW", 0, DecodeINCW); |
||
1238 | AddInstTable(InstTable, "LDST", 0, DecodeLDST); |
||
1239 | AddInstTable(InstTable, "TRAP", 0, DecodeTRAP); |
||
1240 | AddInstTable(InstTable, "TST", 0, DecodeTST); |
||
1241 | AddInstTable(InstTable, "DBIT", 0, DecodeDBIT); |
||
1242 | |||
1243 | InitFixed("CLRC" , 0x00b0); InitFixed("DINT" , 0xf000); |
||
1244 | InitFixed("EINT" , 0xf00c); InitFixed("EINTH", 0xf004); |
||
1245 | InitFixed("EINTL", 0xf008); InitFixed("IDLE" , 0x00f6); |
||
1246 | InitFixed("LDSP" , 0x00fd); InitFixed("NOP" , 0x00ff); |
||
1247 | InitFixed("RTI" , 0x00fa); InitFixed("RTS" , 0x00f9); |
||
1248 | InitFixed("SETC" , 0x00f8); InitFixed("STSP" , 0x00fe); |
||
1249 | |||
1250 | InitRel8("JMP", 0x00); InitRel8("JC" , 0x03); InitRel8("JEQ", 0x02); |
||
1251 | InitRel8("JG" , 0x0e); InitRel8("JGE", 0x0d); InitRel8("JHS", 0x0b); |
||
1252 | InitRel8("JL" , 0x09); InitRel8("JLE", 0x0a); InitRel8("JLO", 0x0f); |
||
1253 | InitRel8("JN" , 0x01); InitRel8("JNC", 0x07); InitRel8("JNE", 0x06); |
||
1254 | InitRel8("JNV", 0x0c); InitRel8("JNZ", 0x06); InitRel8("JP" , 0x04); |
||
1255 | InitRel8("JPZ", 0x05); InitRel8("JV" , 0x08); InitRel8("JZ" , 0x02); |
||
1256 | |||
1257 | InitALU1("ADC", 9); InitALU1("ADD", 8); |
||
1258 | InitALU1("DAC", 14); InitALU1("DSB", 15); |
||
1259 | InitALU1("SBB", 11); InitALU1("SUB", 10); InitALU1("MPY", 12); |
||
1260 | |||
1261 | InitALU2("AND" , 3); InitALU2("BTJO", 0x0106); |
||
1262 | InitALU2("BTJZ", 0x0107); InitALU2("OR" , 4); InitALU2("XOR", 5); |
||
1263 | |||
1264 | InitJmp("BR" , 12); InitJmp("CALL" , 14); |
||
1265 | InitJmp("JMPL", 0x0109); InitJmp("CALLR", 0x010f); |
||
1266 | |||
1267 | InitABReg("CLR" , 5); InitABReg("COMPL", 11); InitABReg("DEC" , 2); |
||
1268 | InitABReg("INC" , 3); InitABReg("INV" , 4); InitABReg("POP" , 0x0209); |
||
1269 | InitABReg("PUSH" , 0x0208); InitABReg("RL" , 14); InitABReg("RLC" , 15); |
||
1270 | InitABReg("RR" , 12); InitABReg("RRC" , 13); InitABReg("SWAP" , 7); |
||
1271 | InitABReg("XCHB" , 6); InitABReg("DJNZ" , 0x010a); |
||
1272 | |||
1273 | InitBit("CMPBIT", 5); InitBit("JBIT0" , 0x0107); InitBit("JBIT1" , 0x0106); |
||
1274 | InitBit("SBIT0" , 3); InitBit("SBIT1" , 4); |
||
1275 | |||
1276 | AddIntelPseudo(InstTable, eIntPseudoFlag_BigEndian); |
||
1277 | } |
||
1278 | |||
1279 | static void DeinitFields(void) |
||
1280 | { |
||
1281 | DestroyInstTable(InstTable); |
||
1282 | } |
||
1283 | |||
1284 | /****************************************************************************/ |
||
1285 | |||
1286 | static void MakeCode_370(void) |
||
1287 | { |
||
1288 | OpSize = 0; |
||
1289 | |||
1290 | if (!LookupInstTable(InstTable, OpPart.str.p_str)) |
||
1291 | WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart); |
||
1292 | } |
||
1293 | |||
1294 | static Boolean IsDef_370(void) |
||
1295 | { |
||
1296 | return (Memo("DBIT")); |
||
1297 | } |
||
1298 | |||
1299 | static void InternSymbol_370(char *Asc, TempResult *Erg) |
||
1300 | { |
||
1301 | Boolean OK; |
||
1302 | String h; |
||
1303 | LargeInt Num; |
||
1304 | |||
1305 | as_tempres_set_none(Erg); |
||
1306 | if ((strlen(Asc) < 2) || ((as_toupper(*Asc) != 'R') && (as_toupper(*Asc) != 'P'))) |
||
1307 | return; |
||
1308 | |||
1309 | strcpy(h, Asc + 1); |
||
1310 | if ((*h == '0') && (strlen(h) > 1)) |
||
1311 | *h = '$'; |
||
1312 | Num = ConstLongInt(h, &OK, 10); |
||
1313 | if (!OK || (Num < 0) || (Num > 255)) |
||
1314 | return; |
||
1315 | |||
1316 | if (as_toupper(*Asc) == 'P') |
||
1317 | Num += 0x1000; |
||
1318 | as_tempres_set_int(Erg, Num); |
||
1319 | } |
||
1320 | |||
1321 | static void SwitchFrom_370(void) |
||
1322 | { |
||
1323 | DeinitFields(); |
||
1324 | } |
||
1325 | |||
1326 | static void SwitchTo_370(void) |
||
1327 | { |
||
1328 | TurnWords = False; |
||
1329 | SetIntConstMode(eIntConstModeIntel); |
||
1330 | |||
1331 | PCSymbol = "$"; |
||
1332 | HeaderID = 0x49; |
||
1333 | NOPCode = 0xff; |
||
1334 | DivideChars = ","; |
||
1335 | HasAttrs = False; |
||
1336 | |||
1337 | ValidSegs = 1 << SegCode; |
||
1338 | Grans[SegCode ] = 1; |
||
1339 | ListGrans[SegCode ] = 1; |
||
1340 | SegInits[SegCode ] = 0; |
||
1341 | SegLimits[SegCode] = 0xffff; |
||
1342 | |||
1343 | MakeCode = MakeCode_370; |
||
1344 | IsDef = IsDef_370; |
||
1345 | SwitchFrom = SwitchFrom_370; |
||
1346 | InternSymbol = InternSymbol_370; |
||
1347 | DissectBit = DissectBit_370; |
||
1348 | |||
1349 | InitFields(); |
||
1350 | } |
||
1351 | |||
1352 | void code370_init(void) |
||
1353 | { |
||
1354 | CPU37010 = AddCPU("370C010" , SwitchTo_370); |
||
1355 | CPU37020 = AddCPU("370C020" , SwitchTo_370); |
||
1356 | CPU37030 = AddCPU("370C030" , SwitchTo_370); |
||
1357 | CPU37040 = AddCPU("370C040" , SwitchTo_370); |
||
1358 | CPU37050 = AddCPU("370C050" , SwitchTo_370); |
||
1359 | } |