Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* code77230.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* Makroassembler AS                                                         */
6
/*                                                                           */
7
/* Codegenerator NEC uPD77230                                                */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
/*---------------------------------------------------------------------------*/
12
/* Includes */
13
 
14
#include "stdinc.h"
15
#include <string.h>
16
#include <ctype.h>
17
 
18
#include "strutil.h"
19
#include "nls.h"
20
#include "be_le.h"
21
#include "necfloat.h"
22
#include "bpemu.h"
23
 
24
#include "asmdef.h"
25
#include "asmsub.h"
26
#include "asmpars.h"
27
#include "asmitree.h"
28
#include "headids.h"
29
#include "codevars.h"
30
#include "codepseudo.h"
31
#include "onoff_common.h"
32
#include "errmsg.h"
33
#include "chartrans.h"
34
 
35
#include "code77230.h"
36
 
37
/*---------------------------------------------------------------------------*/
38
/* Definitionen */
39
 
40
#define CaseCnt 17
41
 
42
typedef struct
43
{
44
  LongWord Code;
45
} FixedOrder;
46
 
47
typedef struct
48
{
49
  const char *Name;
50
  LongWord Code;
51
} Register;
52
 
53
enum
54
{
55
  InstrLDI, InstrBranch,
56
  InstrALU, InstrMove,
57
  InstrM0, InstrM1, InstrDP0, InstrDP1,
58
  InstrEA, InstrRP, InstrFC, InstrLC,
59
  InstrBASE0, InstrBASE1, InstrRPC,
60
  InstrP2, InstrP3, InstrEM, InstrBM,
61
  InstrL, InstrRW, InstrWT, InstrNF, InstrWI,
62
  InstrFIS, InstrFD, InstrSHV, InstrRPS, InstrNAL, InstrCnt
63
};
64
 
65
static LongWord CaseMasks[CaseCnt] =
66
{
67
  (1l << InstrLDI),
68
  (1l << InstrBranch) | (1l << InstrMove),
69
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrM0) | (1l << InstrM1) | (1l << InstrDP0) | (1l << InstrDP1),
70
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrEA) | (1l << InstrDP0) | (1l << InstrDP1),
71
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrRP) | (1l << InstrM0) | (1l << InstrDP0) | (1l << InstrFC),
72
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrRP) | (1l << InstrM1) | (1l << InstrDP1) | (1l << InstrFC),
73
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrRP) | (1l << InstrM0) | (1l << InstrM1) | (1l << InstrL) | (1l << InstrFC),
74
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrBASE0) | (1l << InstrBASE1) | (1l << InstrFC),
75
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrRPC) | (1l << InstrL) | (1l << InstrFC),
76
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrP3) | (1l << InstrP2) | (1l << InstrEM) | (1l << InstrBM) | (1l << InstrL) | (1l << InstrFC),
77
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrRW) | (1l << InstrL) | (1l << InstrFC),
78
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrWT) | (1l << InstrL) | (1l << InstrFC),
79
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrNF) | (1l << InstrWI) | (1l << InstrL) | (1l << InstrFC),
80
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrFIS) | (1l << InstrFD) | (1l << InstrL),
81
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrSHV),
82
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrRPS),
83
  (1l << InstrALU) | (1l << InstrMove) | (1l << InstrNAL)
84
};
85
 
86
static CPUVar CPU77230;
87
static LongWord InstrMask;
88
static Boolean Error;
89
static LongWord *InstrComps, *InstrDefs;
90
 
91
static Register *SrcRegs, *ALUSrcRegs, *DestRegs;
92
static FixedOrder *JmpOrders, *ALU1Orders, *ALU2Orders;
93
 
94
/*---------------------------------------------------------------------------*/
95
/* Hilfsroutinen */
96
 
97
static int DiscCnt, SplittedArg;
98
static char *DiscPtr;
99
 
100
static Boolean SplitArgs(int Count)
101
{
102
  char *p, *p1, *p2;
103
 
104
  SplittedArg = DiscCnt = Count;
105
 
106
  if (Count == 0)
107
  {
108
    if (ArgCnt > 0)
109
    {
110
      DiscPtr = ArgStr[1].str.p_str - 1;
111
      SplittedArg = 1;
112
    }
113
    else
114
      DiscPtr = NULL;
115
    return True;
116
  }
117
 
118
  if (!ChkArgCnt(Count, ArgCntMax))
119
  {
120
    Error = True;
121
    return False;
122
  }
123
 
124
  for (p = ArgStr[SplittedArg].str.p_str; isspace(((usint)*p) & 0xff); p++);
125
  p1 = QuotPos(p, ' ');
126
  p2 = QuotPos(p, '\t');
127
  DiscPtr = ((!p1) || ((p2) && (p2 < p1))) ? p2 : p1;
128
  if (DiscPtr)
129
    *(DiscPtr) = '\0';
130
 
131
  return True;
132
}
133
 
134
static void DiscardArgs(void)
135
{
136
  char *p, *p2;
137
  int z;
138
  Boolean Eaten;
139
 
140
  if (DiscPtr)
141
  {
142
    for (p = DiscPtr + 1; as_isspace(*p); p++)
143
      if (*p == '\0') break;
144
    for (p2 = p; !as_isspace(*p2); p2++)
145
      if (*p2 == '\0') break;
146
    Eaten = (*p2 == '\0');
147
    *p2 = '\0';
148
    strmov(OpPart.str.p_str, p);
149
    NLS_UpString(OpPart.str.p_str);
150
    if (Eaten)
151
    {
152
      for (z = 1; z < ArgCnt; z++)
153
        strmov(ArgStr[z].str.p_str, ArgStr[z + 1].str.p_str);
154
      ArgCnt--;
155
    }
156
    else
157
    {
158
      if (p2)
159
        for (p2++; as_isspace(*p2); p2++);
160
      strmov(ArgStr[SplittedArg].str.p_str, p2);
161
    }
162
  }
163
  else
164
    *OpPart.str.p_str = '\0';
165
  if (DiscCnt > 0)
166
  {
167
    for (z = 0; z <= ArgCnt - DiscCnt; z++)
168
      strmov(ArgStr[z + 1].str.p_str, ArgStr[z + DiscCnt].str.p_str);
169
    ArgCnt -= DiscCnt - 1;
170
  }
171
}
172
 
