Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* code8x30x.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS-Portierung                                                             */
6
/*                                                                           */
7
/* Codegenerator Signetics 8X30x                                             */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
#include "stdinc.h"
12
#include <string.h>
13
#include <ctype.h>
14
 
15
#include "nls.h"
16
#include "chunks.h"
17
#include "bpemu.h"
18
#include "strutil.h"
19
 
20
#include "asmdef.h"
21
#include "asmsub.h"
22
#include "asmpars.h"
23
#include "asmitree.h"
24
#include "codevars.h"
25
#include "codepseudo.h"
26
#include "errmsg.h"
27
 
28
#include "code8x30x.h"
29
 
30
/*****************************************************************************/
31
 
32
static CPUVar CPU8x300, CPU8x305;
33
 
34
/*-------------------------------------------------------------------------*/
35
 
36
static Boolean DecodeReg(const tStrComp *pArg, Word *Erg, ShortInt *ErgLen)
37
{
38
  Boolean OK;
39
  Word Acc;
40
  LongInt Adr;
41
  char *z;
42
  int Len = strlen(pArg->str.p_str);
43
 
44
  *ErgLen = -1;
45
 
46
  if (!as_strcasecmp(pArg->str.p_str, "AUX"))
47
  {
48
    *Erg = 0;
49
    return True;
50
  }
51
 
52
  if (!as_strcasecmp(pArg->str.p_str, "OVF"))
53
  {
54
    *Erg = 8;
55
    return True;
56
  }
57
 
58
  if (!as_strcasecmp(pArg->str.p_str, "IVL"))
59
  {
60
    *Erg = 7;
61
    return True;
62
  }
63
 
64
  if (!as_strcasecmp(pArg->str.p_str, "IVR"))
65
  {
66
    *Erg = 15;
67
    return True;
68
  }
69
 
70
  if ((as_toupper(*pArg->str.p_str) == 'R') && (Len > 1) && (Len < 4))
71
  {
72
    Acc = 0;
73
    OK = True;
74
    for (z = pArg->str.p_str + 1; *z != '\0'; z++)
75
      if (OK)
76
      {
77
        if ((*z < '0') || (*z > '7'))
78
          OK = False;
79
        else
80
          Acc = (Acc << 3) + (*z - '0');
81
      }
82
    if ((OK) && (Acc < 32))
83
    {
84
      if ((MomCPU == CPU8x300) && (Acc > 9) && (Acc < 15))
85
      {
86
        WrStrErrorPos(ErrNum_InvReg, pArg);
87
        return False;
88
      }
89
      else *Erg = Acc;
90
      return True;
91
    }
92
  }
93
 
94
  if ((Len == 4) && (as_strncasecmp(pArg->str.p_str + 1, "IV", 2) == 0) && (pArg->str.p_str[3] >= '0') && (pArg->str.p_str[3] <= '7'))
95
  {
96
    if (as_toupper(*pArg->str.p_str) == 'L')
97
    {
98
      *Erg = pArg->str.p_str[3]-'0' + 0x10;
99
      return True;
100
    }
101
    else if (as_toupper(*pArg->str.p_str) == 'R')
102
    {
103
      *Erg = pArg->str.p_str[3] - '0' + 0x18;
104
      return True;
105
    }
106
  }
107
 
108
  /* IV - Objekte */
109
 
110
  Adr = EvalStrIntExpression(pArg, UInt24, &OK);
111
  if (OK)
112
  {
113
    *ErgLen = Adr & 7;
114
    *Erg = 0x10 | ((Adr & 0x10) >> 1) | ((Adr & 0x700) >> 8);
115
    return True;
116
  }
117
  else
118
    return False;
119
}
120
 
121
static char *HasDisp(char *Asc)
122
{
123
  int Lev;
124
  char *z;
125
  int l = strlen(Asc);
126
 
127
  if (Asc[l - 1] == ')')
128
  {
129
    z = Asc + l - 2;
130
    Lev = 0;
131
    while ((z >= Asc) && (Lev != -1))
132
    {
133
      switch (*z)
134
      {
135
        case '(':
136
          Lev--;
137
          break;
138
        case ')':
139
          Lev++;
140
          break;
141
      }
142
      if (Lev != -1)
143
        z--;
144
    }
145
    if (Lev != -1)
146
    {
147
      WrError(ErrNum_BrackErr);
148
      return NULL;
149
    }
150
  }
151
  else
152
    z = NULL;
153
 
154
  return z;
155
}
156
 
