1 /* code78c10.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* Codegenerator NEC uPD78(C)1x */
8 /* */
9 /*****************************************************************************/
10
11 #include "stdinc.h"
12 #include <ctype.h>
13 #include <string.h>
14
15 #include "bpemu.h"
16 #include "strutil.h"
17 #include "asmdef.h"
18 #include "asmsub.h"
19 #include "asmpars.h"
20 #include "asmitree.h"
21 #include "codepseudo.h"
22 #include "intpseudo.h"
23 #include "codevars.h"
24 #include "errmsg.h"
25
26 #include "code78c10.h"
27
28 /*---------------------------------------------------------------------------*/
29
30 typedef struct
31 {
32 const char *Name;
33 Byte Code;
34 } SReg;
35
36 typedef struct
37 {
38 const char *pName;
39 Byte Code;
40 Byte MayIndirect;
41 } tAdrMode;
42
43 #define SRegCnt 28
44
45
46 static LongInt WorkArea;
47
48 static CPUVar CPU7810, CPU78C10;
49
50 static SReg *SRegs;
51
52 static ASSUMERec ASSUME78C10s[] =
53 {
54 {"V" , &WorkArea, 0, 0xff, 0x100, NULL}
55 };
56
57 /*--------------------------------------------------------------------------------*/
58
Decode_r(char * Asc,ShortInt * Erg)59 static Boolean Decode_r(char *Asc, ShortInt *Erg)
60 {
61 static const char Names[] = "VABCDEHL";
62 const char *p;
63
64 if (strlen(Asc) != 1) return False;
65 p = strchr(Names, as_toupper(*Asc));
66 if (!p) return False;
67 *Erg = p - Names;
68 return True;
69 }
70
Decode_r1(char * Asc,ShortInt * Erg)71 static Boolean Decode_r1(char *Asc, ShortInt *Erg)
72 {
73 if (!as_strcasecmp(Asc, "EAL")) *Erg = 1;
74 else if (!as_strcasecmp(Asc, "EAH")) *Erg = 0;
75 else
76 {
77 if (!Decode_r(Asc, Erg)) return False;
78 return (*Erg > 1);
79 }
80 return True;
81 }
82
Decode_r2(char * Asc,ShortInt * Erg)83 static Boolean Decode_r2(char *Asc, ShortInt *Erg)
84 {
85 if (!Decode_r(Asc, Erg)) return False;
86 return ((*Erg > 0) && (*Erg < 4));
87 }
88
Decode_rp2(char * Asc,ShortInt * Erg)89 static Boolean Decode_rp2(char *Asc, ShortInt *Erg)
90 {
91 static const SReg Regs[] =
92 {
93 { "SP" , 0 },
94 { "B" , 1 },
95 { "BC" , 1 },
96 { "D" , 2 },
97 { "DE" , 2 },
98 { "H" , 3 },
99 { "HL" , 3 },
100 { "EA" , 4 },
101 { NULL , 0 },
102 };
103
104 for (*Erg = 0; Regs[*Erg].Name; (*Erg)++)
105 if (!as_strcasecmp(Asc, Regs[*Erg].Name))
106 {
107 *Erg = Regs[*Erg].Code;
108 return True;
109 }
110 return False;
111 }
112
Decode_rp(char * Asc,ShortInt * Erg)113 static Boolean Decode_rp(char *Asc, ShortInt *Erg)
114 {
115 if (!Decode_rp2(Asc, Erg)) return False;
116 return (*Erg < 4);
117 }
118
Decode_rp1(char * Asc,ShortInt * Erg)119 static Boolean Decode_rp1(char *Asc, ShortInt *Erg)
120 {
121 if (!as_strcasecmp(Asc, "V")) *Erg = 0;
122 else
123 {
124 if (!Decode_rp2(Asc, Erg)) return False;
125 return (*Erg != 0);
126 }
127 return True;
128 }
129
Decode_rp3(char * Asc,ShortInt * Erg)130 static Boolean Decode_rp3(char *Asc, ShortInt *Erg)
131 {
132 if (!Decode_rp2(Asc, Erg)) return False;
133 return ((*Erg < 4) && (*Erg > 0));
134 }
135
DecodeAdrMode(char * pAsc,const tAdrMode pModes[],ShortInt * pErg,Boolean * pWasIndirect)136 static Boolean DecodeAdrMode(char *pAsc, const tAdrMode pModes[],
137 ShortInt *pErg, Boolean *pWasIndirect)
138 {
139 int z;
140
141 if (!*pWasIndirect && (IsIndirect(pAsc)))
142 {
143 strmov(pAsc, pAsc + 1);
144 pAsc[strlen(pAsc) - 1] = '\0';
145 *pWasIndirect = True;
146 }
147
148 for (z = 0; pModes[z].pName; z++)
149 {
150 if (*pWasIndirect && !pModes[z].MayIndirect)
151 continue;
152 if (!as_strcasecmp(pAsc, pModes[z].pName))
153 {
154 *pErg = pModes[z].Code;
155 return True;
156 }
157 }
158 return False;
159 }
160
Decode_rpa2(const tStrComp * pArg,Boolean * pWasIndirect,ShortInt * Erg,ShortInt * Disp)161 static Boolean Decode_rpa2(const tStrComp *pArg, Boolean *pWasIndirect, ShortInt *Erg, ShortInt *Disp)
162 {
163 static const tAdrMode AdrModes[] =
164 {
165 { "B" , 1 , True },
166 { "BC" , 1 , True },
167 { "D" , 2 , True },
168 { "DE" , 2 , True },
169 { "H" , 3 , True },
170 { "HL" , 3 , True },
171 { "D+" , 4 , True },
172 { "DE+" , 4 , True },
173 { "(DE)+", 4 , False },
174 { "H+" , 5 , True },
175 { "HL+" , 5 , True },
176 { "(HL)+", 5 , False },
177 { "D-" , 6 , True },
178 { "DE-" , 6 , True },
179 { "(DE)-", 6 , False },
180 { "H-" , 7 , True },
181 { "HL-" , 7 , True },
182 { "(HL)-", 7 , False },
183 { "H+A" , 12 , True },
184 { "HL+A" , 12 , True },
185 { "A+H" , 12 , True },
186 { "A+HL" , 12 , True },
187 { "H+B" , 13 , True },
188 { "HL+B" , 13 , True },
189 { "B+H" , 13 , True },
190 { "B+HL" , 13 , True },
191 { "H+EA" , 14 , True },
192 { "HL+EA", 14 , True },
193 { "EA+H" , 14 , True },
194 { "EA+HL", 14 , True },
195 { NULL , 0 , False },
196 };
197
198 char *p, Save;
199 Boolean OK;
200 ShortInt BaseReg;
201 tStrComp Left, Right;
202
203 if (DecodeAdrMode(pArg->Str, AdrModes, Erg, pWasIndirect))
204 {
205 *Disp = 0;
206 return True;
207 }
208
209 p = QuotMultPos(pArg->Str, "+-");
210 if (!p) return False;
211
212 Save = StrCompSplitRef(&Left, &Right, pArg, p);
213 OK = (Decode_rp2(Left.Str, &BaseReg));
214 *p = Save;
215 if (!OK || ((BaseReg != 2) && (BaseReg != 3)))
216 return False;
217 *Erg = (BaseReg == 3) ? 15 : 11;
218 *Disp = EvalStrIntExpressionOffs(pArg, p - pArg->Str, SInt8, &OK);
219 return OK;
220 }
221
Decode_rpa(const tStrComp * pArg,ShortInt * Erg)222 static Boolean Decode_rpa(const tStrComp *pArg, ShortInt *Erg)
223 {
224 ShortInt Dummy;
225 Boolean WasIndirect = False;
226
227 if (!Decode_rpa2(pArg, &WasIndirect, Erg, &Dummy)) return False;
228 return (*Erg <= 7);
229 }
230
Decode_rpa1(const tStrComp * pArg,ShortInt * Erg)231 static Boolean Decode_rpa1(const tStrComp *pArg, ShortInt *Erg)
232 {
233 ShortInt Dummy;
234 Boolean WasIndirect = False;
235
236 if (!Decode_rpa2(pArg, &WasIndirect, Erg, &Dummy)) return False;
237 return (*Erg <= 3);
238 }
239
Decode_rpa3(const tStrComp * pArg,ShortInt * Erg,ShortInt * Disp)240 static Boolean Decode_rpa3(const tStrComp *pArg, ShortInt *Erg, ShortInt *Disp)
241 {
242 static const tAdrMode AdrModes[] =
243 {
244 { "D++" , 4 , True },
245 { "DE++" , 4 , True },
246 { "(DE)++", 4 , False },
247 { "H++" , 5 , True },
248 { "HL++" , 5 , True },
249 { "(HL)++", 5 , False },
250 { NULL , 0 , False },
251 };
252 Boolean WasIndirect = False;
253
254 if (DecodeAdrMode(pArg->Str, AdrModes, Erg, &WasIndirect))
255 {
256 *Disp = 0;
257 return True;
258 }
259
260 if (!Decode_rpa2(pArg, &WasIndirect, Erg, Disp))
261 return False;
262 return ((*Erg == 2) || (*Erg == 3) || (*Erg >= 8));
263 }
264
Decode_f(char * Asc,ShortInt * Erg)265 static Boolean Decode_f(char *Asc, ShortInt *Erg)
266 {
267 #define FlagCnt 3
268 static const char Flags[FlagCnt][3] = {"CY", "HC", "Z"};
269
270 for (*Erg = 0; *Erg < FlagCnt; (*Erg)++)
271 if (!as_strcasecmp(Flags[*Erg], Asc)) break;
272 *Erg += 2; return (*Erg <= 4);
273 }
274
Decode_sr0(char * Asc,ShortInt * Erg)275 static Boolean Decode_sr0(char *Asc, ShortInt *Erg)
276 {
277 int z;
278
279 for (z = 0; z < SRegCnt; z++)
280 if (!as_strcasecmp(Asc, SRegs[z].Name)) break;
281 if ((z == SRegCnt-1) && (MomCPU == CPU7810))
282 {
283 WrError(ErrNum_InvCtrlReg); return False;
284 }
285 if (z < SRegCnt)
286 {
287 *Erg = SRegs[z].Code; return True;
288 }
289 else return False;
290 }
291
Decode_sr1(char * Asc,ShortInt * Erg)292 static Boolean Decode_sr1(char *Asc, ShortInt *Erg)
293 {
294 if (!Decode_sr0(Asc, Erg)) return False;
295 return (((*Erg >= 0) && (*Erg <= 9)) || (*Erg == 11) || (*Erg == 13) || (*Erg == 25) || ((*Erg >= 32) && (*Erg <= 35)));
296 }
297
Decode_sr(char * Asc,ShortInt * Erg)298 static Boolean Decode_sr(char *Asc, ShortInt *Erg)
299 {
300 if (!Decode_sr0(Asc, Erg)) return False;
301 return (((*Erg >= 0) && (*Erg <= 24)) || (*Erg == 26) || (*Erg == 27) || (*Erg == 40));
302 }
303
Decode_sr2(char * Asc,ShortInt * Erg)304 static Boolean Decode_sr2(char *Asc, ShortInt *Erg)
305 {
306 if (!Decode_sr0(Asc, Erg)) return False;
307 return (((*Erg >= 0) && (*Erg <= 9)) || (*Erg == 11) || (*Erg == 13));
308 }
309
Decode_sr3(char * Asc,ShortInt * Erg)310 static Boolean Decode_sr3(char *Asc, ShortInt *Erg)
311 {
312 if (!as_strcasecmp(Asc, "ETM0")) *Erg = 0;
313 else if (!as_strcasecmp(Asc, "ETM1")) *Erg = 1;
314 else return False;
315 return True;
316 }
317
Decode_sr4(char * Asc,ShortInt * Erg)318 static Boolean Decode_sr4(char *Asc, ShortInt *Erg)
319 {
320 if (!as_strcasecmp(Asc, "ECNT")) *Erg = 0;
321 else if (!as_strcasecmp(Asc, "ECPT")) *Erg = 1;
322 else return False;
323 return True;
324 }
325
Decode_irf(char * Asc,ShortInt * Erg)326 static Boolean Decode_irf(char *Asc, ShortInt *Erg)
327 {
328 #undef FlagCnt
329 #define FlagCnt 18
330 static const char FlagNames[FlagCnt][5] =
331 { "NMI" , "FT0" , "FT1" , "F1" , "F2" , "FE0" ,
332 "FE1" , "FEIN", "FAD" , "FSR" , "FST" , "ER" ,
333 "OV" , "AN4" , "AN5" , "AN6" , "AN7" , "SB" };
334 static const ShortInt FlagCodes[FlagCnt] =
335 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16, 17, 18, 19, 20 };
336
337 for (*Erg = 0; *Erg < FlagCnt; (*Erg)++)
338 if (!as_strcasecmp(FlagNames[*Erg], Asc)) break;
339 if (*Erg >= FlagCnt) return False;
340 *Erg = FlagCodes[*Erg];
341 return True;
342 }
343
Decode_wa(const tStrComp * pArg,Byte * Erg)344 static Boolean Decode_wa(const tStrComp *pArg, Byte *Erg)
345 {
346 Word Adr;
347 Boolean OK;
348 tSymbolFlags Flags;
349
350 Adr = EvalStrIntExpressionWithFlags(pArg, Int16, &OK, &Flags);
351 if (!OK) return False;
352 if (!mFirstPassUnknown(Flags) && (Hi(Adr) != WorkArea)) WrError(ErrNum_InAccPage);
353 *Erg = Lo(Adr);
354 return True;
355 }
356
HasDisp(ShortInt Mode)357 static Boolean HasDisp(ShortInt Mode)
358 {
359 return ((Mode & 11) == 11);
360 }
361
362 /*--------------------------------------------------------------------------------*/
363
DecodeFixed(Word Code)364 static void DecodeFixed(Word Code)
365 {
366 if (ChkArgCnt(0, 0))
367 {
368 CodeLen = 0;
369 if (Hi(Code) != 0)
370 BAsmCode[CodeLen++] = Hi(Code);
371 BAsmCode[CodeLen++] = Lo(Code);
372 }
373 }
374
DecodeMOV(Word Code)375 static void DecodeMOV(Word Code)
376 {
377 Boolean OK;
378 ShortInt HReg;
379 Integer AdrInt;
380
381 UNUSED(Code);
382
383 if (!ChkArgCnt(2, 2));
384 else if (!as_strcasecmp(ArgStr[1].Str, "A"))
385 {
386 if (Decode_sr1(ArgStr[2].Str, &HReg))
387 {
388 CodeLen = 2;
389 BAsmCode[0] = 0x4c;
390 BAsmCode[1] = 0xc0 + HReg;
391 }
392 else if (Decode_r1(ArgStr[2].Str, &HReg))
393 {
394 CodeLen = 1;
395 BAsmCode[0] = 0x08 + HReg;
396 }
397 else
398 {
399 AdrInt = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
400 if (OK)
401 {
402 CodeLen = 4;
403 BAsmCode[0] = 0x70;
404 BAsmCode[1] = 0x69;
405 BAsmCode[2] = Lo(AdrInt);
406 BAsmCode[3] = Hi(AdrInt);
407 }
408 }
409 }
410 else if (!as_strcasecmp(ArgStr[2].Str, "A"))
411 {
412 if (Decode_sr(ArgStr[1].Str, &HReg))
413 {
414 CodeLen = 2;
415 BAsmCode[0] = 0x4d;
416 BAsmCode[1] = 0xc0 + HReg;
417 }
418 else if (Decode_r1(ArgStr[1].Str, &HReg))
419 {
420 CodeLen = 1;
421 BAsmCode[0] = 0x18 + HReg;
422 }
423 else
424 {
425 AdrInt = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
426 if (OK)
427 {
428 CodeLen = 4;
429 BAsmCode[0] = 0x70;
430 BAsmCode[1] = 0x79;
431 BAsmCode[2] = Lo(AdrInt);
432 BAsmCode[3] = Hi(AdrInt);
433 }
434 }
435 }
436 else if (Decode_r(ArgStr[1].Str, &HReg))
437 {
438 AdrInt = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
439 if (OK)
440 {
441 CodeLen = 4;
442 BAsmCode[0] = 0x70;
443 BAsmCode[1] = 0x68 + HReg;
444 BAsmCode[2] = Lo(AdrInt);
445 BAsmCode[3] = Hi(AdrInt);
446 }
447 }
448 else if (Decode_r(ArgStr[2].Str, &HReg))
449 {
450 AdrInt = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
451 if (OK)
452 {
453 CodeLen = 4;
454 BAsmCode[0] = 0x70;
455 BAsmCode[1] = 0x78 + HReg;
456 BAsmCode[2] = Lo(AdrInt);
457 BAsmCode[3] = Hi(AdrInt);
458 }
459 }
460 else
461 WrError(ErrNum_InvAddrMode);
462 }
463
DecodeMVI(Word Code)464 static void DecodeMVI(Word Code)
465 {
466 UNUSED(Code);
467
468 if (ChkArgCnt(2, 2))
469 {
470 ShortInt HReg;
471 Boolean OK;
472
473 BAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
474 if (OK)
475 {
476 if (Decode_r(ArgStr[1].Str, &HReg))
477 {
478 CodeLen = 2;
479 BAsmCode[0] = 0x68 + HReg;
480 }
481 else if (Decode_sr2(ArgStr[1].Str, &HReg))
482 {
483 CodeLen = 3;
484 BAsmCode[2] = BAsmCode[1];
485 BAsmCode[0] = 0x64;
486 BAsmCode[1] = (HReg & 7) + ((HReg & 8) << 4);
487 }
488 else WrError(ErrNum_InvAddrMode);
489 }
490 }
491 }
492
DecodeMVIW(Word Code)493 static void DecodeMVIW(Word Code)
494 {
495 Boolean OK;
496
497 UNUSED(Code);
498
499 if (!ChkArgCnt(2, 2));
500 else if (Decode_wa(&ArgStr[1], BAsmCode + 1))
501 {
502 BAsmCode[2] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
503 if (OK)
504 {
505 CodeLen = 3;
506 BAsmCode[0] = 0x71;
507 }
508 }
509 }
510
DecodeMVIX(Word Code)511 static void DecodeMVIX(Word Code)
512 {
513 Boolean OK;
514 ShortInt HReg;
515
516 UNUSED(Code);
517
518 if (!ChkArgCnt(2, 2));
519 else if (!Decode_rpa1(&ArgStr[1], &HReg)) WrError(ErrNum_InvAddrMode);
520 else
521 {
522 BAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
523 if (OK)
524 {
525 BAsmCode[0] = 0x48 + HReg;
526 CodeLen = 2;
527 }
528 }
529 }
530
DecodeLDAX_STAX(Word Code)531 static void DecodeLDAX_STAX(Word Code)
532 {
533 ShortInt HReg;
534 Boolean WasIndirect = False;
535
536 if (!ChkArgCnt(1, 1));
537 else if (!Decode_rpa2(&ArgStr[1], &WasIndirect, &HReg, (ShortInt *) BAsmCode + 1)) WrError(ErrNum_InvAddrMode);
538 else
539 {
540 CodeLen = 1 + Ord(HasDisp(HReg));
541 BAsmCode[0] = Code + ((HReg & 8) << 4) + (HReg & 7);
542 }
543 }
544
DecodeLDEAX_STEAX(Word Code)545 static void DecodeLDEAX_STEAX(Word Code)
546 {
547 ShortInt HReg;
548
549 if (!ChkArgCnt(1, 1));
550 else if (!Decode_rpa3(&ArgStr[1], &HReg, (ShortInt *) BAsmCode + 2)) WrError(ErrNum_InvAddrMode);
551 else
552 {
553 CodeLen = 2 + Ord(HasDisp(HReg));
554 BAsmCode[0] = 0x48;
555 BAsmCode[1] = Code + HReg;
556 }
557 }
558
DecodeLXI(Word Code)559 static void DecodeLXI(Word Code)
560 {
561 ShortInt HReg;
562 Integer AdrInt;
563 Boolean OK;
564
565 UNUSED(Code);
566
567 if (!ChkArgCnt(2, 2));
568 else if (!Decode_rp2(ArgStr[1].Str, &HReg)) WrError(ErrNum_InvAddrMode);
569 else
570 {
571 AdrInt = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
572 if (OK)
573 {
574 CodeLen = 3;
575 BAsmCode[0] = 0x04 + (HReg << 4);
576 BAsmCode[1] = Lo(AdrInt);
577 BAsmCode[2] = Hi(AdrInt);
578 }
579 }
580 }
581
DecodePUSH_POP(Word Code)582 static void DecodePUSH_POP(Word Code)
583 {
584 ShortInt HReg;
585
586 if (!ChkArgCnt(1, 1));
587 else if (!Decode_rp1(ArgStr[1].Str, &HReg)) WrError(ErrNum_InvAddrMode);
588 else
589 {
590 CodeLen = 1;
591 BAsmCode[0] = Code + HReg;
592 }
593 }
594
DecodeDMOV(Word Code)595 static void DecodeDMOV(Word Code)
596 {
597 ShortInt HReg;
598
599 UNUSED(Code);
600
601 if (ChkArgCnt(2, 2))
602 {
603 Boolean Swap = as_strcasecmp(ArgStr[1].Str, "EA") || False;
604 char *pArg1 = Swap ? ArgStr[2].Str : ArgStr[1].Str,
605 *pArg2 = Swap ? ArgStr[1].Str : ArgStr[2].Str;
606
607 if (as_strcasecmp(pArg1, "EA")) WrError(ErrNum_InvAddrMode);
608 else if (Decode_rp3(pArg2, &HReg))
609 {
610 CodeLen = 1;
611 BAsmCode[0] = 0xa4 + HReg;
612 if (Swap)
613 BAsmCode[0] += 0x10;
614 }
615 else if (((Swap) && (Decode_sr3(pArg2, &HReg)))
616 || ((!Swap) && (Decode_sr4(pArg2, &HReg))))
617 {
618 CodeLen = 2;
619 BAsmCode[0] = 0x48;
620 BAsmCode[1] = 0xc0 + HReg;
621 if (Swap)
622 BAsmCode[1] += 0x12;
623 }
624 else
625 WrError(ErrNum_InvAddrMode);
626 }
627 }
628
DecodeALUImm(Word Code)629 static void DecodeALUImm(Word Code)
630 {
631 ShortInt HVal8, HReg;
632 Boolean OK;
633
634 if (ChkArgCnt(2, 2))
635 {
636 HVal8 = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
637 if (OK)
638 {
639 if (!as_strcasecmp(ArgStr[1].Str, "A"))
640 {
641 CodeLen = 2;
642 BAsmCode[0] = 0x06 + ((Code & 14) << 3) + (Code & 1);
643 BAsmCode[1] = HVal8;
644 }
645 else if (Decode_r(ArgStr[1].Str, &HReg))
646 {
647 CodeLen = 3;
648 BAsmCode[0] = 0x74;
649 BAsmCode[2] = HVal8;
650 BAsmCode[1] = HReg + (Code << 3);
651 }
652 else if (Decode_sr2(ArgStr[1].Str, &HReg))
653 {
654 CodeLen = 3;
655 BAsmCode[0] = 0x64;
656 BAsmCode[2] = HVal8;
657 BAsmCode[1] = (HReg & 7) + (Code << 3) + ((HReg & 8) << 4);
658 }
659 else WrError(ErrNum_InvAddrMode);
660 }
661 }
662 }
663
DecodeALUReg(Word Code)664 static void DecodeALUReg(Word Code)
665 {
666 ShortInt HReg;
667
668 if (ChkArgCnt(2, 2))
669 {
670 Boolean NoSwap = !as_strcasecmp(ArgStr[1].Str, "A");
671 char *pArg1 = NoSwap ? ArgStr[1].Str : ArgStr[2].Str,
672 *pArg2 = NoSwap ? ArgStr[2].Str : ArgStr[1].Str;
673
674 if (as_strcasecmp(pArg1, "A")) WrError(ErrNum_InvAddrMode);
675 else if (!Decode_r(pArg2, &HReg)) WrError(ErrNum_InvAddrMode);
676 else
677 {
678 CodeLen = 2;
679 BAsmCode[0] = 0x60;
680 BAsmCode[1] = (Code << 3) + HReg;
681 if ((NoSwap) || (Memo("ONA")) || (Memo("OFFA")))
682 BAsmCode[1] += 0x80;
683 }
684 }
685 }
686
DecodeALURegW(Word Code)687 static void DecodeALURegW(Word Code)
688 {
689 if (!ChkArgCnt(1, 1));
690 else if (Decode_wa(&ArgStr[1], BAsmCode + 2))
691 {
692 CodeLen = 3;
693 BAsmCode[0] = 0x74;
694 BAsmCode[1] = 0x80 + (Code << 3);
695 }
696 }
697
DecodeALURegX(Word Code)698 static void DecodeALURegX(Word Code)
699 {
700 ShortInt HReg;
701
702 if (!ChkArgCnt(1, 1));
703 else if (!Decode_rpa(&ArgStr[1], &HReg)) WrError(ErrNum_InvAddrMode);
704 else
705 {
706 CodeLen = 2;
707 BAsmCode[0] = 0x70;
708 BAsmCode[1] = 0x80 + (Code << 3) + HReg;
709 }
710 }
711
DecodeALUEA(Word Code)712 static void DecodeALUEA(Word Code)
713 {
714 ShortInt HReg;
715
716 if (!ChkArgCnt(2, 2));
717 else if (as_strcasecmp(ArgStr[1].Str, "EA")) WrError(ErrNum_InvAddrMode);
718 else if (!Decode_rp3(ArgStr[2].Str, &HReg)) WrError(ErrNum_InvAddrMode);
719 else
720 {
721 CodeLen = 2;
722 BAsmCode[0] = 0x74;
723 BAsmCode[1] = 0x84 + (Code << 3) + HReg;
724 }
725 }
726
DecodeALUImmW(Word Code)727 static void DecodeALUImmW(Word Code)
728 {
729 Boolean OK;
730
731 if (!ChkArgCnt(2, 2));
732 else if (Decode_wa(&ArgStr[1], BAsmCode + 1))
733 {
734 BAsmCode[2] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
735 if (OK)
736 {
737 CodeLen = 3;
738 BAsmCode[0] = 0x05 + ((Code >> 1) << 4);
739 }
740 }
741 }
742
DecodeAbs(Word Code)743 static void DecodeAbs(Word Code)
744 {
745 if (!ChkArgCnt(1, 1));
746 else
747 {
748 Boolean OK;
749 Integer AdrInt;
750
751 AdrInt = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
752 if (OK)
753 {
754 CodeLen = 0;
755 if (Hi(Code) != 0)
756 BAsmCode[CodeLen++] = Hi(Code);
757 BAsmCode[CodeLen++] = Lo(Code);
758 BAsmCode[CodeLen++] = Lo(AdrInt);
759 BAsmCode[CodeLen++] = Hi(AdrInt);
760 }
761 }
762 }
763
DecodeReg2(Word Code)764 static void DecodeReg2(Word Code)
765 {
766 ShortInt HReg;
767
768 if (!ChkArgCnt(1, 1));
769 else if (!Decode_r2(ArgStr[1].Str, &HReg)) WrError(ErrNum_InvAddrMode);
770 else
771 {
772 CodeLen = 0;
773 if (Hi(Code) != 0)
774 BAsmCode[CodeLen++] = Hi(Code);
775 BAsmCode[CodeLen++] = Lo(Code) + HReg;
776 }
777 }
778
DecodeWork(Word Code)779 static void DecodeWork(Word Code)
780 {
781 if (ChkArgCnt(1, 1)
782 && Decode_wa(&ArgStr[1], BAsmCode + 1))
783 {
784 CodeLen = 2;
785 BAsmCode[0] = Code;
786 }
787 }
788
DecodeEA(Word Code)789 static void DecodeEA(Word Code)
790 {
791 if (!ChkArgCnt(1, 1));
792 else if (as_strcasecmp(ArgStr[1].Str, "EA")) WrError(ErrNum_InvAddrMode);
793 else
794 {
795 CodeLen = 2;
796 BAsmCode[0] = Hi(Code);
797 BAsmCode[1] = Lo(Code);
798 }
799 return;
800 }
801
DecodeDCX_INX(Word Code)802 static void DecodeDCX_INX(Word Code)
803 {
804 ShortInt HReg;
805
806 if (!ChkArgCnt(1, 1));
807 else if (!as_strcasecmp(ArgStr[1].Str, "EA"))
808 {
809 CodeLen = 1;
810 BAsmCode[0] = 0xa8 + Code;
811 }
812 else if (Decode_rp(ArgStr[1].Str, &HReg))
813 {
814 CodeLen = 1;
815 BAsmCode[0] = 0x02 + Code + (HReg << 4);
816 }
817 else
818 WrError(ErrNum_InvAddrMode);
819 }
820
DecodeEADD_ESUB(Word Code)821 static void DecodeEADD_ESUB(Word Code)
822 {
823 ShortInt HReg;
824
825 if (!ChkArgCnt(2, 2));
826 else if (as_strcasecmp(ArgStr[1].Str, "EA")) WrError(ErrNum_InvAddrMode);
827 else if (!Decode_r2(ArgStr[2].Str, &HReg)) WrError(ErrNum_InvAddrMode);
828 else
829 {
830 CodeLen = 2;
831 BAsmCode[0] = 0x70;
832 BAsmCode[1] = Code + HReg;
833 }
834 }
835
DecodeJ_JR_JRE(Word Type)836 static void DecodeJ_JR_JRE(Word Type)
837 {
838 Boolean OK;
839 Integer AdrInt;
840 tSymbolFlags Flags;
841
842 if (!ChkArgCnt(1, 1))
843 return;
844
845 AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags) - (EProgCounter() + 1);
846 if (!OK)
847 return;
848
849 if (!Type) /* generic J */
850 Type = RangeCheck(AdrInt, SInt6) ? 1 : 2;
851
852 switch (Type)
853 {
854 case 1: /* JR */
855 if (!mSymbolQuestionable(Flags) && !RangeCheck(AdrInt, SInt6)) WrError(ErrNum_JmpDistTooBig);
856 else
857 {
858 CodeLen = 1;
859 BAsmCode[0] = 0xc0 + (AdrInt & 0x3f);
860 }
861 break;
862 case 2:
863 AdrInt--; /* JRE is 2 bytes long */
864 if (!mSymbolQuestionable(Flags) && !RangeCheck(AdrInt, SInt9)) WrError(ErrNum_JmpDistTooBig);
865 else
866 {
867 CodeLen = 2;
868 BAsmCode[0] = 0x4e + (Hi(AdrInt) & 1);
869 BAsmCode[1] = Lo(AdrInt);
870 }
871 break;
872 }
873 }
874
DecodeCALF(Word Code)875 static void DecodeCALF(Word Code)
876 {
877 UNUSED(Code);
878
879 if (ChkArgCnt(1, 1))
880 {
881 Boolean OK;
882 Integer AdrInt;
883 tSymbolFlags Flags;
884
885 AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
886 if (OK)
887 {
888 if (!mFirstPassUnknown(Flags) && ((AdrInt >> 11) != 1)) WrError(ErrNum_NotFromThisAddress);
889 else
890 {
891 CodeLen = 2;
892 BAsmCode[0] = Hi(AdrInt) + 0x70;
893 BAsmCode[1] = Lo(AdrInt);
894 }
895 }
896 }
897 }
898
DecodeCALT(Word Code)899 static void DecodeCALT(Word Code)
900 {
901 UNUSED(Code);
902
903 if (ChkArgCnt(1, 1))
904 {
905 Boolean OK;
906 Integer AdrInt;
907 tSymbolFlags Flags;
908
909 AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
910 if (OK)
911 {
912 if (!mFirstPassUnknown(Flags) && ((AdrInt & 0xffc1) != 0x80)) WrError(ErrNum_NotFromThisAddress);
913 else
914 {
915 CodeLen = 1;
916 BAsmCode[0] = 0x80 + ((AdrInt & 0x3f) >> 1);
917 }
918 }
919 }
920 }
921
DecodeBIT(Word Code)922 static void DecodeBIT(Word Code)
923 {
924 UNUSED(Code);
925
926 if (ChkArgCnt(2, 2))
927 {
928 Boolean OK;
929 ShortInt HReg;
930
931 HReg = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
932 if (OK)
933 if (Decode_wa(&ArgStr[2], BAsmCode + 1))
934 {
935 CodeLen = 2; BAsmCode[0] = 0x58 + HReg;
936 }
937 }
938 }
939
DecodeSK_SKN(Word Code)940 static void DecodeSK_SKN(Word Code)
941 {
942 ShortInt HReg;
943
944 if (!ChkArgCnt(1, 1));
945 else if (!Decode_f(ArgStr[1].Str, &HReg)) WrError(ErrNum_InvAddrMode);
946 else
947 {
948 CodeLen = 2;
949 BAsmCode[0] = 0x48;
950 BAsmCode[1] = Code + HReg;
951 }
952 }
953
DecodeSKIT_SKNIT(Word Code)954 static void DecodeSKIT_SKNIT(Word Code)
955 {
956 ShortInt HReg;
957
958 if (!ChkArgCnt(1, 1));
959 else if (!Decode_irf(ArgStr[1].Str, &HReg)) WrError(ErrNum_InvAddrMode);
960 else
961 {
962 CodeLen = 2;
963 BAsmCode[0] = 0x48;
964 BAsmCode[1] = Code + HReg;
965 }
966 }
967
968 /*--------------------------------------------------------------------------------*/
969
AddFixed(const char * NName,Word NCode)970 static void AddFixed(const char *NName, Word NCode)
971 {
972 if ((!strcmp(NName, "STOP")) && (MomCPU == CPU7810));
973 else
974 AddInstTable(InstTable, NName, NCode, DecodeFixed);
975 }
976
AddSReg(const char * NName,Word NCode)977 static void AddSReg(const char *NName, Word NCode)
978 {
979 if (InstrZ >= SRegCnt) exit(255);
980 SRegs[InstrZ].Name = NName;
981 SRegs[InstrZ++].Code = NCode;
982 }
983
AddALU(Byte NCode,const char * NNameI,const char * NNameReg,const char * NNameEA)984 static void AddALU(Byte NCode, const char *NNameI, const char *NNameReg, const char *NNameEA)
985 {
986 char Name[20];
987
988 AddInstTable(InstTable, NNameI, NCode, DecodeALUImm);
989 AddInstTable(InstTable, NNameReg, NCode, DecodeALUReg);
990 AddInstTable(InstTable, NNameEA, NCode, DecodeALUEA);
991 as_snprintf(Name, sizeof(Name), "%sW", NNameReg);
992 AddInstTable(InstTable, Name, NCode, DecodeALURegW);
993 as_snprintf(Name, sizeof(Name), "%sX", NNameReg);
994 AddInstTable(InstTable, Name, NCode, DecodeALURegX);
995 as_snprintf(Name, sizeof(Name), "%sW", NNameI);
996 AddInstTable(InstTable, Name, NCode, DecodeALUImmW);
997 }
998
AddAbs(const char * NName,Word NCode)999 static void AddAbs(const char *NName, Word NCode)
1000 {
1001 AddInstTable(InstTable, NName, NCode, DecodeAbs);
1002 }
1003
AddReg2(const char * NName,Word NCode)1004 static void AddReg2(const char *NName, Word NCode)
1005 {
1006 AddInstTable(InstTable, NName, NCode, DecodeReg2);
1007 }
1008
AddWork(const char * NName,Word NCode)1009 static void AddWork(const char *NName, Word NCode)
1010 {
1011 AddInstTable(InstTable, NName, NCode, DecodeWork);
1012 }
1013
AddEA(const char * NName,Word NCode)1014 static void AddEA(const char *NName, Word NCode)
1015 {
1016 AddInstTable(InstTable, NName, NCode, DecodeEA);
1017 }
1018
InitFields(void)1019 static void InitFields(void)
1020 {
1021 InstTable = CreateInstTable(301);
1022 SetDynamicInstTable(InstTable);
1023
1024 AddInstTable(InstTable, "MOV", 0, DecodeMOV);
1025 AddInstTable(InstTable, "MVI", 0, DecodeMVI);
1026 AddInstTable(InstTable, "MVIW", 0, DecodeMVIW);
1027 AddInstTable(InstTable, "MVIX", 0, DecodeMVIX);
1028 AddInstTable(InstTable, "LDAX", 0x28, DecodeLDAX_STAX);
1029 AddInstTable(InstTable, "STAX", 0x38, DecodeLDAX_STAX);
1030 AddInstTable(InstTable, "LDEAX", 0x80, DecodeLDEAX_STEAX);
1031 AddInstTable(InstTable, "STEAX", 0x90, DecodeLDEAX_STEAX);
1032 AddInstTable(InstTable, "LXI", 0, DecodeLXI);
1033 AddInstTable(InstTable, "PUSH", 0xb0, DecodePUSH_POP);
1034 AddInstTable(InstTable, "POP", 0xa0, DecodePUSH_POP);
1035 AddInstTable(InstTable, "DMOV", 0, DecodeDMOV);
1036 AddInstTable(InstTable, "DCX", 1, DecodeDCX_INX);
1037 AddInstTable(InstTable, "INX", 0, DecodeDCX_INX);
1038 AddInstTable(InstTable, "EADD", 0x40, DecodeEADD_ESUB);
1039 AddInstTable(InstTable, "ESUB", 0x60, DecodeEADD_ESUB);
1040 AddInstTable(InstTable, "JR", 1, DecodeJ_JR_JRE);
1041 AddInstTable(InstTable, "JRE", 2, DecodeJ_JR_JRE);
1042 AddInstTable(InstTable, "J", 0, DecodeJ_JR_JRE);
1043 AddInstTable(InstTable, "CALF", 0, DecodeCALF);
1044 AddInstTable(InstTable, "CALT", 0, DecodeCALT);
1045 AddInstTable(InstTable, "BIT", 0, DecodeBIT);
1046 AddInstTable(InstTable, "SK", 0x08, DecodeSK_SKN);
1047 AddInstTable(InstTable, "SKN", 0x18, DecodeSK_SKN);
1048 AddInstTable(InstTable, "SKIT", 0x40, DecodeSKIT_SKNIT);
1049 AddInstTable(InstTable, "SKNIT", 0x60, DecodeSKIT_SKNIT);
1050
1051 AddFixed("EXX" , 0x0011); AddFixed("EXA" , 0x0010);
1052 AddFixed("EXH" , 0x0050); AddFixed("BLOCK", 0x0031);
1053 AddFixed("TABLE", 0x48a8); AddFixed("DAA" , 0x0061);
1054 AddFixed("STC" , 0x482b); AddFixed("CLC" , 0x482a);
1055 AddFixed("NEGA" , 0x483a); AddFixed("RLD" , 0x4838);
1056 AddFixed("RRD" , 0x4839); AddFixed("JB" , 0x0021);
1057 AddFixed("JEA" , 0x4828); AddFixed("CALB" , 0x4829);
1058 AddFixed("SOFTI", 0x0072); AddFixed("RET" , 0x00b8);
1059 AddFixed("RETS" , 0x00b9); AddFixed("RETI" , 0x0062);
1060 AddFixed("NOP" , 0x0000); AddFixed("EI" , 0x00aa);
1061 AddFixed("DI" , 0x00ba); AddFixed("HLT" , 0x483b);
1062 AddFixed("STOP" , 0x48bb);
1063
1064 SRegs = (SReg *) malloc(sizeof(SReg)*SRegCnt); InstrZ = 0;
1065 AddSReg("PA" , 0x00); AddSReg("PB" , 0x01);
1066 AddSReg("PC" , 0x02); AddSReg("PD" , 0x03);
1067 AddSReg("PF" , 0x05); AddSReg("MKH" , 0x06);
1068 AddSReg("MKL" , 0x07); AddSReg("ANM" , 0x08);
1069 AddSReg("SMH" , 0x09); AddSReg("SML" , 0x0a);
1070 AddSReg("EOM" , 0x0b); AddSReg("ETMM", 0x0c);
1071 AddSReg("TMM" , 0x0d); AddSReg("MM" , 0x10);
1072 AddSReg("MCC" , 0x11); AddSReg("MA" , 0x12);
1073 AddSReg("MB" , 0x13); AddSReg("MC" , 0x14);
1074 AddSReg("MF" , 0x17); AddSReg("TXB" , 0x18);
1075 AddSReg("RXB" , 0x19); AddSReg("TM0" , 0x1a);
1076 AddSReg("TM1" , 0x1b); AddSReg("CR0" , 0x20);
1077 AddSReg("CR1" , 0x21); AddSReg("CR2" , 0x22);
1078 AddSReg("CR3" , 0x23); AddSReg("ZCM" , 0x28);
1079
1080 AddALU(10, "ACI" , "ADC" , "DADC" );
1081 AddALU( 4, "ADINC", "ADDNC", "DADDNC");
1082 AddALU( 8, "ADI" , "ADD" , "DADD" );
1083 AddALU( 1, "ANI" , "ANA" , "DAN" );
1084 AddALU(15, "EQI" , "EQA" , "DEQ" );
1085 AddALU( 5, "GTI" , "GTA" , "DGT" );
1086 AddALU( 7, "LTI" , "LTA" , "DLT" );
1087 AddALU(13, "NEI" , "NEA" , "DNE" );
1088 AddALU(11, "OFFI" , "OFFA" , "DOFF" );
1089 AddALU( 9, "ONI" , "ONA" , "DON" );
1090 AddALU( 3, "ORI" , "ORA" , "DOR" );
1091 AddALU(14, "SBI" , "SBB" , "DSBB" );
1092 AddALU( 6, "SUINB", "SUBNB", "DSUBNB");
1093 AddALU(12, "SUI" , "SUB" , "DSUB" );
1094 AddALU( 2, "XRI" , "XRA" , "DXR" );
1095
1096 AddAbs("CALL", 0x0040); AddAbs("JMP" , 0x0054);
1097 AddAbs("LBCD", 0x701f); AddAbs("LDED", 0x702f);
1098 AddAbs("LHLD", 0x703f); AddAbs("LSPD", 0x700f);
1099 AddAbs("SBCD", 0x701e); AddAbs("SDED", 0x702e);
1100 AddAbs("SHLD", 0x703e); AddAbs("SSPD", 0x700e);
1101
1102 AddReg2("DCR" , 0x0050); AddReg2("DIV" , 0x483c);
1103 AddReg2("INR" , 0x0040); AddReg2("MUL" , 0x482c);
1104 AddReg2("RLL" , 0x4834); AddReg2("RLR" , 0x4830);
1105 AddReg2("SLL" , 0x4824); AddReg2("SLR" , 0x4820);
1106 AddReg2("SLLC", 0x4804); AddReg2("SLRC", 0x4800);
1107
1108 AddWork("DCRW", 0x30); AddWork("INRW", 0x20);
1109 AddWork("LDAW", 0x01); AddWork("STAW", 0x63);
1110
1111 AddEA("DRLL", 0x48b4); AddEA("DRLR", 0x48b0);
1112 AddEA("DSLL", 0x48a4); AddEA("DSLR", 0x48a0);
1113 }
1114
DeinitFields(void)1115 static void DeinitFields(void)
1116 {
1117 DestroyInstTable(InstTable);
1118 free(SRegs);
1119 }
1120
1121 /*--------------------------------------------------------------------------*/
1122
MakeCode_78C10(void)1123 static void MakeCode_78C10(void)
1124 {
1125 CodeLen = 0;
1126 DontPrint = False;
1127
1128 /* zu ignorierendes */
1129
1130 if (Memo("")) return;
1131
1132 /* Pseudoanweisungen */
1133
1134 if (DecodeIntelPseudo(False)) return;
1135
1136 if (!LookupInstTable(InstTable, OpPart.Str))
1137 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
1138 }
1139
InitCode_78C10(void)1140 static void InitCode_78C10(void)
1141 {
1142 WorkArea = 0x100;
1143 }
1144
IsDef_78C10(void)1145 static Boolean IsDef_78C10(void)
1146 {
1147 return False;
1148 }
1149
SwitchFrom_78C10(void)1150 static void SwitchFrom_78C10(void)
1151 {
1152 DeinitFields();
1153 }
1154
SwitchTo_78C10(void)1155 static void SwitchTo_78C10(void)
1156 {
1157 TurnWords = False; ConstMode = ConstModeIntel;
1158
1159 PCSymbol = "$"; HeaderID = 0x7a; NOPCode = 0x00;
1160 DivideChars = ","; HasAttrs = False;
1161
1162 ValidSegs = 1 << SegCode;
1163 Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
1164 SegLimits[SegCode] = 0xffff;
1165
1166 pASSUMERecs = ASSUME78C10s;
1167 ASSUMERecCnt = sizeof(ASSUME78C10s) / sizeof(*ASSUME78C10s);
1168
1169 MakeCode = MakeCode_78C10; IsDef = IsDef_78C10;
1170 SwitchFrom = SwitchFrom_78C10;
1171 InitFields();
1172 }
1173
code78c10_init(void)1174 void code78c10_init(void)
1175 {
1176 CPU7810 = AddCPU("7810" , SwitchTo_78C10);
1177 CPU78C10 = AddCPU("78C10", SwitchTo_78C10);
1178
1179 AddInitPassProc(InitCode_78C10);
1180 }
1181