173
static void AddComp(int Index, LongWord Value)
174
{
175
  if ((InstrMask & (1l << Index)) != 0)
176
  {
177
    WrError(ErrNum_InvParAddrMode);
178
    Error = True;
179
  }
180
  else
181
  {
182
    InstrMask |= (1l << Index);
183
    InstrComps[Index] = Value;
184
  }
185
}
186
 
187
static Boolean DecodeReg(char *Asc, LongWord *Erg, Register *Regs)
188
{
189
  int z;
190
 
191
  for (z = 0; Regs[z].Name; z++)
192
    if (!as_strcasecmp(Asc, Regs[z].Name))
193
    {
194
      *Erg = Regs[z].Code;
195
      return True;
196
    }
197
  *Erg = 0;
198
  return False;
199
}
200
 
201
/*---------------------------------------------------------------------------*/
202
/* Dekoder fuer Routinen */
203
 
204
static void DecodeJmp(Word Index)
205
{
206
  FixedOrder *Op = JmpOrders + Index;
207
  int acnt = Hi(Op->Code);
208
  LongWord Adr;
209
 
210
  if (!SplitArgs(acnt))
211
    return;
212
  if (acnt == 0)
213
  {
214
    Adr = 0;
215
    Error = True;
216
  }
217
  else
218
    Adr = EvalStrIntExpression(&ArgStr[1], UInt13, &Error);
219
  Error = !Error;
220
  if (!Error)
221
    AddComp(InstrBranch, Lo(Op->Code) + (Adr << 5));
222
  DiscardArgs();
223
}
224
 
225
static void DecodeMOV(Word Index)
226
{
227
  LongWord DReg, SReg;
228
  UNUSED(Index);
229
 
230
  if (!SplitArgs(2))
231
    return;
232
  if (!DecodeReg(ArgStr[1].str.p_str, &DReg, DestRegs))
233
  {
234
    WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
235
    Error = True;
236
  }
237
  else if (!DecodeReg(ArgStr[2].str.p_str, &SReg, SrcRegs))
238
  {
239
    WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
240
    Error = True;
241
  }
242
  else
243
    AddComp(InstrMove, (SReg << 5) + DReg);
244
  DiscardArgs();
245
}
246
 
247
static void DecodeLDI(Word Index)
248
{
249
  LongWord DReg, Src = 0;
250
  UNUSED(Index);
251
 
252
  if (!SplitArgs(2))
253
    return;
254
  if (!DecodeReg(ArgStr[1].str.p_str, &DReg, DestRegs))
255
  {
256
    WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
257
    Error = True;
258
  }
259
  else
260
    Src = EvalStrIntExpression(&ArgStr[2], Int24, &Error);
261
  Error = !Error;
262
  if (!Error)
263
    AddComp(InstrLDI, (Src << 5) + DReg);
264
  DiscardArgs();
265
}
266
 
267
static void DecodeNOP(Word Index)
268
{
269
  UNUSED(Index);
270
 
271
  if (!SplitArgs(0))
272
    return;
273
  AddComp(InstrALU, 0);
274
  DiscardArgs();
275
}
276
 
277
static void DecodeALU1(Word Index)
278
{
279
  FixedOrder *Op = ALU1Orders + Index;
280
  LongWord DReg;
281
 
282
  if (!SplitArgs(1))
283
    return;
284
  if ((!DecodeReg(ArgStr[1].str.p_str, &DReg, DestRegs))
285
   || (DReg < 16) || (DReg > 23))
286
  {
287
    WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
288
    Error = True;
289
  }
290
  else
291
    AddComp(InstrALU, (Op->Code << 17) + (DReg & 7));
292
  DiscardArgs();
293
}
294
 
295
static void DecodeALU2(Word Index)
296
{
297
  FixedOrder *Op = ALU2Orders + Index;
298
  LongWord DReg, SReg;
299
 
300
  if (!SplitArgs(2)) return;
301
  if ((!DecodeReg(ArgStr[1].str.p_str, &DReg, DestRegs))
302
   || (DReg < 16) || (DReg > 23))
303
  {
304
    WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
305
    Error = True;
306
  }
307
  else if (!DecodeReg(ArgStr[2].str.p_str, &SReg, ALUSrcRegs))
308
  {
309
    WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
310
    Error = True;
311
  }
312
  else
313
    AddComp(InstrALU, (Op->Code << 17) + (SReg << 3) + (DReg & 7));
314
  DiscardArgs();
315
}
316
 
317
static void DecodeM0(Word Index)
318
{
319
  if (!SplitArgs(0))
320
    return;
321
 
322
  AddComp(InstrM0, Index);
323
  DiscardArgs();
324
}
325
 
326
static void DecodeM1(Word Index)
327
{
328
  if (!SplitArgs(0))
329
    return;
330
 
331
  AddComp(InstrM1, Index);
332
  DiscardArgs();
333
}
334
 
335
static void DecodeDP0(Word Index)
336
{
337
  if (!SplitArgs(0))
338
    return;
339
 
340
  AddComp(InstrDP0, Index);
341
  DiscardArgs();
342
}
343
 
