Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1126 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 "ieeefloat.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
  LongWord temp;
590
  LongInt sign, mant, expo, Size;
591
 
592
  if (Memo("DW"))
593
  {
594
    if (ChkArgCnt(1, ArgCntMax))
595
    {
596
      TempResult t;
597
      Boolean OK = True;
598
      tStrComp *pArg;
599
 
600
      as_tempres_ini(&t);
601
      forallargs(pArg, OK)
602
      {
603
        EvalStrExpression(pArg, &t);
604
        switch(t.Typ)
605
        {
606
          case TempString:
607
            if (MultiCharToInt(&t, 4))
608
              goto ToInt;
609
 
610
            if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pArg))
611
              OK = False;
612
            else
613
              OK = !string_2_dasm_code(&t.Contents.str, Packing ? 4 : 1, True);
614
            break;
615
          case TempInt:
616
          ToInt:
617
            if (!RangeCheck(t.Contents.Int, Int32))
618
            {
619
              WrStrErrorPos(ErrNum_OverRange, pArg);
620
              OK = False;
621
              break;
622
            }
623
            DAsmCode[CodeLen++] = t.Contents.Int;
624
            break;
625
          case TempFloat:
626
            if (!FloatRangeCheck(t.Contents.Float, Float32))
627
            {
628
              WrStrErrorPos(ErrNum_OverRange, pArg);
629
              OK = False;
630
              break;
631
            }
632
            Double_2_ieee4(t.Contents.Float, (Byte*) &temp, HostBigEndian);
633
            sign = (temp >> 31) & 1;
634
            expo = (temp >> 23) & 255;
635
            mant = temp & 0x7fffff;
636
            if ((mant == 0) && (expo == 0))
637
              DAsmCode[CodeLen++] = 0x80000000;
638
            else
639
            {
640
              if (expo > 0)
641
              {
642
                mant |= 0x800000;
643
                expo -= 127;
644
              }
645
              else
646
                expo -= 126;
647
              if (mant >= 0x800000)
648
              {
649
                mant = mant >> 1;
650
                expo += 1;
651
              }
652
              if (sign == 1)
653
                mant = ((mant ^ 0xffffff) + 1);
654
              DAsmCode[CodeLen++] = ((expo & 0xff) << 24) | (mant & 0xffffff);
655
            }
656
            break;
657
          default:
658
            OK = False;
659
        }
660
      }
661
      if (!OK)
662
        CodeLen = 0;
663
      as_tempres_free(&t);
664
    }
665
    return True;
666
  }
667
 
668
  if (Memo("DS"))
669
  {
670
    if (ChkArgCnt(1, 1))
671
    {
672
      tSymbolFlags Flags;
673
      Boolean OK;
674
 
675
      Size = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
676
      if (mFirstPassUnknown(Flags))
677
      {
678
        WrError(ErrNum_FirstPassCalc);
679
        OK = False;
680
      }
681
      if (OK)
682
      {
683
        DontPrint = True;
684
        if (!Size)
685
          WrError(ErrNum_NullResMem);
686
        CodeLen = Size;
687
        BookKeeping();
688
      }
689
    }
690
    return True;
691
  }
692
 
693
  return FALSE;
694
}
695
 
696
/*---------------------------------------------------------------------------*/
697
/* Codetabellenverwaltung */
698
 
699
static void AddJmp(const char *NName, LongWord NCode)
700
{
701
  order_array_rsv_end(JmpOrders, FixedOrder);
702
  JmpOrders[InstrZ].Code = NCode;
703
  AddInstTable(InstTable, NName, InstrZ++, DecodeJmp);
704
}
705
 
706
static void AddALU1(const char *NName, LongWord NCode)
707
{
708
  order_array_rsv_end(ALU1Orders, FixedOrder);
709
  ALU1Orders[InstrZ].Code = NCode;
710
  AddInstTable(InstTable, NName, InstrZ++, DecodeALU1);
711
}
712
 
713
static void AddALU2(const char *NName, LongWord NCode)
714
{
715
  order_array_rsv_end(ALU2Orders, FixedOrder);
716
  ALU2Orders[InstrZ].Code = NCode;
717
  AddInstTable(InstTable, NName, InstrZ++, DecodeALU2);
718
}
719
 
