Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* codest6.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS-Portierung                                                             */
6
/*                                                                           */
7
/* Codegenerator ST6-Familie                                                 */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
#include "stdinc.h"
12
#include <string.h>
13
 
14
#include "strutil.h"
15
#include "bpemu.h"
16
#include "asmdef.h"
17
#include "asmsub.h"
18
#include "asmpars.h"
19
#include "asmitree.h"
20
#include "asmstructs.h"
21
#include "codepseudo.h"
22
#include "motpseudo.h"
23
#include "codevars.h"
24
#include "errmsg.h"
25
#include "intformat.h"
26
 
27
#include "codest6.h"
28
 
29
#define ModNone (-1)
30
#define ModAcc 0
31
#define MModAcc (1 << ModAcc)
32
#define ModDir 1
33
#define MModDir (1 << ModDir)
34
#define ModInd 2
35
#define MModInd (1 << ModInd)
36
 
37
 
38
static Byte AdrMode;
39
static ShortInt AdrType;
40
static Byte AdrVal;
41
 
42
static LongInt WinAssume, PRPRVal;
43
 
44
typedef struct
45
{
46
  const char *pName;
47
  IntType CodeAdrInt;
48
} tCPUProps;
49
 
50
#define ASSUMEST6Count 2
51
static ASSUMERec ASSUMEST6s[ASSUMEST6Count] =
52
{
53
  { "PRPR",    &PRPRVal  , 0, 0x03, 0x04, NULL },
54
  { "ROMBASE", &WinAssume, 0, 0x3f, 0x40, NULL },
55
};
56
static const tCPUProps *pCurrCPUProps;
57
 
58
/*---------------------------------------------------------------------------------*/
59
/* Helper Functions */
60
 
61
static void ResetAdr(void)
62
{
63
  AdrType = ModNone; AdrCnt = 0;
64
}
65
 
66
static void DecodeAdr(const tStrComp *pArg, Byte Mask)
67
{
68
  Integer AdrInt;
69
  tEvalResult EvalResult;
70
 
71
  ResetAdr();
72
 
73
  if ((!as_strcasecmp(pArg->str.p_str, "A")) && (Mask & MModAcc))
74
  {
75
    AdrType = ModAcc;
76
    goto chk;
77
  }
78
 
79
  if (!as_strcasecmp(pArg->str.p_str, "(X)"))
80
  {
81
    AdrType = ModInd;
82
    AdrMode = 0;
83
    goto chk;
84
  }
85
 
86
  if (!as_strcasecmp(pArg->str.p_str, "(Y)"))
87
  {
88
    AdrType = ModInd;
89
    AdrMode = 1;
90
    goto chk;
91
  }
92
 
93
  AdrInt = EvalStrIntExpressionWithResult(pArg, UInt16, &EvalResult);
94
  if (EvalResult.OK)
95
  {
96
    if (EvalResult.AddrSpaceMask & (1 << SegCode))
97
    {
98
      AdrType = ModDir;
99
      AdrVal = (AdrInt & 0x3f) + 0x40;
100
      AdrCnt=1;
101
      if (!mFirstPassUnknown(EvalResult.Flags))
102
        if (WinAssume != (AdrInt >> 6)) WrError(ErrNum_InAccPage);
103
    }
104
    else
105
    {
106
      if (mFirstPassUnknown(EvalResult.Flags)) AdrInt = Lo(AdrInt);
107
      if (AdrInt > 0xff) WrError(ErrNum_OverRange);
108
      else
109
      {
110
        AdrType = ModDir;
111
        AdrVal = AdrInt;
112
        goto chk;
113
      }
114
    }
115
  }
116
 
117
chk:
118
  if ((AdrType != ModNone) && (!(Mask & (1 << AdrType))))
119
  {
120
    ResetAdr(); WrError(ErrNum_InvAddrMode);
121
  }
122
}
123
 
124
static Boolean IsReg(Byte Adr)
125
{
126
  return ((Adr & 0xfc) == 0x80);
127
}
128
 
129
static Byte MirrBit(Byte inp)
130
{
131
  return (((inp & 1) << 2) + (inp & 2) + ((inp & 4) >> 2));
132
}
133
 
134
/*--------------------------------------------------------------------------*/
135
/* Bit Symbol Handling */
136
 