344
static void DecodeDP1(Word Index)
345
{
346
  if (!SplitArgs(0))
347
    return;
348
 
349
  AddComp(InstrDP1, Index);
350
  DiscardArgs();
351
}
352
 
353
static void DecodeEA(Word Index)
354
{
355
  if (!SplitArgs(0))
356
    return;
357
 
358
  AddComp(InstrEA, Index);
359
  DiscardArgs();
360
}
361
 
362
static void DecodeFC(Word Index)
363
{
364
  if (!SplitArgs(0))
365
    return;
366
 
367
  AddComp(InstrFC, Index);
368
  DiscardArgs();
369
}
370
 
371
static void DecodeRP(Word Index)
372
{
373
  if (!SplitArgs(0))
374
    return;
375
 
376
  AddComp(InstrRP, Index);
377
  DiscardArgs();
378
}
379
 
380
static void DecodeL(Word Index)
381
{
382
  if (!SplitArgs(0))
383
    return;
384
 
385
  AddComp(InstrL, Index);
386
  DiscardArgs();
387
}
388
 
389
static void DecodeBASE(Word Index)
390
{
391
  LongWord Value;
392
 
393
  if (!SplitArgs(1))
394
    return;
395
  Value = EvalStrIntExpression(&ArgStr[1], UInt3, &Error);
396
  Error = !Error;
397
  if (!Error)
398
    AddComp(Index, Value);
399
  DiscardArgs();
400
}
401
 
402
static void DecodeRPC(Word Index)
403
{
404
  LongWord Value;
405
  tSymbolFlags Flags;
406
 
407
  UNUSED(Index);
408
 
409
  if (!SplitArgs(1))
410
    return;
411
 
412
  Value = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt4, &Error, &Flags);
413
  if (mFirstPassUnknown(Flags))
414
    Value &= 7;
415
  Error = (Value > 9) ? True : !Error;
416
  if (!Error)
417
    AddComp(InstrRPC, Value);
418
  DiscardArgs();
419
}
420
 
421
static void DecodeP2(Word Index)
422
{
423
  if (!SplitArgs(0))
424
    return;
425
 
426
  AddComp(InstrP2, Index);
427
  DiscardArgs();
428
}
429
 
430
static void DecodeP3(Word Index)
431
{
432
  if (!SplitArgs(0))
433
    return;
434
 
435
  AddComp(InstrP3, Index);
436
  DiscardArgs();
437
}
438
 
439
static void DecodeBM(Word Index)
440
{
441
  /* Wenn EM-Feld schon da war, muss es EI gewesen sein */
442
 
443
  if (!SplitArgs(0))
444
    return;
445
 
446
  if ((InstrMask & (1 << InstrEM)) != 0)
447
  {
448
    Error = (InstrComps[InstrEM] == 0);
449
    if (Error) WrError(ErrNum_InvParAddrMode);
450
    else
451
      AddComp(InstrBM, Index);
452
  }
453
  else
454
    AddComp(InstrBM, Index);
455
  DiscardArgs();
456
}
457
 
458
static void DecodeEM(Word Index)
459
{
460
  /* Wenn BM-Feld schon da war, muss es EI sein */
461
 
462
  if (!SplitArgs(0))
463
    return;
464
 
465
  if ((InstrMask & (1 << InstrBM)) != 0)
466
  {
467
    Error = (Index == 0);
468
    if (Error)
469
      WrError(ErrNum_InvParAddrMode);
470
    else
471
      AddComp(InstrEM, Index);
472
  }
473
  else
474
  {
475
    AddComp(InstrEM, Index);
476
    if (Index == 0)
477
      InstrComps[InstrBM] = 3;
478
  }
479
  DiscardArgs();
480
}
481
 
482
static void DecodeRW(Word Index)
483
{
484
  if (!SplitArgs(0))
485
    return;
486
 
487
  AddComp(InstrRW, Index);
488
  DiscardArgs();
489
}
490
 
491
static void DecodeWT(Word Index)
492
{
493
  if (!SplitArgs(0))
494
    return;
495
 
496
  AddComp(InstrWT, Index);
497
  DiscardArgs();
498
}
499
 
500
static void DecodeNF(Word Index)
501
{
502
  if (!SplitArgs(0))
503
    return;
504
 
505
  AddComp(InstrNF, Index);
506
  DiscardArgs();
507
}
508
 
509
static void DecodeWI(Word Index)
510
{
511
  if (!SplitArgs(0))
512
    return;
513
 
514
  AddComp(InstrWI, Index);
515
  DiscardArgs();
516
}
517
 
518
static void DecodeFIS(Word Index)
519
{
520
  if (!SplitArgs(0))
521
    return;
522
 
523
  AddComp(InstrFIS, Index);
524
  DiscardArgs();
525
}
526
 
527
static void DecodeFD(Word Index)
528
{
529
  if (!SplitArgs(0))
530
    return;
531
 
532
  AddComp(InstrFD, Index);
533
  DiscardArgs();
534
}
535
 
536
static void DecodeSHV(Word Index)
537
{
538
  LongWord Value;
539
  tSymbolFlags Flags;
540
 
541
  if (!SplitArgs(1))
542
    return;
543
 
544
  Value = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt6, &Error, &Flags);
545
  if (mFirstPassUnknown(Flags))
546
    Value &= 31;
547
  Error = (Value > 46) ? True : !Error;
548
  if (!Error)
549
    AddComp(InstrSHV, (Index << 6) + Value);
550
  DiscardArgs();
551
}
552
 
553
static void DecodeRPS(Word Index)
554
{
555
  LongWord Value;
556
  UNUSED(Index);
557
 
558
  if (!SplitArgs(1))
559
    return;
560
  Value = EvalStrIntExpression(&ArgStr[1], UInt9, &Error);
561
  Error = !Error;
562
  if (!Error)
563
    AddComp(InstrRPS, Value);
564
  DiscardArgs();
565
}
566
 