720
static void AddSrcReg(const char *NName, LongWord NCode)
721
{
722
  order_array_rsv_end(SrcRegs, Register);
723
  SrcRegs[InstrZ].Name = NName;
724
  SrcRegs[InstrZ++].Code = NCode;
725
}
726
 
727
static void AddALUSrcReg(const char *NName, LongWord NCode)
728
{
729
  order_array_rsv_end(ALUSrcRegs, Register);
730
  ALUSrcRegs[InstrZ].Name = NName;
731
  ALUSrcRegs[InstrZ++].Code = NCode;
732
}
733
 
734
static void AddDestReg(const char *NName, LongWord NCode)
735
{
736
  order_array_rsv_end(DestRegs, Register);
737
  DestRegs[InstrZ].Name = NName;
738
  DestRegs[InstrZ++].Code = NCode;
739
}
740
 
741
static void InitFields(void)
742
{
743
  InstTable = CreateInstTable(201);
744
 
745
  AddInstTable(InstTable, "MOV", 0, DecodeMOV);
746
  AddInstTable(InstTable, "LDI", 0, DecodeLDI);
747
  AddInstTable(InstTable, "NOP", 0, DecodeNOP);
748
 
749
  AddInstTable(InstTable, "SPCBP0", 1, DecodeM0);
750
  AddInstTable(InstTable, "SPCIX0", 2, DecodeM0);
751
  AddInstTable(InstTable, "SPCBI0", 3, DecodeM0);
752
 
753
  AddInstTable(InstTable, "SPCBP1", 1, DecodeM1);
754
  AddInstTable(InstTable, "SPCIX1", 2, DecodeM1);
755
  AddInstTable(InstTable, "SPCBI1", 3, DecodeM1);
756
 
757
  AddInstTable(InstTable, "INCBP0", 1, DecodeDP0);
758
  AddInstTable(InstTable, "DECBP0", 2, DecodeDP0);
759
  AddInstTable(InstTable, "CLRBP0", 3, DecodeDP0);
760
  AddInstTable(InstTable, "STIX0" , 4, DecodeDP0);
761
  AddInstTable(InstTable, "INCIX0", 5, DecodeDP0);
762
  AddInstTable(InstTable, "DECIX0", 6, DecodeDP0);
763
  AddInstTable(InstTable, "CLRIX0", 7, DecodeDP0);
764
 
765
  AddInstTable(InstTable, "INCBP1", 1, DecodeDP1);
766
  AddInstTable(InstTable, "DECBP1", 2, DecodeDP1);
767
  AddInstTable(InstTable, "CLRBP1", 3, DecodeDP1);
768
  AddInstTable(InstTable, "STIX1" , 4, DecodeDP1);
769
  AddInstTable(InstTable, "INCIX1", 5, DecodeDP1);
770
  AddInstTable(InstTable, "DECIX1", 6, DecodeDP1);
771
  AddInstTable(InstTable, "CLRIX1", 7, DecodeDP1);
772
 
773
  AddInstTable(InstTable, "INCAR" , 1, DecodeEA);
774
  AddInstTable(InstTable, "DECAR" , 2, DecodeEA);
775
 
776
  AddInstTable(InstTable, "XCHPSW", 1, DecodeFC);
777
 
778
  AddInstTable(InstTable, "INCRP" , 1, DecodeRP);
779
  AddInstTable(InstTable, "DECRP" , 2, DecodeRP);
780
  AddInstTable(InstTable, "INCBRP", 3, DecodeRP);
781
 
782
  AddInstTable(InstTable, "DECLC" , 1, DecodeL);
783
 
784
  AddInstTable(InstTable, "MCNBP0", InstrBASE0, DecodeBASE);
785
  AddInstTable(InstTable, "MCNBP1", InstrBASE1, DecodeBASE);
786
 
787
  AddInstTable(InstTable, "BITRP" , 0, DecodeRPC);
788
 
789
  AddInstTable(InstTable, "CLRP2" , 0, DecodeP2);
790
  AddInstTable(InstTable, "SETP2" , 1, DecodeP2);
791
 
792
  AddInstTable(InstTable, "CLRP3" , 0, DecodeP3);
793
  AddInstTable(InstTable, "SETP3" , 1, DecodeP3);
794
 
795
  AddInstTable(InstTable, "DI"    , 0, DecodeEM);
796
  AddInstTable(InstTable, "EI"    , 1, DecodeEM);
797
  AddInstTable(InstTable, "CLRBM" , 1, DecodeBM);
798
  AddInstTable(InstTable, "SETBM" , 2, DecodeBM);
799
 
800
  AddInstTable(InstTable, "RD"    , 1, DecodeRW);
801
  AddInstTable(InstTable, "WR"    , 2, DecodeRW);
802
 
803
  AddInstTable(InstTable, "WRBORD", 1, DecodeWT);
804
  AddInstTable(InstTable, "WRBL24", 2, DecodeWT);
805
  AddInstTable(InstTable, "WRBL23", 3, DecodeWT);
806
  AddInstTable(InstTable, "WRBEL8", 4, DecodeWT);
807
  AddInstTable(InstTable, "WRBL8E", 5, DecodeWT);
808
  AddInstTable(InstTable, "WRBXCH", 6, DecodeWT);
809
  AddInstTable(InstTable, "WRBBRV", 7, DecodeWT);
810
 
811
  AddInstTable(InstTable, "TRNORM", 2, DecodeNF);
812
  AddInstTable(InstTable, "RDNORM", 4, DecodeNF);
813
  AddInstTable(InstTable, "FLTFIX", 6, DecodeNF);
814
  AddInstTable(InstTable, "FIXMA" , 7, DecodeNF);
815
 
816
  AddInstTable(InstTable, "BWRL24", 1, DecodeWI);
817
  AddInstTable(InstTable, "BWRORD", 2, DecodeWI);
818
 
819
  AddInstTable(InstTable, "SPCPSW0", 1, DecodeFIS);
820
  AddInstTable(InstTable, "SPCPSW1", 2, DecodeFIS);
821
  AddInstTable(InstTable, "CLRPSW0", 4, DecodeFIS);
822
  AddInstTable(InstTable, "CLRPSW1", 5, DecodeFIS);
823
  AddInstTable(InstTable, "CLRPSW" , 6, DecodeFIS);
824
 
825
  AddInstTable(InstTable, "SPIE", 1, DecodeFD);
826
  AddInstTable(InstTable, "IESP", 2, DecodeFD);
827
 
828
  AddInstTable(InstTable, "SETSVL", 0, DecodeSHV);
829
  AddInstTable(InstTable, "SETSVR", 1, DecodeSHV);
830
 
831
  AddInstTable(InstTable, "SPCRA", 0, DecodeRPS);
832
  AddInstTable(InstTable, "JBLK" , 0, DecodeNAL);
833
 
834
  InstrZ = 0;
835
  AddJmp("JMP"   , 0x0100); AddJmp("CALL"  , 0x0101); AddJmp("RET"   , 0x0002);
836
  AddJmp("JNZRP" , 0x0103); AddJmp("JZ0"   , 0x0104); AddJmp("JNZ0"  , 0x0105);
837
  AddJmp("JZ1"   , 0x0106); AddJmp("JNZ1"  , 0x0107); AddJmp("JC0"   , 0x0108);
838
  AddJmp("JNC0"  , 0x0109); AddJmp("JC1"   , 0x010a); AddJmp("JNC1"  , 0x010b);
839
  AddJmp("JS0"   , 0x010c); AddJmp("JNS0"  , 0x010d); AddJmp("JS1"   , 0x010e);
840
  AddJmp("JNS1"  , 0x010f); AddJmp("JV0"   , 0x0110); AddJmp("JNV0"  , 0x0111);
841
  AddJmp("JV1"   , 0x0112); AddJmp("JNV1"  , 0x0113); AddJmp("JEV0"  , 0x0114);
842
  AddJmp("JEV1"  , 0x0115); AddJmp("JNFSI" , 0x0116); AddJmp("JNESO" , 0x0117);
843
  AddJmp("JIP0"  , 0x0118); AddJmp("JIP1"  , 0x0119); AddJmp("JNZIX0", 0x011a);
844
  AddJmp("JNZIX1", 0x011b); AddJmp("JNZBP0", 0x011c); AddJmp("JNZBP1", 0x011d);
845
  AddJmp("JRDY"  , 0x011e); AddJmp("JRQM"  , 0x011f);
846
 
847
  InstrZ = 0;
848
  AddALU1("INC"  , 0x01); AddALU1("DEC"  , 0x02); AddALU1("ABS"  , 0x03);
849
  AddALU1("NOT"  , 0x04); AddALU1("NEG"  , 0x05); AddALU1("SHLC" , 0x06);
850
  AddALU1("SHRC" , 0x07); AddALU1("ROL"  , 0x08); AddALU1("ROR"  , 0x09);
851
  AddALU1("SHLM" , 0x0a); AddALU1("SHRM" , 0x0b); AddALU1("SHRAM", 0x0c);
852
  AddALU1("CLR"  , 0x0d); AddALU1("NORM" , 0x0e); AddALU1("CVT"  , 0x0f);
853
 
854
  InstrZ = 0;
855
  AddALU2("ADD"  , 0x10); AddALU2("SUB"  , 0x11); AddALU2("ADDC" , 0x12);
856
  AddALU2("SUBC" , 0x13); AddALU2("CMP"  , 0x14); AddALU2("AND"  , 0x15);
857
  AddALU2("OR"   , 0x16); AddALU2("XOR"  , 0x17); AddALU2("ADDF" , 0x18);
858
  AddALU2("SUBF" , 0x19);
859
 
860
  InstrZ = 0;
861
  AddSrcReg("NON" , 0x00); AddSrcReg("RP"  , 0x01); AddSrcReg("PSW0" , 0x02);
862
  AddSrcReg("PSW1", 0x03); AddSrcReg("SVR" , 0x04); AddSrcReg("SR"   , 0x05);
863
  AddSrcReg("LC"  , 0x06); AddSrcReg("STX" , 0x07); AddSrcReg("M"    , 0x08);
864
  AddSrcReg("ML"  , 0x09); AddSrcReg("ROM" , 0x0a); AddSrcReg("TR"   , 0x0b);
865
  AddSrcReg("AR"  , 0x0c); AddSrcReg("SI"  , 0x0d); AddSrcReg("DR"   , 0x0e);
866
  AddSrcReg("DRS" , 0x0f); AddSrcReg("WR0" , 0x10); AddSrcReg("WR1"  , 0x11);
867
  AddSrcReg("WR2" , 0x12); AddSrcReg("WR3" , 0x13); AddSrcReg("WR4"  , 0x14);
868
  AddSrcReg("WR5" , 0x15); AddSrcReg("WR6" , 0x16); AddSrcReg("WR7"  , 0x17);
869
  AddSrcReg("RAM0", 0x18); AddSrcReg("RAM1", 0x19); AddSrcReg("BP0"  , 0x1a);
870
  AddSrcReg("BP1" , 0x1b); AddSrcReg("IX0" , 0x1c); AddSrcReg("IX1"  , 0x1d);
871
  AddSrcReg("K"   , 0x1e); AddSrcReg("L"   , 0x1f); AddSrcReg(NULL   , 0);
872
 
873
  InstrZ = 0;
874
  AddALUSrcReg("IB"  , 0x00); AddALUSrcReg("M"   , 0x01);
875
  AddALUSrcReg("RAM0", 0x02); AddALUSrcReg("RAM1", 0x03);
876
  AddALUSrcReg(NULL  , 0);
877
 
878
  InstrZ = 0;
879
  AddDestReg("NON" , 0x00); AddDestReg("RP"  , 0x01); AddDestReg("PSW0" , 0x02);
880
  AddDestReg("PSW1", 0x03); AddDestReg("SVR" , 0x04); AddDestReg("SR"   , 0x05);
881
  AddDestReg("LC"  , 0x06); AddDestReg("STK" , 0x07); AddDestReg("LKR0" , 0x08);
882
  AddDestReg("KLR1", 0x09); AddDestReg("TRE" , 0x0a); AddDestReg("TR"   , 0x0b);
883
  AddDestReg("AR"  , 0x0c); AddDestReg("SO"  , 0x0d); AddDestReg("DR"   , 0x0e);
884
  AddDestReg("DRS" , 0x0f); AddDestReg("WR0" , 0x10); AddDestReg("WR1"  , 0x11);
885
  AddDestReg("WR2" , 0x12); AddDestReg("WR3" , 0x13); AddDestReg("WR4"  , 0x14);
886
  AddDestReg("WR5" , 0x15); AddDestReg("WR6" , 0x16); AddDestReg("WR7"  , 0x17);
887
  AddDestReg("RAM0", 0x18); AddDestReg("RAM1", 0x19); AddDestReg("BP0"  , 0x1a);
888
  AddDestReg("BP1" , 0x1b); AddDestReg("IX0" , 0x1c); AddDestReg("IX1"  , 0x1d);
889
  AddDestReg("K"   , 0x1e); AddDestReg("L"   , 0x1f); AddDestReg(NULL   , 0);
890
 
891
  InstrComps = (LongWord*) malloc(sizeof(LongWord) * InstrCnt);
892
  InstrDefs = (LongWord*) malloc(sizeof(LongWord) * InstrCnt);
893
  for (InstrZ = 0; InstrZ < InstrCnt; InstrDefs[InstrZ++] = 0xffffffff);
894
  InstrDefs[InstrALU] = 0;
895
  InstrDefs[InstrMove] = 0;
896
  InstrDefs[InstrBM] = 0;
897
  InstrDefs[InstrEM] = 0;
898
  InstrDefs[InstrDP0] = 0;
899
  InstrDefs[InstrDP1] = 0;
900
  InstrDefs[InstrEA] = 0;
901
  InstrDefs[InstrFC] = 0;
902
  InstrDefs[InstrFD] = 0;
903
  InstrDefs[InstrFIS] = 0;
904
  InstrDefs[InstrL] = 0;
905
  InstrDefs[InstrM0] = 0;
906
  InstrDefs[InstrM1] = 0;
907
  InstrDefs[InstrNF] = 0;
908
  InstrDefs[InstrRP] = 0;
909
  InstrDefs[InstrRW] = 0;
910
  InstrDefs[InstrWI] = 0;
911
  InstrDefs[InstrWT] = 0;
912
}
913
 