157
static Boolean GetLen(const tStrComp *pArg, Word *Erg, tSymbolFlags *pFlags)
158
{
159
  Boolean OK;
160
 
161
  *Erg = EvalStrIntExpressionWithFlags(pArg, UInt4, &OK, pFlags);
162
  if (!OK)
163
    return False;
164
  if (mFirstPassUnknown(*pFlags))
165
    *Erg = 8;
166
  if (!ChkRange(*Erg, 1, 8))
167
    return False;
168
  *Erg &= 7;
169
  return True;
170
}
171
 
172
/*-------------------------------------------------------------------------*/
173
 
174
static void DecodeNOP(Word Code)     /* NOP = MOVE AUX,AUX */
175
{
176
  UNUSED(Code);
177
 
178
  if (ChkArgCnt(0, 0))
179
  {
180
    WAsmCode[0] = 0x0000;
181
    CodeLen = 1;
182
  }
183
}
184
 
185
static void DecodeHALT(Word Code)      /* HALT = JMP * */
186
{
187
  UNUSED(Code);
188
 
189
  if (ChkArgCnt(0, 0))
190
  {
191
    WAsmCode[0] = 0xe000 | (EProgCounter() & 0x1fff);
192
    CodeLen = 1;
193
  }
194
}
195
 
196
static void DecodeXML_XMR(Word Code)
197
{
198
  if (ChkArgCnt(1, 1)
199
   && ChkMinCPU(CPU8x305))
200
  {
201
    Boolean OK;
202
    Word Adr = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
203
    if (OK)
204
    {
205
      WAsmCode[0] = Code | (Adr & 0xff);
206
      CodeLen = 1;
207
    }
208
  }
209
}
210
 
211
static void DecodeSEL(Word Code)
212
{
213
  UNUSED(Code);
214
 
215
  if (ChkArgCnt(1, 1))
216
  {
217
    Boolean OK;
218
    LongInt Op = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
219
    if (OK)
220
    {
221
      WAsmCode[0] = 0xc700 | ((Op & 0x10) << 7) | ((Op >> 16) & 0xff);
222
      CodeLen = 1;
223
    }
224
  }
225
}
226
 
227
static void DecodeXMIT(Word Code)
228
{
229
  Word SrcReg, Rot;
230
  ShortInt SrcLen;
231
  Boolean OK;
232
  tSymbolFlags Flags;
233
  LongInt Adr;
234
 
235
  UNUSED(Code);
236
 
237
  if (ChkArgCnt(2, 3)
238
   && DecodeReg(&ArgStr[2], &SrcReg, &SrcLen))
239
  {
240
    if (SrcReg < 16)
241
    {
242
      if (ChkArgCnt(2, 2))
243
      {
244
        Adr = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
245
        if (OK)
246
        {
247
          WAsmCode[0] = 0xc000 | (SrcReg << 8) | (Adr & 0xff);
248
          CodeLen = 1;
249
        }
250
      }
251
    }
252
    else
253
    {
254
      if (ArgCnt == 2)
255
      {
256
        Rot = 0xffff; OK = True; Flags = eSymbolFlag_None;
257
      }
258
      else
259
        OK = GetLen(&ArgStr[3], &Rot, &Flags);
260
      if (OK)
261
      {
262
        if (Rot == 0xffff)
263
          Rot = (SrcLen == -1) ? 0 : SrcLen;
264
        if ((SrcLen != -1) && (Rot != SrcLen)) WrError(ErrNum_ConfOpSizes);
265
        else
266
        {
267
          Adr = EvalStrIntExpression(&ArgStr[1], Int5, &OK);
268
          if (OK)
269
          {
270
            WAsmCode[0] = 0xc000 | (SrcReg << 8) | (Rot << 5) | (Adr & 0x1f);
271
            CodeLen = 1;
272
          }
273
        }
274
      }
275
    }
276
  }
277
}
278
 
