Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

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