137
/*
138
 * Compact representation of bits in symbol table:
139
 * bits 0..2: bit position
140
 * bits 3...10: register address in DATA/SFR space
141
 */
142
 
143
/*!------------------------------------------------------------------------
144
 * \fn     EvalBitPosition(const tStrComp *pArg, Boolean *pOK)
145
 * \brief  evaluate bit position
146
 * \param  bit position argument (with or without #)
147
 * \param  pOK parsing OK?
148
 * \return numeric bit position
149
 * ------------------------------------------------------------------------ */
150
 
151
static LongWord EvalBitPosition(const tStrComp *pArg, Boolean *pOK)
152
{
153
  return EvalStrIntExpressionOffs(pArg, !!(*pArg->str.p_str == '#'), UInt3, pOK);
154
}
155
 
156
/*!------------------------------------------------------------------------
157
 * \fn     AssembleBitSymbol(Byte BitPos, Word Address)
158
 * \brief  build the compact internal representation of a bit symbol
159
 * \param  BitPos bit position in word
160
 * \param  Address register address
161
 * \return compact representation
162
 * ------------------------------------------------------------------------ */
163
 
164
static LongWord AssembleBitSymbol(Byte BitPos, Word Address)
165
{
166
  return (BitPos & 7)
167
       | (((LongWord)Address & 0xff) << 3);
168
}
169
 
170
/*!------------------------------------------------------------------------
171
 * \fn     DecodeBitArg2(LongWord *pResult, const tStrComp *pRegArg, const tStrComp *pBitArg)
172
 * \brief  encode a bit symbol, address & bit position separated
173
 * \param  pResult resulting encoded bit
174
 * \param  pRegArg register argument
175
 * \param  pBitArg bit argument
176
 * \return True if success
177
 * ------------------------------------------------------------------------ */
178
 
179
static Boolean DecodeBitArg2(LongWord *pResult, const tStrComp *pRegArg, const tStrComp *pBitArg)
180
{
181
  Boolean OK;
182
  LongWord Addr;
183
  Byte BitPos;
184
 
185
  BitPos = EvalBitPosition(pBitArg, &OK);
186
  if (!OK)
187
    return False;
188
 
189
  Addr = EvalStrIntExpression(pRegArg, UInt8, &OK);
190
  if (!OK)
191
    return False;
192
 
193
  *pResult = AssembleBitSymbol(BitPos, Addr);
194
 
195
  return True;
196
}
197
 
198
/*!------------------------------------------------------------------------
199
 * \fn     DecodeBitArg(LongWord *pResult, int Start, int Stop)
200
 * \brief  encode a bit symbol from instruction argument(s)
201
 * \param  pResult resulting encoded bit
202
 * \param  Start first argument
203
 * \param  Stop last argument
204
 * \return True if success
205
 * ------------------------------------------------------------------------ */
206
 
207
static Boolean DecodeBitArg(LongWord *pResult, int Start, int Stop)
208
{
209
  *pResult = 0;
210
 
211
  /* Just one argument -> parse as bit argument */
212
 
213
  if (Start == Stop)
214
  {
215
    tEvalResult EvalResult;
216
 
217
    *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], UInt11, &EvalResult);
218
    if (EvalResult.OK)
219
      ChkSpace(SegBData, EvalResult.AddrSpaceMask);
220
    return EvalResult.OK;
221
  }
222
 
223
  /* register & bit position are given as separate arguments */
224
 
225
  else if (Stop == Start + 1)
226
    return DecodeBitArg2(pResult, &ArgStr[Stop], &ArgStr[Start]);
227
 
228
  /* other # of arguments not allowed */
229
 
230
  else
231
  {
232
    WrError(ErrNum_WrongArgCnt);
233
    return False;
234
  }
235
}
236
 
237
/*!------------------------------------------------------------------------
238
 * \fn     DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos)
239
 * \brief  transform compact represenation of bit (field) symbol into components
240
 * \param  BitSymbol compact storage
241
 * \param  pAddress (I/O) register address
242
 * \param  pBitPos (start) bit position
243
 * \return constant True
244
 * ------------------------------------------------------------------------ */
245
 