279
static void DecodeAri(Word Code)
280
{
281
  Word SrcReg, DestReg, Rot;
282
  ShortInt SrcLen, DestLen;
283
  char *p;
284
  Boolean OK;
285
 
286
  if (ChkArgCnt(2, 3)
287
   && DecodeReg(&ArgStr[ArgCnt], &DestReg, &DestLen))
288
  {
289
    if (DestReg < 16)         /* Ziel Register */
290
    {
291
      if (ArgCnt == 2)        /* wenn nur zwei Operanden und Ziel Register... */
292
      {
293
        p = HasDisp(ArgStr[1].str.p_str); /* kann eine Rotation dabei sein */
294
        if (p)
295
        {                 /* jau! */
296
          tStrComp RegArg, RotArg;
297
 
298
          StrCompSplitRef(&RegArg, &RotArg, &ArgStr[1], p);
299
          StrCompShorten(&RotArg, 1);
300
          Rot = EvalStrIntExpression(&RotArg, UInt3, &OK);
301
          if (OK)
302
          {
303
            if (DecodeReg(&RegArg, &SrcReg, &SrcLen))
304
            {
305
              if (SrcReg >= 16) WrStrErrorPos(ErrNum_InvReg, &RegArg);
306
              else
307
              {
308
                WAsmCode[0] = (Code << 13) | (SrcReg << 8) | (Rot << 5) | DestReg;
309
                CodeLen = 1;
310
              }
311
            }
312
          }
313
        }
314
        else                   /* noi! */
315
        {
316
          if (DecodeReg(&ArgStr[1], &SrcReg, &SrcLen))
317
          {
318
            WAsmCode[0] = (Code << 13) | (SrcReg << 8) | DestReg;
319
            if ((SrcReg >= 16) && (SrcLen != -1)) WAsmCode[0] += SrcLen << 5;
320
            CodeLen = 1;
321
          }
322
        }
323
      }
324
      else                     /* 3 Operanden --> Quelle ist I/O */
325
      {
326
        tSymbolFlags Flags;
327
 
328
        if (GetLen(&ArgStr[2], &Rot, &Flags))
329
         if (DecodeReg(&ArgStr[1], &SrcReg, &SrcLen))
330
         {
331
           if (SrcReg < 16) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
332
           else if ((SrcLen != -1) && (SrcLen != Rot)) WrError(ErrNum_ConfOpSizes);
333
           else
334
           {
335
             WAsmCode[0] = (Code << 13) | (SrcReg << 8) | (Rot << 5) | DestReg;
336
             CodeLen = 1;
337
           }
338
         }
339
      }
340
    }
341
    else                       /* Ziel I/O */
342
    {
343
      if (ArgCnt == 2)           /* 2 Argumente: Laenge=Laenge Ziel */
344
      {
345
        Rot = DestLen; OK = True;
346
      }
347
      else                     /* 3 Argumente: Laenge=Laenge Ziel+Angabe */
348
      {
349
        tSymbolFlags Flags;
350
 
351
        OK = GetLen(&ArgStr[2], &Rot, &Flags);
352
        if (OK)
353
        {
354
          if (mFirstPassUnknown(Flags)) Rot = DestLen;
355
          if (DestLen == -1) DestLen = Rot;
356
          OK = Rot == DestLen;
357
          if (!OK) WrError(ErrNum_ConfOpSizes);
358
        }
359
      }
360
      if (OK)
361
       if (DecodeReg(&ArgStr[1], &SrcReg, &SrcLen))
362
       {
363
         if (Rot == 0xffff)
364
           Rot = ((SrcLen == -1)) ? 0 : SrcLen;
365
         if ((DestReg >= 16) && (SrcLen != -1) && (SrcLen != Rot)) WrError(ErrNum_ConfOpSizes);
366
         else
367
         {
368
           WAsmCode[0] = (Code << 13) | (SrcReg << 8) | (Rot << 5) | DestReg;
369
           CodeLen = 1;
370
         }
371
       }
372
    }
373
  }
374
}
375
 