567
static void DecodeNAL(Word Index)
568
{
569
  LongWord Value;
570
  tSymbolFlags Flags;
571
 
572
  UNUSED(Index);
573
 
574
  if (!SplitArgs(1))
575
    return;
576
 
577
  Value = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt13, &Error, &Flags);
578
  Error = !Error;
579
  if (!Error)
580
  {
581
    if (ChkSamePage(Value, EProgCounter(), 9, Flags))
582
      AddComp(InstrNAL, Value & 0x1ff);
583
  }
584
  DiscardArgs();
585
}
586
 
587
static Boolean DecodePseudo(void)
588
{
589
  LongInt Size;
590
 
591
  if (Memo("DW"))
592
  {
593
    if (ChkArgCnt(1, ArgCntMax))
594
    {
595
      TempResult t;
596
      Boolean OK = True;
597
      tStrComp *pArg;
598
 
599
      as_tempres_ini(&t);
600
      forallargs(pArg, OK)
601
      {
602
        EvalStrExpression(pArg, &t);
603
        switch(t.Typ)
604
        {
605
          case TempString:
606
            if (MultiCharToInt(&t, 4))
607
              goto ToInt;
608
 
609
            if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pArg))
610
              OK = False;
611
            else
612
              OK = !string_2_dasm_code(&t.Contents.str, Packing ? 4 : 1, True);
613
            break;
614
          case TempInt:
615
          ToInt:
616
            if (!RangeCheck(t.Contents.Int, Int32))
617
            {
618
              WrStrErrorPos(ErrNum_OverRange, pArg);
619
              OK = False;
620
              break;
621
            }
622
            DAsmCode[CodeLen++] = t.Contents.Int;
623
            break;
624
          case TempFloat:
625
          {
626
            int ret;
627
 
628
            if ((ret = as_float_2_nec_4(t.Contents.Float, &DAsmCode[CodeLen])) < 0)
629
            {
630
              asmerr_check_fp_dispose_result(ret, pArg);
631
              OK = False;
632
              break;
633
            }
634
            CodeLen++;
635
            break;
636
          }
637
          default:
638
            OK = False;
639
        }
640
      }
641
      if (!OK)
642
        CodeLen = 0;
643
      as_tempres_free(&t);
644
    }
645
    return True;
646
  }
647
 
648
  if (Memo("DS"))
649
  {
650
    if (ChkArgCnt(1, 1))
651
    {
652
      tSymbolFlags Flags;
653
      Boolean OK;
654
 
655
      Size = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
656
      if (mFirstPassUnknown(Flags))
657
      {
658
        WrError(ErrNum_FirstPassCalc);
659
        OK = False;
660
      }
661
      if (OK)
662
      {
663
        DontPrint = True;
664
        if (!Size)
665
          WrError(ErrNum_NullResMem);
666
        CodeLen = Size;
667
        BookKeeping();
668
      }
669
    }
670
    return True;
671
  }
672
 
673
  return FALSE;
674
}
675
 
676
/*---------------------------------------------------------------------------*/
677
/* Codetabellenverwaltung */
678
 
679
static void AddJmp(const char *NName, LongWord NCode)
680
{
681
  order_array_rsv_end(JmpOrders, FixedOrder);
682
  JmpOrders[InstrZ].Code = NCode;
683
  AddInstTable(InstTable, NName, InstrZ++, DecodeJmp);
684
}
685
 
686
static void AddALU1(const char *NName, LongWord NCode)
687
{
688
  order_array_rsv_end(ALU1Orders, FixedOrder);
689
  ALU1Orders[InstrZ].Code = NCode;
690
  AddInstTable(InstTable, NName, InstrZ++, DecodeALU1);
691
}
692
 
693
static void AddALU2(const char *NName, LongWord NCode)
694
{
695
  order_array_rsv_end(ALU2Orders, FixedOrder);
696
  ALU2Orders[InstrZ].Code = NCode;
697
  AddInstTable(InstTable, NName, InstrZ++, DecodeALU2);
698
}
699
 
700
static void AddSrcReg(const char *NName, LongWord NCode)
701
{
702
  order_array_rsv_end(SrcRegs, Register);
703
  SrcRegs[InstrZ].Name = NName;
704
  SrcRegs[InstrZ++].Code = NCode;
705
}
706
 
707
static void AddALUSrcReg(const char *NName, LongWord NCode)
708
{
709
  order_array_rsv_end(ALUSrcRegs, Register);
710
  ALUSrcRegs[InstrZ].Name = NName;
711
  ALUSrcRegs[InstrZ++].Code = NCode;
712
}
713
 
714
static void AddDestReg(const char *NName, LongWord NCode)
715
{
716
  order_array_rsv_end(DestRegs, Register);
717
  DestRegs[InstrZ].Name = NName;
718
  DestRegs[InstrZ++].Code = NCode;
719
}
720
 