246
static Boolean DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos)
247
{
248
  *pAddress = (BitSymbol >> 3) & 0xffff;
249
  *pBitPos = BitSymbol & 7;
250
  return True;
251
}
252
 
253
/*!------------------------------------------------------------------------
254
 * \fn     DissectBit_ST6(char *pDest, size_t DestSize, LargeWord Inp)
255
 * \brief  dissect compact storage of bit (field) into readable form for listing
256
 * \param  pDest destination for ASCII representation
257
 * \param  DestSize destination buffer size
258
 * \param  Inp compact storage
259
 * ------------------------------------------------------------------------ */
260
 
261
static void DissectBit_ST6(char *pDest, size_t DestSize, LargeWord Inp)
262
{
263
  Byte BitPos;
264
  Word Address;
265
 
266
  DissectBitSymbol(Inp, &Address, &BitPos);
267
 
268
  as_snprintf(pDest, DestSize, "%02.*u%s.%u",
269
              ListRadixBase, (unsigned)Address, GetIntConstIntelSuffix(ListRadixBase),
270
              (unsigned)BitPos);
271
}
272
 
273
/*!------------------------------------------------------------------------
274
 * \fn     ExpandST6Bit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
275
 * \brief  expands bit definition when a structure is instantiated
276
 * \param  pVarName desired symbol name
277
 * \param  pStructElem element definition
278
 * \param  Base base address of instantiated structure
279
 * ------------------------------------------------------------------------ */
280
 
281
static void ExpandST6Bit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
282
{
283
  LongWord Address = Base + pStructElem->Offset;
284
 
285
  if (pInnermostNamedStruct)
286
  {
287
    PStructElem pElem = CloneStructElem(pVarName, pStructElem);
288
 
289
    if (!pElem)
290
      return;
291
    pElem->Offset = Address;
292
    AddStructElem(pInnermostNamedStruct->StructRec, pElem);
293
  }
294
  else
295
  {
296
    if (!ChkRange(Address, 0, 0xff)
297
     || !ChkRange(pStructElem->BitPos, 0, 7))
298
      return;
299
 
300
    PushLocHandle(-1);
301
    EnterIntSymbol(pVarName, AssembleBitSymbol(pStructElem->BitPos, Address), SegBData, False);
302
    PopLocHandle();
303
    /* TODO: MakeUseList? */
304
  }
305
}
306
 
307
/*---------------------------------------------------------------------------------*/
308
/* Instruction Decoders */
309
 
310
static void DecodeFixed(Word Code)
311
{
312
  if (ChkArgCnt(0, 0))
313
  {
314
    CodeLen = 1;
315
    BAsmCode[0] = Code;
316
  }
317
}
318
 
319
static void DecodeLD(Word Code)
320
{
321
  UNUSED(Code);
322
 
323
  if (ChkArgCnt(2, 2))
324
  {
325
    DecodeAdr(&ArgStr[1], MModAcc | MModDir | MModInd);
326
    switch (AdrType)
327
    {
328
      case ModAcc:
329
        DecodeAdr(&ArgStr[2], MModDir | MModInd);
330
        switch (AdrType)
331
        {
332
          case ModDir:
333
            if (IsReg(AdrVal))
334
            {
335
              CodeLen = 1;
336
              BAsmCode[0] = 0x35 + ((AdrVal & 3) << 6);
337
            }
338
            else
339
            {
340
              CodeLen = 2;
341
              BAsmCode[0] = 0x1f;
342
              BAsmCode[1] = AdrVal;
343
            }
344
            break;
345
          case ModInd:
346
            CodeLen = 1;
347
            BAsmCode[0] = 0x07 + (AdrMode << 3);
348
            break;
349
        }
350
        break;
351
      case ModDir:
352
        DecodeAdr(&ArgStr[2], MModAcc);
353
        if (AdrType != ModNone)
354
        {
355
          if (IsReg(AdrVal))
356
          {
357
            CodeLen = 1;
358
            BAsmCode[0] = 0x3d + ((AdrVal & 3) << 6);
359
          }
360
          else
361
          {
362
            CodeLen = 2;
363
            BAsmCode[0] = 0x9f;
364
            BAsmCode[1] = AdrVal;
365
          }
366
        }
367
        break;
368
      case ModInd:
369
        DecodeAdr(&ArgStr[2], MModAcc);
370
        if (AdrType != ModNone)
371
        {
372
          CodeLen = 1;
373
          BAsmCode[0] = 0x87 + (AdrMode << 3);
374
        }
375
        break;
376
    }
377
  }
378
}
379
 