914
static void DeinitFields(void)
915
{
916
  DestroyInstTable(InstTable);
917
 
918
  order_array_free(SrcRegs);
919
  order_array_free(ALUSrcRegs);
920
  order_array_free(DestRegs);
921
 
922
  order_array_free(JmpOrders);
923
  order_array_free(ALU1Orders);
924
  order_array_free(ALU2Orders);
925
 
926
  free(InstrComps);
927
  free(InstrDefs);
928
}
929
 
930
/*---------------------------------------------------------------------------*/
931
/* Callbacks */
932
 
933
static void MakeCode_77230(void)
934
{
935
  int z, z2;
936
  LongWord Diff;
937
 
938
  /* Nullanweisung */
939
 
940
  if (Memo("") && !*AttrPart.str.p_str && (ArgCnt == 0))
941
    return;
942
 
943
  /* Pseudoanweisungen */
944
 
945
  if (DecodePseudo())
946
    return;
947
 
948
  /* solange dekodieren, bis keine Operanden mehr da oder Fehler */
949
 
950
  Error = False;
951
  InstrMask = 0;
952
  memset(InstrComps, 0, sizeof(LongWord) * InstrCnt);
953
  do
954
  {
955
    if (!LookupInstTable(InstTable, OpPart.str.p_str))
956
    {
957
      WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
958
      Error = True;
959
    }
960
  }
961
  while (!Error && (*OpPart.str.p_str != '\0'));
962
 
963
  /* passende Verknuepfung suchen */
964
 
965
  if (!Error)
966
  {
967
    for (z = 0; z < CaseCnt; z++)
968
    {
969
      /* Bits ermitteln, die nur in einer Maske vorhanden sind */
970
 
971
      Diff = InstrMask^CaseMasks[z];
972
 
973
      /* Fall nur moeglich, wenn Bits im aktuellen Fall gesetzt sind, die
974
         der Fall nicht hat */
975
 
976
      if ((Diff & InstrMask) == 0)
977
      {
978
        /* ist irgendein Feld unbenutzt, fuer das wir keinen Default haben? */
979
 
980
        for (z2 = 0; z2 < InstrCnt; z2++)
981
          if (((Diff & (1l << z2)) != 0) && (InstrDefs[z2] == 0xffffffff))
982
            break;
983
        if (z2 == InstrCnt)
984
          break;
985
      }
986
    }
987
 
988
    switch (z)
989
    {
990
      case 0: /* nur LDI */
991
        DAsmCode[0] = 0xe0000000 + InstrComps[InstrLDI];
992
        CodeLen = 1;
993
        break;
994
      case 1: /* JMP + MOV */
995
        DAsmCode[0] = 0xd0000000 + (InstrComps[InstrBranch] << 10)
996
                                 + InstrComps[InstrMove];
997
        CodeLen = 1;
998
        break;
999
      case 2: /* ALU + MOV + M0 + M1 + DP0 + DP1 */
1000
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1001
                    + (InstrComps[InstrDP1] << 15) + (InstrComps[InstrDP0] << 18)
1002
                    + (InstrComps[InstrM1] << 21) + (InstrComps[InstrM0] << 23);
1003
        CodeLen = 1;
1004
        break;
1005
      case 3: /* ALU + MOV + EA + DP0 + DP1 */
1006
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1007
                    + (InstrComps[InstrDP1] << 15) + (InstrComps[InstrDP0] << 18)
1008
                    + (InstrComps[InstrEA] << 21) + 0x02000000;
1009
        CodeLen = 1;
1010
        break;
1011
      case 4: /* ALU + MOV + RP + M0 + DP0 + FC */
1012
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1013
                    + (InstrComps[InstrRP] << 21) + (InstrComps[InstrFC] << 15)
1014
                    + (InstrComps[InstrM0] << 19) + (InstrComps[InstrDP0] << 16)
1015
                    + 0x02800000;
1016
        CodeLen = 1;
1017
        break;
1018
      case 5: /* ALU + MOV + RP + M1 + DP1 + FC */
1019
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1020
                    + (InstrComps[InstrRP] << 21) + (InstrComps[InstrFC] << 15)
1021
                    + (InstrComps[InstrM1] << 19) + (InstrComps[InstrDP1] << 16)
1022
                    + 0x03000000;
1023
        CodeLen = 1;
1024
        break;
1025
      case 6: /* ALU + MOV + RP + M0 + M1 + L + FC */
1026
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1027
                    + (InstrComps[InstrRP] << 21) + (InstrComps[InstrL] << 16)
1028
                    + (InstrComps[InstrM0] << 19) + (InstrComps[InstrM1] << 17)
1029
                    + (InstrComps[InstrFC] << 15) + 0x03800000;
1030
        CodeLen = 1;
1031
        break;
1032
      case 7: /* ALU + MOV + BASE0 + BASE1 + FC */
1033
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1034
                    + (InstrComps[InstrBASE0] << 19) + (InstrComps[InstrBASE1] << 16)
1035
                    + (InstrComps[InstrFC] << 15) + 0x04000000;
1036
        CodeLen = 1;
1037
        break;
1038
      case 8: /* ALU + MOV + RPC + L+ FC */
1039
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1040
                    + (InstrComps[InstrRPC] << 18) + (InstrComps[InstrL] << 16)
1041
                    + (InstrComps[InstrFC] << 15) + 0x04400000;
1042
        CodeLen = 1;
1043
        break;
1044
      case 9: /* ALU + MOV + P2 + P3 + EM + BM + L + FC */
1045
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1046
                    + (InstrComps[InstrP2] << 20) + (InstrComps[InstrP3] << 21)
1047
                    + (InstrComps[InstrEM] << 19) + (InstrComps[InstrBM] << 17)
1048
                    + (InstrComps[InstrL] << 16) + (InstrComps[InstrFC] << 15)
1049
                    + 0x04800000;
1050
        CodeLen = 1;
1051
        break;
1052
      case 10: /* ALU + MOV + RW + L + FC */
1053
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1054
                    + (InstrComps[InstrRW] << 20) + (InstrComps[InstrL] << 16)
1055
                    + (InstrComps[InstrFC] << 15) + 0x04c00000;
1056
        CodeLen = 1;
1057
        break;
1058
      case 11: /* ALU + MOV + WT + L + FC */
1059
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1060
                    + (InstrComps[InstrWT] << 19) + (InstrComps[InstrL] << 16)
1061
                    + (InstrComps[InstrFC] << 15) + 0x05000000;
1062
        CodeLen = 1;
1063
        break;
1064
      case 12: /* ALU + MOV + NF + WI + L + FC */
1065
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1066
                    + (InstrComps[InstrNF] << 19) + (InstrComps[InstrWI] << 17)
1067
                    + (InstrComps[InstrL] << 16) + (InstrComps[InstrFC] << 15)
1068
                    + 0x05400000;
1069
        CodeLen = 1;
1070
        break;
1071
      case 13: /* ALU + MOV + FIS + FD + L */
1072
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1073
                    + (InstrComps[InstrFIS] << 19) + (InstrComps[InstrFD] << 17)
1074
                    + (InstrComps[InstrL] << 16) + 0x05800000;
1075
        CodeLen = 1;
1076
        break;
1077
      case 14: /* ALU + MOV + SHV */
1078
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1079
                    + (InstrComps[InstrSHV] << 15) + 0x05c00000;
1080
        CodeLen = 1;
1081
        break;
1082
      case 15: /* ALU + MOV + RPS */
1083
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1084
                    + (InstrComps[InstrRPS] << 15) + 0x06000000;
1085
        CodeLen = 1;
1086
        break;
1087
      case 16: /* ALU + MOV + NAL */
1088
        DAsmCode[0] = (InstrComps[InstrALU] << 10) + InstrComps[InstrMove]
1089
                    + (InstrComps[InstrNAL] << 15) + 0x07000000;
1090
        CodeLen = 1;
1091
        break;
1092
      default:
1093
        WrError(ErrNum_InvParAddrMode);
1094
    }
1095
  }
1096
}
1097
 