721
static void InitFields(void)
722
{
723
  InstTable = CreateInstTable(201);
724
 
725
  AddInstTable(InstTable, "MOV", 0, DecodeMOV);
726
  AddInstTable(InstTable, "LDI", 0, DecodeLDI);
727
  AddInstTable(InstTable, "NOP", 0, DecodeNOP);
728
 
729
  AddInstTable(InstTable, "SPCBP0", 1, DecodeM0);
730
  AddInstTable(InstTable, "SPCIX0", 2, DecodeM0);
731
  AddInstTable(InstTable, "SPCBI0", 3, DecodeM0);
732
 
733
  AddInstTable(InstTable, "SPCBP1", 1, DecodeM1);
734
  AddInstTable(InstTable, "SPCIX1", 2, DecodeM1);
735
  AddInstTable(InstTable, "SPCBI1", 3, DecodeM1);
736
 
737
  AddInstTable(InstTable, "INCBP0", 1, DecodeDP0);
738
  AddInstTable(InstTable, "DECBP0", 2, DecodeDP0);
739
  AddInstTable(InstTable, "CLRBP0", 3, DecodeDP0);
740
  AddInstTable(InstTable, "STIX0" , 4, DecodeDP0);
741
  AddInstTable(InstTable, "INCIX0", 5, DecodeDP0);
742
  AddInstTable(InstTable, "DECIX0", 6, DecodeDP0);
743
  AddInstTable(InstTable, "CLRIX0", 7, DecodeDP0);
744
 
745
  AddInstTable(InstTable, "INCBP1", 1, DecodeDP1);
746
  AddInstTable(InstTable, "DECBP1", 2, DecodeDP1);
747
  AddInstTable(InstTable, "CLRBP1", 3, DecodeDP1);
748
  AddInstTable(InstTable, "STIX1" , 4, DecodeDP1);
749
  AddInstTable(InstTable, "INCIX1", 5, DecodeDP1);
750
  AddInstTable(InstTable, "DECIX1", 6, DecodeDP1);
751
  AddInstTable(InstTable, "CLRIX1", 7, DecodeDP1);
752
 
753
  AddInstTable(InstTable, "INCAR" , 1, DecodeEA);
754
  AddInstTable(InstTable, "DECAR" , 2, DecodeEA);
755
 
756
  AddInstTable(InstTable, "XCHPSW", 1, DecodeFC);
757
 
758
  AddInstTable(InstTable, "INCRP" , 1, DecodeRP);
759
  AddInstTable(InstTable, "DECRP" , 2, DecodeRP);
760
  AddInstTable(InstTable, "INCBRP", 3, DecodeRP);
761
 
762
  AddInstTable(InstTable, "DECLC" , 1, DecodeL);
763
 
764
  AddInstTable(InstTable, "MCNBP0", InstrBASE0, DecodeBASE);
765
  AddInstTable(InstTable, "MCNBP1", InstrBASE1, DecodeBASE);
766
 
767
  AddInstTable(InstTable, "BITRP" , 0, DecodeRPC);
768
 
769
  AddInstTable(InstTable, "CLRP2" , 0, DecodeP2);
770
  AddInstTable(InstTable, "SETP2" , 1, DecodeP2);
771
 
772
  AddInstTable(InstTable, "CLRP3" , 0, DecodeP3);
773
  AddInstTable(InstTable, "SETP3" , 1, DecodeP3);
774
 
775
  AddInstTable(InstTable, "DI"    , 0, DecodeEM);
776
  AddInstTable(InstTable, "EI"    , 1, DecodeEM);
777
  AddInstTable(InstTable, "CLRBM" , 1, DecodeBM);
778
  AddInstTable(InstTable, "SETBM" , 2, DecodeBM);
779
 
780
  AddInstTable(InstTable, "RD"    , 1, DecodeRW);
781
  AddInstTable(InstTable, "WR"    , 2, DecodeRW);
782
 
783
  AddInstTable(InstTable, "WRBORD", 1, DecodeWT);
784
  AddInstTable(InstTable, "WRBL24", 2, DecodeWT);
785
  AddInstTable(InstTable, "WRBL23", 3, DecodeWT);
786
  AddInstTable(InstTable, "WRBEL8", 4, DecodeWT);
787
  AddInstTable(InstTable, "WRBL8E", 5, DecodeWT);
788
  AddInstTable(InstTable, "WRBXCH", 6, DecodeWT);
789
  AddInstTable(InstTable, "WRBBRV", 7, DecodeWT);
790
 
791
  AddInstTable(InstTable, "TRNORM", 2, DecodeNF);
792
  AddInstTable(InstTable, "RDNORM", 4, DecodeNF);
793
  AddInstTable(InstTable, "FLTFIX", 6, DecodeNF);
794
  AddInstTable(InstTable, "FIXMA" , 7, DecodeNF);
795
 
796
  AddInstTable(InstTable, "BWRL24", 1, DecodeWI);
797
  AddInstTable(InstTable, "BWRORD", 2, DecodeWI);
798
 
799
  AddInstTable(InstTable, "SPCPSW0", 1, DecodeFIS);
800
  AddInstTable(InstTable, "SPCPSW1", 2, DecodeFIS);
801
  AddInstTable(InstTable, "CLRPSW0", 4, DecodeFIS);
802
  AddInstTable(InstTable, "CLRPSW1", 5, DecodeFIS);
803
  AddInstTable(InstTable, "CLRPSW" , 6, DecodeFIS);
804
 
805
  AddInstTable(InstTable, "SPIE", 1, DecodeFD);
806
  AddInstTable(InstTable, "IESP", 2, DecodeFD);
807
 
808
  AddInstTable(InstTable, "SETSVL", 0, DecodeSHV);
809
  AddInstTable(InstTable, "SETSVR", 1, DecodeSHV);
810
 
811
  AddInstTable(InstTable, "SPCRA", 0, DecodeRPS);
812
  AddInstTable(InstTable, "JBLK" , 0, DecodeNAL);
813
 
814
  InstrZ = 0;
815
  AddJmp("JMP"   , 0x0100); AddJmp("CALL"  , 0x0101); AddJmp("RET"   , 0x0002);
816
  AddJmp("JNZRP" , 0x0103); AddJmp("JZ0"   , 0x0104); AddJmp("JNZ0"  , 0x0105);
817
  AddJmp("JZ1"   , 0x0106); AddJmp("JNZ1"  , 0x0107); AddJmp("JC0"   , 0x0108);
818
  AddJmp("JNC0"  , 0x0109); AddJmp("JC1"   , 0x010a); AddJmp("JNC1"  , 0x010b);
819
  AddJmp("JS0"   , 0x010c); AddJmp("JNS0"  , 0x010d); AddJmp("JS1"   , 0x010e);
820
  AddJmp("JNS1"  , 0x010f); AddJmp("JV0"   , 0x0110); AddJmp("JNV0"  , 0x0111);
821
  AddJmp("JV1"   , 0x0112); AddJmp("JNV1"  , 0x0113); AddJmp("JEV0"  , 0x0114);
822
  AddJmp("JEV1"  , 0x0115); AddJmp("JNFSI" , 0x0116); AddJmp("JNESO" , 0x0117);
823
  AddJmp("JIP0"  , 0x0118); AddJmp("JIP1"  , 0x0119); AddJmp("JNZIX0", 0x011a);
824
  AddJmp("JNZIX1", 0x011b); AddJmp("JNZBP0", 0x011c); AddJmp("JNZBP1", 0x011d);
825
  AddJmp("JRDY"  , 0x011e); AddJmp("JRQM"  , 0x011f);
826
 
827
  InstrZ = 0;
828
  AddALU1("INC"  , 0x01); AddALU1("DEC"  , 0x02); AddALU1("ABS"  , 0x03);
829
  AddALU1("NOT"  , 0x04); AddALU1("NEG"  , 0x05); AddALU1("SHLC" , 0x06);
830
  AddALU1("SHRC" , 0x07); AddALU1("ROL"  , 0x08); AddALU1("ROR"  , 0x09);
831
  AddALU1("SHLM" , 0x0a); AddALU1("SHRM" , 0x0b); AddALU1("SHRAM", 0x0c);
832
  AddALU1("CLR"  , 0x0d); AddALU1("NORM" , 0x0e); AddALU1("CVT"  , 0x0f);
833
 
834
  InstrZ = 0;
835
  AddALU2("ADD"  , 0x10); AddALU2("SUB"  , 0x11); AddALU2("ADDC" , 0x12);
836
  AddALU2("SUBC" , 0x13); AddALU2("CMP"  , 0x14); AddALU2("AND"  , 0x15);
837
  AddALU2("OR"   , 0x16); AddALU2("XOR"  , 0x17); AddALU2("ADDF" , 0x18);
838
  AddALU2("SUBF" , 0x19);
839
 
840
  InstrZ = 0;
841
  AddSrcReg("NON" , 0x00); AddSrcReg("RP"  , 0x01); AddSrcReg("PSW0" , 0x02);
842
  AddSrcReg("PSW1", 0x03); AddSrcReg("SVR" , 0x04); AddSrcReg("SR"   , 0x05);
843
  AddSrcReg("LC"  , 0x06); AddSrcReg("STX" , 0x07); AddSrcReg("M"    , 0x08);
844
  AddSrcReg("ML"  , 0x09); AddSrcReg("ROM" , 0x0a); AddSrcReg("TR"   , 0x0b);
845
  AddSrcReg("AR"  , 0x0c); AddSrcReg("SI"  , 0x0d); AddSrcReg("DR"   , 0x0e);
846
  AddSrcReg("DRS" , 0x0f); AddSrcReg("WR0" , 0x10); AddSrcReg("WR1"  , 0x11);
847
  AddSrcReg("WR2" , 0x12); AddSrcReg("WR3" , 0x13); AddSrcReg("WR4"  , 0x14);
848
  AddSrcReg("WR5" , 0x15); AddSrcReg("WR6" , 0x16); AddSrcReg("WR7"  , 0x17);
849
  AddSrcReg("RAM0", 0x18); AddSrcReg("RAM1", 0x19); AddSrcReg("BP0"  , 0x1a);
850
  AddSrcReg("BP1" , 0x1b); AddSrcReg("IX0" , 0x1c); AddSrcReg("IX1"  , 0x1d);
851
  AddSrcReg("K"   , 0x1e); AddSrcReg("L"   , 0x1f); AddSrcReg(NULL   , 0);
852
 
853
  InstrZ = 0;
854
  AddALUSrcReg("IB"  , 0x00); AddALUSrcReg("M"   , 0x01);
855
  AddALUSrcReg("RAM0", 0x02); AddALUSrcReg("RAM1", 0x03);
856
  AddALUSrcReg(NULL  , 0);
857
 
858
  InstrZ = 0;
859
  AddDestReg("NON" , 0x00); AddDestReg("RP"  , 0x01); AddDestReg("PSW0" , 0x02);
860
  AddDestReg("PSW1", 0x03); AddDestReg("SVR" , 0x04); AddDestReg("SR"   , 0x05);
861
  AddDestReg("LC"  , 0x06); AddDestReg("STK" , 0x07); AddDestReg("LKR0" , 0x08);
862
  AddDestReg("KLR1", 0x09); AddDestReg("TRE" , 0x0a); AddDestReg("TR"   , 0x0b);
863
  AddDestReg("AR"  , 0x0c); AddDestReg("SO"  , 0x0d); AddDestReg("DR"   , 0x0e);
864
  AddDestReg("DRS" , 0x0f); AddDestReg("WR0" , 0x10); AddDestReg("WR1"  , 0x11);
865
  AddDestReg("WR2" , 0x12); AddDestReg("WR3" , 0x13); AddDestReg("WR4"  , 0x14);
866
  AddDestReg("WR5" , 0x15); AddDestReg("WR6" , 0x16); AddDestReg("WR7"  , 0x17);
867
  AddDestReg("RAM0", 0x18); AddDestReg("RAM1", 0x19); AddDestReg("BP0"  , 0x1a);
868
  AddDestReg("BP1" , 0x1b); AddDestReg("IX0" , 0x1c); AddDestReg("IX1"  , 0x1d);
869
  AddDestReg("K"   , 0x1e); AddDestReg("L"   , 0x1f); AddDestReg(NULL   , 0);
870
 
871
  InstrComps = (LongWord*) malloc(sizeof(LongWord) * InstrCnt);
872
  InstrDefs = (LongWord*) malloc(sizeof(LongWord) * InstrCnt);
873
  for (InstrZ = 0; InstrZ < InstrCnt; InstrDefs[InstrZ++] = 0xffffffff);
874
  InstrDefs[InstrALU] = 0;
875
  InstrDefs[InstrMove] = 0;
876
  InstrDefs[InstrBM] = 0;
877
  InstrDefs[InstrEM] = 0;
878
  InstrDefs[InstrDP0] = 0;
879
  InstrDefs[InstrDP1] = 0;
880
  InstrDefs[InstrEA] = 0;
881
  InstrDefs[InstrFC] = 0;
882
  InstrDefs[InstrFD] = 0;
883
  InstrDefs[InstrFIS] = 0;
884
  InstrDefs[InstrL] = 0;
885
  InstrDefs[InstrM0] = 0;
886
  InstrDefs[InstrM1] = 0;
887
  InstrDefs[InstrNF] = 0;
888
  InstrDefs[InstrRP] = 0;
889
  InstrDefs[InstrRW] = 0;
890
  InstrDefs[InstrWI] = 0;
891
  InstrDefs[InstrWT] = 0;
892
}
893
 