380
static void DecodeLDI(Word Code)
381
{
382
  UNUSED(Code);
383
 
384
  if (ChkArgCnt(2, 2))
385
  {
386
    Boolean OK;
387
 
388
    Integer AdrInt = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
389
    if (OK)
390
    {
391
      DecodeAdr(&ArgStr[1], MModAcc | MModDir);
392
      switch (AdrType)
393
      {
394
        case ModAcc:
395
          CodeLen = 2;
396
          BAsmCode[0] = 0x17;
397
          BAsmCode[1] = Lo(AdrInt);
398
          break;
399
        case ModDir:
400
          CodeLen = 3;
401
          BAsmCode[0] = 0x0d;
402
          BAsmCode[1] = AdrVal;
403
          BAsmCode[2] = Lo(AdrInt);
404
          break;
405
      }
406
    }
407
  }
408
}
409
 
410
static void DecodeRel(Word Code)
411
{
412
  if (ChkArgCnt(1, 1))
413
  {
414
    Boolean OK;
415
    tSymbolFlags Flags;
416
    Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &OK, &Flags) - (EProgCounter() + 1);
417
 
418
    if (OK)
419
    {
420
      if (!mSymbolQuestionable(Flags) && ((AdrInt < -16) || (AdrInt > 15))) WrError(ErrNum_JmpDistTooBig);
421
      else
422
      {
423
        CodeLen = 1;
424
        BAsmCode[0] = Code + ((AdrInt << 3) & 0xf8);
425
      }
426
    }
427
  }
428
}
429
 
430
static void DecodeJP_CALL(Word Code)
431
{
432
  if (ChkArgCnt(1, 1))
433
  {
434
    Boolean OK;
435
    Word AdrInt;
436
    tSymbolFlags Flags;
437
 
438
    AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], pCurrCPUProps->CodeAdrInt, &OK, &Flags);
439
    if (OK)
440
    {
441
      Word DestPage = AdrInt >> 11;
442
 
443
      /* CPU program space's page 1 (800h...0fffh) always accesses ROM space page 1.
444
         CPU program space's page 0 (000h...7ffh) accesses 2K ROM space pages as defined by PRPR. */
445
 
446
      if (!mFirstPassUnknown(Flags) && (DestPage != 1))
447
      {
448
        Word SrcPage = EProgCounter() >> 11;
449
 
450
        /* Jump from page 1 is allowed to page defined by PRPR.
451
           Jump from any other page is only allowed back to page 1 or within same page. */
452
 
453
        if (DestPage != ((SrcPage == 1) ? PRPRVal : SrcPage)) WrError(ErrNum_InAccPage);
454
 
455
        AdrInt &= 0x7ff;
456
      }
457
      CodeLen = 2;
458
      BAsmCode[0] = Code + ((AdrInt & 0x00f) << 4);
459
      BAsmCode[1] = AdrInt >> 4;
460
    }
461
  }
462
}
463
 
464
static void DecodeALU(Word Code)
465
{
466
  if (ChkArgCnt(2, 2))
467
  {
468
    DecodeAdr(&ArgStr[1], MModAcc);
469
    if (AdrType != ModNone)
470
    {
471
      DecodeAdr(&ArgStr[2], MModDir | MModInd);
472
      switch (AdrType)
473
      {
474
        case ModDir:
475
          CodeLen = 2;
476
          BAsmCode[0] = Code + 0x18;
477
          BAsmCode[1] = AdrVal;
478
          break;
479
        case ModInd:
480
          CodeLen = 1;
481
          BAsmCode[0] = Code + (AdrMode << 3);
482
          break;
483
      }
484
    }
485
  }
486
}
487
 
488
static void DecodeALUImm(Word Code)
489
{
490
  if (ChkArgCnt(2, 2))
491
  {
492
    DecodeAdr(&ArgStr[1], MModAcc);
493
    if (AdrType != ModNone)
494
    {
495
      Boolean OK;
496
      BAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
497
      if (OK)
498
      {
499
        CodeLen = 2;
500
        BAsmCode[0] = Code + 0x10;
501
      }
502
    }
503
  }
504
}
505
 