376
static void DecodeXEC(Word Code)
377
{
378
  char *p;
379
  Word SrcReg, Rot;
380
  ShortInt SrcLen;
381
  Boolean OK;
382
 
383
  UNUSED(Code);
384
 
385
  if (ChkArgCnt(1, 2))
386
  {
387
    p = HasDisp(ArgStr[1].str.p_str);
388
    if (!p) WrError(ErrNum_InvAddrMode);
389
    else
390
    {
391
      tStrComp DispArg, RegArg;
392
 
393
      StrCompSplitRef(&DispArg, &RegArg, &ArgStr[1], p);
394
      StrCompShorten(&RegArg, 1);
395
      if (DecodeReg(&RegArg, &SrcReg, &SrcLen))
396
      {
397
        if (SrcReg < 16)
398
        {
399
          if (ChkArgCnt(1, 1))
400
          {
401
            WAsmCode[0] = EvalStrIntExpression(&DispArg, UInt8, &OK);
402
            if (OK)
403
            {
404
              WAsmCode[0] |= 0x8000 | (SrcReg << 8);
405
              CodeLen = 1;
406
            }
407
          }
408
        }
409
        else
410
        {
411
          tSymbolFlags Flags;
412
 
413
          if (ArgCnt == 1)
414
          {
415
            Rot = 0xffff; OK = True; Flags = eSymbolFlag_None;
416
          }
417
          else OK = GetLen(&ArgStr[2], &Rot, &Flags);
418
          if (OK)
419
          {
420
            if (Rot == 0xffff)
421
             Rot = (SrcLen == -1) ? 0 : SrcLen;
422
            if ((SrcLen != -1) && (Rot != SrcLen)) WrError(ErrNum_ConfOpSizes);
423
            else
424
            {
425
              WAsmCode[0] = EvalStrIntExpression(&DispArg, UInt5, &OK);
426
              if (OK)
427
              {
428
                WAsmCode[0] |= 0x8000 | (SrcReg << 8) | (Rot << 5);
429
                CodeLen = 1;
430
              }
431
            }
432
          }
433
        }
434
      }
435
    }
436
  }
437
}
438
 
439
static void DecodeJMP(Word Code)
440
{
441
  UNUSED(Code);
442
 
443
  if (ChkArgCnt(1, 1))
444
  {
445
    Boolean OK;
446
 
447
    WAsmCode[0] = EvalStrIntExpression(&ArgStr[1], UInt13, &OK);
448
    if (OK)
449
    {
450
      WAsmCode[0] |= 0xe000;
451
      CodeLen = 1;
452
    }
453
  }
454
  return;
455
}
456
 
457
static void DecodeNZT(Word Code)
458
{
459
  Word SrcReg, Adr, Rot;
460
  ShortInt SrcLen;
461
  Boolean OK;
462
  tSymbolFlags Flags;
463
 
464
  UNUSED(Code);
465
 
466
  if (ChkArgCnt(2, 3)
467
   && DecodeReg(&ArgStr[1], &SrcReg, &SrcLen))
468
  {
469
    if (SrcReg < 16)
470
    {
471
      if (ChkArgCnt(2, 2))
472
      {
473
        Adr = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt13, &OK, &Flags);
474
        if (OK && ChkSamePage(Adr, EProgCounter(), 8, Flags))
475
        {
476
          WAsmCode[0] = 0xa000 | (SrcReg << 8) | (Adr & 0xff);
477
          CodeLen = 1;
478
        }
479
      }
480
    }
481
    else
482
    {
483
      if (ArgCnt == 2)
484
      {
485
        Rot = 0xffff; OK = True; Flags = eSymbolFlag_None;
486
      }
487
      else OK = GetLen(&ArgStr[2], &Rot, &Flags);
488
      if (OK)
489
      {
490
        if (Rot == 0xffff)
491
         Rot = (SrcLen == -1) ? 0 : SrcLen;
492
        if ((SrcLen != -1) && (Rot != SrcLen)) WrError(ErrNum_ConfOpSizes);
493
        else
494
        {
495
          Adr = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], UInt13, &OK, &Flags);
496
          if (OK && ChkSamePage(Adr, EProgCounter(), 5, Flags))
497
          {
498
            WAsmCode[0] = 0xa000 | (SrcReg << 8) | (Rot << 5) | (Adr & 0x1f);
499
            CodeLen = 1;
500
          }
501
        }
502
      }