1098
static Boolean IsDef_77230(void)
1099
{
1100
  return False;
1101
}
1102
 
1103
static void SwitchFrom_77230(void)
1104
{
1105
  DeinitFields();
1106
}
1107
 
1108
static void SwitchTo_77230(void)
1109
{
1110
  const TFamilyDescr *FoundDescr;
1111
 
1112
  FoundDescr = FindFamilyByName("77230");
1113
 
1114
  TurnWords = False;
1115
  SetIntConstMode(eIntConstModeIntel);
1116
  PCSymbol = "$";
1117
  HeaderID = FoundDescr->Id;
1118
  NOPCode = 0x00000000;
1119
  DivideChars = ",";
1120
  HasAttrs = False;
1121
 
1122
  ValidSegs = (1 << SegCode) | (1 << SegXData) | (1 << SegYData) | (1 << SegRData);
1123
  Grans[SegCode ] = 4; ListGrans[SegCode ] = 4; SegInits[SegCode ] = 0;
1124
  SegLimits[SegCode ] = 0x1fff;
1125
  Grans[SegXData] = 4; ListGrans[SegXData] = 4; SegInits[SegXData] = 0;
1126
  SegLimits[SegXData] = 0x1ff;
1127
  Grans[SegYData] = 4; ListGrans[SegYData] = 4; SegInits[SegYData] = 0;
1128
  SegLimits[SegYData] = 0x1ff;
1129
  Grans[SegRData] = 4; ListGrans[SegRData] = 4; SegInits[SegRData] = 0;
1130
  SegLimits[SegRData] = 0x3ff;
1131
 
1132
  onoff_packing_add(True);
1133
 
1134
  MakeCode = MakeCode_77230;
1135
  IsDef = IsDef_77230;
1136
  SwitchFrom = SwitchFrom_77230;
1137
 
1138
  InitFields();
1139
}
1140
 
1141
/*---------------------------------------------------------------------------*/
1142
/* Initialisierung */
1143
 
1144
void code77230_init(void)
1145
{
1146
  CPU77230 = AddCPU("77230", SwitchTo_77230);
1147
}