506
static void DecodeCLR(Word Code)
507
{
508
  UNUSED(Code);
509
 
510
  if (ChkArgCnt(1, 1))
511
  {
512
    DecodeAdr(&ArgStr[1], MModAcc | MModDir);
513
    switch (AdrType)
514
    {
515
      case ModAcc:
516
        CodeLen = 2;
517
        BAsmCode[0] = 0xdf;
518
        BAsmCode[1] = 0xff;
519
        break;
520
      case ModDir:
521
        CodeLen = 3;
522
        BAsmCode[0] = 0x0d;
523
        BAsmCode[1] = AdrVal;
524
        BAsmCode[2] = 0;
525
        break;
526
    }
527
  }
528
}
529
 
530
static void DecodeAcc(Word Code)
531
{
532
  if (ChkArgCnt(1, 1))
533
  {
534
    DecodeAdr(&ArgStr[1], MModAcc);
535
    if (AdrType != ModNone)
536
    {
537
      BAsmCode[CodeLen++] = Lo(Code);
538
      if (Hi(Code))
539
        BAsmCode[CodeLen++] = Hi(Code);
540
    }
541
  }
542
}
543
 
544
static void DecodeINC_DEC(Word Code)
545
{
546
  if (ChkArgCnt(1, 1))
547
  {
548
    DecodeAdr(&ArgStr[1], MModDir | MModInd);
549
    switch (AdrType)
550
    {
551
      case ModDir:
552
        if (IsReg(AdrVal))
553
        {
554
          CodeLen = 1;
555
          BAsmCode[0] = Code + 0x15 + ((AdrVal & 3) << 6);
556
        }
557
        else
558
        {
559
          CodeLen = 2;
560
          BAsmCode[0] = 0x7f + (Code << 4);
561
          BAsmCode[1] = AdrVal;
562
        }
563
        break;
564
      case ModInd:
565
        CodeLen = 1;
566
        BAsmCode[0] = 0x67 + (AdrMode << 3) + (Code << 4);
567
        break;
568
    }
569
  }
570
}
571
 
572
static void DecodeSET_RES(Word Code)
573
{
574
  LongWord PackedAddr;
575
 
576
  if (ChkArgCnt(1, 2)
577
   && DecodeBitArg(&PackedAddr, 1, ArgCnt))
578
  {
579
    Word RegAddr;
580
    Byte BitPos;
581
 
582
    DissectBitSymbol(PackedAddr, &RegAddr, &BitPos);
583
    BAsmCode[0] = (MirrBit(BitPos) << 5) | Code;
584
    BAsmCode[1] = RegAddr;
585
    CodeLen = 2;
586
  }
587
}
588
 
589
static void DecodeJRR_JRS(Word Code)
590
{
591
  LongWord PackedAddr;
592
 
593
  if (ChkArgCnt(2, 3)
594
   && DecodeBitArg(&PackedAddr, 1, ArgCnt - 1))
595
  {
596
    Word RegAddr;
597
    Byte BitPos;
598
    Boolean OK;
599
    Integer AdrInt;
600
    tSymbolFlags Flags;
601
 
602
    DissectBitSymbol(PackedAddr, &RegAddr, &BitPos);
603
    BAsmCode[0] = (MirrBit(BitPos) << 5) | Code;
604
    BAsmCode[1] = RegAddr;
605
    AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], UInt16, &OK, &Flags) - (EProgCounter() + 3);
606
    if (OK)
607
    {
608
      if (!mSymbolQuestionable(Flags) && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
609
      else
610
      {
611
        CodeLen = 3;
612
        BAsmCode[2] = Lo(AdrInt);
613
      }
614
    }
615
  }
616
}
617
 
618
static void DecodeSFR(Word Code)
619
{
620
  UNUSED(Code);
621
  CodeEquate(SegData, 0, 0xff);
622
}
623
 
624
/*!------------------------------------------------------------------------
625
 * \fn     DecodeASCII_ASCIZ(Word IsZ)
626
 * \brief  handle ASCII/ASCIZ instructions
627
 * \param  IsZ 1 if it's ASCIZ
628
 * ------------------------------------------------------------------------ */