894
static void DeinitFields(void)
895
{
896
  DestroyInstTable(InstTable);
897
 
898
  order_array_free(SrcRegs);
899
  order_array_free(ALUSrcRegs);
900
  order_array_free(DestRegs);
901
 
902
  order_array_free(JmpOrders);
903
  order_array_free(ALU1Orders);
904
  order_array_free(ALU2Orders);
905
 
906
  free(InstrComps);
907
  free(InstrDefs);
908
}
909
 
910
/*---------------------------------------------------------------------------*/
911
/* Callbacks */
912
 
913
static void MakeCode_77230(void)
914
{
915
  int z, z2;
916
  LongWord Diff;
917
 
918
  /* Nullanweisung */
919
 
920
  if (Memo("") && !*AttrPart.str.p_str && (ArgCnt == 0))
921
    return;
922
 
923
  /* Pseudoanweisungen */
924
 
925
  if (DecodePseudo())
926
    return;
927
 
928
  /* solange dekodieren, bis keine Operanden mehr da oder Fehler */
929
 
930
  Error = False;
931
  InstrMask = 0;
932
  memset(InstrComps, 0, sizeof(LongWord) * InstrCnt);
933
  do
934
  {
935
    if (!LookupInstTable(InstTable, OpPart.str.p_str))
936
    {
937
      WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
938
      Error = True;
939
    }
940
  }
941
  while (!Error && (*OpPart.str.p_str != '\0'));
942
 
943
  /* passende Verknuepfung suchen */
944
 
945
  if (!Error)
946
  {
947
    for (z = 0; z < CaseCnt; z++)
948
    {
949
      /* Bits ermitteln, die nur in einer Maske vorhanden sind */
950
 
951
      Diff = InstrMask^CaseMasks[z];
952
 
953
      /* Fall nur moeglich, wenn Bits im aktuellen Fall gesetzt sind, die
954
         der Fall nicht hat */
955
 
956
      if ((Diff & InstrMask) == 0)
957
      {
958
        /* ist irgendein Feld unbenutzt, fuer das wir keinen Default haben? */
959
 
960
        for (z2 = 0; z2 < InstrCnt; z2++)
961
          if (((Diff & (1l << z2)) != 0) && (InstrDefs[z2] == 0xffffffff))
962
            break;
963
        if (z2 == InstrCnt)
964
          break;
965
      }
966
    }
967
 
968
    switch (z)
969
    {
970
      case 0: /* nur LDI */
971
        DAsmCode[0] = 0xe0000000 + InstrComps[InstrLDI];
972
        CodeLen = 1;
973
        break;
974
      case 1: /* JMP + MOV */
975
        DAsmCode[0] = 0xd0000000 + (InstrComps[InstrBranch] << 10)
976
                                 + InstrComps[InstrMove];
977
        CodeLen = 1;
978
        break;
979
      case 2: /* ALU + MOV + M0 + M1 + DP0 + DP1 */
980
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
981
                    + (InstrComps[InstrDP1] << 15) + (InstrComps[InstrDP0] << 18)
982
                    + (InstrComps[InstrM1] << 21) + (InstrComps[InstrM0] << 23);
983
        CodeLen = 1;
984
        break;
985
      case 3: /* ALU + MOV + EA + DP0 + DP1 */
986
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
987
                    + (InstrComps[InstrDP1] << 15) + (InstrComps[InstrDP0] << 18)
988
                    + (InstrComps[InstrEA] << 21) + 0x02000000;
989
        CodeLen = 1;
990
        break;
991
      case 4: /* ALU + MOV + RP + M0 + DP0 + FC */
992
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
993
                    + (InstrComps[InstrRP] << 21) + (InstrComps[InstrFC] << 15)
994
                    + (InstrComps[InstrM0] << 19) + (InstrComps[InstrDP0] << 16)
995
                    + 0x02800000;
996
        CodeLen = 1;
997
        break;
998
      case 5: /* ALU + MOV + RP + M1 + DP1 + FC */
999
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1000
                    + (InstrComps[InstrRP] << 21) + (InstrComps[InstrFC] << 15)
1001
                    + (InstrComps[InstrM1] << 19) + (InstrComps[InstrDP1] << 16)
1002
                    + 0x03000000;
1003
        CodeLen = 1;
1004
        break;
1005
      case 6: /* ALU + MOV + RP + M0 + M1 + L + FC */
1006
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1007
                    + (InstrComps[InstrRP] << 21) + (InstrComps[InstrL] << 16)
1008
                    + (InstrComps[InstrM0] << 19) + (InstrComps[InstrM1] << 17)
1009
                    + (InstrComps[InstrFC] << 15) + 0x03800000;
1010
        CodeLen = 1;
1011
        break;
1012
      case 7: /* ALU + MOV + BASE0 + BASE1 + FC */
1013
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1014
                    + (InstrComps[InstrBASE0] << 19) + (InstrComps[InstrBASE1] << 16)
1015
                    + (InstrComps[InstrFC] << 15) + 0x04000000;
1016
        CodeLen = 1;
1017
        break;
1018
      case 8: /* ALU + MOV + RPC + L+ FC */
1019
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1020
                    + (InstrComps[InstrRPC] << 18) + (InstrComps[InstrL] << 16)
1021
                    + (InstrComps[InstrFC] << 15) + 0x04400000;
1022
        CodeLen = 1;
1023
        break;
1024
      case 9: /* ALU + MOV + P2 + P3 + EM + BM + L + FC */
1025
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1026
                    + (InstrComps[InstrP2] << 20) + (InstrComps[InstrP3] << 21)
1027
                    + (InstrComps[InstrEM] << 19) + (InstrComps[InstrBM] << 17)
1028
                    + (InstrComps[InstrL] << 16) + (InstrComps[InstrFC] << 15)
1029
                    + 0x04800000;
1030
        CodeLen = 1;
1031
        break;
1032
      case 10: /* ALU + MOV + RW + L + FC */
1033
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1034
                    + (InstrComps[InstrRW] << 20) + (InstrComps[InstrL] << 16)
1035
                    + (InstrComps[InstrFC] << 15) + 0x04c00000;
1036
        CodeLen = 1;
1037
        break;
1038
      case 11: /* ALU + MOV + WT + L + FC */
1039
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1040
                    + (InstrComps[InstrWT] << 19) + (InstrComps[InstrL] << 16)
1041
                    + (InstrComps[InstrFC] << 15) + 0x05000000;
1042
        CodeLen = 1;
1043
        break;
1044
      case 12: /* ALU + MOV + NF + WI + L + FC */
1045
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1046
                    + (InstrComps[InstrNF] << 19) + (InstrComps[InstrWI] << 17)
1047
                    + (InstrComps[InstrL] << 16) + (InstrComps[InstrFC] << 15)
1048
                    + 0x05400000;
1049
        CodeLen = 1;
1050
        break;
1051
      case 13: /* ALU + MOV + FIS + FD + L */
1052
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1053
                    + (InstrComps[InstrFIS] << 19) + (InstrComps[InstrFD] << 17)
1054
                    + (InstrComps[InstrL] << 16) + 0x05800000;
1055
        CodeLen = 1;
1056
        break;
1057
      case 14: /* ALU + MOV + SHV */
1058
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1059
                    + (InstrComps[InstrSHV] << 15) + 0x05c00000;
1060
        CodeLen = 1;
1061
        break;
1062
      case 15: /* ALU + MOV + RPS */
1063
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1064
                    + (InstrComps[InstrRPS] << 15) + 0x06000000;
1065
        CodeLen = 1;
1066
        break;
1067
      case 16: /* ALU + MOV + NAL */
1068
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1069
                    + (InstrComps[InstrNAL] << 15) + 0x07000000;
1070
        CodeLen = 1;
1071
        break;
1072
      default:
1073
        WrError(ErrNum_InvParAddrMode);
1074
    }
1075
  }
1076
}
1077
 