503
    }
504
  }
505
}
506
 
507
/* Symbol: 00AA0ORL */
508
 
509
static void DecodeLIV_RIV(Word Code)
510
{
511
  LongInt Adr, Ofs;
512
  Word Len;
513
  Boolean OK;
514
  tSymbolFlags Flags;
515
 
516
  if (ChkArgCnt(3, 3))
517
  {
518
    Adr = EvalStrIntExpression(&ArgStr[1], UInt8, &OK);
519
    if (OK)
520
    {
521
      Ofs = EvalStrIntExpression(&ArgStr[2], UInt3, &OK);
522
      if (OK)
523
       if (GetLen(&ArgStr[3], &Len, &Flags))
524
       {
525
         PushLocHandle(-1);
526
         EnterIntSymbol(&LabPart, Code | (Adr << 16) | (Ofs << 8) | (Len & 7), SegNone, False);
527
         PopLocHandle();
528
       }
529
    }
530
  }
531
}
532
 
533
/*-------------------------------------------------------------------------*/
534
 
535
static void AddAri(const char *NName, Word NCode)
536
{
537
  AddInstTable(InstTable, NName, NCode, DecodeAri);
538
}
539
 
540
static void InitFields(void)
541
{
542
  InstTable = CreateInstTable(103);
543
 
544
  add_null_pseudo(InstTable);
545
 
546
  AddInstTable(InstTable, "NOP", 0, DecodeNOP);
547
  AddInstTable(InstTable, "HALT", 0, DecodeHALT);
548
  AddInstTable(InstTable, "XML", 0xca00, DecodeXML_XMR);
549
  AddInstTable(InstTable, "XMR", 0xcb00, DecodeXML_XMR);
550
  AddInstTable(InstTable, "SEL", 0, DecodeSEL);
551
  AddInstTable(InstTable, "XMIT", 0, DecodeXMIT);
552
  AddInstTable(InstTable, "XEC", 0, DecodeXEC);
553
  AddInstTable(InstTable, "JMP", 0, DecodeJMP);
554
  AddInstTable(InstTable, "NZT", 0, DecodeNZT);
555
  AddInstTable(InstTable, "LIV", 0, DecodeLIV_RIV);
556
  AddInstTable(InstTable, "RIV", 0x10, DecodeLIV_RIV);
557
 
558
  AddAri("MOVE", 0); AddAri("ADD", 1); AddAri("AND", 2); AddAri("XOR", 3);
559
}
560
 
561
static void DeinitFields(void)
562
{
563
  DestroyInstTable(InstTable);
564
}
565
 
566
/*-------------------------------------------------------------------------*/
567
 
568
/*-------------------------------------------------------------------------*/
569
 
570
static void MakeCode_8x30X(void)
571
{
572
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
573
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
574
}
575
 
576
static Boolean IsDef_8x30X(void)
577
{
578
  return (Memo("LIV") || Memo("RIV"));
579
}
580
 
581
static void SwitchFrom_8x30X(void)
582
{
583
  DeinitFields();
584
}
585
 
586
static void SwitchTo_8x30X(void)
587
{
588
  TurnWords = False;
589
  SetIntConstMode(eIntConstModeMoto);
590
 
591
  PCSymbol = "*";
592
  HeaderID = 0x3a;
593
  NOPCode = 0x0000;
594
  DivideChars = ",";
595
  HasAttrs = False;
596
 
597
  ValidSegs = 1 << SegCode;
598
  Grans[SegCode] = 2;
599
  ListGrans[SegCode] = 2;
600
  SegInits[SegCode] = 0;
601
  SegLimits[SegCode] = 0x1fff;
602
 
603
  MakeCode = MakeCode_8x30X;
604
  IsDef = IsDef_8x30X;
605
  SwitchFrom = SwitchFrom_8x30X;
606
  InitFields();
607
}
608
 
609
void code8x30x_init(void)
610
{
611
  CPU8x300 = AddCPU("8x300", SwitchTo_8x30X);
612
  CPU8x305 = AddCPU("8x305", SwitchTo_8x30X);
613
}