629
 
630
static void DecodeASCII_ASCIZ(Word IsZ)
631
{
632
  if (ChkArgCnt(1, ArgCntMax))
633
  {
634
    int l;
635
    Boolean OK = True;
636
    tStrComp *pArg;
637
    TempResult t;
638
 
639
    as_tempres_ini(&t);
640
    forallargs(pArg, OK)
641
    {
642
      EvalStrExpression(pArg, &t);
643
      switch (t.Typ)
644
      {
645
        case TempString:
646
        {
647
          if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pArg))
648
            OK = False;
649
          else
650
          {
651
            l = t.Contents.str.len;
652
            if (SetMaxCodeLen(CodeLen + l + IsZ))
653
            {
654
              WrStrErrorPos(ErrNum_CodeOverflow, pArg); OK = False;
655
            }
656
            else
657
            {
658
              memcpy(BAsmCode + CodeLen, t.Contents.str.p_str, l);
659
              CodeLen += l;
660
              if (IsZ)
661
                BAsmCode[CodeLen++] = 0;
662
            }
663
          }
664
          break;
665
        }
666
        case TempNone:
667
          OK = False;
668
          break;
669
        default:
670
          WrStrErrorPos(ErrNum_ExpectString, pArg);
671
          OK = False;
672
      }
673
    }
674
    as_tempres_free(&t);
675
    if (!OK)
676
      CodeLen = 0;
677
  }
678
}
679
 
680
/*!------------------------------------------------------------------------
681
 * \fn     DecodeBIT(Word Code)
682
 * \brief  decode BIT instruction
683
 * ------------------------------------------------------------------------ */
684
 
685
static void DecodeBIT(Word Code)
686
{
687
  LongWord BitSpec;
688
 
689
  UNUSED(Code);
690
 
691
  /* if in structure definition, add special element to structure */
692
 
693
  if (ActPC == StructSeg)
694
  {
695
    Boolean OK;
696
    Byte BitPos;
697
    PStructElem pElement;
698
 
699
    if (!ChkArgCnt(2, 2))
700
      return;
701
    BitPos = EvalBitPosition(&ArgStr[2], &OK);
702
    if (!OK)
703
      return;
704
    pElement = CreateStructElem(&LabPart);
705
    if (!pElement)
706
      return;
707
    pElement->pRefElemName = as_strdup(ArgStr[1].str.p_str);
708
    pElement->OpSize = eSymbolSize8Bit;
709
    pElement->BitPos = BitPos;
710
    pElement->ExpandFnc = ExpandST6Bit;
711
    AddStructElem(pInnermostNamedStruct->StructRec, pElement);
712
  }
713
  else
714
  {
715
    if (DecodeBitArg(&BitSpec, 1, ArgCnt))
716
    {
717
      *ListLine = '=';
718
      DissectBit_ST6(ListLine + 1, STRINGSIZE - 3, BitSpec);
719
      PushLocHandle(-1);
720
      EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
721
      PopLocHandle();
722
      /* TODO: MakeUseList? */
723
    }
724
  }
725
}
726
 
727
/*---------------------------------------------------------------------------------*/
728
/* code table handling */
729
 
730
static void AddFixed(const char *NName, Byte NCode)
731
{
732
  AddInstTable(InstTable, NName, NCode, DecodeFixed);
733
}
734
 
735
static void AddRel(const char *NName, Byte NCode)
736
{
737
  AddInstTable(InstTable, NName, NCode, DecodeRel);
738
}
739
 
740
static void AddALU(const char *NName, const char *NNameImm, Byte NCode)
741
{
742
  AddInstTable(InstTable, NName, NCode, DecodeALU);
743
  AddInstTable(InstTable, NNameImm, NCode, DecodeALUImm);
744
}
745
 
746
static void AddAcc(const char *NName, Word NCode)
747
{
748
  AddInstTable(InstTable, NName, NCode, DecodeAcc);
749
}
750
 