1078
static Boolean IsDef_77230(void)
1079
{
1080
  return False;
1081
}
1082
 
1083
static void SwitchFrom_77230(void)
1084
{
1085
  DeinitFields();
1086
}
1087
 
1088
static void SwitchTo_77230(void)
1089
{
1090
  const TFamilyDescr *FoundDescr;
1091
 
1092
  FoundDescr = FindFamilyByName("77230");
1093
 
1094
  TurnWords = False;
1095
  SetIntConstMode(eIntConstModeIntel);
1096
  PCSymbol = "$";
1097
  HeaderID = FoundDescr->Id;
1098
  NOPCode = 0x00000000;
1099
  DivideChars = ",";
1100
  HasAttrs = False;
1101
 
1102
  ValidSegs = (1 << SegCode) | (1 << SegXData) | (1 << SegYData) | (1 << SegRData);
1103
  Grans[SegCode ] = 4; ListGrans[SegCode ] = 4; SegInits[SegCode ] = 0;
1104
  SegLimits[SegCode ] = 0x1fff;
1105
  Grans[SegXData] = 4; ListGrans[SegXData] = 4; SegInits[SegXData] = 0;
1106
  SegLimits[SegXData] = 0x1ff;
1107
  Grans[SegYData] = 4; ListGrans[SegYData] = 4; SegInits[SegYData] = 0;
1108
  SegLimits[SegYData] = 0x1ff;
1109
  Grans[SegRData] = 4; ListGrans[SegRData] = 4; SegInits[SegRData] = 0;
1110
  SegLimits[SegRData] = 0x3ff;
1111
 
1112
  onoff_packing_add(True);
1113
 
1114
  MakeCode = MakeCode_77230;
1115
  IsDef = IsDef_77230;
1116
  SwitchFrom = SwitchFrom_77230;
1117
 
1118
  InitFields();
1119
}
1120
 
1121
/*---------------------------------------------------------------------------*/
1122
/* Initialisierung */
1123
 
1124
void code77230_init(void)
1125
{
1126
  CPU77230 = AddCPU("77230", SwitchTo_77230);
1127
}