751
static void InitFields(void)
752
{
753
  InstTable = CreateInstTable(201);
754
 
755
  add_null_pseudo(InstTable);
756
 
757
  AddInstTable(InstTable, "LD", 0, DecodeLD);
758
  AddInstTable(InstTable, "LDI", 0, DecodeLDI);
759
  AddInstTable(InstTable, "JP", 0x09, DecodeJP_CALL);
760
  AddInstTable(InstTable, "CALL", 0x01, DecodeJP_CALL);
761
  AddInstTable(InstTable, "CLR", 0, DecodeCLR);
762
  AddInstTable(InstTable, "INC", 0, DecodeINC_DEC);
763
  AddInstTable(InstTable, "DEC", 8, DecodeINC_DEC);
764
  AddInstTable(InstTable, "SET", 0x1b, DecodeSET_RES);
765
  AddInstTable(InstTable, "RES", 0x0b, DecodeSET_RES);
766
  AddInstTable(InstTable, "JRR", 0x03, DecodeJRR_JRS);
767
  AddInstTable(InstTable, "JRS", 0x13, DecodeJRR_JRS);
768
  AddInstTable(InstTable, "SFR", 0, DecodeSFR);
769
  AddInstTable(InstTable, "ASCII", 0, DecodeASCII_ASCIZ);
770
  AddInstTable(InstTable, "ASCIZ", 1, DecodeASCII_ASCIZ);
771
  AddInstTable(InstTable, "BYTE", 0, DecodeMotoBYT);
772
  AddInstTable(InstTable, "WORD", e_moto_pseudo_flags_le, DecodeMotoADR);
773
  AddInstTable(InstTable, "BLOCK", e_moto_pseudo_flags_none, DecodeMotoDFS);
774
  AddInstTable(InstTable, "BIT", 0, DecodeBIT);
775
 
776
  AddFixed("NOP" , 0x04);
777
  AddFixed("RET" , 0xcd);
778
  AddFixed("RETI", 0x4d);
779
  AddFixed("STOP", 0x6d);
780
  AddFixed("WAIT", 0xed);
781
 
782
  AddRel("JRZ" , 0x04);
783
  AddRel("JRNZ", 0x00);
784
  AddRel("JRC" , 0x06);
785
  AddRel("JRNC", 0x02);
786
 
787
  AddALU("ADD" , "ADDI" , 0x47);
788
  AddALU("AND" , "ANDI" , 0xa7);
789
  AddALU("CP"  , "CPI"  , 0x27);
790
  AddALU("SUB" , "SUBI" , 0xc7);
791
 
792
  AddAcc("COM", 0x002d);
793
  AddAcc("RLC", 0x00ad);
794
  AddAcc("SLA", 0xff5f);
795
}
796
 
797
static void DeinitFields(void)
798
{
799
  DestroyInstTable(InstTable);
800
}
801
 
802
/*!------------------------------------------------------------------------
803
 * \fn     MakeCode_ST6(void)
804
 * \brief  entry point to decode machine instructions
805
 * ------------------------------------------------------------------------ */
806
 
807
static void MakeCode_ST6(void)
808
{
809
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
810
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
811
}
812
 
813
/*!------------------------------------------------------------------------
814
 * \fn     InitCode_ST6(void)
815
 * \brief  per-pass initializations for ST6
816
 * ------------------------------------------------------------------------ */
817
 
818
static void InitCode_ST6(void)
819
{
820
  WinAssume = 0x40;
821
  PRPRVal = 0;
822
}
823
 
824
/*!------------------------------------------------------------------------
825
 * \fn     IsDef_ST6(void)
826
 * \brief  does instruction consume label field?
827
 * \return true if to be consumed
828
 * ------------------------------------------------------------------------ */
829
 
830
static Boolean IsDef_ST6(void)
831
{
832
  return Memo("SFR") || Memo("BIT");
833
}
834
 
835
/*!------------------------------------------------------------------------
836
 * \fn     SwitchFrom_ST6(void)
837
 * \brief  cleanup after switching away from target
838
 * ------------------------------------------------------------------------ */
839
 
840
static void SwitchFrom_ST6(void)
841
{
842
  DeinitFields();
843
}
844
 
845
static Boolean TrueFnc(void)
846
{
847
  return True;
848
}
849
 
850
/*!------------------------------------------------------------------------
851
 * \fn     InternSymbol_ST6(char *pArg, TempResult *pErg)
852
 * \brief  check for built-in symbols
853
 * \param  pAsc ASCII repr. of symbol
854
 * \param  pErg result buffer
855
 * ------------------------------------------------------------------------ */
856
 
857
static void InternSymbol_ST6(char *pArg, TempResult *pErg)
858
{
859
  int z;
860
#define RegCnt 5
861
  static const char RegNames[RegCnt + 1][2] = {"A", "V", "W", "X", "Y"};
862
  static const Byte RegCodes[RegCnt + 1] = {0xff, 0x82, 0x83, 0x80, 0x81};
863
 
864
  for (z = 0; z < RegCnt; z++)
865
    if (!as_strcasecmp(pArg, RegNames[z]))
866
    {
867
      as_tempres_set_int(pErg, RegCodes[z]);
868
      pErg->AddrSpaceMask |= (1 << SegData);
869
    }
870
}
871
 
872
/*!------------------------------------------------------------------------
873
 * \fn     SwitchTo_ST6(void)
874
 * \brief  switch to target
875
 * ------------------------------------------------------------------------ */
876
 
877
static void SwitchTo_ST6(void *pUser)
878
{
879
  int ASSUMEOffset;
880
 
881
  pCurrCPUProps = (const tCPUProps*)pUser;
882
  TurnWords = False;
883
  SetIntConstMode(eIntConstModeIntel);
884
  SetIsOccupiedFnc = TrueFnc;
885
 
886
  PCSymbol = "PC"; HeaderID = 0x78; NOPCode = 0x04;
887
  DivideChars = ","; HasAttrs = False;
888
 
889
  ValidSegs = (1 << SegCode) | (1 << SegData);
890
  Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
891
  SegLimits[SegCode] = IntTypeDefs[pCurrCPUProps->CodeAdrInt].Max;
892
  Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 0;
893
  SegLimits[SegData] = 0xff;
894
 
895
  ASSUMEOffset = (SegLimits[SegCode] > 0xfff) ? 0 : 1;
896
  pASSUMERecs = ASSUMEST6s + ASSUMEOffset;
897
  ASSUMERecCnt = ASSUMEST6Count - ASSUMEOffset;
898
 
899
  MakeCode = MakeCode_ST6;
900
  IsDef = IsDef_ST6;
901
  SwitchFrom = SwitchFrom_ST6;
902
  DissectBit = DissectBit_ST6;
903
  InternSymbol = InternSymbol_ST6;
904
 
905
  InitFields();
906
}
907
 
908
/*!------------------------------------------------------------------------
909
 * \fn     codest6_init(void)
910
 * \brief  register ST6 target
911
 * ------------------------------------------------------------------------ */
912
 
913
static const tCPUProps CPUProps[] =
914
{
915
  { "ST6200", UInt12 },
916
  { "ST6201", UInt12 },
917
  { "ST6203", UInt12 },
918
  { "ST6208", UInt12 },
919
  { "ST6209", UInt12 },
920
  { "ST6210", UInt12 },
921
  { "ST6215", UInt12 },
922
  { "ST6218", UInt13 },
923
  { "ST6220", UInt12 },
924
  { "ST6225", UInt12 },
925
  { "ST6228", UInt13 },
926
  { "ST6230", UInt13 },
927
  { "ST6232", UInt13 },
928
  { "ST6235", UInt13 },
929
  { "ST6240", UInt13 },
930
  { "ST6242", UInt13 },
931
  { "ST6245", UInt12 },
932
  { "ST6246", UInt12 },
933
  { "ST6252", UInt12 },
934
  { "ST6253", UInt12 },
935
  { "ST6255", UInt12 },
936
  { "ST6260", UInt12 },
937
  { "ST6262", UInt12 },
938
  { "ST6263", UInt12 },
939
  { "ST6265", UInt12 },
940
  { "ST6280", UInt13 },
941
  { "ST6285", UInt13 },
942
  { NULL    , (IntType)0 },
943
};
944
 
945
void codest6_init(void)
946
{
947
  const tCPUProps *pProp;
948
 
949
  for (pProp = CPUProps; pProp->pName; pProp++)
950
    (void)AddCPUUser(pProp->pName, SwitchTo_ST6, (void*)pProp, NULL);
951
 
952
  AddInitPassProc(InitCode_ST6);
953
}